INTRODUCTION :
___________________________________________________________
___________________________________________________________
Nowadays our privacy is more than ever under pressure, when Internet Service Providers or governements are enforcing "security" laws
to either watch for criminal activities online, or to censor some websites. Some ISP are also checking to which website you are going to, not
to spy on you, but just to lower your connection speed when you go on a bandwidth hungry streaming website (like the famous youtube). Finally,
common attacks such as man-in-the-middle can be used againt DNS on open WIFI networks.
If you think that connecting to an HTTPS website is enough to prevent your ISP or anyone else to know where you are going, think again. Indeed, while your connection is fully encrypted from start to end, you still have to ask your DNS server the IP address corresponding to the website name (domain). Consequently, you are telling where you go.
There is a DNS provider out there who has created a tool to remediate this problem : OpenDNS.
Their tool is named DNSCrypt.
If you think that connecting to an HTTPS website is enough to prevent your ISP or anyone else to know where you are going, think again. Indeed, while your connection is fully encrypted from start to end, you still have to ask your DNS server the IP address corresponding to the website name (domain). Consequently, you are telling where you go.
There is a DNS provider out there who has created a tool to remediate this problem : OpenDNS.
Their tool is named DNSCrypt.
Image taken from http://www.opendns.com
DESCRIPTION :
___________________________________________________________
___________________________________________________________
DNSCrypt enables you to encrypt your DNS queries made to
OpenDNS's DNS servers. That means that your DNS queries will be protected from spying and tampering, improving both your
security and your privacy.
DNSCrypt only works with OpenDNS servers, which means that for using DNSCrypt you will have to agree to use OpenDNS. It won't work with any other DNS provider as queries are made on remote UDP port 443, and OpenDNS IP addresses are used by default.
While I will explain how to setup DNSCrypt on ArchlinuxARM on a Raspberry Pi (Raspberry Pi is a trademark of the Raspberry Pi Foundation), DNSCrypt is in fact available for Windows, Mac, and others Linux distributions.
This article is based on my previous PIWALL article, but it can be adapted to any Linux distribution.
DNSCrypt only works with OpenDNS servers, which means that for using DNSCrypt you will have to agree to use OpenDNS. It won't work with any other DNS provider as queries are made on remote UDP port 443, and OpenDNS IP addresses are used by default.
While I will explain how to setup DNSCrypt on ArchlinuxARM on a Raspberry Pi (Raspberry Pi is a trademark of the Raspberry Pi Foundation), DNSCrypt is in fact available for Windows, Mac, and others Linux distributions.
This article is based on my previous PIWALL article, but it can be adapted to any Linux distribution.
SUMMARY :
___________________________________________________________
___________________________________________________________
1. DNSMASQ
___________________________________________________________
___________________________________________________________
Before installing DNSCrypt, I assume that you have a working dnsmasq (DNS cacher/server) on your system. If this is not the case, you can check
the chapter SETTING UP DHCP & DNS
in my previous article. Anyway, below is a quick check list for DNS dnsmasq configuration (I skip DHCP parameters) :
The listen address is the one from PiWall. You should modify it accordingly to your system IP address.
Above are the two OpenDNS DNS servers IP addresses.
If your dnsmasq is working correctly, listening on both 192.168.1.3:53 and 127.0.0.1:53, then you can go to the next chapter.
$ sudo vi /etc/dnsmasq.conf
## DNS CONFIGURATION ##
# Interfaces for DNS
interface=eth0
listen-address=192.168.1.3
bind-interfaces
# Never forward plain names (without a dot or domain part)
domain-needed
# Never forward addresses in the non-routed address spaces.
bogus-priv
# Max concurrent DNS queries (default = 150)
dns-forward-max=150
# DNS cache size (default = 150)
cache-size=300
# Interfaces for DNS
interface=eth0
listen-address=192.168.1.3
bind-interfaces
# Never forward plain names (without a dot or domain part)
domain-needed
# Never forward addresses in the non-routed address spaces.
bogus-priv
# Max concurrent DNS queries (default = 150)
dns-forward-max=150
# DNS cache size (default = 150)
cache-size=300
The listen address is the one from PiWall. You should modify it accordingly to your system IP address.
$ sudo vi /etc/resolv.conf
nameserver 127.0.0.1
nameserver 208.67.220.220
nameserver 208.67.222.222
nameserver 208.67.220.220
nameserver 208.67.222.222
Above are the two OpenDNS DNS servers IP addresses.
If your dnsmasq is working correctly, listening on both 192.168.1.3:53 and 127.0.0.1:53, then you can go to the next chapter.
2. DNSCRYPT : INSTALLATION
___________________________________________________________
___________________________________________________________
First check the last version of DNSCrypt source code available on github. At the time
I am writing, it is 1.2.0 :
We will need gcc to build our program from sources :
Now let's build DNSCrypt, but be aware that it will take a long time to compile on a Raspberry :
If you are setting up DNSCrypt on a PiWall, or are using iptables on another system, you will need to allow beforehand DNScrypt trafic in your rules. Below is an example for the PiWall advanced script :
Now let's try to start DNScrypt from the console and check that it launches correctly :
You should see DNSCrypt starting, retrieving a certificate, and listening on 127.0.0.2:53. The default 127.0.0.1 is already used by dnsmasq, so we cannot use it. If it does not work here, check your firewall rules, and your system date and time (they must be correct in order for DNSCrypt to check for certificate validity).
Once it's running correctly, interrupt it with CTRL+C and go to the next chapter.
$ wget https://github.com/downloads/opendns/dnscrypt-proxy/dnscrypt-proxy-1.2.0.tar.gz
We will need gcc to build our program from sources :
$ sudo pacman -S gcc
Now let's build DNSCrypt, but be aware that it will take a long time to compile on a Raspberry :
$ tar zxpvf ./dnscrypt-proxy-1.2.0.tar.gz
$ cd dnscrypt-proxy-1.2.0
$ ./configure
$ make
$ sudo make install
$ cd dnscrypt-proxy-1.2.0
$ ./configure
$ make
$ sudo make install
If you are setting up DNSCrypt on a PiWall, or are using iptables on another system, you will need to allow beforehand DNScrypt trafic in your rules. Below is an example for the PiWall advanced script :
DNS_SERVER1="208.67.220.220"
DNS_SERVER2="208.67.222.222"
iptables -A GATEWAY_INTERNET -p udp --sport $UNPRIV_PORTS -d $DNS_SERVER1 -m multiport --dports domain,https -j ACCEPT
iptables -A GATEWAY_INTERNET -p udp --sport $UNPRIV_PORTS -d $DNS_SERVER2 -m multiport --dports domain,https -j ACCEPT
iptables -A GATEWAY_INTERNET -p tcp --sport $UNPRIV_PORTS -d $DNS_SERVER1 -m multiport --dports domain,https -j ACCEPT
iptables -A GATEWAY_INTERNET -p tcp --sport $UNPRIV_PORTS -d $DNS_SERVER2 -m multiport --dports domain,https -j ACCEPT
DNS_SERVER2="208.67.222.222"
iptables -A GATEWAY_INTERNET -p udp --sport $UNPRIV_PORTS -d $DNS_SERVER1 -m multiport --dports domain,https -j ACCEPT
iptables -A GATEWAY_INTERNET -p udp --sport $UNPRIV_PORTS -d $DNS_SERVER2 -m multiport --dports domain,https -j ACCEPT
iptables -A GATEWAY_INTERNET -p tcp --sport $UNPRIV_PORTS -d $DNS_SERVER1 -m multiport --dports domain,https -j ACCEPT
iptables -A GATEWAY_INTERNET -p tcp --sport $UNPRIV_PORTS -d $DNS_SERVER2 -m multiport --dports domain,https -j ACCEPT
Now let's try to start DNScrypt from the console and check that it launches correctly :
$ sudo /usr/local/sbin/dnscrypt-proxy -a 127.0.0.2:53
You should see DNSCrypt starting, retrieving a certificate, and listening on 127.0.0.2:53. The default 127.0.0.1 is already used by dnsmasq, so we cannot use it. If it does not work here, check your firewall rules, and your system date and time (they must be correct in order for DNSCrypt to check for certificate validity).
Once it's running correctly, interrupt it with CTRL+C and go to the next chapter.
3. DNSCRYPT : CONFIGURATION
___________________________________________________________
___________________________________________________________
Now that both dnsmasq and DNSCrypt are functional, we have to make the former going trough the later.
Indeed, dnsmasq will still be the DNS cache/server for the LAN, but it should make it's requests to DNSCrypt.
Before going further, we will make sure DNSCrypt is launched at startup :
The first thing that comes to mind to make dnsmasq use DNSCrypt, is to modify the /etc/resolv.conf file, as dnsmasq sends it's queries by default to the DNS servers written there :
127.0.0.2 being DNSCrypt, it should theoretically work.
In fact, it will on any Linux distribution running on a common hardware with a Real Time Clock (RTC), but it won't on a Raspberry Pi because it does not have one.
Why not having a RTC will prevent DNSCrypt to work with the above configuration on a Raspberry Pi you say ?
Everytime the Raspberry boots up, it starts openntpd to synchronise it's clock from an Internet NTP server. However, the file /etc/ntpd.conf targets a ntp server defined by a domain name :
At startup, openntpd will query 127.0.0.1 (dnsmasq) for "pool.ntp.org", dnsmasq will then ask 127.0.0.2 (DNSCrypt) to resolve the name, however DNScrypt cannot initialise because it is waiting openntpd to synchronise system time to be able to retrieve DNS certificates !
That's quite a "chiken-and-egg" story.
While we may be tempted at first to use instead a static NTP IP address, it is not advised. NTP addresses may change, and you would end up with no internet connection.
We can cleanly solve this issue thanks to a dnsmasq parameter, to tell it to use another "resolv.conf" file, as below :
Then we have to create this file :
Your regular resolv file can be like this :
Thanks to this modification :
- At startup openntpd can query opendns servers directly (resolv.conf file) to resolv by itself ntp server domain name, synchronising system date and time.
- DNSCrypt can then initialise and pull opendns certificates.
- Any subsequent DNS requests from the LAN to dnsmasq will be forwarded to DNSCrypt (resolv-dnsmasq.conf) if not already in dnsmasq's cache.
Now you can launch DNSCrypt like this :
Check that everything works. Once it's ok, reboot your Linux to check that it is still working after the startup.
To check that DNS queries are effectively sent encrypted, you can use tcpdump, and then surf on a computer on your LAN :
You should only see remote UDP port 443 being used, not 53 :
Before going further, we will make sure DNSCrypt is launched at startup :
$ sudo vi /etc/rc.local
echo "Starting DNSCrypt"
/usr/local/sbin/dnscrypt-proxy -a 127.0.0.2:53 –daemonize
/usr/local/sbin/dnscrypt-proxy -a 127.0.0.2:53 –daemonize
The first thing that comes to mind to make dnsmasq use DNSCrypt, is to modify the /etc/resolv.conf file, as dnsmasq sends it's queries by default to the DNS servers written there :
nameserver 127.0.0.1
nameserver 127.0.0.2
nameserver 127.0.0.2
127.0.0.2 being DNSCrypt, it should theoretically work.
In fact, it will on any Linux distribution running on a common hardware with a Real Time Clock (RTC), but it won't on a Raspberry Pi because it does not have one.
Why not having a RTC will prevent DNSCrypt to work with the above configuration on a Raspberry Pi you say ?
Everytime the Raspberry boots up, it starts openntpd to synchronise it's clock from an Internet NTP server. However, the file /etc/ntpd.conf targets a ntp server defined by a domain name :
servers pool.ntp.org
At startup, openntpd will query 127.0.0.1 (dnsmasq) for "pool.ntp.org", dnsmasq will then ask 127.0.0.2 (DNSCrypt) to resolve the name, however DNScrypt cannot initialise because it is waiting openntpd to synchronise system time to be able to retrieve DNS certificates !
That's quite a "chiken-and-egg" story.
While we may be tempted at first to use instead a static NTP IP address, it is not advised. NTP addresses may change, and you would end up with no internet connection.
We can cleanly solve this issue thanks to a dnsmasq parameter, to tell it to use another "resolv.conf" file, as below :
$ sudo vi /etc/dnsmasq.conf
## DNS CONFIGURATION ##
# Interfaces for DNS
interface=eth0
listen-address=192.168.1.3
bind-interfaces
resolv-file=/etc/resolv-dnsmasq.conf
# Interfaces for DNS
interface=eth0
listen-address=192.168.1.3
bind-interfaces
resolv-file=/etc/resolv-dnsmasq.conf
Then we have to create this file :
$ sudo vi /etc/resolv-dnsmasq.conf
nameserver 127.0.0.2
Your regular resolv file can be like this :
nameserver 127.0.0.1
nameserver 208.67.220.220
nameserver 208.67.222.222
nameserver 208.67.220.220
nameserver 208.67.222.222
Thanks to this modification :
- At startup openntpd can query opendns servers directly (resolv.conf file) to resolv by itself ntp server domain name, synchronising system date and time.
- DNSCrypt can then initialise and pull opendns certificates.
- Any subsequent DNS requests from the LAN to dnsmasq will be forwarded to DNSCrypt (resolv-dnsmasq.conf) if not already in dnsmasq's cache.
Now you can launch DNSCrypt like this :
$ sudo /usr/local/sbin/dnscrypt-proxy -a 127.0.0.2:53 –daemonize
Check that everything works. Once it's ok, reboot your Linux to check that it is still working after the startup.
To check that DNS queries are effectively sent encrypted, you can use tcpdump, and then surf on a computer on your LAN :
$ sudo tcpdump -i eth0 dst host 208.67.222.222 or dst host 208.67.220.220 or src host 208.67.222.222 or src host 208.67.220.220 -n
You should only see remote UDP port 443 being used, not 53 :
23:00:41.806710 IP 192.168.1.3.58619 > 208.67.220.220.443: UDP, length 260
23:00:41.843235 IP 208.67.220.220.443 > 192.168.1.3.58619: UDP, length 496
23:00:41.843235 IP 208.67.220.220.443 > 192.168.1.3.58619: UDP, length 496
CONCLUSION
___________________________________________________________
___________________________________________________________
While HTTPS is widespread for securing HTTP, DNS however goes in clear text and there is no common alternative. Thanks to OpenDNS, DNSCrypt
brings a solution.
The advantage of implementing DNScrypt on a network gateway is that it then works for every network device you can have on your LAN, even the ones for which there is no client (video games consoles, printers, NAS, iPad, etc...).
Even if DNSCrypt does not fix DNS protocol's vulnerabilities (that should be addressed with the DNSSEC protocol), it still does a good job at improving privacy and security.
As a last note, I'm pleased to see that the Raspberry Pi (256MB model) can handle flawlessly all of these roles :
- Network gateway
- Firewall
- DHCP server
- DNS cache/server with encryption
- NIDS/Snort (Network Intrusion Detection System)
- Alert notifications (firewall or NIDS) by email (requires Python language)
Do not forget to check Raspberry Pi website.
The advantage of implementing DNScrypt on a network gateway is that it then works for every network device you can have on your LAN, even the ones for which there is no client (video games consoles, printers, NAS, iPad, etc...).
Even if DNSCrypt does not fix DNS protocol's vulnerabilities (that should be addressed with the DNSSEC protocol), it still does a good job at improving privacy and security.
As a last note, I'm pleased to see that the Raspberry Pi (256MB model) can handle flawlessly all of these roles :
- Network gateway
- Firewall
- DHCP server
- DNS cache/server with encryption
- NIDS/Snort (Network Intrusion Detection System)
- Alert notifications (firewall or NIDS) by email (requires Python language)
Do not forget to check Raspberry Pi website.
LINKS
___________________________________________________________
___________________________________________________________
The Raspberry Pi Foundation : http://www.raspberrypi.org
OpenDNS : http://www.opendns.com
DNSCrypt : http://www.opendns.com/technology/dnscrypt/
Archlinux ARM : http://archlinuxarm.org
Netfilter/iptables : http://www.netfilter.org
OpenDNS : http://www.opendns.com
DNSCrypt : http://www.opendns.com/technology/dnscrypt/
Archlinux ARM : http://archlinuxarm.org
Netfilter/iptables : http://www.netfilter.org
Legal notice : banner made from various free pictures available at FreeDigitalPhotos.net
Hi,
ReplyDeleteThank you for a very concise and informative guide.
Using the latest DNSProxy (1.2.1), the switches are slightly different:
sudo /usr/local/sbin/dnscrypt-proxy --local-address=127.0.0.2:53 –-daemonize
Thanks for the write up, it really helped.
ReplyDeleteCheers
The daemonize argument should be with two slashes in front in the latest version - --daemonize or short -d.
ReplyDeleteThis is outdated now.
ReplyDeleteArch even got updated version in pacman <3 sudo pacman -S dnscrypt-proxy. With systemd service ready to start.
If you want to it i probably a userbase interested in seeing a updated guide