View running iptables rules
sudo iptables-save > rules.txt
cat rules.txt
Delete a rule by number
sudo iptables -L
sudo iptables -L -n
sudo iptables -L -n -v --line-numbers
sudo iptables -L INPUT -n -v --line-numbers
sudo iptables -L OUTPUT -n -v --line-numbers
sudo iptables -L -t nat --line-numbers
sudo iptables -D INPUT X
sudo iptables -t nat -D POSTROUTING X
Delete a rule by its command
sudo iptables -t nat -D POSTROUTING -o wan -j MASQUERADE
Open port 443 to 3389
################ WAN 443 to local 3389 (192.168.1.13) Local host's gateway is firewall so POSTROUTING not required.
-A PREROUTING -s 175.xx.xx.xx/32 -i wan -p tcp -m tcp -d 2xx.xx.xx.xx --dport 443 -j DNAT --to-destination 192.168.1.13:3389
#-A POSTROUTING -o eth0LAN -p tcp --dport 3389 -d 192.168.1.13 -j MASQUERADE
* MASQUERADE is required if LAN host gateway is not configured.
Open port 8888 to 80
################ WAN 8888 to 80
-A PREROUTING -s 175.xx.xx.xx/32 -i wan -p tcp -m tcp -d 2xx.xx.xx.xx --dport 8888 -j DNAT --to-destination 192.168.1.2:80
-A POSTROUTING -o lanIface -p tcp --dport 80 -d 192.168.1.2 -j MASQUERADE
* Due to MASQUERADE, internal web server sees request coming from firewall only
Below are the same thing. 192.168.1.1 = firewall
-A POSTROUTING -o eth0LAN -p tcp --dport 80 -d 192.168.1.2 -j SNAT --to-source 192.168.1.1
-A POSTROUTING -o eth0LAN -p tcp --dport 80 -d 192.168.1.2 -j MASQUERADE
Open port 3389 to 3389
################ WAN 3389 to 3389 (192.168.1.200)
-A PREROUTING -s 175.xx.xx.xx/32 -p tcp -m tcp -d 2xx.xx.xx.xx --dport 3389 -j DNAT --to-destination 192.168.1.200:3389
-A POSTROUTING -o eth0LAN -p tcp --dport 3389 -d 192.168.1.200 -j SNAT --to-source 192.168.1.1
Assuming 192.168.1.1 = firewall
To flush everything
If you have installed iptables-persistent, below single line will hand it
sudo service iptables-persistent flush
sudo iptables -F
sudo iptables -X
sudo iptables -P INPUT ACCEPT
sudo iptables -P OUTPUT ACCEPT
sudo iptables -P FORWARD ACCEPT
sudo iptables -t nat -F
sudo iptables -t nat -X
sudo iptables -t nat -P INPUT ACCEPT
sudo iptables -t nat -P OUTPUT ACCEPT
sudo iptables -t nat -P POSTROUTING ACCEPT
sudo iptables -t mangle -F
sudo iptables -t mangle -X
sudo iptables -t mangle -P INPUT ACCEPT
sudo iptables -t mangle -P OUTPUT ACCEPT
sudo iptables -t mangle -P POSTROUTING ACCEPT
-F Flushing
-X Delete chain
-t table name
-P Policy (set default policy such as DROP, ACCEPT, REJECT)
Insert a rule on top
iptables -I INPUT 98 -s 111.22.33.44 -j ACCEPT
iptables -I INPUT 99 -s 192.168.1.44 -j ACCEPT
Insert a rule between 1 & 2
sudo iptables -I INPUT 2 -s 111.222.00.00 -j ACCEPT
Block incoming traffic (in default setting)
sudo iptables -P INPUT DROP
sudo iptables -P FORWARD DROP
sudo iptables -P OUTPUT ACCEPT
sudo iptables -A INPUT -m state --state NEW,ESTABLISHED -j ACCEPT
DROP private network on WAN interface
sudo iptables -A INPUT -i eth1 -s 192.168.0.0/24 -j DROP
sudo iptables -A INPUT -i eth1 -s 10.0.0.0/8 -j DROP
DROP incoming IP 12.12.12.12 on port 22-23
sudo iptables -A INPUT -s 12.12.12.12/32 -p tcp -m tcp --dport 22:23 -j DROP
Allow one way direction
Allow SSH in from 8.8.8.8 but DROP all SSH out to 8.8.8.8
sudo iptables -I INPUT -p tcp --dport ssh -s 8.8.8.8 -m state --state NEW,ESTABLISHED -j ACCEPT
sudo iptables -I OUTPUT -p tcp --sport 22 -d 8.8.8.8 -m state --state ESTABLISHED -j ACCEPT
IPv4 Address Ranges For Private Networks
10.0.0.0/8 (A)
172.16.0.0/12 (B)
192.168.0.0/16 (C)
224.0.0.0/4 (MULTICAST D)
240.0.0.0/5 (E)
Block an attacker IP
sudo iptables -A INPUT -s x.x.x.x -j DROP
sudo iptables -A INPUT -s 192.168.0.0/24 -j DROP
Block all incoming request on port 80
sudo iptables -A INPUT -p tcp --dport 80 -j DROP
Block incoming request on port 80 on WAN interface
sudo iptables -A INPUT -i eth1 -p tcp --dport 80 -j DROP
Block incoming request on port 80 from specific address
sudo iptables -A INPUT -p tcp -s 1.2.3.4 --dport 80 -j DROP
Block incoming request on port 80 from specific address on WAN interface
sudo iptables -A INPUT -i eth1 -p tcp -s 1.2.3.4 --dport 80 -j DROP
How to block outgoing destination. Example www.Facebook.com
host -t a www.facebook.com
whois x.x.x.x | grep inetnum
sudo iptables -A OUTPUT -p tcp -d x.x.x.x/18 -j DROP
How to block outgoing destination. Example Facebook.com
host -t a facebook.com
whois x.x.x.x | grep CIDR
sudo iptables -A OUTPUT -p tcp -d x.x.x.x/18 -j DROP
Log and drop IP spoofing on WAN interface
sudo iptables -A INPUT -i eth1 -s 10.0.0.0/8 -j LOG --log-prefix "Kim_IP_SPOOF A: "
sudo iptables -A INPUT -i eth1 -s 10.0.0.0/8 -j DROP
tail -f /var/log/x
grep 'IP_SPOOF' /var/log/x
Log and drop with limited log entries
sudo iptables -A INPUT -i eth1 -s 10.0.0.0/8 -m limit --limit 5/m --limit-burse 7 -j LOG --log-prefix "Kim_Flooding_IP_SPOOF"
sudo iptables -A INPUT -i eth1 -s 10.0.0.0/8 -j DROP
DROP or ACCEPT from MAC address
sudo iptables -A INPUT -m mac --mac-source xx:yy:zz:xx:yy:zz -j DROP
sudo iptables -A INPUT -p tcp --destination-port 22 -m mac --mac-source xx:yy:zz:xx:yy:zz -j ACCEPT
Block ICMP ping request completely
sudo iptables -A INPUT -p icmp --icmp-type echo-request -j DROP
Block ICMP ping request on WAN interface
sudo iptables -A INPUT -i eth1 -p icmp --icmp-type echo-request -j DROP
ACCEPT ICMP ping request from certain networks only
sudo iptables -A INPUT -s 192.168.1.0/24 -p icmp --icmp-type echo-request -j ACCEPT
ACCEPT ICMP (limited to certain ICMP request assuming INPUT policy is DROP)
sudo iptables -A INPUT -p icmp --icmp-type echo-reply -j ACCEPT
sudo iptables -A INPUT -p icmp --icmp-type echo-request -j ACCEPT
sudo iptables -A INPUT -p icmp --icmp-type destination-unreachable -j ACCEPT
sudo iptables -A INPUT -p icmp --icmp-type time-exceeded -j ACCEPT
Open range of ports
sudo iptables -A INPUT -m state --state NEW -m tcp -p tcp --dport 22222:33333 -j ACCEPT
Open range of IP addresses for port 80
sudo iptables -A INPUT -p tcp --destination-port 80 -m iprange --src-range 192.168.1.100-192.168.1.200 -j ACCEPT
Send crit log to /var/log/x instead of console
sudo iptables -A INPUT -s 1.2.3.4 -p tcp --destination-port 80 -j LOG --log-level crit
Block or Open common ports
# Open ssh tcp port 22
sudo iptables -A INPUT -m state --state NEW -m tcp -p tcp --dport 22 -j ACCEPT
sudo iptables -A INPUT -s 192.168.1.0/24 -m state --state NEW -p tcp --dport 22 -j ACCEPT
Open cups (printing service) port 631
sudo iptables -A INPUT -s 192.168.1.0/24 -p udp -m udp --dport 631 -j ACCEPT
sudo iptables -A INPUT -s 192.168.1.0/24 -p tcp -m tcp --dport 631 -j ACCEPT
Open NTP time sync udp port 123
sudo iptables -A INPUT -s 192.168.1.0/24 -m state --state NEW -p udp --dport 123 -j ACCEPT
Open DNS port 53 (When default OUTPUT is DROP)
sudo iptables -A INPUT -m state --state NEW -p udp --dport 53 -j ACCEPT
sudo iptables -A INPUT -m state --state NEW -p tcp --dport 53 -j ACCEPT
Open DNS port 53 (When default INPUT is DROP)
sudo iptables -A INPUT -m state --state NEW -p udp --sport 53 -j ACCEPT
sudo iptables -A INPUT -m state --state NEW -p tcp --sport 53 -j ACCEPT
Open DHCP port 67:68 (firewall itself)
sudo iptables -I OUTPUT -o eth0 -p udp --dport 67:68 --sport 67:68 -j ACCEPT
Open http & https
sudo iptables -A INPUT -m state --state NEW -p tcp --dport 80 -j ACCEPT
sudo iptables -A INPUT -m state --state NEW -p tcp --dport 443 -j ACCEPT
Open Outbound HTTP (if default output policy is DROP)
sudo iptables -I OUTPUT -o eth1 -p tcp -m tcp --dport 80 -m state --state NEW -j ACCEPT
sudo iptables -I OUTPUT -o eth1 -p tcp -m tcp --dport 443 -m state --state NEW -j ACCEPT
Open smtp (Outgoing) tcp port 25
# Secure (TLS = 587)
# Secure (SSL = 465)
sudo iptables -A INPUT -m state --state NEW -p tcp --dport 25 -j ACCEPT
Open pop3 (Incoming) tcp 110
# Secure (SSL = 995)
sudo iptables -A INPUT -m state --state NEW -p tcp --dport 110 -j ACCEPT
Open IMAP (Internet Message Access Protocol) tcp 143
sudo iptables -A INPUT -m state --state NEW -p tcp --dport 143 -j ACCEPT
# Gmail smtp SSL 465
# Gmail smtp TLS 587
# Gmail pop SSL 995
# Office 365 Outlook smtp TLS 587
# Office 365 Outlook pop SSL 995
# Yahoo smtp SSL 465
# Yahoo pop SSL 995
Open Samba 445
sudo iptables -A INPUT -s 192.168.1.0/24 -m state --state NEW -p tcp --dport 445 -j ACCEPT
Open Samba ports 137-139 NetBios Name resolution
sudo iptables -A INPUT -s 192.168.1.0/24 -m state --state NEW -p tcp --dport 137 -j ACCEPT
sudo iptables -A INPUT -s 192.168.1.0/24 -m state --state NEW -p tcp --dport 138 -j ACCEPT
sudo iptables -A INPUT -s 192.168.1.0/24 -m state --state NEW -p tcp --dport 139 -j ACCEPT
Open proxy port 3128
iptables -A INPUT -s 192.168.1.0/24 -m state --state NEW -p tcp --dport 3128 -j ACCEPT
Open mysql port 3306
sudo iptables -I INPUT -p tcp --dport 3306 -j ACCEPT
Allow existing connections to continue
sudo iptables -I INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
########################
### restriction in iptables ###
########################
# Restrict number of parallel connections per client IP
# Restrict to 3 ssh request per client
sudo iptables -A INPUT -p tcp --syn --dport 22 -m connlimit --connlimit-above 3 -j REJECT
Restrict to 10 http request per client
sudo iptables -I INPUT -p tcp --syn --dport 80 -m connlimit --connlimit-above 10 --connlimit-mask 24 -j DROP
--connlimit-above 3 : Match if the number of existing connections is above 3
--connlimit-mask 24 : Group hosts using the prefix length. (IPv4 between 0 and 32)
Restrict https to 5 requests per client
sudo iptables -A INPUT -p tcp --syn --dport https -m connlimit --connlimit-above 5 -j REJECT
Always allow lo (loopback interface)
sudo iptables -I INPUT 1 -i lo -j ACCEPT
Open SSH port
sudo iptables -A INPUT -p tcp --dport 22 -j ACCEPT
# Allow already opened and running SSH
sudo iptables -A INPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
##################
### Test first ###
##################
# Restrict 80,443 to 10 connections in 100 seconds
sudo iptables -A INPUT -p tcp -m multiport –dport 80,443 -m state –state NEW -m recent –set
sudo iptables -A INPUT -p tcp -m multiport –dport 80,443 -m state –state NEW -m recent –update –seconds 100 –hitcount 10 -j DROP
Allow Facebook during lunch time only
sudo iptables -A OUTPUT -p tcp -m multiport --dport http,https -o ethx -m time --timestart 12:00 --timestop 13:00 -d 31.13.64.0/18 -j ACCEPT
#My router1 iptables config at home (default to drop all)
#WAN = eth1
#LAN = eth0
-A INPUT -i eth0 -p tcp -m tcp -j ACCEPT
-A INPUT -s 192.168.1.0/24 -i eth0 -p icmp -j ACCEPT
-A FORWARD -i eth0 -p tcp -m tcp -j ACCEPT
-A OUTPUT -s 192.168.1.0/24 -p tcp -m tcp -j ACCEPT
-A OUTPUT -d 192.168.1.0/24 -p icmp -j ACCEPT
Survive reboot manually
sudo nano /etc/network/if-pre-up.d/firewall-kim
sudo chmod +x /etc/network/if-pre-up.d/firewall-kim
#Content of firewall-kim
#!/bin/sh
/sbin/iptables-restore < /etc/iptables.firewall.rules-custom
To enable IP masquerading (NAT) (assuming WAN = eth1)
sudo iptables -t nat -A POSTROUTING -o eth1 -j MASQUERADE
sudo iptables -A FORWARD -i eth1 -o eth0 -m state -–state RELATED,ESTABLISHED -j ACCEPT
sudo iptables -A FORWARD -i eth0 -o eth1 -j ACCEPT
Log All Packets from WAN interface
Creating LOGGING chain
sudo iptables -N LOGGING
sudo iptables -I INPUT -j LOGGING
iptables -A LOGGING -i eth1 -j LOG --log-prefix "Kim iptables: " --log-level 4
iptables -A LOGGING -m limit --limit 2/min -j LOG --log-prefix "Kim iptables: " --log-level 4
-log-level 0 (emergency)
-log-level 1 (Alert)
-log-level 2 (Critical)
-log-level 3 (Error)
–log-level 4 (warning)
-log-level 5 (Notice)
-log-level 6 (Info)
-log-level 7 (debug)
How to read iptables logs
IN= Incoming interface. This will be empty for outgoing packets
OUT= Outgoing interface. This will be empty for incoming packets.
SRC= Surce ip-address from where the packet originated
DST= Destination ip-address where the packets was sent to
LEN= Length of the packet
PROTO= Indicates the protocol
SPT= Source port
DPT= Destination port
#My router2
*filter
-A INPUT -m state –state RELATED,ESTABLISHED -j ACCEPT
-A INPUT -p icmp -j ACCEPT
-A INPUT -i lo -j ACCEPT
-A INPUT -p tcp -m state –state NEW -m tcp –dport 22 -j ACCEPT
-A INPUT -j REJECT -reject-with icmp-host-prohibited
-A FORWARD -i LAN -o WAN -j ACCEPT
-A FORWARD -i WAN -o LAN -m state –state RELATED,ESTABLISHED -j ACCEPT
#### All examples ####
# DNAT (WAN coming into a host in LAN)
sudo iptables -t nat -I PREROUTING -p tcp –dport 8080 -d 202.11.22.33 -j DNAT –to 192.168.1.222:80
# DNAT (WAN TO LAN 1:1)
sudo iptables -t nat -I PREROUTING -d 202.11.22.44 -j DNAT –to-destination 192.168.1.123
# SNAT (LAN going out with WAN IP)
sudo iptables -t nat -I POSTROUTING -s 192.168.1.33 SNAT –to-source 200.11.22.33
# SNAT (LAN going out with multiple WAN IPs)
sudo iptables -t nat -A POSTROUTING -j SNAT –to-source 200.11.22.33-200.11.22.44
#Example (/etc/rc.local)
/sbin/iptables -P FORWARD ACCEPT
/sbin/iptables –table nat -A POSTROUTING -o eth0 -j MASQUERADE
#Example NAT allow rdp (3389)
iptables -t nat -A PREROUTING -p tcp -i eth0 -d xxx.com.sg –dport 3389 -j DNAT –to 172.17.207.4:3389
Port forwarding
sysctl net.ipv4.ip_forward=1
yours_wan_ip=101.23.3.1
-A PREROUTING -p tcp -m tcp -d $wan_ip --dport 443 -j DNAT --to-destination 192.168.1.200:3389
-A FORWARD -m state -p tcp -d 192.168.1.200 --dport 3389 --state NEW,ESTABLISHED,RELATED -j ACCEPT
-A POSTROUTING -p tcp -m tcp -s 192.168.1.200 --sport 3389 -j SNAT --to-source $wan_ip
Port forwarding
Port forwarding from WAN to LAN
PREROUTING WAN 8888 to LAN 80
(LAN host does not have default gateway or pointed to another gateway)
-A PREROUTING -i wan -p tcp --dport 8888 -j DNAT --to-destination 192.168.1.6
Allow first packet to initiate new connection
-A FORWARD -i wan -o lan -p tcp --syn --dport 80 -m conntrack --ctstate NEW -j ACCEPT
Allow ESTABLISHED,RELATED traffic
-A FORWARD -i wan -o lan -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
-A FORWARD -i lan -o wan -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
POSTROUTING
(important to use the port 80 instead of 8888. It’s internal communication)
############## They are the same as MASQUERADING. Use only 1 of the syntax
-A POSTROUTING -o lan -p tcp --dport 80 -d 192.168.1.6 -jSNAT --to-source IP.OF.FIREWALL.LAN
-A POSTROUTING -o lan -p tcp --dport 80 -d 192.168.1.6 -jMASQUERADE
Firewall’s LAN interface will be the one accessing the local host 192.168.1.6