Skip to content

Instantly share code, notes, and snippets.

@SpaghettiBorgar
Last active January 15, 2026 23:34
Show Gist options
  • Select an option

  • Save SpaghettiBorgar/83dccbcec9edcd2951bbd5debde67136 to your computer and use it in GitHub Desktop.

Select an option

Save SpaghettiBorgar/83dccbcec9edcd2951bbd5debde67136 to your computer and use it in GitHub Desktop.
NAT-PMP multi port symmetric forwarding script for wireguard connections
#!/bin/bash
### Wireguard NAT-PMP port forwarding script
# https://gist.github.com/SpaghettiBorgar/83dccbcec9edcd2951bbd5debde67136
# Default values
: ${PMP_ROUTER:=10.2.0.1}
: ${PMP_INTERVAL:=50} # nat-pmp request lifetime will be set to PMP_INTERVAL+10
: ${PMP_PORT_PREFIX:=5000} # maps to local por1ts 50001-50009
: ${PMP_TUN:=tun0}
: ${PMP_PORT_UP_CMD1:='echo Port 1 is $PORT'} # use $PORT for the forwarded port and be sure to escape the entire command as a bash command string
echo Started Port Forwarder
map_port() {
iptables -t nat -D PREROUTING -p $3 --dport $1 -j REDIRECT --to-ports $2 2>/dev/null
iptables -t nat -A PREROUTING -p $3 --dport $1 -j REDIRECT --to-ports $2
iptables -t filter -D INPUT -i $PMP_TUN -p $3 -m $3 --dport $2 -j ACCEPT 2>/dev/null
iptables -t filter -A INPUT -i $PMP_TUN -p $3 -m $3 --dport $2 -j ACCEPT
}
request_port() {
PORT=$(natpmpc -a 1 $1 udp $(($PMP_INTERVAL + 10)) -g "$PMP_ROUTER" | sed "s/protocol UDP //" | grep "Mapped public port" | tee /dev/stderr | cut -d' ' -f4) &&
natpmpc -a 1 $1 tcp $(($PMP_INTERVAL + 10)) -g "$PMP_ROUTER" ||
{ echo "ERROR with natpmpc" > /dev/stderr; unset PORT; return 1; }
if [ -z "$PORT" ]; then
echo "Something went wrong, port not set." > /dev/stderr
unset PORT
return 1
fi
map_port $1 $PORT udp
map_port $1 $PORT tcp
return
}
sleep 2
while true; do
for i in {1..9}; do
CMD_VAR="PMP_PORT_UP_CMD$i"
if [ -z "${!CMD_VAR}" ]; then
break
fi
request_port $PMP_PORT_PREFIX$i
if [ -n "$PORT" ]; then
eval "${!CMD_VAR}"
fi
done
sleep $PMP_INTERVAL
done
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment