Craig Huther Home of Hilgarth

Wireguard with Unbound DNS, server and client setup

Wireguard is the new hotness out there, promising quicker speeds and modern cryptography. Lets add Unbound to that, bringing us better security and no DNS leakage.

Variables

I am using the following settings:

Port: 51820
Subnet: 10.10.69.0/24
Ethernet Interface: ens18

Install Wireguard on server

Add source:

sudo add-apt-repository ppa:wireguard/wireguard -y
sudo apt update &&  sudo apt upgrade -y && sudo apt install wireguard -y

Reboot or modprobe enable wireguard

sudo modprobe wireguard

Configure Wireguard

Enter root user, stay as root until client1.conf is made

$ sudo su

Generate the private/public keys:

cd /etc/wireguard
umask 077
wg genkey | tee server-privatekey | wg pubkey > server-publickey

Create the file /etc/wireguard/wg0.conf

[Interface]
PrivateKey = {server-privatekey}
Address = 10.10.69.1/24, fd86:ea04:1111::1/64
ListenPort = 51820
PostUp = iptables -A FORWARD -i wg0 -j ACCEPT; iptables -t nat -A POSTROUTING -o ens18 -j MASQUERADE; ip6tables -A FORWARD -i wg0 -j ACCEPT; ip6tables -t nat -A POSTROUTING -o ens18 -j MASQUERADE
PostDown = iptables -D FORWARD -i wg0 -j ACCEPT; iptables -t nat -D POSTROUTING -o ens18 -j MASQUERADE; ip6tables -D FORWARD -i wg0 -j ACCEPT; ip6tables -t nat -D POSTROUTING -o ens18 -j MASQUERADE
SaveConfig = true

Generate and add client keys

Generate key pair for the cliens:

cd /etc/wireguard
umask 077
wg genkey | tee client1-privatekey | wg pubkey > client1-publickey

Add this to the end of /etc/wireguard/wg0.conf

#Client1
[Peer]
PublicKey = {client1-publickey}
AllowedIPs = 10.10.69.2/32, fd86:ea04:1111::2/128

Connecting the client to the server

You must create a client1.conf file for the client. You should fill it out this way:

[Interface]
PrivateKey = {client1-privatekey}
Address = 10.10.69.2/32, fd86:ea04:1111::2/128
DNS = 10.10.69.1

[Peer]
PublicKey = {server-publickey}
Endpoint = SERVER_PUBLIC_IP:PORT
AllowedIPs = 0.0.0.0/0, ::/0

Now enable the Wireguard interface at boot

sudo systemctl enable wg-quick@wg0.service

Open Firewalls (this was a hangup for me):

This opens the firewall

sudo iptables -A INPUT -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
sudo iptables -A FORWARD -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
sudo iptables -A INPUT -p udp -m udp --dport 51820 -m conntrack --ctstate NEW -j ACCEPT
sudo iptables -A INPUT -s 10.10.69.0/24 -p tcp -m tcp --dport 53 -m conntrack --ctstate NEW -j ACCEPT
sudo iptables -A INPUT -s 10.10.69.0/24 -p udp -m udp --dport 53 -m conntrack --ctstate NEW -j ACCEPT
sudo iptables -A OUTPUT -p udp -m udp --sport 51820 -j ACCEPT
sudo ufw allow 22/tcp
sudo ufw allow 51820/udp
sudo ufw enable

Enable persistance across reboots

sudo apt install iptables-persistent -y
sudo systemctl enable netfilter-persistent
sudo netfilter-persistent save

Forwarding the Traffic though the Server

We have to enable IPv4 & IPv6 routing on the server:

sudo su
echo "net.ipv4.ip_forward = 1" >> /etc/sysctl.conf
echo "net.ipv6.conf.all.forward = 1" >> /etc/sysctl.conf
echo "net.ipv4.conf.all.proxy_arp = 1" >> /etc/sysctl.conf
sysctl --system
exit

The Next step depends on the client.

Mobile:

The easiest way to connect the mobile client is to use a QR code addition. This works for the Wireguard app on Android and iOS:

sudo apt install qrencode -y
sudo su
qrencode -t ansiutf8 < /etc/wireguard/client1.conf
exit

Then in the android app, wireguard, add a new connection via QR code.

Run this to bring the VPN link up, note that you must down the link before adding a new client.

sudo systemctl start wg-quick@wg0

Note you must do systemctl stop wg-quick@wg0 before you add a new client to wg0.conf

Install Unbound as DNS forwarder

This allows all DNS requests to be sent to the VPN, increasing security

sudo apt install unbound unbound-host -y
sudo curl -o /var/lib/unbound/root.hints https://www.internic.net/domain/named.cache
sudo chown unbound:unbound /var/lib/unbound/root.hints
sudo vi /etc/unbound/unbound.conf

Add these contents to the file:

server:
  num-threads: 4

  #Enable logs
  verbosity: 1

  #list of Root DNS Server
  root-hints: "/var/lib/unbound/root.hints"

  #Respond to DNS requests on all interfaces
  interface: 0.0.0.0
  max-udp-size: 3072

  #Authorized IPs to access the DNS Server
  access-control: 0.0.0.0/0                 refuse
  access-control: 127.0.0.1                 allow
  access-control: 10.10.69.0/24         allow

  #not allowed to be returned for public internet  names
  private-address: 10.10.69.0/24

  # Hide DNS Server info
  hide-identity: yes
  hide-version: yes

  #Limit DNS Fraud and use DNSSEC
  harden-glue: yes
  harden-dnssec-stripped: yes
  harden-referral-path: yes

  #Add an unwanted reply threshold to clean the cache and avoid when possible a DNS Poisoning
  unwanted-reply-threshold: 10000000

  #Have the validator print validation failures to the log.
  val-log-level: 1

  #Minimum lifetime of cache entries in seconds
  cache-min-ttl: 1800 

  #Maximum lifetime of cached entries
  cache-max-ttl: 14400
  prefetch: yes
  prefetch-key: yes

Remove Systemd-resolved from running

sudo systemctl disable systemd-resolved
sudo systemctl stop systemd-resolved

Now enable unbound

sudo systemctl enable unbound
sudo systemctl start unbound

Test to see if unbound is working

nslookup google.com 127.0.0.1

  Server:	127.0.0.1
  Address:	127.0.0.1#53

  Non-authoritative answer:
  Name:	google.com
  Address:	172.217.10.142
  Name:	google.com
  Address:	2607:f8b0:4006:802::200e
nslookup google.com 10.10.69.1

  Server:	10.10.69.1
  Address:	10.10.69.1#53

  Non-authoritative answer:
  Name:	google.com
  Address:	172.217.10.142
  Name:	google.com
  Address:	2607:f8b0:4006:802::200e

Minor Hangups

I had issues with unbound failing to start, the exact error was:

sudo unbound-checkconf
  [1557921216] unbound-checkconf[5819:0] error: trust anchor presented twice
  [1557921216] unbound-checkconf[5819:0] error: could not parse auto-trust-anchor-file /var/lib/unbound/root.key line 2
  [1557921216] unbound-checkconf[5819:0] error: error reading auto-trust-anchor-file: /var/lib/unbound/root.key
  [1557921216] unbound-checkconf[5819:0] error: validator: error in trustanchors config
  [1557921216] unbound-checkconf[5819:0] error: validator: could not apply configuration settings.
  [1557921216] unbound-checkconf[5819:0] fatal error: bad config for validator module

The fix was to comment out a line in /etc/unbound/unbound.conf : auto-trust-anchors-file config

Credits

With help from some guides.

[ tech  wireguard  unbound  ]