I am attempting a chained/double-hop VPN setup where all client traffic passes through 2 servers before reaching the internet:
Client → Server1 → Server2 → Public Internet
All peers are on these private address blocks: 10.103.213.0/24
(IPv4) and fd6f:9403:2887:9cd6:10:103:213:0/112
(IPv6). Below are the configurations of the peers and the IPTables rules in place. (Please also note the names of the configuration files, in case it matters.)
Server2 Configuration
File: /etc/wireguard/wg0.conf
# Server2
[Interface]
PrivateKey = SERVER2_PRIVATE_KEY
Address = 10.103.213.2/24, fd6f:9403:2887:9cd6:10:103:213:2/112
ListenPort = 53701
SaveConfig = false
# CLIENTS
[Peer] # Server1
PublicKey = SERVER1_PUBLIC_KEY
PresharedKey = SERVER1_PRESHARED_KEY
# ↓ to allow traffic from client (10.103.213.11/32) via Server1 (10.103.213.1/32), allow both
AllowedIPs = 10.103.213.0/24, fd6f:9403:2887:9cd6:10:103:213:0/112
Firewall config. commands:
ufw allow 53701/udp comment 'WireGuard VPN'
iptables -A FORWARD -i wg0 -j ACCEPT &&
iptables -A FORWARD -o wg0 -j ACCEPT &&
ip6tables -A FORWARD -i wg0 -j ACCEPT &&
ip6tables -A FORWARD -o wg0 -j ACCEPT
iptables -t nat -A POSTROUTING -s 10.103.213.0/24 -o enp8s0 -j MASQUERADE
ip6tables -t nat -A POSTROUTING -s fd6f:9403:2887:9cd6:10:103:213:0/112 -o enp8s0 -j MASQUERADE
Server1 Configuration
File: /etc/wireguard/wg0.conf
# Server1
[Interface]
PrivateKey = SERVER1_PRIVATE_KEY
Address = 10.103.213.1/24, fd6f:9403:2887:9cd6:10:103:213:1/112
ListenPort = 53701
SaveConfig = false
# CLIENTS
[Peer] # Server2
PublicKey = SERVER2_PUBLIC_KEY
PresharedKey = SERVER1_PRESHARED_KEY
Endpoint = SERVER2_PUBLIC_IP:53701
AllowedIPs = 10.103.213.2/32, fd6f:9403:2887:9cd6:10:103:213:2/128
#PersistentKeepalive = 25
[Peer] # PC
PublicKey = CLIENT_PUBLIC_KEY
PresharedKey = CLIENT_PRESHARED_KEY
AllowedIPs = 10.103.213.11/32, fd6f:9403:2887:9cd6:10:103:213:11/128
Firewall config. commands:
ufw allow 53701/udp comment 'WireGuard VPN'
iptables -A FORWARD -i wg0 -j ACCEPT &&
iptables -A FORWARD -o wg0 -j ACCEPT &&
ip6tables -A FORWARD -i wg0 -j ACCEPT &&
ip6tables -A FORWARD -o wg0 -j ACCEPT
Client Configuration
# CLIENT: PC
[Interface]
PrivateKey = CLIENT_PRIVATE_KEY
Address = 10.103.213.11/24, fd6f:9403:2887:9cd6:10:103:213:11/112
DNS = 10.103.213.1, fd6f:9403:2887:9cd6:10:103:213:1
[Peer] # Server1
PublicKey = SERVER1_PUBLIC_KEY
PresharedKey = CLIENT_PRESHARED_KEY
Endpoint = SERVER1_PUBLIC_IP:53701
AllowedIPs = 0.0.0.0/0, ::0/0
#PersistentKeepalive = 25
Now, like I said, I am able to ping Server1 (10.103.213.2
) and Server2 (10.103.213.1
) from the Client (10.103.213.11
) on the private (WireGuard) network when the VPN is enabled on all peers, but I cannot access the internet.
I know I'm missing some much needed IP routes or IPTables rules, but despite trying to find a solution that I can understand for days, I've had no success. I see that there's little hope for me without actually reading a book on Linux networking/firewall.
For now, I am hoping someone can help me with a solution along with an explanation as to what we are doing and why, so I can understand better and take notes.
Thank you very much!
NOTES:
If I'm missing any useful information, please ask and I'll be happy to get it.
Client runs macOS. Server1 and Server2 run Debian 11 "Bullseye". Just an FYI, in case it's relevant.
Server1 and Server2 have Unbound installed and set up for local DNS resolution. That's why you see
DNS = 10.103.213.1, fd6f:9403:2887:9cd6:10:103:213:1
in Client config. If not for that, I'd be using either CloudFlare or Google's IPs there.Someone on #wireguard IRC suggested that I try adding
Table = 123
under[Interface]
in Server1's WireGuard config. and then running the commandip rule add iif wg0 table 123
. That didn't work and I couldn't understand what it's supposed to do either (I couldn't make sense of the man pages or the technical details).From my reading I came to the conclusion that
iptables
andufw
can be used together—except one has to be careful when usingiptables-persistent
. You need to runnetfilter-persistent save
even after runningufw
commands for the firewall rules to be persistent across reboots even ifufw status
says they are in place. If for some reason you reboot before saving, delete the UFW rules and add them again and then runnetfilter-persistent save
.
iptables-persistent
(netfilter-persistent save
even after runningufw
commands). No others issues whatsoever.