1. Linux当中的iptables介绍
我们一般把iptables称作防火墙,但是实际上防火墙并不是iptables,netfilter才是真正的防火墙,它工作在Linux内核当中,iptables则是操作netfilter的一个客户端,工作在用户态。
Linux的iptables当中目前支持的规则表有以下几类:
- raw表,支持处理数据包连接跟踪。
- filter表,支持处理流量是拦截还是放行,用于实现防火墙的功能。
- nat表,用于实现地址转换的功能,支持处理对于ip和端口号的修改(包括源ip、源端口、目标ip和目标端口)。
- mangle表,支持处理报文的拆包、经过处理之后重新封包的功能。
Linux网络数据包流转有很多的阶段,虽然iptables支持以上四种的规则表,但是并不是每个阶段都可以应用以上的所有规则。Linux当中的iptables执行流程一共有5个阶段,每个阶段都分别有一些支持的规则表,下面是各个阶段支持的规则表。
- PREROUTING(支持raw表、mangle表、nat表)
- INPUT(支持mangle表和filter表)
- OUTPUT(支持mangle表、filter表、nat表)
- POSTROUTING(支持mangle表和nat表)
- FORWARD(支持mangle表和filter表)
对于防火墙的流量主要有三类:入流量、出流量和转发流量。入流量,也就是别人往你的服务器发请求;出流量也就是你往别人的服务器发请求;转发流量则是,别人往你的机器发流量,你需要将流量重新转发给别人。
对于入流量来说,数据包的流转情况如下图所示:
网络入口 -> PREROUTING -> ROUTING -> INPUT -> TCP/IP协议栈 -> NGINX/TOMCAT
对于出流量来说,数据包的流转情况如下图所示:
NGINX/TOMCAT -> TCP/IP协议栈 -> ROUTING -> OUTPUT -> POSTROUTING -> 网络出口
对于转发流量来说,数据包的流转情况如下图所示:
网络入口 -> PREROUTING -> ROUTING -> FORWARD -> POSTROUTING -> 网络出口
2.自定义服务器的iptables规则
2.1 新增iptables规则
我们可以通过iptables命令去新增iptables规则表,对于规则表的参数支持情况如下:
- 通过
-A
参数(add
)指定,要去进行干预的阶段(PREROUTING、POSTROUTING、INPUT、OUTPUT和FORWARD),往规则表最后新加一条规则,如果需要往最前面插入,可以使用-I
命令(insert
)。 - 通过
-p
参数指定,要去进行匹配的协议类型(tcp、udp、icmp)。 - 通过
-s
和-d
参数指定要匹配的源IP/目标IP,或者是源IP和目标IP的网段CIDR(例如192.168.1.0/24、10.0.0.0/8)。 - 通过
--sport
和--dport
指定要匹配的源端口(--sport
)/目标端口(--dport
)。如果需要匹配多个端口,可以使用--sports
和--dports
,多个端口号之前使用英文,分割就行,例如--sports 80,8080,18080
。 - 通过
-i
指定要匹配的网卡接口,例如-i eth0
用于匹配从eth0
网卡进来的流量。 - 通过
-t
参数指定,该阶段下要去进行干预的规则表,比如nat、filter、mangle,如果不指定的话默认是filter
表。 - 通过
-j
参数指定,在匹配上规则之后,我们要去进行的目标操作是什么,支持以下几种操作。 - ACCEPT:允许数据包通过。
- DROP:直接丢弃数据包(丢包,客户端没有任何响应,直到等到超时)。
- REJECT:拒绝请求发送数据包并发送响应给客户端。
- LOG:在
/var/log/messages
当中打印日志。 - SNAT:修改源(Source)地址,包括源IP和源端口号。
- DNAT:修改目标(Destination)地址,包括目标IP和目标端口号。
- REDIRECT:重定向到本地端口(针对nat表),比如我们将443端口的流量转发到30777端口,就用到这个操作。
- MASQUERADE:隐藏源IP,统一使用指定的网卡接口的IP进行流量的出栈,用于类似实现路由器的NAT地址转换功能。
例如,下面的命令用于操作filter表(默认),允许入流量的80端口,直接放行(ACCEPT)。
iptables -A INPUT -p tcp --dport 80 -j ACCEPT
再比如,下面的命令用于操作filter表(默认),对入流量的源IP为192.168.1.100,并且访问当前服务器的端口12345流量,直接拒绝掉。
iptables -A INPUT -s 192.168.1.100 --dport=12345 -j REJECT
再比如,通过如下的命令实现本机的端口转发,比如我现有一个服务在30777端口启动,我需要通过HTTPS默认的443端口访问这个服务,此时我们就可以将443端口的流量转发给本机的30777端口。
# -d指定本机ip, --dport指定访问本机的443端口
iptables -t nat -A PREROUTING -p tcp -d 10.0.0.166 --dport 443 -j REDIRECT --to-port 30777
# (推荐)-i指定本机要添加的规则的网卡端口, --dport指定访问本机的443端口
iptables -t nat -A PREROUTING -p tcp -i eth0 --dport 443 -j REDIRECT --to-port 31889
# !!!! 请勿使用不指定ip和网卡的端口转发, 会出现容器的https请求都无法使用, 因为都被转发到30777端口
iptables -t nat -A PREROUTING -p tcp --dport 443 -j REDIRECT --to-port 30777
再比如,路由器的NAT地址转换,通过下面的命令,我们将10.0.8.0/24
网段的地址,在流量流出服务器时,将IP修改成为eth0
网卡的端口,比如eth0
是公网IP,那么通过如下的命令,就代表我们将10.0.8.0/24
网段的内网地址,转换成为公网IP地址。
iptables -t nat -A POSTROUTING -s 10.0.8.0/24 -o eth0 -j MASQUERADE
2.2 查看iptables规则
可以通过如下的命令去查看当前操作系统当中的iptables规则表
iptables -L -n -t nat --line-numbers
参数介绍:
-L
参数表达我们需要去查看iptables规则。-n
参数用于禁用DNS解析,如果不加-n参数,可能会对域名进行DNS解析,会将常见的端口进行映射成为对应的协议名称,比如将TCP的443端口解析成为https(通过cat /etc/services
可以查看到对应的服务名称的映射关系)。-t nat
指定我们只想要查看nat表。--line-number
用于展示iptables规则表当中每一行的行号。
如果我们想要查看443端口的处理情况,可以尝试使用如下的命令:
iptables -L -n -t nat --line-numbers | grep 443
2.3 删除iptables规则
如果想要删除iptables规则,可以通过iptables -D
命令实现。
删除iptables的第一种使用方式:通过-t
指定规则表,-D
指定要删除的规则所处的阶段,并且按照行号进行删除。对于行号需要通过iptables -L -n -t nat --line-numbers
命令的结果进行查看。
iptables -t nat -D PREROUTING ${line-number}
删除iptables的第二种使用方式:通过将新增时是用到的-A
和-I
命令,换成-D
命令,iptables会进行匹配表中的项的内容实现删除。
iptables -t nat -A PREROUTING -p tcp -d 10.0.0.166 --dport 443 -j REDIRECT --to-port 30777
# 对应删除命令
iptables -t nat -A PREROUTING -p tcp -d 10.0.0.166 --dport 443 -j REDIRECT --to-port 30777
3. iptables规则的持久化与自动加载
iptables的变化只针对机器的本次启动时生效,如果机器发生重启,那么规则就会丢失。如果我们需要对后续一直生效的话,此时我们就涉及到iptables的持久化。我们可以安装iptables-persistent
工具实现iptables的持久化。
sudo apt install iptables-persistent
使用如下的命令,对当前的规则进行持久化保存到文件当中:
sudo netfilter-persistent save
执行上述命令的输出结果:
run-parts: executing /usr/share/netfilter-persistent/plugins.d/15-ip4tables save
run-parts: executing /usr/share/netfilter-persistent/plugins.d/25-ip6tables save
其实就是让它执行/usr/share/netfilter-persistent/plugins.d/15-ip4tables save
脚本,将IPV4规则保存到/etc/iptables/rules.v4
,IPV6规则保存到/etc/iptables/rules.v6
,系统重启时netfilter-persistent
会自动加载规则表。
本质上netfilter-persistent
就是Linux系统的一个服务,基于Linux的服务去实现的启动时可以配置快照的自动加载。
sudo systemctl status netfilter-persistent
评论