Iptables is a very important skill that must be learned by every system administrator.
Basic Usage
Enable iptables on centos 7 as root.
1
2
3
4
5
|
$ systemctl stop firewalld
$ yum install -y iptables-servers
$ systemctl start iptables
$ systemctl enable iptables
|
There are 3 tables including NAT
, FILTER
, MANGLE
and 5 chains including PREROUTING
, POSTROUTING
, INPUT
, OUTPUT
, REDIRECT
. Different chains depends on the specific table.
Iptables default configuration file is /etc/sysconfig/iptables
, anytime you restart the service, it will read iptables rules from the file. Let’s see the default rules looks like.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
|
# /etc/sysconfig/iptables
*nat
:PREROUTING ACCEPT [0:0] # default policy is ACCEPT
:INPUT ACCEPT [0:0] # default policy is ACCEPT
:OUTPUT ACCEPT [0:0] # default policy is ACCEPT
:POSTROUTING ACCEPT [0:0] # default policy is ACCEPT
COMMIT
*filter
:INPUT ACCEPT [0:0] # default policy is ACCEPT
:FORWARD ACCEPT [0:0] # default policy is ACCEPT
:OUTPUT ACCEPT [0:0] # default policy is ACCEPT
-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 -j REJECT --reject-with icmp-host-prohibited
COMMIT
|
Here are some examples of iptables commands usages as root.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
|
# print filter table all rules
$ iptable -t filter -nvL
# print filter table INPUT rules
$ iptable -t filter -nvL INPUT
# default table is filter and show rules num
$ iptable -nvL --line
# set filter table FORWARD chains's default policy is REJECT
$ iptable -P FORWARD REJECT
# allow port 8000
$ iptable -t filter -A INPUT -p tcp -m state --state NEW -m tcp --dport 8000 -j ACCEPT
# delete a rule depend on the rule number
$ iptables -t filter -nvL INPUT --line
$ iptables -t filter INPUT -D 2 # 2 is the rule's number
|
Forward
Forward also very important especially you want to run Linux as a router or gateway. Let’s do some experiments to know more in details. Assuming you have deployed the network environment as follow.
Do these experiment on your local machines and run commands as root !!!
1
2
3
4
5
6
|
RouterA # 3.1-eth0
├── PC1 # 3.10
├── PC2 # 3.20
└── RouterB/PC3 # 3.30-enp0s3/8.1-enp0s8
├── PC3 # 8.2
└── PC4 # 8.3
|
Now we want PC2 can communicate with PC4 each other through PC3 .
PC3 basic requirement settings.
1
2
3
4
5
6
7
8
9
10
11
|
# enable kernel ip_forward
$ echo 'net.ipv4.ip_forward = 1' >> /etc/sysctl.conf
$ sysctl -p
# if the result is 1, meaning you turn on the ip_forward
$ cat /proc/sys/net/ipv4/ip_forward
# use deault iptables rules showed before.
# set filter table FORWARD chain's default policy is ACCEPT
$ systemctl restart iptable
$ iptable -t filter FORWARD -P ACCEPT
|
PC2 settings
1
2
|
# add a new route rule
$ route add -net 192.168.8.0/24 gw 192.168.3.30
|
Now PC2 and PC4 can ping each other, but let’s add a new rule on PC3 .
1
|
$ iptable -t filter -A FORWARD -j REJECT
|
They can’t ping each other this time, now we need to add specific rules which ports was allowed to communicate. Assume we want the 8000 port.
1
2
3
4
5
|
# pc4, disable iptables temporarily
$ python -m SimpleHTTPServer 8000 &
# pc2, disable iptables temporarily
$ python -m SimpleHTTPServer 8000 &
|
Allow PC2 telnet PC4 8000 port
1
2
3
4
5
|
# pc3 setting
$ iptables -t filter -I FORWARD -s 192.168.3.0/24 -p tcp --dport 8000 -j ACCEPT
# remeber to add return rules
$ iptables -t filter -I FORWARD -s 192.168.8.0/24 -p tcp --sport 8000 -j ACCEPT
|
Allow PC4 telnet PC2 8000 port
1
2
3
4
5
|
# pc3 setting
$ iptables -t filter -I FORWARD -s 192.168.8.0/24 -p tcp --dport 8000 -j ACCEPT
# remeber to add return rules
$ iptables -t filter -I FORWARD -s 192.168.3.0/24 -p tcp --sport 8000 -j ACCEPT
|
The return rules can replace by this rule.
1
2
|
# pc3
$ iptable -t filter -I FORWARD -m state --state ESTABLISHED,RELATED -j ACCEPT
|
If you want subnet 192.168.3.0/24 communicate with 192.168.8.0/24 each other.
1
2
|
# RouterA
$ route add -net 192.168.8.0/24 gw 192.168.3.30 dev eth0
|
NAT
Assume 192.168.3.0 is WAN and 192.1168.8.0 is LAN. This time PC3 work as a router, Router B. Don’t forget the basic requirement settings.
PC2 only knows the request comes from Router B, when PC4 browse PC2 8000 port.
1
2
|
# Router B or PC3
$ iptables -t nat -A POSTROUTING -s 192.168.8.0/24 -j SNAT --to-source 192.168.330
|
If Router B is not a static ip, such as PPPOE client used dynamic ip, then use the special action, MASQUERADE
.
1
2
|
# Router B or PC3
$ iptables -t nat -A POSTROUTING -s 192.168.8.0/24 -o enp0s3 -j MASQUERADE
|
Browse the web server behind Router B throng Router B ip address. Assume PC4 web server created by python is allow browse on PC2 throng 192.168.3.30:80 .
1
2
|
# Router B or PC3
$ iptable -t nat -A PREROUTING -d 192.168.3.30 -p tcp --dport 80 -j DNAT --to-destination 192.168.8.3:8000
|
PPPOE dynamic ip
1
2
|
# Router B or PC3
$ iptable -t nat -A PREROUTING -i enp0s3 -p tcp --dport 80 -j DNAT --to-destination 192.168.8.3:8000
|
Others
Only use on local port redirect. 80 -> 8000
1
2
3
|
# PC4
$ iptable -t filter -A REDIRECT -m state --state NEW -p tcp --dport 80 -j REDIRECT --to-ports 8000
$ iptables -t filter -A INPUT -m state --state NEW -p tcp -m multiport 80,8000 -j ACCEPT
|
Log all 1194 udp port activity.
1
2
3
4
5
6
|
# /etc/rsyslog.conf
$ echo 'kern.warning /var/log/iptables.log' >> /etc/rsyslog.conf
$ systemctl restart rsyslog
# iptables rule
$ iptable -t filter -m state --state NEW -p udp -m udp --dport 1194 -j LOG
|
Allow port 80 communicate during 8:00 a.m. to 20:00 p.m.
1
|
$ iptables -t filter -p tcp -m state NEW -m tcp --dport 80 -m time --datestart 08:00 --datestop 20:00 -j ACCEPT
|
Summary
There is no summary, cause I haven’t finish this post yet 😂