When using WireGuard to tunnel your traffic through a VPS, your P2P applications like qBittorrent or AirDC++ lose direct inbound connectivity because:
- The VPS becomes your network gateway
- Incoming ports aren't automatically forwarded like on a home router
- NAT traversal needs explicit iptables rules
First ensure these prerequisites:
# On your VPS (as root):
sysctl -w net.ipv4.ip_forward=1
echo 'net.ipv4.ip_forward = 1' >> /etc/sysctl.conf
ufw allow 56000/tcp
ufw allow 56000/udp
Modify your /etc/wireguard/wg0.conf
to include:
[Interface]
Address = 10.66.66.1/24
ListenPort = 49503
PrivateKey = YOUR_SERVER_PRIVATE_KEY
PostUp = iptables -A FORWARD -i %i -j ACCEPT; iptables -t nat -A PREROUTING -p tcp --dport 56000 -j DNAT --to-destination 10.66.66.2; iptables -t nat -A PREROUTING -p udp --dport 56000 -j DNAT --to-destination 10.66.66.2
PostDown = iptables -D FORWARD -i %i -j ACCEPT; iptables -t nat -D PREROUTING -p tcp --dport 56000 -j DNAT --to-destination 10.66.66.2; iptables -t nat -D PREROUTING -p udp --dport 56000 -j DNAT --to-destination 10.66.66.2
[Peer]
PublicKey = CLIENT_PUBLIC_KEY
AllowedIPs = 10.66.66.2/32
After restarting WireGuard (wg-quick down wg0 && wg-quick up wg0
), verify with:
# Check NAT rules:
iptables -t nat -L -n -v
# Test port forwarding:
nc -zv YOUR_VPS_IP 56000
For handling multiple ports (e.g., 56000-56100):
PostUp = iptables -t nat -A PREROUTING -p tcp --match multiport --dports 56000:56100 -j DNAT --to-destination 10.66.66.2
PostDown = iptables -t nat -D PREROUTING -p tcp --match multiport --dports 56000:56100 -j DNAT --to-destination 10.66.66.2
Ensure your client config (/etc/wireguard/wg0.conf
) has:
[Interface]
PrivateKey = CLIENT_PRIVATE_KEY
Address = 10.66.66.2/32
[Peer]
PublicKey = SERVER_PUBLIC_KEY
Endpoint = YOUR_VPS_IP:49503
AllowedIPs = 0.0.0.0/0
PersistentKeepalive = 25
- Verify VPS firewall isn't blocking the forwarded port
- Check kernel IP forwarding is enabled (
cat /proc/sys/net/ipv4/ip_forward
) - Confirm WireGuard connection is active (
wg show
) - Test raw port connectivity before testing with applications
When routing P2P traffic (like qBittorrent or Airdcpp) through a WireGuard VPN on a VPS, you lose direct port accessibility. Unlike home router port forwarding where you map WAN_IP:56000 → 192.168.1.124:56000
, VPS-based VPNs require additional iptables rules to maintain "connectable" status.
Given your current /etc/wireguard/wg0.conf
:
[Interface] Address = 10.66.66.1/24,fd42:42:42::1/64 ListenPort = 49503 PrivateKey = *** PostUp = iptables -A FORWARD -i %i -j ACCEPT; iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE PostDown = iptables -D FORWARD -i %i -j ACCEPT; iptables -t nat -D POSTROUTING -o eth0 -j MASQUERADE [Peer] PublicKey = *** PresharedKey = *** AllowedIPs = 10.66.66.2/32,fd42:42:42::2/128
Key missing components:
- No DNAT rules for port forwarding
- Lacking connection tracking for P2P protocols
Add these rules after your existing PostUp commands:
# Port forwarding for qBittorrent iptables -t nat -A PREROUTING -i eth0 -p tcp --dport 56000 -j DNAT --to-destination 10.66.66.2:56000 iptables -t nat -A PREROUTING -i eth0 -p udp --dport 56000 -j DNAT --to-destination 10.66.66.2:56000 # Allow forwarded traffic through firewall iptables -A FORWARD -i eth0 -o wg0 -p tcp --dport 56000 -j ACCEPT iptables -A FORWARD -i eth0 -o wg0 -p udp --dport 56000 -j ACCEPT # Enable connection tracking (critical for P2P) iptables -A FORWARD -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
After applying changes:
# Check NAT rules sudo iptables -t nat -L PREROUTING -vn # Test port accessibility nc -zv YOUR_VPS_IP 56000 # Monitor forwarded packets sudo conntrack -E
For applications requiring port ranges (e.g., 56000-56020):
iptables -t nat -A PREROUTING -i eth0 -p tcp --dport 56000:56020 -j DNAT --to-destination 10.66.66.2 iptables -t nat -A PREROUTING -i eth0 -p udp --dport 56000:56020 -j DNAT --to-destination 10.66.66.2
- Ensure
net.ipv4.ip_forward=1
is set in/etc/sysctl.conf
- Whitelist ports in UFW:
sudo ufw allow 56000/tcp && sudo ufw allow 56000/udp
- For IPv6, duplicate rules using
ip6tables