iptables 是 Linux 中比较底层的网络服务,它控制了 Linux 系统中的网络操作,在 CentOS 中的 firewalld 和 Ubuntu 中的 ufw 都是在 iptables 之上构建的,只为了简化 iptables 的操作,因此,对于学习了解 iptables 对我们了解 firewalld 和 ufw 的工作机制都是很有益处,当然,这里提一句,firewalld 和 ufw 不仅仅是对 iptables 上层封装那么简单,还有 ipv6 支持等功能。同时,iptables 不仅仅是防火墙这么简单,它基本上能实现你在 linux 上对于网络的所有需求,例如我曾经就使用过 iptables 构建过一个简单的 ap,用到的原理就是 iptables 的转发功能,更多关于 iptables 的功能让我在下面给你介绍。
序号 | 四个表 | 五个链 |
---|---|---|
1 | nat | INPUT |
2 | filter | OUTPUT |
3 | raw | FORWARD |
4 | mangle | PREROUTING |
5 | POSTROUTING |
规则(rules)
规则(rules)其实就是网络管理员预定义的条件,规则一般的定义为“如果数据包头符合这样的条件,就这样处理这个数据包”。规则存储在内核空间的信息包过滤表中,这些规则分别指定了源地址、目的地址、传输协议(如TCP、UDP、ICMP)和服务类型(如HTTP、FTP和SMTP)等。当数据包与规则匹配时,iptables就根据规则所定义的方法来处理这些数据包,如放行(accept)、拒绝(reject)和丢弃(drop)等。配置防火墙的主要工作就是添加、修改和删除这些规则。
链(chains)
链(chains)是数据包传播的路径,每一条链其实就是众多规则中的一个检查清单,每一条链中可以有一条或数条规则。当一个数据包到达一个链时,iptables就会从链中第一条规则开始检查,看该数据包是否满足规则所定义的条件。如果满足,系统就会根据该条规则所定义的方法处理该数据包;否则iptables将继续检查下一条规则,如果该数据包不符合链中任一条规则,iptables就会根据该链预先定义的默认策略来处理数据包。
表(tables)
表(tables)提供特定的功能,iptables内置了4个表,即raw表、filter表、nat表和mangle表,分别用于实现包过滤,网络地址转换和包重构的功能。
表名 | 作用 |
---|---|
raw表 | 只使用在PREROUTING链和OUTPUT链上,因为优先级最高,从而可以对收到的数据包在连接跟踪前进行处理。 一但用户使用了RAW表,在 某个链上,RAW表处理完后,将跳过NAT表和 ip_conntrack处理,即不再做地址转换和 数据包的链接跟踪处理了. |
filter表 | 主要用于过滤数据包,该表根据系统管理员预定义的一组规则过滤符合条件的数据包。对于防火墙而言, 主要利用在filter表中指定的规则来实现对数据包的过滤。Filter表是默认的表,如果没有指定哪个表, iptables 就默认使用filter表来执行所有命令,filter表包含了INPUT链(处理进入的数据包),RORWARD链(处理转发的数据包), OUTPUT链(处理本地生成的数据包)在filter表中只能允许对数据包进行接受,丢弃的操作,而无法对数据包进行更改 |
nat表 | 主要用于网络地址转换NAT,该表可以实现一对一,一对多,多对多等NAT 工作,iptables就是使用该表实现共享上网的, NAT表包含了PREROUTING链(修改即将到来的数据包),POSTROUTING链(修改即将出去的数据包), OUTPUT链(修改路由之前本地生成的数据包) |
mangle表 | 主要用于对指定数据包进行更改,在内核版本2.4.18 后的linux版本中该表包含的链为:INPUT链(处理进入的数据包), FORWARD链(处理转发的数据包),OUTPUT链(处理本地生成的数据包)POSTROUTING链(修改即将出去的数据包), PREROUTING链(修改即将到来的数据包) |
规则表之间的优先顺序
raw——> mangle ——> nat ——> filter
规则链之间的优先顺序
第一种情况:入站数据流向
从外界到达防火墙的数据包,先被PREROUTING规则链处理(是否修改数据包地址等),之后会进行路由选择(判断该数据包应该发往何处),如果数据包 的目标主机是防火墙本机(比如说Internet用户访问防火墙主机中的web服务器的数据包),那么内核将其传给INPUT链进行处理(决定是否允许通 过等),通过以后再交给系统上层的应用程序(比如Apache服务器)进行响应。
第二冲情况:转发数据流向
来自外界的数据包到达防火墙后,首先被PREROUTING规则链处理,之后会进行路由选择,如果数据包的目标地址是其它外部地址(比如局域网用户通过网 关访问QQ站点的数据包),则内核将其传递给FORWARD链进行处理(是否转发或拦截),然后再交给POSTROUTING规则链(是否修改数据包的地 址等)进行处理。
第三种情况:出站数据流向
防火墙本机向外部地址发送的数据包(比如在防火墙主机中测试公网DNS服务器时),首先被OUTPUT规则链处理,之后进行路由选择,然后传递给POSTROUTING规则链(是否修改数据包的地址等)进行处理。
iptable 命令
iptables的命令格式较为复杂,一般的格式如下:
$ iptable [-t 表] 命令选项 [链名] 匹配条件 [-j 动作]
说明:
命令 | 介绍 |
---|---|
-P --policy <链名> | 定义默认策略 |
-L --list <链名> | 查看iptables规则列表 |
-A --append <链名> | 在规则列表的最后增加1条规则 |
-I --insert <链名> | 在指定的位置插入1条规则 |
-D --delete <链名> | 从规则列表中删除1条规则 |
-R --replace <链名> | 替换规则列表中的某条规则 |
-F --flush <链名> | 删除表中所有规则 |
-Z --zero <链名> | 将表中数据包计数器和流量计数器归零 |
-X --delete-chain <链名> | 删除自定义链 |
-v --verbose <链名> | 与-L他命令一起使用显示更多更详细的信息 |
命令 | 介绍 |
---|---|
-i --in-interface 网络接口名> | 指定数据包从哪个网络接口进入, |
-o --out-interface 网络接口名> | 指定数据包从哪个网络接口输出 |
-p --proto 协议类型 | 指定数据包匹配的协议,如TCP、UDP和ICMP等 |
-s --source 源地址或子网> | 指定数据包匹配的源地址 |
--sport 源端口号> | 指定数据包匹配的源端口号 |
--dport 目的端口号> | 指定数据包匹配的目的端口号 |
-m --match 匹配的模块 | 指定数据包规则所使用的过滤模块 |
$ iptables -A INPUT -p TCP --dport 22 -j REJECT --reject-with ICMP echo-reply
$ iptables -t nat -A PREROUTING -p tcp --dport 80 -j REDIRECT--to-ports 8081
$ iptables -t nat -A POSTROUTING -p TCP -j MASQUERADE --to-ports 21000-31000
iptables -A INPUT -p tcp -j LOG --log-prefix "input packet"
iptables -t nat -A POSTROUTING -p tcp -o eth0 -j SNAT --to-source 192.168.10.15-192.168.10.160:2100-3200
iptables -t nat -A PREROUTING -p tcp -d 15.45.23.67 --dport 80 -j DNAT --to-destination 192.168.10.1-192.168.10.10:80-100
MIRROR 镜像数据包,也就是将来源 IP与目的地IP对调后,将数据包返回,进行完此处理动作后,将会中断过滤程序。
QUEUE 中断过滤程序,将封包放入队列,交给其它程序处理。透过自行开发的处理程序,可以进行其它应用,例如:计算联机费用…等。
RETURN 结束在目前规则链中的过滤程序,返回主规则链继续过滤,如果把自订规则炼看成是一个子程序,那么这个动作,就相当于提早结束子程序并返回到主程序中。
MARK 将封包标上某个代号,以便提供作为后续过滤的条件判断依据,进行完此处理动作后,将会继续比对其它规则。范例如下:
iptables -t mangle -A PREROUTING -p tcp --dport 22 -j MARK --set-mark 22
$ iptables -L -n -v --line-numbers
$ service iptables stop
$ service iptables start
$ service iptables restart
$ iptables -L INPUT -n --line-numbers
$ iptables -L OUTPUT -n --line-numbers
$ iptables -L OUTPUT -n --line-numbers | less
$ iptables -L OUTPUT -n --line-numbers | grep 202.54.1.1
$ iptables -I INPUT 2 -s 202.54.1.2 -j DROP
$ service iptables save
$ iptables-restore < /root/my.active.firewall.rules
$ iptables -A INPUT -i eth1 -s 192.168.0.0/24 -j DROP
$ iptables -A INPUT -i eth1 -s 10.0.0.0/8 -j DROP
$ iptables -A INPUT -s 1.2.3.4 -j DROP
$ iptables -A INPUT -s 192.168.0.0/24 -j DROP
$ iptables -A INPUT -p tcp -s 1.2.3.4 --dport 80 -j DROP
$ iptables -A INPUT -i eth1 -p tcp -s 192.168.1.0/24 --dport 80 -j DROP
$ iptables -A OUTPUT -d 192.168.1.0/24 -j DROP
$ iptables -A OUTPUT -o eth1 -d 192.168.1.0/24 -j DROP
$ 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
$ iptables -A INPUT -m mac --mac-source 00:0F:EA:91:04:08 -j DROP
# only accept traffic for TCP port 8080 from mac 00:0F:EA:91:04:07
$ iptables -A INPUT -p tcp --destination-port 22 -m mac --mac-source 00:0F:EA:91:04:07 -j ACCEPT
$ iptables -A INPUT -p icmp --icmp-type echo-request -j DROP
$ iptables -A INPUT -i eth1 -p icmp --icmp-type echo-request -j DROP
iptables -A INPUT -m state --state NEW -m tcp -p tcp --dport 7000:7010 -j ACCEPT
iptables -A INPUT -p tcp --destination-port 80 -m iprange --src-range 192.168.1.100-192.168.1.200 -j ACCEPT
iptables -D INPUT 4
术语解释
企业内部的主机A若配了一个公网地址6.6.6.6,访问互联网上其他网段的公有地址不受限制,但若访问互联网上同网段的地址即6.0.0.0/8网段的地址,由于A的路由表就有到达该网段的路由记录,就直接访问了,不会去查询路由器,但是实际上访问的不是互联网上的主机,而是本地局域网的主机,也就是说该网段的所有公有地址A都将无法访问。所以企业内部的主机一般是私有地址,但是互联网上没有私有地址的路由,也就是说私有地址无法连接互联网,可以利用防火墙的nat表(network address translation 地址转换规则表)将私有地址转换为公有地址再去访问互联网。
SNAT
企业内部的主机A想访问互联网上的主机C,首先将请求数据包(源:ipA,目标:ipC)发送到防火墙所在主机B,B收到后将数据包源地址改为本机公网网卡的ip(源:ipA,目标:ipB),然后经互联网发送给C;C收到后将回应包(源:ipC,目标:ipB)转发给C的路由器,经互联网将回应包转发给B,B收到回应包后修改其目的地址,即回应包改为(源:ipC,目标:ipA)然后将数据包转发给A。
在这个过程中,修改了请求报文的源地址,叫做SNAT(source NAT POSTROUTING),用于局域网访问互联网。
不能在防火墙B的prerouting链上设置转换源地址的防火墙策略,因为若在B的prerouting链上设置转换源地址的防火墙策略,此时还未检查路由表,还不知道要到达数据包中目标主机需经过本机的哪个网卡接口,即还不知道需将源地址替换为哪个公网网卡的ip,需在postrouting设置转换源地址的防火墙策略。
实验环境:实验中用172.18.0.0/16网段模拟公网ip
destination | gateway | netmask | iface |
---|---|---|---|
192.168.25.0 | 0.0.0.0 | 255.255.255.0 | eth0 |
172.18.0.0 | 0.0.0.0 | 255.255.0.0 | eth1 |
表示主机A可以到达192.168.25.0/24、172.18.0.0/16两个网络,网关为0.0.0.0也就是说怎么都可以到达,所以每台主机不需经过路由器就可以与和它同网段的主机通讯,若主机A想与和它不同网段的主机通讯,需要添加路由记录,添加时可以不指定接口,主机A会自动使用与网关ip同网段的ip所在网卡
0.0.0.0 172.18.0.107 255.255.0.0 eth1
即到达任何未知网络时将数据包转发到网关,也就是路由器的某个网卡,网关ip必须是本机可以到达的某个网段的ip,即必须是192.168.25.0/24、172.18.0.0/16两个网端的某个ip.
路由器的路由表实际上也是类似的,也有本机ip所在网段的路由和到其他网段的路由,只是在普通主机的基础上启用了路由转发功能,普通主机收到目标主机不是自己的数据包后会抛弃,路由器收到目标主机不是自己的数据包后会检查路由表,将数据包转发出去,也就是说普通主机的路由表只能供自己发送数据包时使用,路由器的路由表是公用的。
参数 | 功能 |
---|---|
-t | 指定防火墙策略应用哪个表 |
-A | 指定防火墙策略应用在该表的哪个链 |
-s | 源地址 |
-j | 动作 |
--to-source | 指定转换后的源地址 |
172.18.0.108上抓包,如图,显示源地址为172.18.0.107
在C看来,是B在访问C,而不是A,但是实际上是A在访问C,数据包是从A发往C的,只是经过B时将源地址改为B,但实际上是A发过来的数据包
若企业内部有A、C、D等主机都要访问互联网,
终端 | 请求数据 包源地址 |
源端口 | 公网地址 | 目标端口 |
---|---|---|---|---|
A | ip1 | 12345 | 替换为 B公网ip | 12345 |
C | ip2 | 23456 | 替换为 B公网ip | 23456 |
D | ip3 | 23456 | 替换为 B公网ip | 24414 |
DNAT
实验环境:本实验中用172.18.0.0/16网段模拟公网ip
打开服务配置文件
Httpd默认监听在标准端口80,将端口改为非标准端口8000
因为selinux阻止使用非标准端口,所以重启失败
使用setenforce 0临时关闭selinux
参数 | 功能 |
---|---|
-t | 指定防火墙策略应用哪个表 |
-A | 指定防火墙策略应用在该表的哪个链 |
-s | 源地址 |
-j | 动作 |
--to-destination | 指定转换后的目标地址 |