Last active
January 15, 2026 23:34
-
-
Save SpaghettiBorgar/83dccbcec9edcd2951bbd5debde67136 to your computer and use it in GitHub Desktop.
NAT-PMP multi port symmetric forwarding script for wireguard connections
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #!/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