dns-heaven fixes macOS DNS stack by enabling the usage of the native DNS stack through /etc/resolv.conf.
Overview
Some programs like dig, nslookup and anything compiled with Go doesn't use macOS native name resolution stack. This makes some features like split DNS to not work with those programs.
This occurs because macOS native name resolution uses a set of rules that aren't compatible with resolv.conf. This includes:
Per interface DNS settings (scoped)
Per domain settings
In order to support programs that uses resolv.conf, macOS writes a file with only the primary name server and search domains that were configured either through DHCP or manually.
Installation
Just run:
curl -L https://git.io/fix-my-dns-plz | sudo bash
This script downloads the latest version and installs a LaunchAgent making sure that dns-heaven is always running.
If you want to do this manually, just download the latest release or compile dns-heaven yourself, and make sure it's always running.
How it works
dns-heaven exposes a DNS server that acts as a proxy mimicking native macOS behaviour. This is accomplished by periodically reading the output of scutil --dns and updating upstream rules and nameservers.
It also keeps /etc/resolv.conf pointing to 127.0.0.1 as the system will rewrite this file whenever your network settings changes (e.g.: changing wifi network).
Simple DNS server that uses a Tor SOCKS5 proxy to resolve names.
Tor-DNS: Simple DNS server that uses a Tor SOCKS5 proxy to resolve domains.
Introduction
N.B.: The functionality provided by this little application is basically identical to what you get by setting the "DNSPort [address:]port|auto [isolation flags]" parameter in your Tor configuration file. So consider this as a hands-on experiment for Tor proxy communication in Go.
In case you run a torified application (using the torsocks or tsocks helper scripts) and the application in question still uses (domain) names to address computers on the internet, the resulting DNS queries can jeopardize your anonymity if an adversary can monitor your DNS queries to the nameservers.
This little DNS server uses the built-in Tor SOCKS5 functionality to resolve names via the Tor network and therefore helps to ensure your anonymity in the above cases.
Currently the DNS server can only handle very simple queries (like resolving a name or reverse lookup of an IP address), but it can't return other records than those of type "A" (IPv4 addresses), so no "MX", "AAAA", "SOA", "NS" or "TXT" queries are answered at all. This is due to the limitations within the Tor proxy; whenever it is extended, the Tor-DNS service will make use of that new query types.
Prerequisites
This application assumes you have installed Tor on your local computer and that the local Tor relay is up and running as a SOCKS5 proxy.
DNSChef is a highly configurable DNS proxy for Penetration Testers and Malware Analysts. A DNS proxy (aka "Fake DNS") is a tool used for application network traffic analysis among other uses. For example, a DNS proxy can be used to fake requests for "badguy.com" to point to a local machine for termination or interception instead of a real host somewhere on the Internet.
There are several DNS Proxies out there. Most will simply point all DNS queries a single IP address or implement only rudimentary filtering. DNSChef was developed as part of a penetration test where there was a need for a more configurable system. As a result, DNSChef is cross-platform application capable of forging responses based on inclusive and exclusive domain lists, supporting multiple DNS record types, matching domains with wildcards, proxying true responses for nonmatching domains, defining external configuration files, IPv6 and many other features. You can find detailed explanation of each of the features and suggested uses below.
The use of DNS Proxy is recommended in situations where it is not possible to force an application to use some other proxy server directly. For example, some mobile applications completely ignore OS HTTP Proxy settings. In these cases, the use of a DNS proxy server such as DNSChef will allow you to trick that application into forwarding connections to the desired destination.
Version 0.3 introduces support for more DNS record types, DNSSEC, logging, more configurable remote nameservers, support for the updated dnslib library and several bug fixes.
Version 0.2 introduces IPv6 support, large number of new DNS record types, custom ports and other frequently requested features.
Table of Contents
Setting up a DNS Proxy
Installing DNSChef
Running DNSChef
Intercept all responses
Filtering domains
Reverse filtering
External definitions file
Advanced Filtering
Logging
Other configurations
Internal architecture
Setting up a DNS Proxy
Before you can start using DNSChef, you must configure your machine to use a DNS nameserver with the tool running on it. You have several options based on the operating system you are going to use:
Linux - Edit /etc/resolv.conf to include a line on the very top with your traffic analysis host (e.g add "nameserver 127.0.0.1" if you are running locally). Alternatively, you can add a DNS server address using tools such as Network Manager. Inside the Network Manager open IPv4 Settings, select Automatic (DHCP) addresses only or Manual from the Method drop down box and edit DNS Servers text box to include an IP address with DNSChef running.
Windows - Select Network Connections from the Control Panel. Next select one of the connections (e.g. "Local Area Connection"), right-click on it and select properties. From within a newly appearing dialog box, select Internet Protocol (TCP/IP) and click on properties. At last select Use the following DNS server addresses radio button and enter the IP address with DNSChef running. For example, if running locally enter 127.0.0.1.
OS X - Open System Preferences and click on the Network icon. Select the active interface and fill in the DNS Server field. If you are using Airport then you will have to click on Advanced... button and edit DNS servers from there. Alternatively, you can edit /etc/resolv.conf and add a fake nameserver to the very top there (e.g "nameserver 127.0.0.1").
iOS - Open Settings and select General. Next select on Wi-Fi and click on a blue arrow to the right of an active Access Point from the list. Edit DNS entry to point to the host with DNSChef running. Make sure you have disabled Cellular interface (if available).
Android - Open Settings and select Wireless and network. Click on Wi-Fi settings and select Advanced after pressing the Options button on the phone. Enable Use static IP checkbox and configure a custom DNS server.
If you do not have the ability to modify device's DNS settings manually, then you still have several options involving techniques such as ARP Spoofing, Rogue DHCP and other creative methods.
At last you need to configure a fake service where DNSChef will point all of the requests. For example, if you are trying to intercept web traffic, you must bring up either a separate web server running on port 80 or set up a web proxy (e.g. Burp) to intercept traffic. DNSChef will point queries to your proxy/server host with properly configured services.
Installing DNSChef
DNSChef requires dnslib and IPy python libraries. You can obtain their latest versions here:
DNSChef is a cross-platform application developed in Python which should run on most platforms which have a Python interpreter. You can use the supplied dnschef.exe executable to run it on Windows hosts without installing a Python interpreter. This guide will concentrate on Unix environments; however, all of the examples below were tested to work on Windows as well.
Let's get a taste of DNSChef with its most basic monitoring functionality. Execute the following command as root (required to start a server on port 53):
[*] DNSChef started on interface: 127.0.0.1 [*] Using the following nameservers: 8.8.8.8 [*] No parameters were specified. Running in full proxy mode
Without any parameters, DNSChef will run in full proxy mode. This means that all requests will simply be forwarded to an upstream DNS server (8.8.8.8 by default) and returned back to the quering host. For example, let's query an "A" record for a domain and observe results:
$ host -t A thesprawl.org thesprawl.org has address 108.59.3.64
DNSChef will print the following log line showing time, source IP address, type of record requested and most importantly which name was queried:
[23:54:03] 127.0.0.1: proxying the response of type 'A' for thesprawl.org
This mode is useful for simple application monitoring where you need to figure out which domains it uses for its communications.
DNSChef has full support for IPv6 which can be activated using -6 or --ipv6* flags. It works exactly as IPv4 mode with the exception that default listening interface is switched to ::1 and default DNS server is switched to 2001:4860:4860::8888. Here is a sample output:
[*] Using IPv6 mode. [*] DNSChef started on interface: ::1 [*] Using the following nameservers: 2001:4860:4860::8888 [*] No parameters were specified. Running in full proxy mode [00:35:44] ::1: proxying the response of type 'A' for thesprawl.org [00:35:44] ::1: proxying the response of type 'AAAA' for thesprawl.org [00:35:44] ::1: proxying the response of type 'MX' for thesprawl.org
NOTE: By default, DNSChef creates a UDP listener. You can use TCP instead with the --tcp argument discussed later.
Intercept All Responses
Now, that you know how to start DNSChef let's configure it to fake all replies to point to 127.0.0.1 using the --fakeip parameter:
# ./dnschef.py --fakeip 127.0.0.1 -q [*] DNSChef started on interface: 127.0.0.1 [*] Using the following nameservers: 8.8.8.8 [*] Cooking all A replies to point to 127.0.0.1 [23:55:57] 127.0.0.1: cooking the response of type 'A' for google.com to 127.0.0.1 [23:55:57] 127.0.0.1: proxying the response of type 'AAAA' for google.com [23:55:57] 127.0.0.1: proxying the response of type 'MX' for google.com
In the above output you an see that DNSChef was configured to proxy all requests to 127.0.0.1. The first line of log at 08:11:23 shows that we have "cooked" the "A" record response to point to 127.0.0.1. However, further requests for 'AAAA' and 'MX' records are simply proxied from a real DNS server. Let's see the output from requesting program:
$ host google.com localhost google.com has address 127.0.0.1 google.com has IPv6 address 2001:4860:4001:803::1001 google.com mail is handled by 10 aspmx.l.google.com. google.com mail is handled by 40 alt3.aspmx.l.google.com. google.com mail is handled by 30 alt2.aspmx.l.google.com. google.com mail is handled by 20 alt1.aspmx.l.google.com. google.com mail is handled by 50 alt4.aspmx.l.google.com.
As you can see the program was tricked to use 127.0.0.1 for the IPv4 address. However, the information obtained from IPv6 (AAAA) and mail (MX) records appears completely legitimate. The goal of DNSChef is to have the least impact on the correct operation of the program, so if an application relies on a specific mailserver it will correctly obtain one through this proxied request.
Let's fake one more request to illustrate how to target multiple records at the same time:
# ./dnschef.py --fakeip 127.0.0.1 --fakeipv6 ::1 -q [*] DNSChef started on interface: 127.0.0.1 [*] Using the following nameservers: 8.8.8.8 [*] Cooking all A replies to point to 127.0.0.1 [*] Cooking all AAAA replies to point to ::1 [00:02:14] 127.0.0.1: cooking the response of type 'A' for google.com to 127.0.0.1 [00:02:14] 127.0.0.1: cooking the response of type 'AAAA' for google.com to ::1 [00:02:14] 127.0.0.1: proxying the response of type 'MX' for google.com
In addition to the --fakeip flag, I have now specified --fakeipv6 designed to fake 'AAAA' record queries. Here is an updated program output:
$ host google.com localhost google.com has address 127.0.0.1 google.com has IPv6 address ::1 google.com mail is handled by 10 aspmx.l.google.com. google.com mail is handled by 40 alt3.aspmx.l.google.com. google.com mail is handled by 30 alt2.aspmx.l.google.com. google.com mail is handled by 20 alt1.aspmx.l.google.com. google.com mail is handled by 50 alt4.aspmx.l.google.com.
Once more all of the records not explicitly overriden by the application were proxied and returned from the real DNS server. However, IPv4 (A) and IPv6 (AAAA) were both faked to point to a local machine.
DNSChef supports multiple record types from the command line:
+--------+--------------+-----------+--------------------------+ | Record | Description |Argument | Example | +--------+--------------+-----------+--------------------------+ | A | IPv4 address |--fakeip | --fakeip 192.0.2.1 | | AAAA | IPv6 address |--fakeipv6 | --fakeipv6 2001:db8::1 | | MX | Mail server |--fakemail | --fakemail mail.fake.com | | CNAME | CNAME record |--fakealias| --fakealias www.fake.com | | NS | Name server |--fakens | --fakens ns.fake.com | +--------+--------------+-----------+--------------------------+
NOTE: For usability not all DNS record types are exposed on the command line. Additional records such as PTR, TXT, SOA, SRV, DNSKEY, RRSIG, etc. can be specified using the --file flag and an appropriate record header. See the external definitions file section below for details.
At last let's observe how the application handles queries of type ANY:
# ./dnschef.py --fakeip 127.0.0.1 --fakeipv6 ::1 --fakemail mail.fake.com --fakealias www.fake.com --fakens ns.fake.com -q [*] DNSChef started on interface: 127.0.0.1 [*] Using the following nameservers: 8.8.8.8 [*] Cooking all A replies to point to 127.0.0.1 [*] Cooking all AAAA replies to point to ::1 [*] Cooking all MX replies to point to mail.fake.com [*] Cooking all CNAME replies to point to www.fake.com [*] Cooking all NS replies to point to ns.fake.com [00:17:29] 127.0.0.1: cooking the response of type 'ANY' for google.com with all known fake records.
DNS ANY record queries results in DNSChef returning every faked record that it knows about for an applicable domain. Here is the output that the program will see:
$ host -t ANY google.com localhost google.com has address 127.0.0.1 google.com has IPv6 address ::1 google.com mail is handled by 10 mail.fake.com. google.com is an alias for www.fake.com. google.com name server ns.fake.com.
Filtering Domains
Using the above example, consider you only want to intercept requests for thesprawl.org and leave queries to all other domains such as webfaction.com without modification. You can use the --fakedomains parameter as illustrated below:
# ./dnschef.py --fakeip 127.0.0.1 --fakedomains thesprawl.org -q [*] DNSChef started on interface: 127.0.0.1 [*] Using the following nameservers: 8.8.8.8 [*] Cooking replies to point to 127.0.0.1 matching: thesprawl.org [00:23:37] 127.0.0.1: cooking the response of type 'A' for thesprawl.org to 127.0.0.1 [00:23:52] 127.0.0.1: proxying the response of type 'A' for mx9.webfaction.com From the above example the request for thesprawl.org was faked; however, the request for mx9.webfaction.com was left alone. Filtering domains is very useful when you attempt to isolate a single application without breaking the rest.
NOTE: DNSChef will not verify whether the domain exists or not before faking the response. If you have specified a domain it will always resolve to a fake value whether it really exists or not.
Reverse Filtering
In another situation you may need to fake responses for all requests except a defined list of domains. You can accomplish this task using the --truedomains parameter as follows:
# ./dnschef.py --fakeip 127.0.0.1 --truedomains thesprawl.org,*.webfaction.com -q [*] DNSChef started on interface: 127.0.0.1 [*] Using the following nameservers: 8.8.8.8 [*] Cooking replies to point to 127.0.0.1 not matching: *.webfaction.com, thesprawl.org [00:27:57] 127.0.0.1: proxying the response of type 'A' for mx9.webfaction.com [00:28:05] 127.0.0.1: cooking the response of type 'A' for google.com to 127.0.0.1 There are several things going on in the above example. First notice the use of a wildcard (). All domains matching .webfaction.com will be reverse matched and resolved to their true values. The request for 'google.com' returned 127.0.0.1 because it was not on the list of excluded domains.
There may be situations where defining a single fake DNS record for all matching domains may not be sufficient. You can use an external file with a collection of DOMAIN=RECORD pairs defining exactly where you want the request to go.
For example, let create the following definitions file and call it dnschef.ini:
Notice the section header [A], it defines the record type to DNSChef. Now let's carefully observe the output of multiple queries:
# ./dnschef.py --file dnschef.ini -q [*] DNSChef started on interface: 127.0.0.1 [*] Using the following nameservers: 8.8.8.8 [+] Cooking A replies for domain *.google.com with '192.0.2.1' [+] Cooking A replies for domain thesprawl.org with '192.0.2.2' [+] Cooking A replies for domain *.wordpress.* with '192.0.2.3' [00:43:54] 127.0.0.1: cooking the response of type 'A' for google.com to 192.0.2.1 [00:44:05] 127.0.0.1: cooking the response of type 'A' for www.google.com to 192.0.2.1 [00:44:19] 127.0.0.1: cooking the response of type 'A' for thesprawl.org to 192.0.2.2 [00:44:29] 127.0.0.1: proxying the response of type 'A' for www.thesprawl.org [00:44:40] 127.0.0.1: cooking the response of type 'A' for www.wordpress.org to 192.0.2.3 [00:44:51] 127.0.0.1: cooking the response of type 'A' for wordpress.com to 192.0.2.3 [00:45:02] 127.0.0.1: proxying the response of type 'A' for slashdot.org
Both google.com and www.google.com matched the *.google.com entry and correctly resolved to 192.0.2.1. On the other hand www.thesprawl.org request was simply proxied instead of being modified. At last all variations of wordpress.com, www.wordpress.org, etc. matched the .wordpress. mask and correctly resolved to 192.0.2.3. At last an undefined slashdot.org query was simply proxied with a real response.
You can specify section headers for all other supported DNS record types including the ones not explicitly exposed on the command line: [A], [AAAA], [MX], [NS], [CNAME], [PTR], [NAPTR] and [SOA]. For example, let's define a new [PTR] section in the 'dnschef.ini' file:
[PTR] *.2.0.192.in-addr.arpa=fake.com
Let's observe DNSChef's behavior with this new record type:
./dnschef.py --file dnschef.ini -q [sudo] password for iphelix: [*] DNSChef started on interface: 127.0.0.1 [*] Using the following nameservers: 8.8.8.8 [+] Cooking PTR replies for domain *.2.0.192.in-addr.arpa with 'fake.com' [00:11:34] 127.0.0.1: cooking the response of type 'PTR' for 1.2.0.192.in-addr.arpa to fake.com
And here is what a client might see when performing reverse DNS queries:
$ host 192.0.2.1 localhost 1.2.0.192.in-addr.arpa domain name pointer fake.com.
Some records require exact formatting. Good examples are SOA, NAPTR, and SRV records:
You can mix and match input from a file and command line. For example the following command uses both --file and --fakedomains parameters:
# ./dnschef.py --file dnschef.ini --fakeip 6.6.6.6 --fakedomains=thesprawl.org,slashdot.org -q [*] DNSChef started on interface: 127.0.0.1 [*] Using the following nameservers: 8.8.8.8 [+] Cooking A replies for domain *.google.com with '192.0.2.1' [+] Cooking A replies for domain thesprawl.org with '192.0.2.2' [+] Cooking A replies for domain *.wordpress.* with '192.0.2.3' [*] Cooking A replies to point to 6.6.6.6 matching: *.wordpress.*, *.google.com, thesprawl.org [*] Cooking A replies to point to 6.6.6.6 matching: slashdot.org, *.wordpress.*, *.google.com, thesprawl.org [00:49:05] 127.0.0.1: cooking the response of type 'A' for google.com to 192.0.2.1 [00:49:15] 127.0.0.1: cooking the response of type 'A' for slashdot.org to 6.6.6.6 [00:49:31] 127.0.0.1: cooking the response of type 'A' for thesprawl.org to 6.6.6.6 [00:50:08] 127.0.0.1: proxying the response of type 'A' for tor.com
Notice the definition for thesprawl.org in the command line parameter took precedence over dnschef.ini. This could be useful if you want to override values in the configuration file. slashdot.org still resolves to the fake IP address because it was specified in the --fakedomains parameter. tor.com request is simply proxied since it was not specified in either command line or the configuration file. See sample dnschef.ini file for additional examples.
Logging
DNSChef is capable of storing activity log in an external file using the --logfile log1.txt command line parameter. Below is a snippet of a sample DNSChef session:
[05/Nov/2014:22:00:49 -0800] DNSChef is active. [05/Nov/2014:22:01:07 -0800] 127.0.0.1: cooking the response of type 'A' for thesprawl.org to 192.0.2.1 [05/Nov/2014:22:07:24 -0800] DNSChef is shutting down.
Other Configurations
For security reasons, DNSChef listens on a local 127.0.0.1 (or ::1 for IPv6) interface by default. You can make DNSChef listen on another interface using the --interface parameter:
# ./dnschef.py --interface 0.0.0.0 -q [*] DNSChef started on interface: 0.0.0.0 [*] Using the following nameservers: 8.8.8.8 [*] No parameters were specified. Running in full proxy mode [00:50:53] 192.0.2.105: proxying the response of type 'A' for thesprawl.org
or for IPv6:
# ./dnschef.py -6 --interface :: -q [*] Using IPv6 mode. [*] DNSChef started on interface: :: [*] Using the following nameservers: 2001:4860:4860::8888 [*] No parameters were specified. Running in full proxy mode [00:57:46] 2001:db8::105: proxying the response of type 'A' for thesprawl.org
By default, DNSChef uses Google's public DNS server to make proxy requests. However, you can define a custom list of nameservers using the --nameservers parameter:
# ./dnschef.py --nameservers 4.2.2.1,4.2.2.2 -q [*] DNSChef started on interface: 127.0.0.1 [*] Using the following nameservers: 4.2.2.1, 4.2.2.2 [*] No parameters were specified. Running in full proxy mode [00:55:08] 127.0.0.1: proxying the response of type 'A' for thesprawl.org
It is possible to specify non-standard nameserver port using IP#PORT notation:
# ./dnschef.py --nameservers 192.0.2.2#5353 -q [*] DNSChef started on interface: 127.0.0.1 [*] Using the following nameservers: 192.0.2.2#5353 [*] No parameters were specified. Running in full proxy mode [02:03:12] 127.0.0.1: proxying the response of type 'A' for thesprawl.org
By default, DNSChef will connect to remote nameservers using UDP protocol. This behavior can be controlled more precisely using IP#PORT#PROTOCOL notation to use TCP protocol instead:
# ./dnschef.py --nameservers 4.2.2.2#53#tcp -q [*] DNSChef started on interface: 127.0.0.1 [*] Using the following nameservers: 4.2.2.2#53#tcp [*] No parameters were specified. Running in full proxy mode [22:08:48] 127.0.0.1: proxying the response of type 'A' for thesprawl.org
At the same time it is possible to start DNSChef itself on an alternative port using the -p port# parameter:
# ./dnschef.py -p 5353 -q [*] Listening on an alternative port 5353 [*] DNSChef started on interface: 127.0.0.1 [*] Using the following nameservers: 8.8.8.8 [*] No parameters were specified. Running in full proxy mode
DNS protocol can be used over UDP (default) or TCP. DNSChef implements a TCP mode which can be activated with the --tcp flag:
# ./dnschef.py --tcp -q [*] DNSChef started on interface: 127.0.0.1 [*] Using the following nameservers: 8.8.8.8 [*] No parameters were specified. Running in full proxy mode [*] DNSChef is running in TCP mode
Internal Architecture
Here is some information on the internals in case you need to adapt the tool for your needs. DNSChef is built on top of the SocketServer module and uses threading to help process multiple requests simultaneously. The tool is designed to listen on TCP or UDP ports (default is port 53) for incoming requests and forward those requests when necessary to a real DNS server over UDP.
The excellent dnslib library is used to dissect and reassemble DNS packets. It is particularly useful when generating response packets based on queries. IPy is used for IPv6 addresses manipulation. Both libraries come bundled with DNSChef to ease installation.
DNSChef is capable of modifing queries for records of type "A", "AAAA", "MX", "CNAME", "NS", "TXT", "PTR", "NAPTR", "SOA", "SRV", "DNSKEY", "RRSIG", "ANY". It is very easy to expand or modify behavior for any record. Simply add another if qtype == "RECORD TYPE" entry and tell it what to reply with.
Enjoy the tool and forward all requests and comments to iphelix [at] thesprawl.org.
perlbrew is an admin-free perl installation management tool. The latest version is 0.86, read the release note: Release 0.86.
Install, quickly
Copy & Paste this line into your terminal:
\curl -L https://install.perlbrew.pl | bash
Or, if your system does not have curl but something else:
# Linux \wget -O - https://install.perlbrew.pl | bash
# FreeBSD \fetch -o- https://install.perlbrew.pl | sh
If you prefer to install with cpan, there are two steps:
sudo cpan App::perlbrew perlbrew init
If it is installed with cpan, the perlbrew executable should be installed as /usr/bin/perlbrew or /usr/local/bin/perlbrew. For all users who want to use perlbrew, a prior perlbrew init needs to be executed.
The default perlbrew root directory is ~/perl5/perlbrew, which can be changed by setting PERLBREW_ROOTenvironment variable before the installation and initialization. For more advanced installation process, please read the perlbrew document.
Install, other ways
If you use Sparrow there is sparrow plugin named perlbrew to install perlbrew. It's poorly tested but proved to be working for Ubuntu/Debian platforms.
What is perlbrew
perlbrew is a tool to manage multiple perl installations in your $HOME directory. They are completely isolated perl universes. This approach has many benefits:
No need to run sudo to install CPAN modules, any more.
Try the monthly released new perls.
Learn new language features.
Test your production code against different perl versions.
Leave vendor perl (the one that comes with OS) alone
Vendor perl usually serves its own purposes, and it might be a bad idea to mess it up too much.
Especially PITA when trying to upgrade system perl.
While the default is good enough, you may customize it to install to alternative places, or even let multiple users share the whole perlbrew environment.
perlbrew is simple
To install the latest stable release, and use it permanently:
DNS zones manager. Configure your own dns zone in your browser, get a name on the Internet! https://netlib.re
This project is about managing DNS zones with a simple website, providing a name to anyone on the Internet. It is bound to the netlib.re project. This service let you manage your dynamic IP address with your domain so you don't need DynDNS anymore, and it's all libre software !
The association managing the infrastructure behind this service is Alsace Réseau Neutre, which is an ethical ISP based in Alsace, France. Don't be shy, go ask your questions !
I suggest using perlbrew and cpanm for the installation, to not change your current environment. So install them then :
perlbrew install perl-5.18.0 perlbrew switch perl-5.18.0 perlbrew exec sh init/deploiement.sh all
Contribution (but only to the user interface)
If you want to contribute only on the application interface, you don't need to install and configure all the applications involved in the production release of dnsmanager. First, uncomment "isviewtest" on conf/config.yml then :
perlbrew install perl-5.18.0 perlbrew switch perl-5.18.0 perlbrew exec sh init/deploiement.sh installdep perlbrew exec sh init/deploiement.sh perlmodules
Finally, to run the application with fake views :
perlbrew exec plackup --port 3000 bin/app.psgi
DNSmanager (fr)
Ce projet est un programme de gestion de zones DNS à partir d'un site web simple, permettant à chacun d'avoir un nom sur Internet. Il est lié au service en ligne netlib.re. Ce service en ligne peut remplacer avantageusement DynDNS puisqu'il est basé sur du code libre, et une association s'occupe de son maintien (Alsace Réseau Neutre, éthique++).
De manière factuelle :
des utilisateurs peuvent s'enregistrer puis
ajouter, supprimer, modifier des zones DNS
mettre à jour un enregistrement A ou AAAA automatiquement via un script
des administrateurs sont là pour
supprimer des zones, des utilisateurs
vous aider sur IRC (#arn sur irc.geeknode.org) ! \o/
installation (base)
L'installation de l'application se fait de préférence via perlbrew et cpanm ce qui permet d'installer les bibliothèques sans toucher à votre installation de Perl. Installez ces programmes puis faites :
perlbrew install perl-5.18.0 perlbrew switch perl-5.18.0 perlbrew exec sh init/deploiement.sh all
Contribuer (uniquement à l'interface)
Si vous souhaitez contribuer à l'interface, il suffit de décommenter la ligne indiquant "isviewtest" dans le fichier de configuration conf/config.yml. À partir de là, vous pouvez installer l'application comme ceci :
perlbrew install perl-5.18.0 perlbrew switch perl-5.18.0 perlbrew exec sh init/deploiement.sh installdep perlbrew exec sh init/deploiement.sh perlmodules
Server confiurations(config/serv.ini) conf = configuration hostname file(if not defined is set to app://config/conf.json) host = your ip4 addresse to listen(if not defined listen all) port = port to listen(if not defined listen 53) Section nameserver = list of dns server used to found response when no response found on server(as a proxy, but it's eprouve the global performances) [nameserver] nameOfTheDnsServer1 = Ip_Address nameOfTheDnsServer2 = Ip_Address ... nameOfTheDnsServer3 = Ip_Address Section ttl = list of ttl in dns reponse (in secondes) [ttl] ip = ttl for any ip (A or AAAA) address (if not defined 77) ttl = ttl for any field different of ip (A or AAAA) (if not defined 600) refresh = time to refresh the zone (if not defined 1800) retry = time to retry when refresh (above) has expired (if not defined 900) expiration = ttl for DNS response (if not defined 604800)
Command line option Usage: fun_dns [options] Options: --- -p|--port port to listen. --- -h|--host host to bind. --- -c|--conf configuration file(hostname). --- -s|--servConf configuration file(server). --- -v|--version Get the version of fun_dns --- -z|--zone Lookup a zoneWalk --- -l|--log path to log file
Hi! This is my ansible playbook for self-hosting your own email, web hosting, XMPP chat, Matrix Homeserver, Tiny Tiny RSS, Git repos, and and DNS records using OpenBSD. I use it to host everything on c0ffee.net, but you can easily adapt it for your own domain by setting a few variables in vars.yml.
NEW: Read the changelog before running this playbook after updates! There are often breaking changes!!
TLDR
Configure a secondary DNS provider and set them as your nameservers at your registrar. Set up reverse DNS for your server.
./scripts/bootstrap_openbsd.sh
cp vars-sample.yml vars.yml && vi vars.yml
ansible-playbook site.yml
./scripts/ds_records.sh YOURDOMAIN and set DS records at your registrar for DNSSEC.
Create your user account with dankctl useradd.
Assumptions
You have a public-facing server (probably a VPS) running OpenBSD, with an IPv4 and IPv6 address. I recommend Vultr.
You have your own domain name, and a registrar that supports DNSSEC. I recommend Namecheap.
Automatic publishing of DKIM records for outgoing email verification
Keep it Simple
Unopinionated baseline for what most people want from a personal domain
Keep dependencies to a minimum and stick to UNIX conventions
Automate the tedious stuff, so you can focus on hacking!
Usage
Boot up your OpenBSD server.
Create a user account for provisioning the system. Make sure to add the account to the wheel group. Don't use your preferred username for this account - save that for your LDAP username.
Run scripts/bootstrap_openbsd.sh as root to add a package repo URL and set up doas for your user (required for Ansible).
Configure your secondary DNS provider to accept NOTIFYs and perform zone transfers from your server's IP address.
cp vars-sample.yml vars.yml and edit the configuration to your liking.
Run the playbook! ansible-playbook site.yml
Ensure you have reverse DNS in place for your server's IP address. This is a critical step to avoid your outgoing mail being flagged as spam. At Vultr, this is configured under "Settings > IPv4". You should set one for your primary IPv6 address as well.
The last step is to configure DS records for DNSSEC at your domain registrar. Run scripts/ds_records.sh YOURDOMAIN to generate the records. At Namecheap, this is configured under "Advanced DNS > DNSSEC" in the web portal.
Create your "real" user account in LDAP via dankctl useradd your_username -c "Your Name" -G ssh,sudo -r admin -k "your ssh key"
Yell at me via email, xmpp, or matrix when you inevitably find bugs in my code.
Operational Notes
Login info: the credentials for SMTP (STARTTLS, port 587) and IMAP (SSL, port 993) are simply your username (without the @domain.com portion) and login password. XMPP uses the username@domain.com syntax for logins, but the password is the same. Mail is stored under ~/Maildir in each user's home directory for easy access using local clients like mutt.
Email Filtering: any sieve script located at ~/.dovecot.sieve will automatically apply filters to your incoming mail. You can compile the sieve script and check for syntax errors using sievec ~/.dovecot.sieve. For example, to filter all your cron emails into a folder called Logs:
XMPP Chat: the XMPP server, Prosody, is really slick. As configured here, it supports HTTP file upload for image sharing, delivery to multiple devices via carbons, push notifications, group chats, message history, and basically everything you'd expect from a modern chat solution. XMPP isn't all that bad! The best clients are ChatSecure for iOS, Conversations for Android, and Gajim for *nix and Windows. No decent clients for OS X, sadly. All those clients support end-to-end crypto via OMEMO. Easily federate with others on separate XMPP servers for truly decentralized, open communication!
Account Maintenance: to add, remove, and modify accounts and groups, use the dankctl command. It's help output should be quite self-explanatory.
IPv6:spamd does not currently support IPv6, so don't go adding a AAAA record for mail in the zonefile!
Monitoring spamd: just run spamdb to see a list of senders currently greylisted/whitelisted.
Virtual Hosts: a default vhost will be created for www.domain.com, with a bare domain redirect. Shove HTML files into /var/www/htdocs/www.domain.com to start sharing your worthless opinions with the internet! To add more vhosts, just put a configuration file in /etc/sites and include it in /etc/httpd.d/sites.conf.
Greylisting pitfalls:spamd works by greylisting. Unfortunately, big mailers like GMail often don't retry delivery from the same address, resulting in a greylist black hole described here. To alleviate this, I included a daily cron job that whitelists the IP addresses found in the SPF records for some of the big mailers like GMail and Yahoo. If you notice any other problematic domains, override the to the bigmailers list defined in roles/spamd/deaults/main.yml to have their IP ranges whitelisted. (And be sure to send me a pull request!)
Password Resets: Passwords can be reset using dankctl resetpass. Currently, only an administrator can do this, since giving users write access to their LDAP user entry could allow them to write a non-hashed password into their userPassword field. It's on my todo list to make some kind of web interface for this.
SSH: SSH keys are stored in LDAP and can be added/removed using dankctl usermod. If a user has a shell on the box, he can run this command with his own credentials. Users must be in the ssh group to connect.
Backups: another thing I'm leaving up to you, since your requirements will almost certainly be unique. Shouldn't be too difficult:
Maildirs: tar them up, maybe encrypt them, and scp them offsite periodically.
User accounts: back up /etc/{passwd,master.passwd,group}
Backup MX records: I don't bother with a backup MX. They are a massive target for spammers, and legit mail servers will keep retrying delivery for multiple days if your primary MX goes down.
Prosody: periodically tar up the HTTP upload dir and do a pg_dump to save user info and message archives.
Keys: tar up your DNSSEC keys (/var/nsd/keys) and DKIM keys (/etc/mail/dkim)
LDAP: you can either tar up /var/db/ldap or save the output of ldap search as the root DN.
Assuming you copy all these items back to their original locations, the playbook won't generate new keys if they already exist.
DNS Hosting Guide: Hidden Master with DNSSEC: my original guide for running your own DNS. Again, written for FreeBSD, but gives a lot of details about why you'd want a hidden master setup.
There are two ways to install this project from source, which depend on the version of the go version you're using.
If you don't have a golang environment configured you should be able to download a binary release from the github project.
Source Installation go <= 1.11
If you're using go before 1.11 then the following command should fetch/update overseer, and install it upon your system:
cd $GOPATH
go get -u -v github.com/skx/dns-api-go
dns-api-go -h
Source installation go >= 1.12
If you're using a more recent version of go (which is highly recommended), you need to clone to a directory which is not present upon your GOPATH:
git clone https://github.com/skx/dns-api-go cd dns-api-go go install
Rate Limiting
The server has support for rate-limiting, you can enable this by passing the address of a redis server to the binary:
$ dns-api-go -redis-server localhost:6379
If this flag is not present then rate-limiting will be disabled. If a client makes too many requests they will be returned a HTTP 429 status-code. Each request made will return a series of headers prefixed with X-RateLimit to allow clients to see how many requests they have made, and have remaining.
Metrics
If you have a graphite-host you can point the environmental-variable METRICS at it. This will then receive metrics:
If you alter the template-files beneath data/ you will need to rebuild the static.go file before those changes will become visible. (i.e. They are pre-processed and included inline in our generated binary, rather than being read at run-time.)
Now you can regenerate the static.go file using that:
$ implant -input data/ -output static.go
And rebuild the main binary:
$ go build .
Production Deployment
Surprisingly hosting this service publicly results in a ton of:
Bandwidth usage.
Support requests.
The former I tried to handle via cloudflare, but caching DNS data means the service doesn't run in a useful way, as you might expect.
To avoid further support-request and abuse complaints I'm taking the main service dns-api.org offline - unless people pay. The code here will always be open, and available for use though.
The current codebase will serve a "We're retired - unless you pay" message if the file /tmp/retired exists. This will be checked every 30 seconds or so.
This repository is configured to run tests upon every commit, and when pull-requests are created/updated. The testing is carried out via .github/run-tests.sh which is used by the github-action-tester action.
drool can replay DNS traffic from packet capture (PCAP) files and send it to a specified server, with options such as to manipulate the timing between packets, as well as loop packets infinitely or for a set number of iterations. This tool's goal is to be able to produce a high amount of UDP packets per second and TCP sessions per second on common hardware.
The purpose can be to simulate Distributed Denial of Service (DDoS) attacks on the DNS and measure normal DNS querying. For example, the tool could enable you to take a snapshot of a DDoS and be able to replay it later to test if new code or hardening techniques are useful, safe & effective. Another example is to be able to replay a packet stream for a bug that is sequence- and/or timing-related in order to validate the efficacy of subsequent bug fixes.
Known Issues
IP fragments are currently not processed and will be discarded.
TCP sessions are not reassembled, each packet is parsed as DNS after discarding the first two bytes.
Usage example
Send all DNS queries twice as fast as found in the PCAP file to localhost using UDP.
Take all DNS queries found in the PCAP file and send them as fast as possible over UDP to localhost by ignoring both timings, replies and starting 3 threads that will simultaneously send queries.