- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page
Re: Static Routing and NAT (iptables)
- Mark as New
- Bookmark
- Subscribe
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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.
- Mark as New
- Bookmark
- Subscribe
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Re: Static Routing and NAT (iptables)
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.
- Mark as New
- Bookmark
- Subscribe
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Re: Static Routing and NAT (iptables)
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
- Mark as New
- Bookmark
- Subscribe
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
- Mark as New
- Bookmark
- Subscribe
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Re: Static Routing and NAT (iptables) - Updated Script
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
- Mark as New
- Bookmark
- Subscribe
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Re: Static Routing and NAT (iptables) - Now as OpenWRT Service
Last version of this script - I promise! Quick instructions: install socat, netcat and openssl-util on your openwrt router. Drop the script in a file called `/etc/init.d/orbi` - make the file executable. Edit the file to change your password and Orbi IP address - if it's not 192.168.1.1. Then enable the script: `/etc/init.d/orbi enable' and start it: '/etc/init.d/orbi start'.
The script will listen for multicast messages from Orbi - every time it will detect one, it will check if the Orbi is configured for forwarding the internal lan - sleep for 30 seconds and start listening again.
Let me know if anyone finds this useful.
Fabio
#!/bin/sh /etc/rc.common # Example script # Copyright (C) 2007 OpenWrt.org START=10 STOP=15 # NOTE: This script requires socat, openssl and the real netcat to be available, not the BusyBox version. On OpenWRT # you can get them via: # # opkg install socat netcat openssl-util # ORBI_USERNAME="admin" ORBI_PASSWORD="*************" ORBI_ADDRESS=192.168.1.1 ORBI_MCAST_PORT=5353 ORBI_MCAST_ADDR=224.0.0.251 ORBI_MCAST_IF=eth0.2 AUTH_TOKEN=`echo -n "${ORBI_USERNAME}:${ORBI_PASSWORD}" | openssl enc -base64` ORBI_SCRIPT=/etc/init.d/orbi 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 FORWARDING=1 else FORWARDING=0 fi } function enableForwarding() { isForwarding if [ ${FORWARDING} -eq 0 ] then logger -t ORBI -p daemon.info "Enabling forwarding" (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 else logger -t ORBI -p daemon.warn "Forwarding is already enabled!" fi } EXTRA_COMMANDS="on off forward check monitor" EXTRA_HELP=<<EOF on Enable telnet on the Orbi off Disable telnet on the Orbi forward Manually enable forwarding for the Orbi check Check the Orbi to see if forwarding is enabled monitor Enable monitoring of Orbi EOF start () { logger -t ORBI -p daemon.info 'Launching background monitor' (( ${ORBI_SCRIPT} monitor >/dev/null 2>&1 ) & ) & } stop () { if [ -f /tmp/.orbi.running ] then logger -t ORBI -p daemon.info 'Stopping Orbi Service' PID=`cat /tmp/.orbi.running` rm /tmp/.orbi.running kill -TERM ${PID} else logger -t ORBI -p daemon.info 'Orbi Service not Running' fi } restart () { stop sleep 1 start } monitor() { logger -t ORBI -p daemon.info 'Starting Orbi Monitor Service' echo $$ > /tmp/.orbi.running while [ -f /tmp/.orbi.running ] do socat UDP4-RECV:${ORBI_MCAST_PORT},bind=${ORBI_MCAST_ADDR},ip-add-membership=${ORBI_MCAST_ADDR}:${ORBI_MCAST_IF},range=${ORBI_ADDRESS}/32 SYSTEM:"${ORBI_SCRIPT} forward" sleep 30 done logger -t ORBI -p daemon.info 'Orbi Monitor Service Exited' } on () { forceLogout enableTelnet } off () { forceLogout disableTelnet } check () { forceLogout enableTelnet isForwarding if [ ${FORWARDING} -eq 0 ] then echo "Forwarding is disabled" else echo "Forwarding is enabled" fi disableTelnet } forward () { if [ -f /tmp/.orbi.enabling ] then logger -t ORBI -p daemon.warn "Already enabling Orbi forwarding - Ignoring request" else touch /tmp/.orbi.enabling forceLogout enableTelnet enableForwarding disableTelnet rm /tmp/.orbi.enabling fi }
• What is the difference between WiFi 6 and WiFi 7?
• Yes! WiFi 7 is backwards compatible with other Wifi Devices? Learn more