Affiliate disclosure - This post contains Contabo affiliate links. If you grab a VPS through them, we earn a commission at no extra cost to you.
Nearly every WireGuard server config carries some version of this block, and almost nobody who pastes it can say what the third line does:
PostUp = iptables -A FORWARD -i %i -j ACCEPT; iptables -A FORWARD -o %i -j ACCEPT; iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
PostDown = iptables -D FORWARD -i %i -j ACCEPT; iptables -D FORWARD -o %i -j ACCEPT; iptables -t nat -D POSTROUTING -o eth0 -j MASQUERADE
It is worth ten minutes, because these lines are where a working tunnel and a silent one part company.
What PostUp and PostDown actually are
They are not WireGuard features. They are shell commands that wg-quick runs after bringing the interface up and after tearing it down. WireGuard moves encrypted packets and does nothing else: no NAT, no filtering, no forwarding. Everything on top of that is a command you put here.
%i is expanded by wg-quick to the interface name, so the same config file works whether the interface is wg0 or wg1.
This also means PostDown matters more than it looks. Rules added with iptables -A accumulate. A tunnel restarted five times without matching PostDown lines leaves five copies of each rule, and the resulting chain is a mess to read six months later.
Line by line
iptables -A FORWARD -i %i -j ACCEPT accepts packets arriving on the tunnel that need to be forwarded somewhere else. This is traffic from a client heading for the internet.
iptables -A FORWARD -o %i -j ACCEPT accepts packets going out through the tunnel, which is the return path. Without it, replies come back to the server and stop there.
iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE rewrites the source address of outgoing packets to the server's own public address. Without this, a website receives a packet from 10.10.0.2, a private address, and its reply goes nowhere.
Note eth0 in that line. On many modern distributions the interface is not called eth0. Check with ip route get 1.1.1.1 and use whatever it names. A copied config with the wrong interface produces exactly the symptom people describe as "connects but no internet".

The kernel setting the rules cannot replace
None of this works while the kernel refuses to forward:
sysctl -w net.ipv4.ip_forward=1
echo "net.ipv4.ip_forward=1" >> /etc/sysctl.d/99-wireguard.conf
Add net.ipv6.conf.all.forwarding=1 if peers use IPv6. Writing it only with sysctl -w works until the next reboot, and then the tunnel comes up fine and carries nothing, which is a memorable way to spend an evening.
Two rules worth adding, and one worth deleting
Add an MSS clamp if clients report that some sites load and others hang:
PostUp = iptables -t mangle -A FORWARD -o %i -p tcp --tcp-flags SYN,RST SYN -j TCPMSS --clamp-mss-to-pmtu
This makes TCP negotiate a segment size that fits the tunnel, and it removes a whole class of complaints. It overlaps with the MTU question and does not replace it.
Restrict the masquerade to your tunnel subnet rather than everything leaving the box:
iptables -t nat -A POSTROUTING -s 10.10.0.0/24 -o eth0 -j MASQUERADE
On a single purpose VPS the difference is theoretical. On a machine doing other work it stops the rule applying to traffic that was never yours to translate.
Drop the FORWARD accept lines if your server is a pure peer to peer endpoint where each side only reaches the other. Nothing is being forwarded, so the rules do nothing except suggest a routing setup that is not there.
If you already use ufw or nftables
Mixing raw iptables commands with ufw works, because ufw is a front end to the same tables, but the result is a firewall whose state is described in two places. Pick one and stay there: either ufw owns the rules and you add yours with ufw route allow, or ufw is disabled and PostUp owns everything.
On a distribution using nftables natively, the iptables command is usually a compatibility shim. It works. It also means nft list ruleset shows your rules in a translated form that does not match what you wrote, which is worth knowing before you conclude something has gone wrong.
For a full server build with these rules in place from the start, see self-hosting WireGuard on a VPS, and for locking the tunnel down further, WireGuard kill switch with iptables and systemd.
★ Nuremberg GDPR datacenter · ✓ Dedicated IPv4 included · 200+ Mbps guaranteed
Self-host your VPN on your own VPS → ContaboFull root access · public IPv4 · pick your region→


