iptables is a very classic firewall tool for Linux, but the learning curve is very high due to its complex structure, long official documentation, many parameters, and awkward configuration (default does not support persistence, commands added to take effect, etc.), and risky configuration (accidentally lose connection with the server). It is extremely unfriendly to Linux newbies or people with poor memory (I have a very poor memory). The purpose of this article is to let iptables newbies master iptables common operations in 15 minutes, and be able to quickly look up the commands they want as needed.

Disclaimer: This article is the author’s personal use of the process of sharing notes, please understand what you are doing before using the commands in the notes, it is recommended to operate in the experimental environment first, and then apply in the production environment! If you are not sure what you are doing or what you want to do, it is recommended to read the official documentation of iptables: iptables(8) - Linux man page first.

iptables concepts

  • tables: kernel modules corresponding to different processing of packets
    • filter: filtering
    • kernel module: iptables_filter
    • nat: network address translation
    • kernel module: iptables_nat
    • mangle: disassembly and encapsulation of packets
    • raw: the table that first touches the packet and allows a packet to skip the filtering principle

table order is raw -> mangle -> nat -> filter

  • chaining: different access paths go through different chains
    • prerouting
    • input
    • output
    • forward
    • postrouting

Chain order in different tables.

Chain order in different tables

iptables common commands

Configure global policy

Danger! It is best to configure the global policy when a VNC connection is available, or after the configuration is finished.

1
2
3
iptables --policy INPUT DROP
iptables --policy OUTPUT ACCEPT
iptables --policy FORWARD ACCEPT

Show iptables rules

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
# All-purpose medicine
iptables -n -L -v --line-numbers

# Show all rules in the default table (filter)
iptables -n -L

# Record traffic when displaying rules
iptables -n -L -v

# Record line number when displaying rules (for insertion)
iptables -n -L --line-numbers

# Specify a sub-table (most commonly used as nat)
iptables -n -L -t nat

# 只显示某链的规则
iptables -L INPUT

# 以 iptables-save 格式显示规则
iptables -S INPUT

iptables Add/Delete

add

1
2
3
4
5
# Insert a rule after the input chain n position
iptables -I INPUT {n} ...

# Add the rule at the end of the INPUT chain
iptables -A INPUT ...

Delete

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
# Deletes records in the n position of the INPUT chain
iptables -D INPUT {n}

# Delete records based on specific parameters
iptables -D INPUT -m conntrack --ctstate INVALID -j DROP

# Delete all records under the specified chain
iptables -F INPUT

# Delete all records under the specified table
iptables -t nat -F

# Delete all records
iptables -F

iptables packet filtering

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
# Allow specific TCP ports to pass through
iptables -A INPUT -p tcp --dport 22 -j ACCEPT

# Allow specific TCP port segments to pass.
iptables -A INPUT -p tcp --dport 8000:8800 -j ACCEPT
iptables -A INPUT -p tcp -m multiport --dport 80,443 -j ACCEPT

# Allow specific IPs to pass.
iptables -A INPUT -p tcp -s 192.168.1.0/24 --dport 22 -j ACCEPT

# Allow passage from a specific NIC.
iptables -A INPUT -i eth1 -p tcp --dport 3306 -m conntrack --ctstate NEW,ESTABLISHED -j ACCEPT

# Disabling specific ports.
iptables -A OUTPUT -p tcp --dport 25 -j REJECT

# Prohibit and record.
iptables -A INPUT -i eth1 -s 10.0.0.0/8 -j LOG --log-prefix "IP_SPOOF A: "
iptables -A INPUT -i eth1 -s 10.0.0.0/8 -j DROP
tail -f /var/log/messagesgrep --color 'IP SPOOF' /var/log/messages

# Filtering based on specific packet content (non-encrypted).
iptables -A FORWARD -m string --string '.exe' -j DROP

iptables packet forwarding

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
# Packet forwarding prerequisite: ip_forward enabled
echo "net.ipv4.ip_forward = 1" >> /etc/sysctl.conf
sudo sysctl -p

# iptables implementation of NAT gateway
# Assume the intranet segment is 10.0.0.0/24
iptables -t nat -A POSTROUTING -s 10.0.0.0/24 -j MASQUERADE
iptables -t filter -A FORWARD -s 10.0.0.0/24 -j ACCEPT
iptables -t filter -A FORWARD -d 10.0.0.0/24 -j ACCEPT

# iptables port mapping
# Forward the local (192.168.75.5) ports 80~88 to 192.168.75.3:8008
iptables -t nat -A PREROUTING -p tcp -d 192.168.75.5 --dport 80:88 -j DNAT --to-destination 192.168.75.3:8000-8008
iptables -t nat -A POSTROUTING -p tcp -d 192.168.75.3 --dport 8000:8008 -j SNAT --to-source 192.168.75.5

iptables packet flow restriction

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
# Restricted traffic
iptables -A INPUT -p tcp -m multiport --dport 80,443 -m limit --limit 20/s --limit-burst 5 -j ACCEPT

# Limit time
iptables -A INPUT -p tcp -m multiport --dport 80,443 -m time --timestart 21:30 --timestop 22:30 --days Mon,Tue,Wed,Thu,Fri -j ACCEPT

# Prevention of violent attacks
iptables -A INPUT -p tcp -m multiport --dport ssh -m conntrack --ctstate NEW -m recent --setiptables -A INPUT -p tcp --dport ssh -m conntrack --ctstate NEW -m recent --update --seconds 60 --hitcount 10 -j DROP

# Prevent port scanning
iptables -N port-scanningiptables -A port-scanning -p tcp --tcp-flags SYN,ACK,FIN,RST RST -m limit --limit 1/s --limit-burst 2 -j RETURNiptables -A port-scanning -j DROP

iptables save & load & autoload

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
# Save
iptables-save > /etc/iptables/rules.v4

# Load
iptables-restore < /etc/iptables/rules.v4

# Autoload
# deb system
apt install iptables-persistent
# Automatically read configuration files from /etc/iptables/rules.v4 and /etc/iptables/rules.v4

# RHEL System
dnf install iptables-services
sudo systemctl stop firewalld
sudo systemctl disable firewalld
sudo systemctl start iptables
sudo systemctl enable iptables
# Read configuration files from /etc/sysconfig/iptables and /etc/sysconfig/ip6tables

iptables-save configuration file reading and writing

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
# Generated by iptables-save v1.4.21 on Tue Jan 15 15:42:32 2019
--This is a comment
*nat
-- This means that the following is the configuration in the nat table
:PREROUTING ACCEPT [5129516:445315174]
-- :PREROUTING ACCEPT, indicates that the default message policy for the PREROUTING chain in the nat table is accept (no match rule continues),

-- [5129516:445315174] i.e. [packet, bytes],indicates that there are currently 5129516 packages (445315174 bytes)PREROUTING chain through nat table
:INPUT ACCEPT [942957:151143842]
:OUTPUT ACCEPT [23898:3536261]
:POSTROUTING ACCEPT [23898:3536261]
-- Explanation as above
:DOCKER - [0:0]
-- Explanation as above (this article is a custom chain)
---------- Here is how to output all the rules by article ----------
[4075:366986] -A PREROUTING -m addrtype --dst-type LOCAL -j DOCKER
-- [4075:366986] i.e. [packet, bytes],Indicates the number of packets, in bytes, that passed through this rule. The latter part is the command to configure this rule with the iptables command (see the iptables help for more details on the options)[0:0] -A OUTPUT ! -d 127.0.0.0/8 -m addrtype --dst-type LOCAL -j DOCKER
[0:0] -A POSTROUTING -s 172.17.0.0/16 ! -o docker0 -j MASQUERADE
[2:188] -A POSTROUTING -s 192.168.122.0/24 -d 224.0.0.0/24 -j RETURN
[0:0] -A POSTROUTING -s 192.168.122.0/24 -d 255.255.255.255/32 -j RETURN
[0:0] -A POSTROUTING -s 192.168.122.0/24 ! -d 192.168.122.0/24 -p tcp -j MASQUERADE --to-ports 1024-65535
[0:0] -A POSTROUTING -s 192.168.122.0/24 ! -d 192.168.122.0/24 -p udp -j MASQUERADE --to-ports 1024-65535
[0:0] -A POSTROUTING -s 192.168.122.0/24 ! -d 192.168.122.0/24 -j MASQUERADE
[0:0] -A DOCKER -i docker0 -j RETURN
--The above rules are the same as the explanation of the first rule
COMMIT
-- Apply the above configuration
# Completed on Tue Jan 15 15:42:32 2019