NETGEAR is aware of a growing number of phone and online scams. To learn how to stay safe click here.
Forum Discussion
chickenfrog
Apr 21, 2017Follower
Static Routing and NAT (iptables)
*******
I'm posting this as a reference. I struggled with this for about a day, trying to untangle the iptables of my Netgear Orbi.
Maybe this write-up can help others.
USE AT YOUR OWN RISK
These changes will not survive a reboot because iptables-save is broken. (Another reason I wrote it down)
*******
I have a home lab network that needs to access the Internet. I added a static route to my lab network through and internal router. The lab network does not have Internet access. This is a problem with iptables.
Quick break down:
* Home Network - 192.168.1.0/24. (Orbi is 192.168.1.1)
* Lab Network - 192.168.2.0/24. (Accessible through a router at 192.168.1.2)
* "router" at 192.168.1.2 on home side, 192.168.2.1 on lab side.
* static route on Orbi pointing 192.168.2.0/24 to the gateway of 192.168.1.2
* all routing is working internally.
The first problem is in the iptables table "filter" chain loc2net.
root@netgear:/# iptables -t filter -L loc2net Chain loc2net (1 references) target prot opt source destination ACCEPT all -- anywhere anywhere state RELATED,ESTABLISHED DROP tcp -- anywhere anywhere state NEW tcp flags:!FIN,SYN,RST,PSH,ACK,URG/SYN DROP tcp -- anywhere anywhere state INVALID TRIGGER all -- anywhere anywhere [16 bytes of unknown target data] DROP all -- !192.168.1.0/24 anywhere ACCEPT all -- anywhere anywhere
All traffic that is not coming from 192.168.1.0/24 is dropped - easy to remove.
iptables -t filter -D loc2net 5
The next table we need to look at is the table "nat" (shortened for readability)
Chain POSTROUTING (policy ACCEPT) target prot opt source destination br0_masq all -- anywhere anywhere brwan_masq all -- anywhere anywhere Chain br0_masq (1 references) target prot opt source destination HAIRPIN all -- 192.168.1.0/24 anywhere [24 bytes of unknown target data] Chain brwan_masq (1 references) target prot opt source destination SNATP2P all -- 192.168.1.0/24 anywhere [24 bytes of unknown target data]
The chain POSTROUTING calls two other chains which reference other targets that I cannot find nor configure. It should be an easy update to add to the brwan_masq chain since I can copy the existing line and change it to reference my lab network.
root@athena:/# iptables -t nat -A brwan_masq -s 192.168.2.0/24 -j SNATP2P iptables v1.4.21: Couldn't load target `SNATP2P':No such file or directory Try `iptables -h' or 'iptables --help' for more information.
Except it's not. SNATP2P is not a configurable target. Doh.
OK, fine. I'll just use MASQUERADE under the POSTROUTING chain and insert it as the top rule.
root@netgear:/# iptables -t nat -I POSTROUTING 1 -o brwan -j MASQUERADE root@netgear:/# iptables -t nat -L POSTROUTING Chain POSTROUTING (policy ACCEPT) target prot opt source destination MASQUERADE all -- anywhere anywhere br0_masq all -- anywhere anywhere brwan_masq all -- anywhere anywhere root@netgear:/#
I could have been more specific (by limiting the source) on the MASQUERADE, but it was easier to show with and any-to-any config.
That will fix the problem of hosts inside your network that are behind another router.
5 Replies
Sort By
Very cool. I've known for a long time that Netgear stopped support for NAT-ing non-directly-connected subnets. Thanks for finding a workaround, albeit one that won't survive a reboot. Too bad you can't put this into a script that can be saved somewhere non-volatile.
- fabbariTutor
Thanks for the tip! I created a script that I run on the OpenWRT to enable forwarding and check the state of the forwarding. You can hook it up to the DHCP message from the Orbi - so that wen the Orbi comes up the script is automatically executed. More datails on that in another reply I guess. The script should work from any shell that has curl, netcat and openssl installed.
Fabio
#!/bin/sh # NOTE: This script requires openssl and the real netcat to be available, not the BusyBox version. On OpenWRT # you can get them via: # # opkg install netcat openssl-util # ORBI_USERNAME="admin" ORBI_PASSWORD="**********" ORBI_ADDRESS="192.168.1.1" AUTH_TOKEN=`echo -n "${ORBI_USERNAME}:${ORBI_PASSWORD}" | openssl enc -base64` function timeStamp() { curl https://${ORBI_ADDRESS}/debug_detail.htm -s --insecure -H "Authorization: Basic ${AUTH_TOKEN}" | grep -e '^var ts' | sed -e 's/var\W\+ts="\([^"]\+\)".*/\1/g' } function enableTelnet() { TS_CODE=`timeStamp` curl "https://${ORBI_ADDRESS}/apply.cgi?/debug_detail.htm%20timestamp=${TS_CODE}" -H "Authorization: Basic ${AUTH_TOKEN}" --data 'submit_flag=debug_info&hid_telnet=1&enable_telnet=on' --insecure -s > /dev/null } function disableTelnet() { TS_CODE=`timeStamp` curl "https://${ORBI_ADDRESS}/apply.cgi?/debug_detail.htm%20timestamp=${TS_CODE}" -H "Authorization: Basic ${AUTH_TOKEN}" --data 'submit_flag=debug_info&hid_telnet=0&enable_telnet=off' --insecure -s > /dev/null } function isForwarding() { RULE=`(echo "iptables -L --line-numbers"; sleep 2) | netcat -c -t ${ORBI_ADDRESS} 23 | grep '^5\W\+DROP\W\+all\W\+--\W\+!\d\+\.\d\+\.\d\+\.\d\+\/\d\+\W\+anywhere'` if [ "${RULE}" = "" ] then echo "Forwarding enabled" else echo "Forwarding disabled" fi } function enableForwarding() { FORWARD=`isForwarding` if [ "${FORWARD}" = "Forwarding disabled" ] then echo "Enabling forwarding - current state: ${FORWARD}" (echo "iptables -t filter -D loc2net 5 && iptables -t nat -I POSTROUTING 1 -o brwan -j MASQUERADE"; sleep 1) | netcat -c -t ${ORBI_ADDRESS} 23 > /dev/null isForwarding else echo "Forwarding is already enabled!" fi } case "$1" in enable)
enableTelnet
;;
disable)
disableTelnet
;;
check)
enableTelnet
isForwarding
disableTelnet
;;
forward)
enableTelnet
enableForwarding
disableTelnet
;;
*) echo "" echo "$0 [enable|disable|forward]" echo "" echo " enable: enable Orbi telnet interface" echo " disable: disable Orbi telnet interface" echo " check: check if Orbi is forwarding internal networks" echo " forward: allow Orbi to forward internal networks" echo "" esac- Very clever!
- fabbariTutor
I updated the script to make sure we logout any admin using the web-interface. It may be an inconvenience when an admin is using the web interface, but ensures that automated scripts will always run successfully.
#!/bin/sh # NOTE: This script requires openssl and the real netcat to be available, not the BusyBox version. On OpenWRT # you can get them via: # # opkg install netcat openssl-util # ORBI_USERNAME="admin" ORBI_PASSWORD="*********" ORBI_ADDRESS="192.168.1.1" AUTH_TOKEN=`echo -n "${ORBI_USERNAME}:${ORBI_PASSWORD}" | openssl enc -base64` function forceLogout() { curl -s "https://${ORBI_ADDRESS}/change_user.html" -H "Authorization: Basic ${AUTH_TOKEN}" --insecure > /dev/null curl -s "https://${ORBI_ADDRESS}/change_user.html" -H "Authorization: Basic ${AUTH_TOKEN}" --insecure > /dev/null } function timeStamp() { curl https://${ORBI_ADDRESS}/debug_detail.htm -s --insecure -H "Authorization: Basic ${AUTH_TOKEN}" | grep -e '^var ts' | sed -e 's/var\W\+ts="\([^"]\+\)".*/\1/g' } function enableTelnet() { TS_CODE=`timeStamp` curl "https://${ORBI_ADDRESS}/apply.cgi?/debug_detail.htm%20timestamp=${TS_CODE}" -H "Authorization: Basic ${AUTH_TOKEN}" --data 'submit_flag=debug_info&hid_telnet=1&enable_telnet=on' --insecure -s > /dev/null } function disableTelnet() { TS_CODE=`timeStamp` curl "https://${ORBI_ADDRESS}/apply.cgi?/debug_detail.htm%20timestamp=${TS_CODE}" -H "Authorization: Basic ${AUTH_TOKEN}" --data 'submit_flag=debug_info&hid_telnet=0&enable_telnet=off' --insecure -s > /dev/null } function isForwarding() { RULE=`(echo "iptables -L --line-numbers"; sleep 2) | netcat -c -t ${ORBI_ADDRESS} 23 | grep '^5\W\+DROP\W\+all\W\+--\W\+!\d\+\.\d\+\.\d\+\.\d\+\/\d\+\W\+anywhere'` if [ "${RULE}" = "" ] then echo "Forwarding enabled" else echo "Forwarding disabled" fi } function enableForwarding() { FORWARD=`isForwarding` if [ "${FORWARD}" = "Forwarding disabled" ] then echo "Enabling forwarding - current state: ${FORWARD}" (echo "iptables -t filter -D loc2net 5 && iptables -t nat -I POSTROUTING 1 -o brwan -j MASQUERADE"; sleep 1) | netcat -c -t ${ORBI_ADDRESS} 23 > /dev/null isForwarding else echo "Forwarding is already enabled!" fi } case "$1" in enable) forceLogout enableTelnet ;; disable) forceLogout disableTelnet ;; check) forceLogout enableTelnet isForwarding disableTelnet ;; forward) forceLogout enableTelnet enableForwarding disableTelnet ;; *) echo "" echo "$0 [enable|disable|forward]" echo "" echo " enable: enable Orbi telnet interface" echo " disable: disable Orbi telnet interface" echo " check: check if Orbi is forwarding internal networks" echo " forward: allow Orbi to forward internal networks" echo "" esac