How Can We Help?
How To Configure Wireguard
To quote from Wikipedia:
WireGuard is a communication protocol and free and open-source software that implements encrypted virtual private networks (VPNs), and was designed with the goals of ease of use, high speed performance, and low attack surface. It aims for better performance and more power-saving than the IPsec and OpenVPN tunneling protocols. The WireGuard protocol passes traffic over UDP.
Wireguard is a peer-to-peer VPN, in other words, it does not use the traditional client-server model. A Wireguard peer can act as a traditional server or a client. Wireguard operates by establishing a network interface on each peer device that then acts as a tunnel.
Wireguard peers then authenticate each other by exchanging and validating their public keys. These keys are mapped with a list of IP addresses that are permitted to access the tunnel.
In comparison with other VPN solutions, such as OpenVPN and IPsec , WireGuard is much faster, is easier to configure, and also has a smaller footprint. Wireguard will run on Linux, Windows, Android, and macOS.
How to install Wireguard on Ubuntu
Wireguard is Peer-to-Peer – NOT client-server!
NOTE: Wireguard operates using a peer-to-peer architecture, not client-server. In the description below I refer to one of my machines on which I am installing Wireguard as server and the other as client, but this is merely my own designation and has no relevance for Wireguard itself.
The wireguard package contains two binaries:
wg — a tool for managing the configuration of WireGuard interfaces
wg-quick — a tool for easily starting and stopping WireGuard interfaces
To install on Ubuntu:
apt update
apt install wireguard
root@intel:/home/kevin# apt install wireguard Reading package lists... Done Building dependency tree Reading state information... Done The following packages were automatically installed and are no longer required: libphonenumber7 libprotobuf17 Use 'sudo apt autoremove' to remove them. The following additional packages will be installed: wireguard-tools The following NEW packages will be installed: wireguard wireguard-tools 0 upgraded, 2 newly installed, 0 to remove and 0 not upgraded. Need to get 86,6 kB of archives. After this operation, 344 kB of additional disk space will be used. Do you want to continue? [Y/n] y Get:1 http://de.archive.ubuntu.com/ubuntu focal-updates/universe amd64 wireguard-tools amd64 1.0.20200513-1~20.04.2 [83,3 kB] Get:2 http://de.archive.ubuntu.com/ubuntu focal-updates/universe amd64 wireguard all 1.0.20200513-1~20.04.2 [3.264 B] Fetched 86,6 kB in 0s (378 kB/s) Selecting previously unselected package wireguard-tools. (Reading database ... 235908 files and directories currently installed.) Preparing to unpack .../wireguard-tools_1.0.20200513-1~20.04.2_amd64.deb ... Unpacking wireguard-tools (1.0.20200513-1~20.04.2) ... Selecting previously unselected package wireguard. Preparing to unpack .../wireguard_1.0.20200513-1~20.04.2_all.deb ... Unpacking wireguard (1.0.20200513-1~20.04.2) ... Setting up wireguard-tools (1.0.20200513-1~20.04.2) ... wg-quick.target is a disabled or a static unit, not starting it. Setting up wireguard (1.0.20200513-1~20.04.2) ... Processing triggers for man-db (2.9.1-1) ... root@intel:/home/kevin#
Basic Wireguard Configuration
The wg and wg-quick Wireguard command-line tools are used to configure and manage the WireGuard interfaces.
Each device in the WireGuard VPN network must have a private and public key. Generate the key pair with this command:
wg genkey | sudo tee /etc/wireguard/privatekey | wg pubkey | sudo tee /etc/wireguard/publickey
root@intel:~# wg genkey | sudo tee /etc/wireguard/privatekey | wg pubkey | sudo tee /etc/wireguard/publickey Y+BuUdkyp+9pJlyfyBcYkCRgcbFqSv/TENH8TGyT6iA= root@intel:~#
(this is your public key)
Always keep the private keys private and do not share with anyone!
Next, configure the tunnel device that will be used to route the Wireguard VPN traffic. This tunnel device can be set up either from the command line using the ip and wg commands, or else by creating the configuration file as below.
Create a new file named wg0.conf and copy-paste the following contents:
nano /etc/wireguard/wg0.conf
[Interface]
Address = 10.0.0.1/24
SaveConfig = true
ListenPort = 51820
PrivateKey = SERVER_PRIVATE_KEY
PostUp = iptables -A FORWARD -i %i -j ACCEPT; iptables -t nat -A POSTROUTING -o ens3 -j MASQUERADE
PostDown = iptables -D FORWARD -i %i -j ACCEPT; iptables -t nat -D POSTROUTING -o ens3 -j MASQUERADE
NOTE – this is just an initial template. You must replace ens3 after -A POSTROUTING to match the name of your public network interface. In my case, the public internet interface for my machine is wlp2s0
so we have:
[Interface] Address = 10.0.0.1/24 SaveConfig = true ListenPort = 51820 PrivateKey = SERVER_PRIVATE_KEY PostUp = iptables -A FORWARD -i %i -j ACCEPT; iptables -t nat -A POSTROUTING -o wlp2s0 -j MASQUERADE PostDown = iptables -D FORWARD -i %i -j ACCEPT; iptables -t nat -D POSTROUTING -o wlp2s0 -j MASQUERADE
explanation:
Address – A comma-separated list of v4 or v6 IP addresses for the wg0 interface. Use IPs from a range that is reserved for private networks (10.0.0.0/8, 172.16.0.0/12 or 192.168.0.0/16).
ListenPort – The listening port.
PrivateKey – A private key generated by the wg genkey command. (To see the contents of the file type: sudo cat /etc/wireguard/privatekey) Replace SERVER_PRIVATE_KEY with your copy-pasted private key – NOT the path to the privatekey file but the actual contents of the file!
SaveConfig – When set to true, the current state of the interface is saved to the configuration file when shutdown.
PostUp – Command or script that is executed before bringing the interface up. In this example, we’re using iptables to enable masquerading. This allows traffic to leave the server, giving the VPN clients access to the Internet.
Replace the network interface ens0 with your own public internet interface.
You can find this with:
root@intel:/etc/wireguard# ip -o -4 route show to default | awk '{print $5}' wlp2s0 root@intel:/etc/wireguard#
Note for this installation instance Wireguard will be listening on port 51820.
Firewall Config for Wireguard
So you must also open this port in your firewall/s:
ufw allow 51820/udp
Note we are just opening the port for UDP, not for TCP!
Activate firewall if necessary with:
root@intel:~# ufw status
Status: inactive
root@intel:~#
root@intel:~# ufw enable
Firewall is active and enabled on system startup
root@intel:~#
check with:
root@intel:~# ufw verbose Status: active To Action From -- ------ ---- 2812 ALLOW Anywhere 51820/udp ALLOW Anywhere 2812 (v6) ALLOW Anywhere (v6) 51820/udp (v6) ALLOW Anywhere (v6) root@intel:~#
and make sure you save the firewall config:
root@intel:~# iptables-save > /etc/iptables.rules
Then set the file permissions:
root@intel:/etc/wireguard# chmod 600 /etc/wireguard/{privatekey,wg0.conf} root@intel:/etc/wireguard#
and then you should be all set to start the Wireguard interface:
root@intel:/etc/wireguard# wg-quick up wg0 [#] ip link add wg0 type wireguard [#] wg setconf wg0 /dev/fd/63 [#] ip -4 address add 10.0.0.1/24 dev wg0 [#] ip link set mtu 1420 up dev wg0 [#] iptables -A FORWARD -i wg0 -j ACCEPT; iptables -t nat -A POSTROUTING -o wlp2s0 -j MASQUERADE root@intel:/etc/wireguard#
ifconfig shows that the device has been created, and has a virtual IP in the range we specified:
root@intel:/etc/wireguard# ifconfig wg0 wg0: flags=209<UP,POINTOPOINT,RUNNING,NOARP> mtu 1420 inet 10.0.0.1 netmask 255.255.255.0 destination 10.0.0.1 unspec 00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00 txqueuelen 1000 (UNSPEC) RX packets 0 bytes 0 (0.0 B) RX errors 0 dropped 0 overruns 0 frame 0 TX packets 0 bytes 0 (0.0 B) TX errors 174 dropped 0 overruns 0 carrier 0 collisions 0 root@intel:/etc/wireguard#
How To Remove a Wireguard Network Interface
Normally you would not want to do this, but you may wish to in some cases, including if you are deinstalling or deactivating Wireguard. I needed to do this in order to configure the systemd scripts for Wireguard:
root@intel:~# ifconfig wg0 wg0: flags=144<POINTOPOINT,NOARP> mtu 1420 inet 10.0.0.1 netmask 255.255.255.0 destination 10.0.0.1 unspec 00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00 txqueuelen 1000 (UNSPEC) RX packets 0 bytes 0 (0.0 B) RX errors 0 dropped 0 overruns 0 frame 0 TX packets 0 bytes 0 (0.0 B) TX errors 1179 dropped 0 overruns 0 carrier 0 collisions 0 root@intel:~# ip link delete dev wg0 root@intel:~# ifconfig wg0 wg0: error fetching interface information: Device not found root@intel:~# root@intel:~# ip link delete dev wg0 root@intel:~# ifconfig wg0 wg0: error fetching interface information: Device not found root@intel:~# root@intel:~# systemctl enable wg-quick@wg0 Created symlink /etc/systemd/system/multi-user.target.wants/wg-quick@wg0.service → /lib/systemd/system/wg-quick@.service. root@intel:~# systemctl start wg-quick@wg0 root@intel:~# systemctl status wg-quick@wg0 ● wg-quick@wg0.service - WireGuard via wg-quick(8) for wg0 Loaded: loaded (/lib/systemd/system/wg-quick@.service; enabled; vendor preset: enabled) Active: active (exited) since Wed 2021-06-02 14:06:48 CEST; 3s ago Docs: man:wg-quick(8) man:wg(8) https://www.wireguard.com/ https://www.wireguard.com/quickstart/ https://git.zx2c4.com/wireguard-tools/about/src/man/wg-quick.8 https://git.zx2c4.com/wireguard-tools/about/src/man/wg.8 Process: 16684 ExecStart=/usr/bin/wg-quick up wg0 (code=exited, status=0/SUCCESS) Main PID: 16684 (code=exited, status=0/SUCCESS) Jun 02 14:06:48 intel systemd[1]: Starting WireGuard via wg-quick(8) for wg0... Jun 02 14:06:48 intel wg-quick[16684]: [#] ip link add wg0 type wireguard Jun 02 14:06:48 intel wg-quick[16684]: [#] wg setconf wg0 /dev/fd/63 Jun 02 14:06:48 intel wg-quick[16684]: [#] ip -4 address add 10.0.0.1/24 dev wg0 Jun 02 14:06:48 intel wg-quick[16684]: [#] ip link set mtu 1420 up dev wg0 Jun 02 14:06:48 intel wg-quick[16684]: [#] iptables -A FORWARD -i wg0 -j ACCEPT; iptables -t nat -A POSTROUTING -o wlp2s0 -j MASQUERADE Jun 02 14:06:48 intel systemd[1]: Finished WireGuard via wg-quick(8) for wg0. root@intel:~#
The device is then automatically created by the systemd scripts:
root@intel:~# ifconfig wg0 wg0: flags=209<UP,POINTOPOINT,RUNNING,NOARP> mtu 1420 inet 10.0.0.1 netmask 255.255.255.0 destination 10.0.0.1 unspec 00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00 txqueuelen 1000 (UNSPEC) RX packets 0 bytes 0 (0.0 B) RX errors 0 dropped 0 overruns 0 frame 0 TX packets 0 bytes 0 (0.0 B) TX errors 144 dropped 0 overruns 0 carrier 0 collisions 0 root@intel:~# root@intel:~# wg interface: wg0 public key: Y+BuUdkyp+9pJlyfyBcYkCRgcbFqSv/TENH8TGyT6iA= private key: (hidden) listening port: 51820 root@intel:~# root@intel:~# wg --help Usage: wg <cmd> [<args>] Available subcommands: show: Shows the current configuration and device information showconf: Shows the current configuration of a given WireGuard interface, for use with `setconf' set: Change the current configuration, add peers, remove peers, or change peers setconf: Applies a configuration file to a WireGuard interface addconf: Appends a configuration file to a WireGuard interface syncconf: Synchronizes a configuration file to a WireGuard interface genkey: Generates a new private key and writes it to stdout genpsk: Generates a new preshared key and writes it to stdout pubkey: Reads a private key from stdin and writes a public key to stdout You may pass `--help' to any of these subcommands to view usage. root@intel:~#
When you want a client to be given permission to connect to your Wireguard VPN tunnel, you add the following to the wg0.conf:
[Peer] PublicKey = <public_key_of_your_peer> # OPTIONAL, its also possible to define a pre-shared key for additional security.
PresharedKey = <pre-shared key> # at least one peer needs to provide this one.
Endpoint = <end_point_hostname_or_ip:port> # in theory this could be restricted to dn42 networks, however it is easier to do this with iptables/bgp filters/routing table instead just like for openvpn-based peering.
AllowedIPs = 0.0.0.0/0,::/0
Manual Configuration of Wireguard server/client hosts
syntax:
wg set wg0 listen-port 51820 private-key /path/to/peer_A.key
so we do ON server, then on client: same but with different ip – also check the respective network interface device names are correct!
server:
root@gemini:/etc/wireguard# ip link add dev wg0 type wireguard root@gemini:/etc/wireguard# ip addr add 10.0.0.1/24 dev wg0 root@gemini:/etc/wireguard# wg set wg0 listen-port 51820 private-key privatekey root@gemini:/etc/wireguard# ip link set wg0 up root@gemini:/etc/wireguard# wg interface: wg0 public key: L+sHb++AKFZkhDzrSLAhhhxM6SfrpQhVmRFDfUp7lSo= private key: (hidden) listening port: 51820 root@gemini:/etc/wireguard# client:
root@intel:/etc/wireguard# ip link add dev wg0 type wireguard root@intel:/etc/wireguard# ip addr add 10.0.0.2/24 dev wg0 root@intel:/etc/wireguard# wg set wg0 listen-port 51820 private-key privatekey root@intel:/etc/wireguard# ip link set wg0 up root@intel:/etc/wireguard# wg interface: wg0 public key: F8OQkGTjovRIxzvr4YKfpeq7vhAFqQjPKUyh9Eauf04= private key: (hidden) listening port: 51820 root@intel:/etc/wireguard#
then – ESSENTIAL – DO NOT FORGET – this sets the peer relationship – else no connection possible:
root@intel:/etc/wireguard# wg set wg0 peer L+sHb++AKFZkhDzrSLAhhhxM6SfrpQhVmRFDfUp7lSo= allowed-ips 10.0.0.1 endpoint 10.147.18.185:51820 root@intel:/etc/wireguard# wg interface: wg0 public key: F8OQkGTjovRIxzvr4YKfpeq7vhAFqQjPKUyh9Eauf04= private key: (hidden) listening port: 51820
peer: L+sHb++AKFZkhDzrSLAhhhxM6SfrpQhVmRFDfUp7lSo= endpoint: 10.147.18.185:51820 allowed ips: 10.0.0.1/32 root@intel:/etc/wireguard#
and on the other machine:
root@gemini:/etc/wireguard# wg set wg0 peer F8OQkGTjovRIxzvr4YKfpeq7vhAFqQjPKUyh9Eauf04= allowed-ips 10.0.0.2 endpoint 10.147.18.84:51280 root@gemini:/etc/wireguard# root@gemini:/etc/wireguard# wg interface: wg0 public key: L+sHb++AKFZkhDzrSLAhhhxM6SfrpQhVmRFDfUp7lSo= private key: (hidden) listening port: 51820 peer: F8OQkGTjovRIxzvr4YKfpeq7vhAFqQjPKUyh9Eauf04= endpoint: 10.147.18.84:51280 allowed ips: 10.0.0.2/32 transfer: 0 B received, 1.30 KiB sent root@gemini:/etc/wireguard#
Set IP Forwarding:
root@intel:/etc/wireguard# sysctl -w net.ipv6.conf.all.forwarding=1 net.ipv6.conf.all.forwarding = 1 root@intel:/etc/wireguard# sysctl -w net.ipv4.ip_forward=1 net.ipv4.ip_forward = 1 root@intel:/etc/wireguard# sysctl -p net.ipv4.ip_forward = 1 net.ipv4.ip_forward = 1 net.ipv6.conf.default.forwarding = 1 net.ipv6.conf.all.forwarding = 1 net.ipv4.conf.default.rp_filter = 2 net.ipv4.conf.all.rp_filter = 2 root@intel:/etc/wireguard# root@gemini:/etc/wireguard# sysctl -w net.ipv6.conf.all.forwarding=1 net.ipv6.conf.all.forwarding = 1 root@gemini:/etc/wireguard# sysctl -w net.ipv4.ip_forward=1 net.ipv4.ip_forward = 1 root@gemini:/etc/wireguard# sysctl -p net.ipv4.ip_forward = 1 net.ipv6.conf.all.accept_ra = 2 net.core.default_qdisc = fq net.ipv4.tcp_congestion_control = bbr root@gemini:/etc/wireguard#
root@intel:/etc/wireguard# ifconfig wg0 wg0: flags=209<UP,POINTOPOINT,RUNNING,NOARP> mtu 1420 inet 10.0.0.2 netmask 255.255.255.0 destination 10.0.0.2 unspec 00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00 txqueuelen 1000 (UNSPEC) RX packets 0 bytes 0 (0.0 B) RX errors 0 dropped 0 overruns 0 frame 0 TX packets 0 bytes 0 (0.0 B) TX errors 117 dropped 0 overruns 0 carrier 0 collisions 0
root@intel:/etc/wireguard# wg interface: wg0 public key: F8OQkGTjovRIxzvr4YKfpeq7vhAFqQjPKUyh9Eauf04= private key: (hidden) listening port: 48886 root@intel:/etc/wireguard#
server: root@gemini:/etc/wireguard# wg interface: wg0 public key: L+sHb++AKFZkhDzrSLAhhhxM6SfrpQhVmRFDfUp7lSo= private key: (hidden) listening port: 43193 peer: F8OQkGTjovRIxzvr4YKfpeq7vhAFqQjPKUyh9Eauf04= endpoint: 10.147.18.84:36244 allowed ips: 10.0.0.2/32 root@gemini:/etc/wireguard#
root@gemini:/etc/wireguard# cat wg0.conf [Interface] Address = 10.0.0.1/24 SaveConfig = true PostUp = iptables -A FORWARD -i %i -j ACCEPT; iptables -t nat -A POSTROUTING -o ztppizdp4o -j MASQUERADE PostDown = iptables -D FORWARD -i %i -j ACCEPT; iptables -t nat -D POSTROUTING -o ztppizdp4o -j MASQUERADE ListenPort = 43193 PrivateKey = (hidden) [Peer] PublicKey = F8OQkGTjovRIxzvr4YKfpeq7vhAFqQjPKUyh9Eauf04= AllowedIPs = 10.0.0.2/32 Endpoint = 10.147.18.84:36244 root@gemini:/etc/wireguard#
Demo Wireguard Server Connection for Testing Purposes
Wireguard also provides a test script and external server facility for demo purposes which you can use. See below.
After installing WireGuard, you can test your connection using the Wireguard script client.sh located in
/usr/local/bin/wireguard-tools/plain/contrib/examples/ncat-client-server#
$ sudo contrib/examples/ncat-client-server/client.sh
Run this script and it will automatically setup interface wg0, though using a very insecure transport link only suitable for demo purposes:
root@intel:/usr/local/bin/wireguard-tools/plain/contrib/examples/ncat-client-server# ./client.sh root@intel:/usr/local/bin/wireguard-tools/plain/contrib/examples/ncat-client-server# root@intel:/usr/local/bin/wireguard-tools/plain# wg interface: wg0 public key: RORt0LWXzqYdeJ1YYusvyly5JdiBmWrT8hmNgfNlVkk= private key: (hidden) listening port: 49101 peer: JRI8Xc0zKP9kXk8qP84NdUQA04h6DLfFbwJn4g+/PFs= endpoint: 163.172.161.0:12912 allowed ips: 0.0.0.0/0 latest handshake: 1 minute, 25 seconds ago transfer: 40.77 KiB received, 114.82 KiB sent persistent keepalive: every 25 seconds root@intel:/usr/local/bin/wireguard-tools/plain# root@intel:/usr/local/bin/wireguard-tools/plain/contrib/examples/ncat-client-server# ifconfig wg0 wg0: flags=209<UP,POINTOPOINT,RUNNING,NOARP> mtu 1420 inet 192.168.4.46 netmask 255.255.255.0 destination 192.168.4.46 unspec 00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00 txqueuelen 1000 (UNSPEC) RX packets 102 bytes 47496 (47.4 KB) RX errors 0 dropped 0 overruns 0 frame 0 TX packets 1173 bytes 227352 (227.3 KB) TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0 root@intel:/usr/local/bin/wireguard-tools/plain/contrib/examples/ncat-client-server# root@intel:/usr/local/bin/wireguard-tools/plain/contrib/examples/ncat-client-server# route -n Kernel IP routing table Destination Gateway Genmask Flags Metric Ref Use Iface 0.0.0.0 192.168.178.1 0.0.0.0 UG 600 0 0 wlp2s0 10.147.18.0 0.0.0.0 255.255.255.0 U 0 0 0 ztppizdp4o 169.254.0.0 0.0.0.0 255.255.0.0 U 1000 0 0 virbr0 192.168.4.0 0.0.0.0 255.255.255.0 U 0 0 0 wg0 192.168.122.0 0.0.0.0 255.255.255.0 U 0 0 0 virbr0 192.168.178.0 0.0.0.0 255.255.255.0 U 600 0 0 wlp2s0 root@intel:/usr/local/bin/wireguard-tools/plain/contrib/examples/ncat-client-server#
You can then test loading the hidden website at http://192.168.4.1 in a web-browser and sending pings: (you can use any browser, just point browser at the http://192.168.4.1
To redirect your internet traffic using the Wireguard demo server, you can configure it as:
$ sudo contrib/examples/ncat-client-server/client.sh default-route $ curl zx2c4.com/ip 163.172.161.0 demo.wireguard.com curl/7.49.1
However, as Wireguard states, “By connecting to this server, you acknowledge that you will not use it for any abusive or illegal purposes and that your traffic may be monitored.”
When you have finished the test you should disconnect the link:
wg-quick down wg0
root@intel:~# wg-quick down wg0 [#] wg showconf wg0 [#] ip link delete dev wg0 [#] iptables -D FORWARD -i wg0 -j ACCEPT; iptables -t nat -D POSTROUTING -o ztppizdp4o -j MASQUERADE root@intel:~# wg root@intel:~#
Wireguard Debug Info
If you’re using the Linux kernel module and your kernel supports dynamic debugging, you can get useful runtime output by enabling dynamic debug for the module:
# modprobe wireguard && echo module wireguard +p > /sys/kernel/debug/dynamic_debug/control
If you’re using a userspace implementation, set the environment variable export LOG_LEVEL=verbose.
For more info, visit https://www.wireguard.com/quickstart/