You can use multiple gateways with the same IP address. I created a guide here https://forum.opnsense.org/index.php?topic=45163.0 which may help.
This section allows you to view all posts made by this member. Note that you can only see posts made in areas you currently have access to.
Show posts Menu[Interface]
PrivateKey = <Windows private key> # Replace with the private key obtained above
Address = 192.168.3.2/32 # Use a different network than your LAN. For example, if your router is 192.168.1.1, use 192.168.3.2 here.
DNS = 10.2.0.1 # ProtonVPN's DNS and NAT-PMP server
# Sets the route metric of the WireGuard adapter to a lower priority, enabling split tunneling.
PostUp = powershell -command "$ii = (Get-NetAdapter -Name %WIREGUARD_TUNNEL_NAME%).ifIndex; route add 0.0.0.0 mask 0.0.0.0 0.0.0.0 IF $ii metric 9999"
# Removes the route added above.
PreDown = powershell -command "$ii = (Get-NetAdapter -Name %WIREGUARD_TUNNEL_NAME%).ifIndex; route delete 0.0.0.0 IF $ii"
Table = off # Prevents the automatic addition of routes.
[Peer]
PublicKey = <OPNsense Public Key> # To be added later.
AllowedIPs = 0.0.0.0/0, ::/0 # Allows traffic from qBittorrent.
Endpoint = 192.168.3.1:666 # Gateway and port in OPNsense.
PersistentKeepalive = 25
Set-ExecutionPolicy RemoteSigned
Set-ExecutionPolicy -Scope CurrentUser -ExecutionPolicy RemoteSigned -Force
$regPath = 'HKLM:\Software\WireGuard'
New-Item $regPath -Force | Out-Null
New-ItemProperty $regPath -Name DangerousScriptExecution -Value 1 -Force | Out-Null
C:\Windows\System32\OpenSSH\ssh.exe root@192.168.1.1
opnsense-code ports
cd /usr/ports/net/libnatpmp
make install clean
cd /usr
rm -rf ports
pkg install jq
#!/bin/sh
export PATH=$PATH:/usr/local/bin
# OPNsense
readonly GATEWAY="10.2.0.1"
readonly OPNSENSE_URL="https://192.168.1.1"
readonly TCP_ALIAS_NAME="Dynamic_TCP_Port"
readonly UDP_ALIAS_NAME="Dynamic_UDP_Port"
readonly FORWARDED_PORT_ALIAS_NAME="Forwarded_Port"
readonly API_KEY="<api key for OPNsense>"
readonly API_SECRET="<api secret for OPNsense>"
# qBittorrent
readonly QBT_URL="http://192.168.3.2:8080"
readonly QBT_USERNAME="<qBittorrent client username>"
readonly QBT_PASSWORD="<qBittorrent client password>"
# Function to log in to the torrent client and return session ID
login_torrent_client() {
curl -s -k -X POST "$QBT_URL/api/v2/auth/login" \
-H 'Content-Type: application/x-www-form-urlencoded' \
-d "username=$QBT_USERNAME&password=$QBT_PASSWORD" -i | \
grep "set-cookie: SID" | awk -F'[=;]' '{print $2}' | tr -d ' '
}
# Function to get the current port from the torrent client
get_torrent_port() {
local sid="$1"
local port=$(curl -s -k -X GET "$QBT_URL/api/v2/app/preferences" -H "Cookie: SID=$sid" 2>/dev/null | jq -r '.listen_port' 2>/dev/null)
if ! echo "$port" | grep -qE '^[0-9]+$'; then
echo ""
else
echo "$port"
fi
}
# Function to set the port in the torrent client
set_torrent_port() {
local port="$1"
local sid="$2"
curl -s -k -X POST "$QBT_URL/api/v2/app/setPreferences" \
-H "Cookie: SID=$sid" \
-H "Content-Type: application/x-www-form-urlencoded" \
-d "json={\"listen_port\":$port}"
}
# Function to get the alias UUID from OPNsense
get_alias_uuid() {
local alias_id="$1"
response=$(curl -s -k -X GET "$OPNSENSE_URL/api/firewall/alias/getAliasUUID/$alias_id" -u "$API_KEY:$API_SECRET")
echo "$response" | jq -r '.uuid'
}
# Function to get the current value of the alias
get_alias_value() {
local uuid="$1"
response=$(curl -s -k -X GET "$OPNSENSE_URL/api/firewall/alias/get" -u "$API_KEY:$API_SECRET")
echo "$response" | jq -r --arg uuid "$uuid" '.alias.aliases.alias[$uuid].content | keys | .[0]'
}
# Function to set the alias value (forwarded port)
set_alias_value() {
local uuid="$1"
local forwarded_port="$2"
curl -s -k -X POST "$OPNSENSE_URL/api/firewall/alias/setItem/$uuid" -u "$API_KEY:$API_SECRET" \
-H "Content-Type: application/json" \
-d "{\"alias\": {\"content\": \"$forwarded_port\"}}" >/dev/null 2>&1
}
# Function to apply the changes - this takes a few seconds to update
apply_changes() {
curl -s -k -X POST "$OPNSENSE_URL/api/firewall/alias/reconfigure" -u "$API_KEY:$API_SECRET" -d '{}' >/dev/null 2>&1
}
# Get alias for forwarded port from OPNsense
FORWARDED_PORT_UUID=$(get_alias_uuid "$FORWARDED_PORT_ALIAS_NAME")
FORWARDED_PORT=$(get_alias_value "$FORWARDED_PORT_UUID")
#echo "Forwarded port is $FORWARDED_PORT."
# Initialize last public port variables
LAST_UDP_PORT=0
LAST_TCP_PORT=0
# Flag to check if any changes were made to OPNsense port aliases
alias_change_made=false
# Get session id from qBittorrent
SID=$(login_torrent_client)
while true; do
#echo "Last UDP Port is $LAST_UDP_PORT."
#echo "Last TCP Port is $LAST_TCP_PORT."
# Execute natpmpc command for UDP with the last public ports
UDP_PUBLIC_PORT=$(natpmpc -g "$GATEWAY" -a "$LAST_UDP_PORT" "$FORWARDED_PORT" udp 60 | grep -o 'Mapped public port [0-9]*' | awk '{print $4}')
# Execute natpmpc command for TCP with the last public port
TCP_PUBLIC_PORT=$(natpmpc -g "$GATEWAY" -a "$LAST_TCP_PORT" "$FORWARDED_PORT" tcp 60 | grep -o 'Mapped public port [0-9]*' | awk '{print $4}')
# Update the torrent client port if needed
CURRENT_TORRENT_PORT=$(get_torrent_port "$SID")
if [ -z "$CURRENT_TORRENT_PORT" ]; then
SID=$(login_torrent_client) # Re-log if session has expired
CURRENT_TORRENT_PORT=$(get_torrent_port "$SID")
fi
if [ "$CURRENT_TORRENT_PORT" -ne "$UDP_PUBLIC_PORT" ]; then
set_torrent_port "$UDP_PUBLIC_PORT" "$SID"
echo "Updated torrent client port to $UDP_PUBLIC_PORT."
fi
# Check if both ports were successfully mapped
if [ -n "$UDP_PUBLIC_PORT" ] && [ -n "$TCP_PUBLIC_PORT" ]; then
# Update the UDP port if it's different from the last one
if [ "$UDP_PUBLIC_PORT" -ne "$LAST_UDP_PORT" ]; then
LAST_UDP_PORT="$UDP_PUBLIC_PORT"
UDP_UUID=$(get_alias_uuid "$UDP_ALIAS_NAME")
CURRENT_UDP_VALUE=$(get_alias_value "$UDP_UUID")
if [ "$CURRENT_UDP_VALUE" != "$UDP_PUBLIC_PORT" ]; then
set_alias_value "$UDP_UUID" "$UDP_PUBLIC_PORT"
alias_change_made=true
fi
fi
# Update the TCP port if it's different from the last one
if [ "$TCP_PUBLIC_PORT" -ne "$LAST_TCP_PORT" ]; then
LAST_TCP_PORT="$TCP_PUBLIC_PORT"
TCP_UUID=$(get_alias_uuid "$TCP_ALIAS_NAME")
CURRENT_TCP_VALUE=$(get_alias_value "$TCP_UUID")
if [ "$CURRENT_TCP_VALUE" != "$TCP_PUBLIC_PORT" ]; then
set_alias_value "$TCP_UUID" "$TCP_PUBLIC_PORT"
alias_change_made=true
fi
fi
# Apply changes only if updates were made to aliases
if [ "$alias_change_made" = true ]; then
apply_changes
alias_change_made=false
echo "OPNsense Aliases changed."
fi
else
echo "Failed to map ports."
fi
# Wait 45 seconds before requesting another port - recommended by Proton VPN
sleep 45
done
cd /usr/local/bin
vi nat-pmp.sh
chmod +x /usr/local/bin/nat-pmp.sh
/usr/local/bin/nat-pmp.sh
#!/bin/sh
PROVIDE: nat_pmp
REQUIRE: NETWORKING
KEYWORD: shutdown
. /etc/rc.subr
name="nat_pmp"
rcvar="nat_pmp_enable"
command="/usr/local/bin/nat-pmp.sh"
pidfile="/var/run/${name}.pid"
start_cmd="${name}_start"
stop_cmd="${name}_stop"
nat_pmp_start() {
echo "Starting NAT-PMP script..."
/usr/sbin/daemon -p ${pidfile} -f ${command}
}
nat_pmp_stop() {
echo "Stopping NAT-PMP script..."
kill cat ${pidfile} && rm -f ${pidfile}
}
load_rc_config $name
run_rc_command "$1"
cd /usr/local/etc/rc.d
vi nat-pmp
chmod +x /usr/local/etc/rc.d/nat-pmp
echo "nat_pmp_enable=YES" >> /etc/rc.conf
service nat-pmp start
service nat-pmp stop
natpmpc -g 10.2.0.1 -a 0 4 udp 60
You should see output that lists the "Mapped public port" followed by a port number.