Setup Wireguard

Install Wireguard and necessary tools. Since Linux version 5, Wireguard is built in. So Wireguard is available in Ubuntu 20.04 repo.

sudo apt update && sudo apt upgrade -y && sudo apt install net-tools wireguard qrencode -y

Generate Wireguard "server" configuration file. You may change ListenPort to whatever you want. For AWS user, please use something else instead of 10.0.0.*

cd ~/
umask 077
wg genkey | tee server_private_key | wg pubkey > server_public_key
echo -n "[Interface]
PrivateKey = " >> wg0.conf
cat server_private_key >> wg0.conf
echo "Address = 10.0.0.1/24
ListenPort = 51820" >> wg0.conf

Change ens5 to the network interface name. You may find it out by ifconfig

echo "PostUp = iptables -A FORWARD -i wg0 -j ACCEPT; iptables -t nat -A POSTROUTING -o ens5 -j MASQUERADE
PostDown = iptables -D FORWARD -i wg0 -j ACCEPT; iptables -t nat -D POSTROUTING -o ens5 -j MASQUERADE" >> wg0.conf

Move the configuration file to the right place.

sudo mv wg0.conf /etc/wireguard/

Setup network package forwarding

Open this file

sudo nano /etc/sysctl.conf

Uncomment net.ipv4.ip_forward=1 and net.ipv6.conf.all.forwarding=1, so it becomes:

# Uncomment the next line to enable packet forwarding for IPv4
net.ipv4.ip_forward=1

# Uncomment the next line to enable packet forwarding for IPv6
#  Enabling this option disables Stateless Address Autoconfiguration
#  based on Router Advertisements for this host
net.ipv6.conf.all.forwarding=1

Save and close the file by pessing CTRL+X , Y, ENTER

You may confirm the changes by typing in:

sudo sysctl -p

Generate Wireguard client configuration

Remember to change the IP and port if you have specified anything in the server configuration done above. We use ifconfig.co to detect server IP address. Please open client.conf to make sure the detection is correct.

cd ~/
umask 077
wg genkey | tee client_private_key | wg pubkey > client_public_key
echo -n "[Interface]
PrivateKey = $(cat ~/client_private_key)
Address = 10.0.0.2/24
DNS = 10.0.0.1
[Peer]
PublicKey = $(cat ~/server_public_key)
EndPoint = $(curl -4 ifconfig.co):51820
AllowedIPs = 0.0.0.0/0" >> client.conf

Copy client public-key to server configuration, to allow client connection to the server. Remember to change the IP if needed.

If you are not root, run this:

cd ~/
sudo su
echo "[Peer]" >> /etc/wireguard/wg0.conf
echo -n "PublicKey = " >> /etc/wireguard/wg0.conf
cat client_public_key >> /etc/wireguard/wg0.conf
echo "AllowedIPs = 10.0.0.2/32" >> /etc/wireguard/wg0.conf
exit

If you are root, run this:

echo "[Peer]" >> /etc/wireguard/wg0.conf
echo -n "PublicKey = " >> /etc/wireguard/wg0.conf
cat client_public_key >> /etc/wireguard/wg0.conf
echo "AllowedIPs = 10.0.0.2/32" >> /etc/wireguard/wg0.conf

Enable and start Wireguard.

sudo systemctl enable [email protected]
sudo systemctl start [email protected]

Install Stubby

sudo apt install stubby -y

Configure Stubby

sudo nano /etc/stubby/stubby.yml

Press CTRL+W, type upstream_recursive_servers, ENTER to find. Delete any servers you don't want. Uncomment the servers you want to use. I choose to use Cloudflare here.

# Cloudflare 1.1.1.1 and 1.0.0.1
  - address_data: 1.1.1.1
    tls_auth_name: "cloudflare-dns.com"
  - address_data: 1.0.0.1
    tls_auth_name: "cloudflare-dns.com"
# Cloudflare servers
  - address_data: 2606:4700:4700::1111
    tls_auth_name: "cloudflare-dns.com"
  - address_data: 2606:4700:4700::1001
    tls_auth_name: "cloudflare-dns.com"

If you use several DNS provider, keep round_robin_upstreams to be 1. If not, change round_robin_upstreams to be 0.

Search listen_addresses. Add Wireguard server (internal) IP.

listen_addresses:
  - 10.0.0.1
  - 127.0.0.1

Modify Stubby service

sudo nano /lib/systemd/system/stubby.service

Add [email protected] to the service dependence.

Wants=network-online.target,[email protected]
After=network-online.target,[email protected]

Reload the configuration file and restart Stubby

sudo systemctl daemon-reload
sudo systemctl restart stubby

Check if Stubby is listening the correct IP and port:

sudo lsof -i -P -n
stubby    1003          stubby    3u  IPv4  24644      0t0  UDP 10.0.0.1:53
stubby    1003          stubby    4u  IPv4  24645      0t0  TCP 10.0.0.1:53 (LISTEN)
stubby    1003          stubby    5u  IPv4  24646      0t0  UDP 127.0.0.1:53
stubby    1003          stubby    6u  IPv4  24647      0t0  TCP 127.0.0.1:53 (LISTEN)

Use Stubby instead of system default DNS

Try if your system is using NetPlan. If the command below shows you a file with content, please proceed. If not, please find the way to change your DNS.

sudo nano /etc/netplan/*.yaml

It shows something like this:

network:
  version: 2
  renderer: networkd
  ethernets:
    ens5:
      dhcp4: yes

Press CTRL+X to close the file.

sudo nano /etc/netplan/99-custom-dns.yaml

Specify Stubby 127.0.0.1 as DNS

network:
  version: 2
  ethernets:
    ens5:
      nameservers:
        addresses: [127.0.0.1]
      dhcp4-overrides:
        use-dns: false

Press CTRL+X + Y + ENTER to save and close the file.

sudo netplan try

If there is no error, please ENTER

sudo netplan apply
systemd-resolve --status | grep "DNS Servers"

It should show DNS Servers: 127.0.0.1 if the setting is correct.

Transfer the client configuration to the client device. You can show a QR code for phone use by running:

cd
qrencode -t ansiutf8 -r client.conf

Reboot the server to make sure everything applys

sudo reboot now

Something more

  • Please do port-forwarding if needed. Wireguard runs on UDP. There is no need to expose DNS to the Internet. It could be made used to DDoS attack.
  • Delete all client configuration and key files.

Checkpoints

  • One client (physical device) one key / IP.
  • Everytime you have added a client, remember to sudo systemctl restart [email protected] to restart Wireguard
  • If Internet is not accessible, please check:
    - reboot the server to apply changes
    - port-forwarding is done correctly
    - Stubby is listening the correct IP and port

References

https://linuxconfig.org/how-to-create-a-vpn-on-ubuntu-20-04-using-wireguard
https://www.linuxbabe.com/ubuntu/ubuntu-stubby-dns-over-tls
https://aws.amazon.com/premiumsupport/knowledge-center/ec2-static-dns-ubuntu-debian/
https://linuxhint.com/setup_static_ip_address_ubuntu/