FreeBSD DNSCrypt Howto

 

This Howto has been moved to the miniguide section and will be maintained there from now on.

h2. Introduction

This Howto describes the configuration of DNScrypt on FreeBSD using dns/dnscrypt-proxy from the FreeBSD Ports collection.

Installing dnscrypt_proxy  

Install dns/dnscrypt-proxy from the ports collection with root permissions.

# cd /usr/ports/dns/dnscrypt-proxy
# make configure
# make configure-recursive
# make fetch-recursive
# make install clean

Configuring dnscrypt_proxy  

Edit /etc/rc.conf to run dnscrypt_proxy at system startup.

Here a secondary IP address is configured on the loopback device lo0. dnscrypt_proxy is bound to 127.0.0.2 and logging is disabled. It uses one of the public IPredator resolvers with the IP address 194.132.32.32.

# cat >> /etc/rc.conf << EOF
ifconfig_lo0_alias0="inet 127.0.0.2 netmask 0xffffffff"
dnscrypt_proxy_enable="YES"
dnscrypt_proxy_resolver="ipredator"
dnscrypt_proxy_flags="-a 127.0.0.2:53 --provider-key=F581:BDCD:C1F7:469C:6B55:A144:39AA:F2F6:3AD1:8C5F:AE57:7EE1:06C9:B2EC:D29E:6849 --provider-name=2.dnscrypt-cert.ipredator.se --resolver-address=194.132.32.32 -T -E -l /dev/null"
EOF

Starting dnscrypt_proxy  

To start the dnscrypt_proxy without rebooting your machine, invoke the startup script:

# service dnscrypt-proxy start
Starting dnscrypt_proxy.

Testing dnscrypt_proxy  

Beginning with FreeBSD 10 Unbound is part of the FreeBSD base system. This adds the drill command to do DNS lookups.

Send a query for the A record of ipredator.se to the dnscrypt_proxy listening on 127.0.0.2:

# drill -t ipredator.se @127.0.0.2
;; ->>HEADER<<- opcode: QUERY, rcode: NOERROR, id: 53939
;; flags: qr rd ra ; QUERY: 1, ANSWER: 2, AUTHORITY: 4, ADDITIONAL: 0
;; QUESTION SECTION:
;; ipredator.se.        IN      A

;; ANSWER SECTION:
ipredator.se.   600     IN      A       193.234.198.41
ipredator.se.   600     IN      A       193.234.198.40
    
;; AUTHORITY SECTION:
ipredator.se.   600     IN      NS      ns3u.resolv.to.
ipredator.se.   600     IN      NS      ns1a.resolv.to.
ipredator.se.   600     IN      NS      ns2u.resolv.to.
ipredator.se.   600     IN      NS      ns1u.resolv.to.

;; ADDITIONAL SECTION:

;; Query time: 245 msec
;; SERVER: 127.0.0.1
;; WHEN: Fri Jul  3 03:00:52 2015
;; MSG SIZE  rcvd: 147

If you see results in the ANSWER SECTION like above, dnscrypt_proxy basically works. Now you need to setup your system to use dnscrypt_proxy with the unbound resolver.

Configure local DNS cache using Unbound  

The unbound binary that is shipped with FreeBSD in the base system is referred to as local_unbound.

This Howto uses the shipped version of unbound. If you prefer to use unbound from the ports, install dns/unbound. To reference to this version in /etc/rc.conf, use the unbound_enable variable. The configuration file is /usr/local/etc/unbound/unbound.conf.

Configure unbound to be run during system startup:

# echo 'local_unbound_enable="YES"' >> /etc/rc.conf

Edit or create /var/unbound/unbound.conf. unbound listens on 127.0.0.1, only queries originating from 127.0.0.1 are permitted. All queries received by unbound are forwarded to dnscrypt_proxy listening on 127.0.0.2.

server:
    username: unbound
    directory: /var/unbound
    chroot: /var/unbound
  
    interface: 127.0.0.1
    do-ip6: no
  
    access-control: 127.0.0.0/8 allow
    hide-identity: yes
    hide-version: yes
    do-not-query-localhost: no
  
    tcp-upstream: yes
  
    private-address: 10.0.0.0/8
    private-address: 172.16.0.0/12
    private-address: 192.168.0.0/16
  
forward-zone:
    name: "."
    forward-addr: 127.0.0.2@53

Start unbound:

# service local_unbound start

Now do the same query as before, but this time query the unbound resolver:

    # drill ipredator.se @127.0.0.1
    ;; ->>HEADER<<- opcode: QUERY, rcode: NOERROR, id: 16419
    ;; flags: qr rd ra ; QUERY: 1, ANSWER: 2, AUTHORITY: 4, ADDITIONAL: 0
    ;; QUESTION SECTION:
    ;; ipredator.se.        IN      A
   
    ;; ANSWER SECTION:
    ipredator.se.   596     IN      A       193.234.198.41
    ipredator.se.   596     IN      A       193.234.198.40
  
    ;; AUTHORITY SECTION:
    ipredator.se.   596     IN      NS      ns2u.resolv.to.
    ipredator.se.   596     IN      NS      ns1u.resolv.to.
    ipredator.se.   596     IN      NS      ns3u.resolv.to.
    ipredator.se.   596     IN      NS      ns1a.resolv.to.
           
    ;; ADDITIONAL SECTION:
  
    ;; Query time: 3 msec
    ;; SERVER: 127.0.0.1
    ;; WHEN: Fri Jul  3 03:51:11 2015 
    ;; MSG SIZE  rcvd: 147

The outcome should be identical. Note the different SERVER in the answer.

System wide DNS configuration  

On FreeBSD DNS servers are configured in /etc/resolv.conf. Depending on whether your machine uses a statically configured or dynamically assigned address, you can either edit /etc/resolv.conf directly or configure dhclient via /etc/dhclient.conf to supersede the DNS server entries it receives during interface configuration.

DNS queries are to be sent to unbound listening on 127.0.0.1, which in turn forwards the queries to dnscrypt_proxy.

Statically configured IP address

Add 127.0.0.1 as the only nameserver in /etc/resolv.conf. It is important to not have any other nameserver entries in this file, otherwise you are leaking DNS queries to these machines.

# echo "nameserver 127.0.0.1" > /etc/resolv.conf

Dynamically assigned IP address via DHCP

When using DHCP to configure your host's IP address, dhclient needs to supersede the nameservers it receives from local DHCP servers with 127.0.0.1. You still receive an IP address from the network range your machine sits in as well es a default gateway, but all your DNS queries are safely piped through unbound and dnscrypt_proxy.

# echo "supersede domain-name-servers 127.0.0.1;" >> /etc/dhclient.conf

If you experience any problems after following this Howto, please contact support@ipredator.se. For error corrections or feedback please write an email to feedback@ipredator.se. Of course we are also available via our Online Chat.