iptables详解

2019-06-20

在前面 iptables使用 中,简单介绍了下iptables的命令,在 iptables与firewalld 中简单的介绍了下iptables的组成结构,在本文中,详细介绍下iptables的概念和原理。

概要

iptables是运行在用户空间的应用软件,通过控制linux内核netfilter模块,来管理网络数据包的检测、修改、转发、重定向和丢弃。

iptables使用Xtables框架,包含“表(tables)”、“链(chain)”和“规则(rules)”三个层面。

“链”是一些按顺序排列的规则的列表,“链”的网络层处理过程如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
                                                                      +--------------+        ****************
------------->| User Process |------> Routing decision
^ +-------+------+ ****************
| |
| |
| |
| V
+--------------+ +---------------+
| chain: INPUT | | chain: OUTPUT |
+------+-------+ +-------+-------+
^ |
| |
| |
XXXXXXXXXXXX +------------------+ **************** +----------------+ V +--------------------+
X Network X -----> |chain: PREROUTING | ------> Routing decision ------> | chain: FORWARD | --------------->| chain: POSTROUTING |
XXXXXXXXXXXX +---------+--------+ **************** +--------+-------+ +----------+---------+

进入到网卡的数据包先到RREOUTING链,进行前置处理,然后到路由,目标为本机的数据包,会被转到INPUT链,INPUT链处理完后再转发到用户进程,用户进程处理完后,返回的数据包通过路由判断是否需要发送到其他主机,需要发往其他主机的数据包被转到OUTPUT链,OUTPUT链处理完后到POSTROUTING链,另一方面,目标不为本机的数据包会被转到FORWARD链,FORWARD链处理后也转到POSTROUTING链,POSTROUTING链处理完从本机发出。

“链”上的数据会被怎么处理呢?由表和规则来确定。

iptables包含5张表:

1
2
3
4
5
6
7
8
9
filter表:默认的表,如果不指明则使用此表,通常用于过滤数据包。

nat表:用于地址转换操作,包括修改数据包中的源,目标IP地址或端口。

raw表:用于处理异常。

mangle表:用于处理数据包。nat侧重连接,mangle侧重每个数据包。

security表:用于强制访问控制网络规则。

具体可以参见netfilter的官方原理图

image

可以看到一张表可能存在多个链上,filter表在INPUT、OUTPUT、FORWARD链上,nat表在PREROUTING、POSTROUTING、OUTPUT链上,mangle表在PREROUTING、OUTPUT、FORWARD、INPUT、POSTROUTING链上,raw表在PREROUTING、OUTPUT链上。

规则

规则是由一个目标和很多匹配指定,匹配到的数据包执行目标。匹配包括数据包的IP、进入的端口(网卡eth0或者eth1)、数据包的类型(ICMP,TCP或者UDP)、数据包的目的端口和目标IP的匹配。目标使用-j或者--jump指定。目标可以是用户自定义的链、内置的特定目标或者目标扩展。目标为自定义链时,如果条件匹配,跳转到用户自定义的链后,再根据自定义链的规则进行处理。内置的目标包括ACCEPTDROP,QUEUE,RETURN,目标扩展包括REJECT,log。如果目标是内置目标,数据包的命运会立刻被决定并且在当前表的数据包的处理过程会停止。

命令示例

iptables与firewalld 中介绍了iptables命令,本章从表的角度来介绍下iptables命令。

filter表

前面两篇文章中已经介绍了一些命令,主要做了IP的过滤,例如:

1
iptables -I INPUT -p  tcp --dport 80 -s 10.0.0.2 -j DROP

不指明表示使用filter表

拒绝17500端口的探测:

1
iptables -A INPUT -p tcp --dport 17500 -j REJECT --reject-with icmp-port-unreachable

nat表

端口重定向示例:

1
iptables -t nat -A PREROUTING -p tcp --dport 80 -j REDIRECT --to-port 8080

将发往80端口的数据包转向8080端口,注意以上命令只对外部的IP生效,对本地端发起的请求不会遵循nat表上PREROUTING链的设置,想让本地端也生效,可以执行以下指令:

1
iptables -t nat -A OUTPUT -o lo -p tcp --dport 80 -j REDIRECT --to-port 8080

这条规则会将lo接口上的数据包输出由80端口转向到8080端口上面。

网络地址转换示例

例1,办公室用小型局域网,由一台Linux主机作为路由器共享地址接入Internet。

假设局域网接口为eth0,地址使用192.168.0.0/24;而Internet接口为eth1,使用的地址为198.51.100.3。

在局域网用户访问Internet时,源地址需要被转换为198.51.100.3,则使用规则:

1
iptables -t nat -I POSTROUTING -s 192.168.0.0/24 -o eth1 -j SNAT --to 198.51.100.3

例2,还是在以上局域网中,在192.168.0.2上开启HTTP服务,将所有发到198.51.100.3的80端口的请求转到HTTP服务上:

1
iptables -t nat -I PREROUTING -p tcp -d 198.51.100.3 --dport 80 -j DNAT --to 192.168.0.2

没错,不需要代理软件,iptables就能实现代理上网功能。

log表

log是用来记录符合规则的数据包的。例如,记录icmp的数据包,并以"IPTABLES ICMP-IN: "开头:

1
iptables -A INPUT -p icmp -j LOG --log-prefix "IPTABLES ICMP-IN: "

可以在/var/log/messages中看到打印的日志:

1
Jun 21 20:14:45 node5 kernel: IPTABLES ICMP-IN: IN=ens192 OUT= MAC=00:50:56:a7:ef:99:00:50:56:a7:c0:aa:08:00 SRC=128.96.103.19 DST=128.96.103.18 LEN=84 TOS=0x00 PREC=0x00 TTL=64 ID=29961 DF PROTO=ICMP TYPE=8 CODE=0 ID=29100 SEQ=19

删除对应规则:

1
iptables -D INPUT -p icmp -j LOG --log-prefix "IPTABLES ICMP-IN: "

参考

https://wiki.archlinux.org/index.php/Iptables_(%E7%AE%80%E4%BD%93%E4%B8%AD%E6%96%87)

https://zh.wikipedia.org/wiki/Iptables