Wireguard Ubuntu Deployment
Installation
sudo add-apt-repository ppa:wireguard/wireguard
sudo apt install wireguard
Enabling IPv4 Forwarding
sudo echo "net.ipv4.ip_forward = 1" >> /etc/sysctl.conf
sudo echo "net.ipv4.conf.all.proxy_arp = 1" >> /etc/sysctl.conf
sudo sysctl -p /etc/sysctl.conf
This equivalent to commenting the following 2 lines below in /etc/sysctl.conf file and then running sudo sysctl -p
net.ipv4.ip_forward = 1
net.ipv4.conf.all.proxy_arp = 1
Making Wireguard a system service
The command below enables Wireguard as a system service so it always starts on system reboot.
sudo systemctl enable wg-quick@wg0.service
Opening UDP Ports
Before starting, you need to open a UDP port on your firewall pointing to the server. You can use any UDP port. I use 51820/udp because it is the standard Wireguard port.
If you have ufw (uncomplicated firewall) enabled, on the server you must also allow the port thru.
The commands below will allow ports 22/tcp and 51820/udp thru and enable UFW (a second firewall on the server). If you don't want to use UFW you can disable it with sudo ufw disable.
sudo ufw status # To check if ufw is enabled.
sudo ufw allow 22/tcp comment 'OpenSSH'
sudo ufw allow 51820/udp comment 'Wireguard'
sudo ufw enable
sudo ufw status numbered # Repeat to check if the new UFW rules were added.
Server Configuration
First generate a private public key pair. You can do this in either…
- Tunsafe, a Windows Wireguard client
-
or Ubuntu with the commands below
umask 077
wg genkey | tee privatekey | wg pubkey > publickey
# Key pairs are saved in same path you typed these commands in
Now create a configuration file in /etc/wireguard/wg0.conf. Use the example configuration below.
Important! In the example config, replace eth0 with your server’s actual interface name in lines 7-8. Ignore lines 11-18 because they are for reference. You can find the server’s actual interface name with ip a. Continue on below to replace the rest of the variables in the example config.
[Interface]
Address = 10.xx.xx.1/24xx
ListenPort = 51820
PrivateKey = <Server's Private Key Here>
# Demo Config
PostUp = iptables -A FORWARD -i wg0 -j ACCEPT; iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE; ip6tables -A FORWARD -i wg0 -j ACCEPT; ip6tables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
PostDown = iptables -D FORWARD -i wg0 -j ACCEPT; iptables -t nat -D POSTROUTING -o eth0 -j MASQUERADE; ip6tables -D FORWARD -i wg0 -j ACCEPT; ip6tables -t nat -D POSTROUTING -o eth0 -j MASQUERADE
# Demo Config END
# Main Docker Config
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
# Main Docker Config END
# JoinDigital Config START
PostUp = iptables -A FORWARD -i wg0 -j ACCEPT; iptables -t nat -A POSTROUTING -o ens2 -j MASQUERADE; ip6tables -A FORWARD -i wg0 -j ACCEPT; ip6tables -t nat -A POSTROUTING -o ens2 -j MASQUERADE; iptables -A FORWARD -i wg0 -j ACCEPT; iptables -t nat -A POSTROUTING -o ens7 -j MASQUERADE; ip6tables -A FORWARD -i wg0 -j ACCEPT; ip6tables -t nat -A POSTROUTING -o ens2 -j MASQUERADE
PostDown = iptables -D FORWARD -i wg0 -j ACCEPT; iptables -t nat -D POSTROUTING -o ens2 -j MASQUERADE; ip6tables -D FORWARD -i wg0 -j ACCEPT; ip6tables -t nat -D POSTROUTING -o ens2 -j MASQUERADE; iptables -D FORWARD -i wg0 -j ACCEPT; iptables -t nat -D POSTROUTING -o ens7 -j MASQUERADE; ip6tables -D FORWARD -i wg0 -j ACCEPT; ip6tables -t nat -D POSTROUTING -o ens2 -j MASQUERADE
# JoinDigital Config END
# SaveConfig = true #If you want your configs to be saved on restart
[Peer]
PublicKey = <Client's Public Key Here>
AllowedIPs = 10.xx.xx.2/32
[Peer]
PublicKey = <Client's Public Key Heree>
AllowedIPs = 10.xx.xx.3/32
Explanation for [Interface] section
Address = 10.xx.xx.1/xx
For this field create and choose an arbitrary “Private IP address” different from other subnets on this VM’s network to avoid IP conflict. Also specify the IP range you’re going to use like /24. A valid example would be “10.10.10.1/24”.
ListenPort = 51820
This is the UDP port the wireguard instance listens on. If you chose a different port replace 51820 with your specified UDP port.
PrivateKey = <Server’s Private Key Here>
Enter in the key you generated. There were two keys generated, the server’s public and the server’s private key pair. Enter in the server’s private key. For example
PrivateKey = KDNXaJyH+/zlad6d4QjWw7ia6NFVbx0aZUK/MzNfemg=
Explanation for [Peer] section
ForYou an add multiple Peers here. Peers are clients that will be connecting to the Wireguard server. To create a peer justyou will need to generate a new key pair (public and private key) for every new peer. The previous key pair was generated only the server.
For every new peer keep incrementing your arbitrary IP addressAllowedIPs by one &starting usefrom the Server’s IP.
For example,
[Peer]
PublicKey = /OcKAjgY8z6Hjrlyvwv9Fpy46y8K/p+Vbwq42SkGqEo=
AllowedIPs = 10.4.0.2/32
This itconcludes isthe oneServer IP.Configuration. ThenStart enterthe inWireguard theirservice publicwith
sudo systemctl start wg-quick@wg0.service
Adding More Clients to Server
Method #1: While Wireguard Is Live (Restarting Interface)
This method requires SaveConfig = true in your config.
Adding a peer (Changes not saved yet)
sudo wg set wg0 peer <Client Public Key> allowed-ips 10.X.X.X/3
Check if new peer's public key and ip shows up with
sudo wg
Finally do a
sudo systemctl restart wg-quick@wg0.service
Method #2: While Wireguard Is Live (wg-quick save wg0)
Also requires SaveConfig = true in your config.
sudo wg set wg0 peer <Client Public Key> allowed-ips 10.X.X.X/32
sudo wg show
sudo wg-quick save wg0
route 10.X.X.X/32 wg0The difference with using a wg-quick save is that you have to do the 4th command of route add which is easy to fat finger and screw things up.
Method #3: While Wireguard Is Off
sudo wg-quick down wg0
# Edit your /etc/wireguard/wg0.conf file and add the peers you need there
sudo wg-quick up wg0
GeneratingCreating Client.conf Configurationsfile Forfor Users
Peer (Client)
ExampleNow configuration.that Pleaseserver readsetup is complete. We need to create .conf files for the gotchaspeer. The peer will need the .conf file for eachtheir OS.Wireguard client to connect to the server. This is how they “login”.
An example peer .conf based on the example keys generated in this doc is below.
Notice that unlike the server config, in the client config…
-
[Interface] refers to the client.
-
[Peer] refers to the server.
[Interface]
PrivateKey = < Client Private Key Here >6PzKF4A1ERmVwDkEJdd9oDazNOJMFFxI83GRZXCXs18=
Address = 10.X.X.0/244.0.2/32
DNS = 8.8.8.8
[Peer]
PublicKey = < Server Public Key Here >Hudb36rtqyTkHn3YUr+jbUTOfNMzNMQU5mzW9XbZCns=
AllowedIPs = 0.0.0.0/0, ::/0
Endpoint = ServerPublicIPAdress:ServersPublicIPAdress:51820
PersistentKeepalive = 25
Explanation
AAssume coupleI’m the client. Assume the wireguard server is on the same network as 192.168.1.0/24
Setting AllowedIPs = 0.0.0.0/0, ::/0 under [Peer] will create a full tunnel, meaning all of gotchasthe my internet traffic will appear as if it came from Wireguard server. This is similar to note.buying and using a third party VPN provider such as NordVPN.
If I only want traffic to local network resources to be tunneled while the rest of my traffic to be untunneled. I have to do a split tunnel. To do this, change AllowedIPs to a local IP address space.
For example I have local network resources in 192.168.1.0/24, so I set
AllowedIPs = 192.168.1.0/24
Now all traffic that goes to the 192.168.1.0/24 address space will be tunneled. Traffic outside of this space such as to www.google.com will not be tunneled.
Client .conf Gotchas
In Linux, the Address = line needs to end in /32. The DNS = line best be removed.
In Mac OS & Windows the Address = lines needs to end in /24 or theyour subnetpreferred assigned.
Also in Linux the DNS = line cannot be there it has to be erased.space.
In Mac OS the DNS = lineneedsline tois be thererequired. otherwise client cannot browse Internet. You can use DNS = 8.8.8.8 as an example.
In Windows TunsafeWindows, the DNS = line is optional.optional Infor WindowsTunsafe. Wireguard theThe DNS = line is required.required for the official Wireguard client.
Optional
This Configurationsconcludes the full server and client setup.
Optional: Isolating Wireguard Clients From Each Other
This can be achieved with the following IP Tables command below assuming your wireguard interface is "wg0"
iptables -I FORWARD -i wg0 -o wg0 -j REJECT
Command References
sysctl net.ipv4.ip_forward ### Verifies if IP Forward is working
sudo systemctl enable wg-quick@wg0 ### Makes Wireguard auto-start on boot
sudo systemctl restart wg-quick@wg0 ### Restart Wireguard in systemctl
sudo systemctl start wg-quick@wg0 ### Start Wireguard in systemctl
sudo systemctl stop wg-quick@wg0 ### Stop Wireguard in systemctl
sudo wg show ### #Check if VPN tunnel is running
wg-quick up wg0 # Depreciated: Turn on Wireguard Interface
wg-quick down wg0 # Depreciated: Turn off Wireguard Interface
#command to remove client (peer)
wg set wg0 peer peer_pubkey remove
#Don't know if this command is needed after wg-quick save or removal of client
wg addconf wgnet0 <(wg-quick strip wgnet0)
### Generating Key Pairs ###
umask 077
wg genkey | tee privatekey | wg pubkey > publickey
# Key pairs are saved in same path you typed this command in
### End Generating Key Pairs ###