|
guides August 4, 2025, 6:43am 1
This guide was created using the thread linked below, but is expanded to include a service that automatically updates the forwarded port in the firewall.
Port forwarding with proton Network and Wireless Configuration I got Proton setup as the VPN for my home network. I am trying to get port forwarding to work as well. I have been using this guide https://protonvpn.com/support/port-forwarding-manual-setup/ I installed the natpmpc package for openwrt so that I could see which port is open (see natpmpc command below). The problem I am running into, is it still does not appear open. I am assuming I may need a PBR policy or firewall policy just not sure what. while true ; do date ; natpmpc -a 1 0 udp 60 -g 10.…Another important source of information that helped create this guide was:
A guide to manually configuring port forwarding for Proton VPN using the NAT-PMP protocol on macOS and Linux This guide assumes that you have ProtonVPN configured in your OpenWRT router, with a lan and a vpn firewall zone, as well as an application (e.g. Qbittorrent) to forward the port to. If you need a guide to setup wireguard in OpenWRT for any VPN, I recommend this one:
In OpenWRT install natpmpc. This should also install: libnatpmp opkg install natpmpc libnatpmpCheck that port forwarding is allowed on the server you’re connected to. To do this, open a terminal window and enter: natpmpc -g 10.2.0.1Add the following to /etc/config/firewall or manually in https://192.168.1.X > Network > Firewall > Port Forwards nano /etc/config/firewall config redirect option dest 'lan' option target 'DNAT' option src 'vpn' option dest_ip '192.168.1.X' option dest_port '443' option name 'ProtonVPN_Port_Forwarder' option src_dport '12345'This is what you need to know about the redirect firewall configuration: dest = is the lan firewall zone target = is added automatically, not available in GUI. src = is the vpn firewall zone dest_ip = is the local/lan ip of the application you want to forward the port to. (e.g. QbitTorrent) dest_port = 443 is the default SSL port. name = "ProtonVPN_Port_Forwarder" this has to match redirect=$(uci show firewall | grep ".name='ProtonVPN_Port_Forwarder'"in order for the proton service to automatically update the src_dport option. src_dport = is the port opened by ProtonVPN. This option gets updated automatically by the proton service. 12345 is a temporary port, that will change once the proton service starts.Create the proton service to forward ProtonVPN ports (I use nano, but feel free to use VI or any other editor): nano /etc/init.d/proton #!/bin/sh /etc/rc.common # Service name: ProtonVPN_Port_Forwarder # Description: ProtonVPN Port Forwarding # Location: /etc/init.d/proton START=99 STOP=10 PID_FILE="/var/run/ProtonVPNPortForwarder.pid" LOG_FILE="/var/log/ProtonVPNPortForwarder.log" start() { echo "Starting ProtonVPN Port Forwarder" if [ -f "$PID_FILE" ] && kill -0 $(cat "$PID_FILE") 2>/dev/null; then echo "Service already running (PID $(cat "$PID_FILE"))" return 1 fi { while true; do echo "[$(date)] Checking port mappings..." >> "$LOG_FILE" echo "--- UDP Port Forward ---" >> "$LOG_FILE" # Run UDP mapping (silent) natpmpc -a 1 0 udp 60 -g 10.2.0.1 >> "$LOG_FILE" 2>&1 echo "--- TCP Port Forward ---" >> "$LOG_FILE" # Run TCP mapping and extract port number tcp_output=$(natpmpc -a 1 0 tcp 60 -g 10.2.0.1 2>&1) echo "$tcp_output" >> "$LOG_FILE" # Extract ONLY the port number if mapping succeeded if echo "$tcp_output" | grep -q "Mapped public port"; then port=$(echo "$tcp_output" | grep -oE "port [0-9]+" | awk '{print $2}' | head -n1) #echo "$port" # Update /etc/config/firewall redirect=$(uci show firewall | grep ".name='ProtonVPN_Port_Forwarder'" | cut -d'=' -f1 | cut -d'.' -f2) uci set firewall."$redirect".src_dport="$port" uci commit firewall /etc/init.d/firewall reload >> "$LOG_FILE" 2>&1 echo "Updated src_dport in /etc/config/firewall to $port" >> "$LOG_FILE" else echo "ERROR: Port forwarding failed" >> "$LOG_FILE" break fi sleep 45 done } & echo $! > "$PID_FILE" echo "Service started (PID $(cat "$PID_FILE"))" } stop() { echo "Stopping ProtonVPN Port Forwarder" if [ -f "$PID_FILE" ]; then kill $(cat "$PID_FILE") 2>/dev/null rm -f "$PID_FILE" fi killall natpmpc 2>/dev/null echo "Service stopped" } restart() { stop sleep 1 start }Make it executable: chmod +x /etc/init.d/protonEnable it: service proton enable service proton enabledStart it: service proton startGet the port from /etc/config/firewall redirect src_dport nano /etc/config/firewallVerify port is open: Port checker is a utility used to identify your external IP address and detect open ports on your connection. This tool is useful for finding out if your port forwarding is setup correctly or if your server applications are being blocked by a... If you are following this guide for QbitTorrent, you can now change the port in Tools > Options > Connection > Port used for incoming connections And do not forget to disable “Use UPnP / NAT-PMP port forwarding from my router” 3 Likes
Constant firewall reload on OpenWRT 24.10.2 (R4S)
Magenta7602 August 4, 2025, 2:45pm 2
oh cool, glad my thread could be of help!! one thing I will add is using something like grep "Mapped public port" | logger -t natpmpc_udp && natpmpc -a 1 0 tcp 60 -g 10.2.0.1 2>&1 | grep "Mapped public port" | logger -t natpmpc_tcp' so that you can easily see what the open port is by going to the system log in Luci. Not sure if this would be different in this guide, as I do the port forwarding part as a scheduled task instead of a service. 1 Like
guides August 4, 2025, 3:30pm 3
You can actually see the open port in luci from Network > Firewall > Port Forwards and then on ProtonVPN_Port_Forwarder. If anyone is interested on Magenta7602 contribution you can add the logger line after firewall reload: ... /etc/init.d/firewall reload >> "$LOG_FILE" 2>&1 logger -t echo "Updated src_dport in /etc/config/firewall to $port" ...Thank you again Magenta7602! 1 Like
Magenta7602 August 5, 2025, 10:34pm 4
Just tried this out, works great. Really convenient to have the port forward rule auto update. One change I did make was I have the dest port be the dport as well. uci set firewall."$redirect".dest_port="$port" # Set dest_port to the same value1 Like
guides August 8, 2025, 12:30am 5
Another way to add the config redirect to the firewall is using UCI. uci add firewall redirect uci set firewall.@redirect[-1].dest="lan" uci set firewall.@redirect[-1].target="DNAT" uci set firewall.@redirect[-1].src="https://forum.openwrt.org/t/guide-port-forwarding-with-protonvpn-and-openwrt/vpn" uci set firewall.@redirect[-1].dest_ip="192.168.1.X" uci set firewall.@redirect[-1].dest_port="443" uci set firewall.@redirect[-1].name="ProtonVPN_Port_Forwarder" uci set firewall.@redirect[-1].src_dport="12345" uci commit firewall /etc/init.d/firewall restart
guides August 12, 2025, 9:55am 7
In this Thread, Magenta7602 pointed out an issue with the firewall reloading every 45 seconds. To avoid that issue, please update the service code with this one: #!/bin/sh /etc/rc.common # Service name: ProtonVPN_Port_Forwarder # Description: ProtonVPN Port Forwarding # Location: /etc/init.d/proton START=99 STOP=10 PID_FILE="/var/run/ProtonVPNPortForwarder.pid" LOG_FILE="/var/log/ProtonVPNPortForwarder.log" start() { echo "Starting ProtonVPN Port Forwarder" if [ -f "$PID_FILE" ] && kill -0 $(cat "$PID_FILE") 2>/dev/null; then echo "Service already running (PID $(cat "$PID_FILE"))" return 1 fi { while true; do echo "[$(date)] Checking port mappings..." >> "$LOG_FILE" echo "--- UDP Port Forward ---" >> "$LOG_FILE" # Run UDP mapping (silent) natpmpc -a 1 0 udp 60 -g 10.2.0.1 >> "$LOG_FILE" 2>&1 echo "--- TCP Port Forward ---" >> "$LOG_FILE" # Run TCP mapping and extract port number tcp_output=$(natpmpc -a 1 0 tcp 60 -g 10.2.0.1 2>&1) echo "$tcp_output" >> "$LOG_FILE" # Extract ONLY the port number if mapping succeeded if echo "$tcp_output" | grep -q "Mapped public port"; then # Retrieve the current port from the `tcp_output` variable. port=$(echo "$tcp_output" | grep -oE "port [0-9]+" | awk '{print $2}' | head -n1) #echo "$port" # Find the name of the firewall redirect rule. redirect=$(uci show firewall | grep ".name='ProtonVPN_Port_Forwarder'" | cut -d'=' -f1 | cut -d'.' -f2) # Get the current destination port value from the UCI configuration. current_uci_port=$(uci get firewall."$redirect".src_dport) # Compare the new port with the current port from UCI. if [ "$port" != "$current_uci_port" ]; then # If they are different, update and reload the firewall configuration. uci set firewall."$redirect".src_dport="$port" uci commit firewall /etc/init.d/firewall reload >> "$LOG_FILE" 2>&1 echo "Updated src_dport in /etc/config/firewall to $port" >> "$LOG_FILE" logger -t echo "Updated src_dport in /etc/config/firewall to $port" else echo "Port $port already set. Firewall not reloaded." >> "$LOG_FILE" logger -t echo "Port $port already set. Firewall not reloaded." fi else echo "ERROR: Port forwarding failed" >> "$LOG_FILE" break fi sleep 45 done } & echo $! > "$PID_FILE" echo "Service started (PID $(cat "$PID_FILE"))" } stop() { echo "Stopping ProtonVPN Port Forwarder" if [ -f "$PID_FILE" ]; then kill $(cat "$PID_FILE") 2>/dev/null rm -f "$PID_FILE" fi killall natpmpc 2>/dev/null echo "Service stopped" } restart() { stop sleep 1 start }Then restart the service for the new changes to be applied: service proton restartThe updated code first checks if the current destination port in the firewall redirect configuration is different from ProtonVPN forwarded port, if they are different the firewall updates the destination port and reload the configuration, if both ports are the same only a log is added to the logging system. This is what is new: # Extract ONLY the port number if mapping succeeded if echo "$tcp_output" | grep -q "Mapped public port"; then # Retrieve the current port from the `tcp_output` variable. port=$(echo "$tcp_output" | grep -oE "port [0-9]+" | awk '{print $2}' | head -n1) #echo "$port" # Find the name of the firewall redirect rule. redirect=$(uci show firewall | grep ".name='ProtonVPN_Port_Forwarder'" | cut -d'=' -f1 | cut -d'.' -f2) # Get the current destination port value from the UCI configuration. current_uci_port=$(uci get firewall."$redirect".src_dport) # Compare the new port with the current port from UCI. if [ "$port" != "$current_uci_port" ]; then # If they are different, update and reload the firewall configuration. uci set firewall."$redirect".src_dport="$port" uci commit firewall /etc/init.d/firewall reload >> "$LOG_FILE" 2>&1 echo "Updated src_dport in /etc/config/firewall to $port" >> "$LOG_FILE" logger -t echo "Updated src_dport in /etc/config/firewall to $port" else echo "Port $port already set. Firewall not reloaded." >> "$LOG_FILE" logger -t echo "Port $port already set. Firewall not reloaded." fi1 Like
Bob.Dig August 12, 2025, 11:12am 8
Can this script be extended to work automatically if one is using multiple WG-interfaces with port forwarding to proton? They want you to configure the next interface with 10.3.0.2/30, 10.4.0.2/30 and so on.
guides August 12, 2025, 11:27am 9
I do not have multiple WG interfaces to test it, but I do not see why not, is just a matter of modifying the service code: natpmpc -a 1 0 udp 60 -g 10.3.0.1 natpmpc -a 1 0 udp 60 -g 10.4.0.1AI might be able to help you modify the service for that specific requirement. It helped me to create this one. 1 Like
system Closed August 22, 2025, 11:27am 10
This topic was automatically closed 10 days after the last reply. New replies are no longer allowed. (责任编辑:) |


