Iptables Examples

Clear All Rules

The following commands will completely clear all your rules (and ACCEPT everything).

iptables -P INPUT ACCEPT  
iptables -P FORWARD ACCEPT  
iptables -P OUTPUT ACCEPT  
iptables -t nat -F  
iptables -t mangle -F  
iptables -F  
iptables -X  

Simple NAT

Situation:

There are some ISPs in Hungary (and all over the world) which use Carrier-grade NAT and this "feature" makes my life harder.

Devices and Networks:

  • Router
    IP address: 192.168.100.1, Network: 192.168.100.0/24
  • NVR (Network Video Recorder)
    • It connects to the ISP's router. IP address: 192.168.100.4
    • But it has its own network for IP cameras. (3 eth port and WiFi) IP address: 172.20.18.4, Network: 172.20.18.0/24
  • Orange PI zero
    • eth0 - Connected to the router. (192.168.100.230)
    • tun0 - Connected to the OpenVPN server. (10.50.0.230)
    • wlan0 - Connected directly to the NVR over WiFi. (172.20.18.0.6)
  • For example 3 IP cameras:
    • 172.20.18.3
    • 172.20.18.4
    • 172.20.18.5

Picture:

Mission: Access the NVR and the cameras over the VPN network.

So there are three different network:

  • 192.168.100.0/24
  • 10.50.0.0./16
  • 172.20.18.0/24

First we have to determine on which ports the NVR listens.

nmap 192.168.100.4

Starting Nmap 7.40 ( https://nmap.org ) at 2018-11-07 10:30 UTC  
Nmap scan report for 192.168.100.4  
Host is up (0.0015s latency).  
Not shown: 995 closed ports  
PORT     STATE SERVICE  
53/tcp   open  domain  
80/tcp   open  http  
554/tcp  open  rtsp  
5000/tcp open  upnp  
8888/tcp open  sun-answerbook  
MAC Address: 08:EA:40:56:95:EB (Shenzhen Bilian Electronicltd)

Nmap done: 1 IP address (1 host up) scanned in 2.34 seconds  

Solution:

iptables -A FORWARD -i tun0 -j ACCEPT  
iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE  
iptables -t nat -A PREROUTING -i tun0 -p tcp --dport 80 -j DNAT --to 192.168.100.4:80  
iptables -t nat -A PREROUTING -i tun0 -p tcp --dport 554 -j DNAT --to 192.168.100.4:554  
iptables -t nat -A PREROUTING -i tun0 -p tcp --dport 8888 -j DNAT --to 192.168.100.4:8888  
iptables -t nat -A PREROUTING -i tun0 -p tcp --dport 5000 -j DNAT --to 192.168.100.4:5000  

It is very important to enable IP(v4) forwarding.
We can enable it temporary:

# check: cat /proc/sys/net/ipv4/ip_forward
echo -n 1 >/proc/sys/net/ipv4/ip_forward  

Or permanently, by adding the following line to /etc/sysctl.conf file:

net.ipv4.ip_forward=1  

The whole script:

#!/bin/bash

IFS='  
'

iptables -P INPUT ACCEPT  
iptables -P FORWARD ACCEPT  
iptables -P OUTPUT ACCEPT  
iptables -t nat -F  
iptables -t mangle -F  
iptables -F  
iptables -X


echo -n 1 > /proc/sys/net/ipv4/ip_forward

iptables -A FORWARD -i tun0 -j ACCEPT  
iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE  
iptables -t nat -A PREROUTING -i tun0 -p tcp --dport 80 -j DNAT --to 192.168.100.4:80  
iptables -t nat -A PREROUTING -i tun0 -p tcp --dport 554 -j DNAT --to 192.168.100.4:554  
iptables -t nat -A PREROUTING -i tun0 -p tcp --dport 8888 -j DNAT --to 192.168.100.4:8888  
iptables -t nat -A PREROUTING -i tun0 -p tcp --dport 5000 -j DNAT --to 192.168.100.4:5000  

IMPORTANT: This will enable all traffic, and completely turn the firewall off. NOT recommended if you do not have any other firewall in your network and/or your device has public IP address.

And what about the cameras?
Rules for a camera:

iptables -A FORWARD -i tun0 -j ACCEPT  
iptables -t nat -A POSTROUTING -o wlan0 -j MASQUERADE  
iptables -t nat -A PREROUTING -i tun0 -p tcp --dport 80 -j DNAT --to 172.20.18.4:80  
iptables -t nat -A PREROUTING -i tun0 -p tcp --dport 554 -j DNAT --to 172.20.18.4:554  
iptables -t nat -A PREROUTING -i tun0 -p tcp --dport 34567 -j DNAT --to 172.20.18.4:34567  

I have never tried but it may be possible to configure iptables to access all cameras without reconfigure our rules for each camera.
Example:

iptables -t nat -A PREROUTING -i tun0 -p tcp --dport 80 -j DNAT --to 172.20.18.4:80  
iptables -t nat -A PREROUTING -i tun0 -p tcp --dport 81 -j DNAT --to 172.20.18.3:80  
iptables -t nat -A PREROUTING -i tun0 -p tcp --dport 82 -j DNAT --to 172.20.18.5:80  
iptables -t nat -A PREROUTING -i tun0 -p tcp --dport 34567 -j DNAT --to 172.20.18.4:34567  
iptables -t nat -A PREROUTING -i tun0 -p tcp --dport 34568 -j DNAT --to 172.20.18.3:34568  
iptables -t nat -A PREROUTING -i tun0 -p tcp --dport 34569 -j DNAT --to 172.20.18.5:34569  

In order to work these rule perfectly the listen ports have to be (re)configured on the IP camera side as well.
But in my scenario it is not so important, because I don't need frequently access directly the cameras.


Permanently Save Iptables rules (on debian(-like) OS)

  • Save the current configuration
    iptables-save > /etc/iptables.rules
  • Restore the saved configuration from file
    iptables-restore < /etc/iptables.rules

For apply iptables rules on startup use this little script:

cat <<EOF>/etc/network/if-pre-up.d/firewall  
#!/bin/bash
/sbin/iptables-restore < /etc/iptables.rules
EOF

chmod +x /etc/network/if-pre-up.d/firewall  

Port Forwarding To Another Host

My scenario: I wanted to access RTSP port (554) of multiple IP cameras over one host (Gateway).

Host IP address: 172.16.0.230
IP adress of cameras: 172.19.1.1-172.19.1.8
RTSP listen port: 554

Rules:

iptables -t nat -A PREROUTING -p tcp --dport 5541 -j DNAT --to-destination 172.19.1.1:554  
iptables -t nat -A POSTROUTING -p tcp -d 172.19.1.1 --dport 554 -j SNAT --to-source  172.16.0.230 

iptables -t nat -A PREROUTING -p tcp --dport 5542 -j DNAT --to-destination 172.19.1.2:554  
iptables -t nat -A POSTROUTING -p tcp -d 172.19.1.2 --dport 554 -j SNAT --to-source  172.16.0.230 


iptables -t nat -A PREROUTING -p tcp --dport 5543 -j DNAT --to-destination 172.19.1.3:554  
iptables -t nat -A POSTROUTING -p tcp -d 172.19.1.3 --dport 554 -j SNAT --to-source  172.16.0.230 

etc.  

The script with traffic monitoring:

#!/bin/bash

IFS='  
'  
iptables -P INPUT ACCEPT  
iptables -P FORWARD ACCEPT  
iptables -P OUTPUT ACCEPT  
iptables -t nat -F  
iptables -t mangle -F  
iptables -F  
iptables -X


echo -n 1 > /proc/sys/net/ipv4/ip_forward

iptables -A INPUT  -p tcp -m state --state NEW   -j LOG --log-prefix "INPUT: "  
iptables -A OUTPUT  -p tcp -m state --state NEW   -j LOG --log-prefix "OUTPUT: "

iptables -t nat -A PREROUTING  -p tcp  -j LOG --log-prefix "PREROUTING: "  
iptables -t nat -A POSTROUTING  -p tcp  -j LOG --log-prefix "POSTROUTING: "


###
## Traffic
###
iptables -N trafficmon  
iptables -A FORWARD -p tcp --sport 554 -m comment --comment "ALL" -j trafficmon



LOCAL_IP="172.16.0.230"

LISTEN=1554

#  NAME | IP | PORT | URL

CAMS[0]="Pool|172.19.1.1|554|ucast/11"  
CAMS[1]="Garden|172.19.1.2|554|11"  
CAMS[2]="Garage|172.19.1.3|554|user=admin_password=tlJwpbo6_channel=1_stream=0.sdp?real_stream"  
CAMS[3]="Workshop|172.19.1.4|554|user=admin_password=tlJwpbo6_channel=1_stream=0.sdp?real_stream"  
CAMS[4]="Backyard|172.19.1.5|554|user=admin_password=tlJwpbo6_channel=1_stream=0.sdp?real_stream"  
CAMS[5]="Gate|172.19.1.6|554|user=admin_password=tlJwpbo6_channel=1_stream=0.sdp?real_stream"  
CAMS[6]="Street|172.19.1.7|554|user=admin_password=tlJwpbo6_channel=1_stream=0.sdp?real_stream"  
CAMS[7]="Corridor|172.19.1.8|554|11"


for CAM in ${CAMS[@]}  
do  
  NAME=$( echo $CAM | cut -f 1 -d"|" )
  IPADDR=$( echo $CAM | cut -f 2 -d"|" )
  PORT=$( echo $CAM | cut -f 3 -d"|" )
  URL=$( echo $CAM | cut -f 4 -d"|" )

  echo "URL : rtsp://$LOCAL_IP:$LISTEN/$URL (### $NAME ###)"

  iptables -t nat -A PREROUTING -p tcp --dport $LISTEN -j DNAT --to-destination $IPADDR:$PORT -m comment --comment "$NAME"
  iptables -t nat -A POSTROUTING -p tcp -d $IPADDR --dport $PORT -j SNAT --to-source $LOCAL_IP -m comment --comment "$NAME"
  iptables -A FORWARD -p tcp --sport 554 --source $IPADDR -m comment --comment "$NAME" -j trafficmon

  (( LISTEN ++ ))
done



cat <<EOF  
Please Run

iptables-save > /etc/iptables.rules

to make rules permanent!  
EOF  

IPTABLES quick commands & Cheat Sheets

manage chain:  
# iptables -N new_chain                // create a chain
# iptables -E new_chain old_chain          // edit a chain
# iptables -X old_chain                // delete a chain

redirecting packet to a user chain:  
# iptables -A INPUT -p icmp -j new_chain

listing rules:  
# iptables -L                    // list all rules of all tables
# iptables -L -v                // display rules and their counters
# iptables -L -t nat                // display rules for a specific tables
# iptables -L -n --line-numbers            // listing rules with line number for all tables
# iptables -L INPUT -n --line-numbers        // listing rules with line number for specific table

manage rules:  
# iptables -A chain                // append rules to the bottom of the chain
# iptables -I chain [rulenum]            // insert in chain as rulenum (default at the top or 1)
# iptables -R chain rulenum            // replace rules with rules specified for the rulnum
# iptables -D chain    rulenum         // delete rules matching rulenum (default 1)
# iptables -D chain                // delete matching rules

change default policy:  
# iptables -P chain target            // change policy on chain to target
# iptables -P INPUT DROP            // change INPUT table policy to DROP
# iptables -P OUTPUT DROP            // change OUTPUT chain policy to DROP
# iptables -P FORWARD DROP            // change FORWARD chain policy to DROP

Reference: iptables-quick-command-list/

Vincze Janos Istvan

Read more posts by this author.

Hungary

Subscribe to Blog

Get the latest posts delivered right to your inbox.

or subscribe via RSS with Feedly!