小抄来源朱双印个人日志:https://www.zsythink.net/,感谢大佬带来的这么优秀的技术文章
概念
防火墙分类
逻辑上
物理上
iptables 认知
-
它不是真正的防火墙,只是一个客户端代理工具,一个命令行工具
-
真正防火墙是安全框架 netfilter
-
netfilter 它是一个位于内核空间的安全框架
-
咱们是通过 iptables 这个命令行工具来操作真正的安全框架 netfilter
-
这个工具是属于一种包过滤的软件防火墙,它是免费的,不要钱,就很nice
-
它可以用来封包过滤、重定向和地址转换
iptbales 基础
规则
链
表
filter表: 负责过滤功能,防火墙;内核模块:iptables_filter
nat表: network address translation,网络地址转换功能;内核模块:iptable_nat
mangle表: 拆解报文,做出修改,并重新封装的功能;iptable_mangle
raw表: 关闭nat表上启用的连接追踪机制;iptable_raw
表链关系
PREROUTING 的规则可以存在于:raw表,mangle表,nat表。
INPUT 的规则可以存在于:mangle表,filter表,(centos7中还有nat表,centos6中没有)。
FORWARD 的规则可以存在于:mangle表,filter表。
OUTPUT的规则可以存在于:raw表mangle表,nat表,filter表。
POSTROUTING 的规则可以存在于:mangle表,nat表。
raw 表中的规则可以被哪些链使用:PREROUTING,OUTPUT
mangle 表中的规则可以被哪些链使用:PREROUTING,INPUT,FORWARD,OUTPUT,POSTROUTING
nat 表中的规则可以被哪些链使用:PREROUTING,OUTPUT,POSTROUTING(centos7中还有INPUT,centos6中没有)
filter 表中的规则可以被哪些链使用:INPUT,FORWARD,OUTPUT
执行优先级
raw –> mangle –> nat –> filter(由高到低)
数据经过防火墙流程
匹配条件
基本匹配条件
源地址
目标地址
扩展匹配条件
源端口
目标端口
处理动作
ACCEPT:允许数据包通过。
DROP:直接丢弃数据包,不给任何回应信息,这时候客户端会感觉自己的请求泥牛入海了,过了超时时间才会有反应。
REJECT:拒绝数据包通过,必要时会给数据发送端一个响应的信息,客户端刚请求就会收到拒绝的信息。
SNAT:源地址转换,解决内网用户用同一个公网地址上网的问题。
MASQUERADE:是SNAT的一种特殊形式,适用于动态的、临时会变的ip上。
DNAT:目标地址转换。
REDIRECT:在本机做端口映射。
LOG:在/var/log/messages文件中记录日志信息,然后将数据包传递给下一条规则,也就是说除了记录以外不对数据包做任何其他操作,仍然让下一条规则去匹配。
规则管理
查询特定表的规则
# filter 可以随意更换任意表
iptables -t filter -vnL
# 查询结果显示规则编号
iptables -t filter --line-numbers -vnL
# 字段信息这些都挺简单的,就不记录了,反正记不住也要去查的
# 查询相关表中特定的链的规则(就这么简单,你悟了么?)
iptables -t filter --line-numbers -vnL INPUT
规则的增删操作
# 一下子清空链上的所有规则
iptables -t filter -F INPUT
# 增加一条规则,一看就很清楚语法规则,再对比一下,就有很多种写法了
iptables -t filter -I INPUT -s 192.168.204.101 -j DROP
iptables -t filter -I INPUT 2 -s 192.168.204.101 -j DROP
iptables -t filter -I INPUT 2 -s 192.168.204.101 -j ACCEPT
# 删除规则;方式多种多样
iptables -t filter -D INPUT 2
iptables -t filter -D INPUT -s 192.168.204.101 -j ACCCEPT
# 修改规则
直接删除再新建就行了,修改啥子规则嘛。难搞
链的默认规则
# 如何确定链的默认规则,很简单
[root@vm-01 ~]# iptables --line-numbers -vnL INPUT
Chain INPUT (policy ACCEPT 17 packets, 1100 bytes)
num pkts bytes target prot opt in out source destination
[root@vm-01 ~]#
# 上述信息的`policy ACCEPT` 就是默认的规则了,默认规则是通过
保存规则
# centos 6中
service iptables save
# centos 7暂时没有,是另一个工具,不过也可以安装 iptables 来操作,另说了
匹配条件
源地址
用的较多,通过 -s 作为匹配条件,用来匹配报文的源地址
iptables -t filter -I INPUT 1 -s 192.168.204.101 -j ACCEPT
iptables -t filter -I INPUT 2 -s 192.168.204.102,192.168.204.103 -j ACCEPT
iptables -t filter -I INPUT 3 ! -s 192.168.204.104 -j ACCEPT
[root@vm-01 ~]# iptables -t filter -I INPUT 1 -s 192.168.204.101 -j ACCEPT
[root@vm-01 ~]# iptables -t filter -I INPUT 2 -s 192.168.204.102,192.168.204.103 -j ACCEPT
[root@vm-01 ~]# iptables -t filter -I INPUT 3 ! -s 192.168.204.104 -j ACCEPT
[root@vm-01 ~]# iptables -t filter --line-numbers -vnL INPUT
Chain INPUT (policy ACCEPT 0 packets, 0 bytes)
num pkts bytes target prot opt in out source destination
1 0 0 ACCEPT all -- * * 192.168.204.101 0.0.0.0/0
2 0 0 ACCEPT all -- * * 192.168.204.103 0.0.0.0/0
3 10 656 ACCEPT all -- * * !192.168.204.104 0.0.0.0/0
4 0 0 ACCEPT all -- * * 192.168.204.102 0.0.0.0/0
[root@vm-01 ~]#
目标地址
通过 -d 作为匹配条件,用来匹配目标地址
比如说:丢弃掉目标地址为 192.168.204.102 的包,让它从网卡流不出去
[root@vm-01 ~]# ping -c 4 192.168.204.102
PING 192.168.204.102 (192.168.204.102) 56(84) bytes of data.
64 bytes from 192.168.204.102: icmp_seq=1 ttl=64 time=0.330 ms
64 bytes from 192.168.204.102: icmp_seq=2 ttl=64 time=0.525 ms
64 bytes from 192.168.204.102: icmp_seq=3 ttl=64 time=1.05 ms
64 bytes from 192.168.204.102: icmp_seq=4 ttl=64 time=0.541 ms
--- 192.168.204.102 ping statistics ---
4 packets transmitted, 4 received, 0% packet loss, time 3002ms
rtt min/avg/max/mdev = 0.330/0.613/1.056/0.268 ms
[root@vm-01 ~]# iptables -t mangle -I POSTROUTING -d 192.168.204.102 -j DROP
[root@vm-01 ~]# ping -c 4 192.168.204.102
PING 192.168.204.102 (192.168.204.102) 56(84) bytes of data.
ping: sendmsg: 不允许的操作
ping: sendmsg: 不允许的操作
ping: sendmsg: 不允许的操作
ping: sendmsg: 不允许的操作
^C
--- 192.168.204.102 ping statistics ---
4 packets transmitted, 0 received, 100% packet loss, time 2999ms
[root@vm-01 ~]#
多个匹配条件,是‘与’的关系,必须同时满足
协议类型
我们通过使用 -p 选项,来指定需要匹配的报文的协议类型
请看下面:要注意看表名和链名呢,是有关系的,在什么点进行规则设置,才能有效的拦截,虽然有时候我也要去前面翻翻,记不住
[root@vm-01 ~]# ping -c 2 192.168.204.102
PING 192.168.204.102 (192.168.204.102) 56(84) bytes of data.
64 bytes from 192.168.204.102: icmp_seq=1 ttl=64 time=0.429 ms
64 bytes from 192.168.204.102: icmp_seq=2 ttl=64 time=0.407 ms
--- 192.168.204.102 ping statistics ---
2 packets transmitted, 2 received, 0% packet loss, time 999ms
rtt min/avg/max/mdev = 0.407/0.418/0.429/0.011 ms
[root@vm-01 ~]# iptables -t mangle -I POSTROUTING -p icmp -j DROP
[root@vm-01 ~]# ping -c 2 192.168.204.102
PING 192.168.204.102 (192.168.204.102) 56(84) bytes of data.
ping: sendmsg: 不允许的操作
ping: sendmsg: 不允许的操作
^C
--- 192.168.204.102 ping statistics ---
2 packets transmitted, 0 received, 100% packet loss, time 999ms
[root@vm-01 ~]#
- centos6中,-p选项支持如下协议类型
tcp, udp, udplite, icmp, esp, ah, sctp
- centos7中,-p选项支持如下协议类型
tcp, udp, udplite, icmp, icmpv6,esp, ah, sctp, mh
如果不指定匹配协议,默认所有类型的协议都被匹配到
匹配网口
我们可以通过 -i 选项去匹配报文是通过哪块网卡流入本机的
请看下面:阻止了回环网卡的流量(我也不知道说的对不对)
[root@vm-01 ~]# ifconfig
ens32: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 192.168.204.101 netmask 255.255.255.0 broadcast 192.168.204.255
inet6 fe80::20c:29ff:fedd:7e2f prefixlen 64 scopeid 0x20<link>
ether 00:0c:29:dd:7e:2f txqueuelen 1000 (Ethernet)
RX packets 5314 bytes 714077 (697.3 KiB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 2319 bytes 241542 (235.8 KiB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
lo: flags=73<UP,LOOPBACK,RUNNING> mtu 65536
inet 127.0.0.1 netmask 255.0.0.0
inet6 ::1 prefixlen 128 scopeid 0x10<host>
loop txqueuelen 1000 (Local Loopback)
RX packets 8 bytes 672 (672.0 B)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 8 bytes 672 (672.0 B)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
[root@vm-01 ~]# ping -c 2 127.0.0.1
PING 127.0.0.1 (127.0.0.1) 56(84) bytes of data.
64 bytes from 127.0.0.1: icmp_seq=1 ttl=64 time=0.043 ms
64 bytes from 127.0.0.1: icmp_seq=2 ttl=64 time=0.050 ms
--- 127.0.0.1 ping statistics ---
2 packets transmitted, 2 received, 0% packet loss, time 1000ms
rtt min/avg/max/mdev = 0.043/0.046/0.050/0.007 ms
[root@vm-01 ~]# iptables -t filter -I INPUT -i lo -j DROP
[root@vm-01 ~]# ping -c 2 127.0.0.1
PING 127.0.0.1 (127.0.0.1) 56(84) bytes of data.
--- 127.0.0.1 ping statistics ---
2 packets transmitted, 0 received, 100% packet loss, time 999ms
我把它改一下,又可以正常了
[root@vm-01 ~]# iptables -t filter -I INPUT 1 -i lo -j ACCEPT
[root@vm-01 ~]# ping -c 2 127.0.0.1
PING 127.0.0.1 (127.0.0.1) 56(84) bytes of data.
64 bytes from 127.0.0.1: icmp_seq=1 ttl=64 time=0.044 ms
64 bytes from 127.0.0.1: icmp_seq=2 ttl=64 time=0.068 ms
--- 127.0.0.1 ping statistics ---
2 packets transmitted, 2 received, 0% packet loss, time 999ms
rtt min/avg/max/mdev = 0.044/0.056/0.068/0.012 ms
我们还可以通过选项 -o 匹配报文从哪个网卡流出,请看下面的栗子:
[root@vm-01 ~]# ping -c 4 127.0.0.1
PING 127.0.0.1 (127.0.0.1) 56(84) bytes of data.
64 bytes from 127.0.0.1: icmp_seq=1 ttl=64 time=0.035 ms
64 bytes from 127.0.0.1: icmp_seq=2 ttl=64 time=0.058 ms
64 bytes from 127.0.0.1: icmp_seq=3 ttl=64 time=0.048 ms
64 bytes from 127.0.0.1: icmp_seq=4 ttl=64 time=0.070 ms
--- 127.0.0.1 ping statistics ---
4 packets transmitted, 4 received, 0% packet loss, time 2999ms
rtt min/avg/max/mdev = 0.035/0.052/0.070/0.015 ms
[root@vm-01 ~]# iptables -t mangle -I POSTROUTING -o lo -j DROP
[root@vm-01 ~]# ping -c 4 127.0.0.1
PING 127.0.0.1 (127.0.0.1) 56(84) bytes of data.
ping: sendmsg: 不允许的操作
ping: sendmsg: 不允许的操作
ping: sendmsg: 不允许的操作
ping: sendmsg: 不允许的操作
^C
--- 127.0.0.1 ping statistics ---
4 packets transmitted, 0 received, 100% packet loss, time 3000ms
[root@vm-01 ~]#
扩展匹配条件
如何匹配报文的源端口和目标端口
- 使用选项 --dport 可以匹配报文的目标端口,–dport意为destination-port,即表示目标端口
- 有”目标端口”,就有”源端口”,代表”源端口”的扩展匹配条件 --sport
- 使用选项 --dport 必须指定协议(-p)
来演示一下:
首先通过 ssh 方式从 vm01登录到 vm02,设置 vm02的规则组织来自vm01的SSH连接(不要这样尝试,我TM被卡死了)
#########首先通过ssh登录到vm02
[root@vm-01 ~]# ssh 192.168.204.102
root@192.168.204.102's password:
Last login: Wed Jul 20 22:01:56 2022 from 192.168.204.1
[root@vm-02 ~]#
#########登录成功,没问题就退出登录吧
[root@vm-01 ~]# ssh 192.168.204.102
root@192.168.204.102's password:
Last login: Wed Jul 20 22:01:56 2022 from 192.168.204.1
[root@vm-02 ~]# exit
登出
Connection to 192.168.204.102 closed.
[root@vm-01 ~]#
#########在vm02设置规则
[root@vm-02 ~]# iptables -t filter -I INPUT -s 192.168.204.101 -p tcp --dport 22 -j DROP
[root@vm-02 ~]#
#########再去vm01通过ssh登录vm02;一直卡着,没反应了撒
[root@vm-01 ~]# ssh 192.168.204.102
对于扩展匹配,我们一般:
-
使用扩展匹配,需要依赖一些扩展模块
-
扩展模块:-m tcp 表示使用 tcp 扩展模块,上述省略了( iptables 默认会调用与 -p 选项对应的协议名称相同的模块);–dport 表示 tcp 模块中的一个扩展匹配条件
-
-p tcp与 -m tcp 并不冲突,-p 用于匹配报文的协议,-m 用于指定扩展模块的名称,正好,这个扩展模块也叫 tcp
-
也可以配置 ! 进行一个取反:
! --dport 22
,表示目标端口不是22的报文会被匹配 -
也都可以指定一个端口范围
--dport 22:25
,目标端口为22到25之间的所有端口 -
指定多个离散的端口,需要借助扩展模块:multiport
- 使用 multiport 模块的 --sports 扩展条件同时指定多个离散的源端口
- 使用 multiport 模块的 --dports 扩展条件同时指定多个离散的目标端口
- multiport 扩展只能用于 tcp 协议与 udp 协议,即配合 -p tcp 或者 -p udp 使用
[root@vm-01 ~]# iptables -t filter -I INPUT -s 192.168.204.102 -p tcp -m multiport --dports 22,80,443 -j DROP
[root@vm-01 ~]# iptables -vnL INPUT
Chain INPUT (policy ACCEPT 50 packets, 3264 bytes)
pkts bytes target prot opt in out source destination
0 0 DROP tcp -- * * 192.168.204.102 0.0.0.0/0 multiport dports 22,80,443
[root@vm-01 ~]#
##############也可以指定连续的端口范围,并且能够在指定连续的端口范围的同时,指定离散的端口号。
[root@vm-01 ~]# iptables -t filter -I INPUT -s 192.168.204.102 -p tcp -m multiport --dports 22,80:443 -j DROP
[root@vm-01 ~]# iptables -vnL INPUT
Chain INPUT (policy ACCEPT 6 packets, 384 bytes)
pkts bytes target prot opt in out source destination
0 0 DROP tcp -- * * 192.168.204.102 0.0.0.0/0 multiport dports 22,80:443
0 0 DROP tcp -- * * 192.168.204.102 0.0.0.0/0 multiport dports 22,80,443
[root@vm-01 ~]#