Wireguard Port Forwarding
I’ve been trying to setup Wireguard. It’s one of those things where it looks like it should be quite easy, but if it doesn’t work you have no idea why.
I have a computer sitting in our office, and I want to be to access it outside of our office over the internet. Unfortunately, the office is behind a NAT and I can’t just go exposing ports.
SO, I used DigitalOcean to create an tiny Ubuntu server in the cloud. This server has a static IP address, and I have control over which ports are accessible.
My plan is to use Wireguard to create a VPN between the office computer and the cloud server. Then I can forward traffic from the server to the office, quickly and securely.
From now on, I will refer to the office computer as the “client” and the DigitalOcean server as the “server”.
You will need to be root for most of these commands, so I have dropped the
sudo
prefix.
Installing Wireguard
Ubuntu
add-apt-repository ppa:wireguard/wireguard
apt-get update
apt-get install wireguard-dkms wireguard-tools
Arch Linux
You can also use systemd-networkd
to configure wireguard, but I think it just
makes it even more complicated.
pacman -S wireguard-arch wireguard-tools
Generating private/public keys
You need to do this on both the client and the server.
umask 077
cd /etc/wireguard
wg genkey > privatekey
wg pubkey < privatekey > publickey
Configuration
Everything in <>
is a variable and should be replaced.
Server
[Interface]
Address = <SERVER_ADDRESS>
PrivateKey = <SERVER_PRIVATE_KEY>
ListenPort = <SERVER_PORT>
[Peer]
PublicKey = <CLIENT_PUBLIC_KEY>
AllowedIPs = <CLIENT_ADDRESS>/32
Client
[Interface]
Address = <CLIENT_ADDRESS>
PrivateKey = <CLIENT_PRIVATE_KEY>
[Peer]
Endpoint = <SERVER_IP>:<SERVER_PORT>
PublicKey = <SERVER_PUBLIC_KEY>
AllowedIPs = <SERVER_ADDRESS>/32
PersistentKeepalive = 25
Variables
You need to create a new IP address for the client and server. I think this can be any address that isn’t used.
- <SERVER_ADDRESS>: 10.11.12.1
- <CLIENT_ADDRESS>: 10.11.12.2
These are the private and public keys from the different computers. The following are ones I have generated just for this article, and should not be copy/pasted:
- <CLIENT_PRIVATE_KEY>: OOsIW12TAKkv6yec5gp6nNC3TN53/PyajifXHHz1t08=
- <CLIENT_PUBLIC_KEY>: 8xMY/IkM2pEn4ADjEQM+rQLjSbscg4hrqERNqvXAbyg=
- <SERVER_PRIVATE_KEY>: YGSeVUzy6N0KqcvMeYmE2OJXntJCZOq682WYS6elcm4=
- <SERVER_PUBLIC_KEY>: rczpxKe5VPMrjTPZ13/jwCOYQkZEVzgkVFJPeyK2sn8=
Your server should have a static IP. You will also need to pick a port number, and make sure that it isn’t blocked by any firewall.
I like to use random.org to pick port numbers.
- <SERVER_IP>: 175.198.17.240
- <SERVER_PORT>: 45776
Example Server Config
[Interface]
Address = 10.11.12.1
PrivateKey = YGSeVUzy6N0KqcvMeYmE2OJXntJCZOq682WYS6elcm4=
ListenPort = 45776
[Peer]
PublicKey = 8xMY/IkM2pEn4ADjEQM+rQLjSbscg4hrqERNqvXAbyg=
AllowedIPs = 10.11.12.2/32
Example Client Config
[Interface]
Address = 10.11.12.2
PrivateKey = OOsIW12TAKkv6yec5gp6nNC3TN53/PyajifXHHz1t08=
[Peer]
Endpoint = 175.198.17.240:45776
PublicKey = rczpxKe5VPMrjTPZ13/jwCOYQkZEVzgkVFJPeyK2sn8=
AllowedIPs = 10.11.12.1/32
PersistentKeepalive = 25
Starting wireguard
# start wireguard using our config file
systemctl start [email protected]
# set wireguard to start automatically at boot
systemctl enable [email protected]
Checking status
wg show
You should see information about the peer.
interface: wg0
public key: 8xMY/IkM2pEn4ADjEQM+rQLjSbscg4hrqERNqvXAbyg=
private key: (hidden)
listening port: 36494
peer: rczpxKe5VPMrjTPZ13/jwCOYQkZEVzgkVFJPeyK2sn8=
endpoint: 175.198.17.240:45776
allowed ips: 10.11.12.1/32
latest handshake: 9 seconds ago
transfer: 560.43 KiB received, 34.57 KiB sent
persistent keepalive: every 25 seconds
Pinging
Run this on the client to ping the server.
ping 10.11.12.1
Run this on the server to ping the client.
ping 10.11.12.2
Port Forwarding
Now that we have a connection between the client and the server, we can setup port forwarding.
This will forward any incoming traffic to the server on $PORT to the client.
I don’t really understand how iptables
works, I just copied this from:
https://golb.hplar.ch/2019/01/expose-server-vpn.html
#!/usr/bin/env bash
PORT=6379
SERVER_ADDRESS=10.11.12.1
CLIENT_ADDRESS=10.11.12.2
iptables -P FORWARD DROP
iptables -A FORWARD -i eth0 -o wg0 -p tcp --syn --dport ${PORT} -m conntrack --ctstate NEW -j ACCEPT
iptables -A FORWARD -i eth0 -o wg0 -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
iptables -A FORWARD -i wg0 -o eth0 -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
iptables -t nat -A PREROUTING -i eth0 -p tcp --dport ${PORT} -j DNAT --to-destination ${CLIENT_ADDRESS}
iptables -t nat -A POSTROUTING -o wg0 -p tcp --dport ${PORT} -d ${CLIENT_ADDRESS} -j SNAT --to-source ${SERVER_ADDRESS}
Saving IP Tables
This will persist your iptables rules in case the server restarts.
apt install iptables-persistent