Let’s say you have two servers: Cabbage and BEETroot (naming your servers after vegetables is normal, right?). Cabbage hosts a database and some other services and BEETroot hosts your application. You want them to be able to connect to each other securely, without having to deal with securing every one of the services to go over the Internet.
This guide was written for Ubuntu Server 18.04, but should be valid for any Linux system (aside from the installation steps).
sudo add-apt-repository ppa:wireguard/wireguard sudo apt-get install wireguard
On each server, a private key needs to be generated and a public key derived from it. For convenience, the bottom command will save both to files, named after the server’s hostname:
user@both-servers:~ $ wg genkey | tee "$(hostname -s).wgpriv" | wg pubkey > "$(hostname -s).wgpub"
Both should look similar to this:
The Wireguard config files reside in /etc/wireguard/. They are ini files, use the .conf extension and are named after their Wireguard interfaces (wg[number]).
You will also need to decide on a port (which you will have to open) and private IP address for each of the servers (on the same subnet, of course).
Our convention is to use the same iface name and port (starting at 51820) on both sides of a P-P link and IPv4 addresses in a /31 subnet. (
iface wg[n] ipv4 10.0.[n].[0,1]/31 port 51820+[n])
Edit /etc/wireguard/wg[n].conf with root privs:
# P-P link to [other side] # Our config [Interface] Address = [our INTERNAL address]/31 PrivateKey = [our privkey] ListenPort = [our port] # [other side] [Peer] PublicKey = [other side's pubkey] AllowedIPs = [other side's INTERNAL address]/31 Endpoint = [other side's EXTERNAL address]:[other side's port]
An example for Cabbage would therefore be:
# P-P link to BEETroot # Our config [Interface] Address = 10.0.0.1/31 PrivateKey = gMFBuyVWbx/O9DAn2ajAhnNN0GAfZTM8u7d0HTJoqWs= ListenPort = 51820 # BEETroot [Peer] PublicKey = omFWU/kRAAQOU+31j6RoIPA7HLVSqW67BvQuZ9z1uxA= AllowedIPs = 10.0.0.0/31 Endpoint = beetroot.example.com:51820
Applying and testing
Assuming the previous example (wg0):
# Apply config user@both-servers:~ $ sudo wg-quick up wg0 # Start the connection user@both-servers:~ $ systemctl start wg-quick@wg0 # Make start on startup (optional) user@both-servers:~ $ systemctl enable wg-quick@wg0
Let’s see if it works (example output):
user@Cabbage:~ $ sudo wg show interface: wg0 public key: omFWU/kRAAQOU+31j6RoIPA7HLVSqW67BvQuZ9z1uxA= private key: (hidden) listening port: 51820 peer: omFWU/kRAAQOU+31j6RoIPA7HLVSqW67BvQuZ9z1uxA= endpoint: 198.51.100.42:51820 allowed ips: 10.1.0.0/31 latest handshake: 1 second ago transfer: 148 B received, 92 B sent user@Cabbage:~ $ ping 10.1.0.0 -c 1 PING 10.1.0.0 (10.1.0.0) 56(84) bytes of data. 64 bytes from 10.1.0.0: icmp_seq=1 ttl=64 time=46.1 ms --- 10.1.0.0 ping statistics --- 1 packets transmitted, 1 received, 0% packet loss, time 0ms rtt min/avg/max/mdev = 46.174/46.174/46.174/0.000 ms