连接跟踪(conntrack)
机器访问外部 HTTP 服务的连接(目的端口 80) 外部访问机器内 FTP 服务的连接(目的端口 21) 机器访问外部 DNS 服务的连接(目的端口 53)
从数据包中提取元组(tuple)信息,辨别数据流(flow)和对应的连接(connection)。 为所有连接维护一个状态数据库(conntrack table),例如连接的创建时间、发送 包数、发送字节数等等。 回收过期的连接(GC)。 为更上层的功能(例如 NAT)提供服务。
TCP/IP 协议中,连接是一个四层(Layer 4)的概念。TCP 是有连接的,或称面向连接的(connection oriented),发送出去的包都要求对端应答(ACK),并且有重传机制。UDP 是无连接的,发送的包无需对端应答,也没有重传机制。 conntrack(CT) 中,一个元组(tuple)定义的一条数据流(flow )就表示一条连接(connection)。后面会看到 UDP 甚至是 ICMP 这种三层协议在 CT 中也都是有连接记录的,但不是所有协议都会被连接跟踪。
Netfilter
基于 BPF hook 实现数据包的拦截功能(等价于 netfilter 里面的 hook 机制) 在 BPF hook 的基础上,实现一套全新的 conntrack 和 NAT 因此,即便卸载掉 Netfilter ,也不会影响 Cilium 对 Kubernetes ClusterIP、NodePort、ExternalIPs 和 LoadBalancer 等功能的支持。由于这套连接跟踪机制是独立于 Netfilter 的,因此它的 conntrack 和 NAT 信息也没有 存储在内核的(也就是 Netfilter 的)conntrack table 和 NAT table。所以常规的 conntrack/netstats/ss/lsof 等工具是看不到的,要使用 Cilium 的命令,例如:
$ cilium bpf nat list$ cilium bpf ct list global
Iptables
filter 表:用来对数据包进行过滤,具体的规则要求决定如何处理一个数据包。 nat 表:主要用来修改数据包的 IP 地址、端口号信息。 mangle 表:主要用来修改数据包的服务类型,生存周期,为数据包设置标记,实现流量整形、策略路由等。 raw 表:主要用来决定是否对数据包进行状态跟踪。
input 链:当收到访问本机地址的数据包时,将应用此链中的规则。 output 链:当本机向外发送数据包时,将应用此链中的规则。 forward 链:当收到需要转发给其他地址的数据包时,将应用此链中的规则,注意如果需要实现forward转发需要开启Linux内核中的ip_forward功能。 prerouting 链:在对数据包做路由选择之前,将应用此链中的规则。 postrouting 链:在对数据包做路由选择之后,将应用此链中的规则。
到本机某进程的报文:PREROUTING –> INPUT。 由本机转发的报文:PREROUTING –> FORWARD –> POSTROUTING。 由本机的某进程发出报文(通常为响应报文):OUTPUT –> POSTROUTING。
查询规则
-t:表名 -n:不解析IP地址 -v:会显示出计数器的信息,数据包的数量和大小 -x:选项表示显示计数器的精确值 –line-numbers:显示规则的序号(简写为–line) 另外,搜索公众号Linux就该这样学后台回复“猴子”,获取一份惊喜礼包。 -L:链名
#iptables -t filter -nvxL DOCKER --lineChain DOCKER (1 references)num pkts bytes target prot opt in out source destination1 5076 321478 ACCEPT tcp -- !docker0 docker0 0.0.0.0/0 172.17.0.2 tcp dpt:84432 37233 54082508 ACCEPT tcp -- !docker0 docker0 0.0.0.0/0 172.17.0.2 tcp dpt:223 1712 255195 ACCEPT tcp -- !docker0 docker0 0.0.0.0/0 172.17.0.3 tcp dpt:90004 0 0 ACCEPT tcp -- !docker0 docker0 0.0.0.0/0 172.17.0.3 tcp dpt:80005 40224 6343104 ACCEPT tcp -- !docker0 docker0 0.0.0.0/0 172.17.0.4 tcp dpt:34436 21034 2227009 ACCEPT tcp -- !docker0 docker0 0.0.0.0/0 172.17.0.5 tcp dpt:33067 58 5459 ACCEPT tcp -- !docker0 docker0 0.0.0.0/0 172.17.0.6 tcp dpt:808 826 70081 ACCEPT tcp -- !docker0 docker0 0.0.0.0/0 172.17.0.6 tcp dpt:4439 10306905 1063612492 ACCEPT tcp -- !docker0 docker0 0.0.0.0/0 172.17.0.9 tcp dpt:330610 159775 12297727 ACCEPT tcp -- !docker0 docker0 0.0.0.0/0 172.17.0.7 tcp dpt:11111
增加规则
命令语法:iptables -t 表名 -A 链名 匹配条件 -j 动作示例:iptables -t filter -A INPUT -s 192.168.1.146 -j DROP
命令语法:iptables -t 表名 -I 链名 匹配条件 -j 动作示例:iptables -t filter -I INPUT -s 192.168.1.146 -j ACCEPT
命令语法:iptables -t 表名 -I 链名 规则序号 匹配条件 -j 动作示例:iptables -t filter -I INPUT 5 -s 192.168.1.146 -j REJECT
删除规则
命令语法:iptables -t 表名 -D 链名 规则序号示例:iptables -t filter -D INPUT 3
命令语法:iptables -t 表名 -D 链名 匹配条件 -j 动作示例:iptables -t filter -D INPUT -s 192.168.1.146 -j DROP
命令语法:iptables -t 表名 -F 链名示例:iptables -t filter -F INPUT
修改规则
命令语法:iptables -t 表名 -R 链名 规则序号 规则原本的匹配条件 -j 动作示例:iptables -t filter -R INPUT 3 -s 192.168.1.146 -j ACCEPT
命令语法:iptables -t 表名 -P 链名 动作示例:iptables -t filter -P FORWARD ACCEPT
保存规则
方式一
service iptables save
#配置好yum源以后安装iptables-serviceyum install -y iptables-services#停止firewalldsystemctl stop firewalld#禁止firewalld自动启动systemctl disable firewalld#启动iptablessystemctl start iptables#将iptables设置为开机自动启动,以后即可通过iptables-service控制iptables服务systemctl enable iptables
方式二
iptables-save > /etc/sysconfig/iptables
加载规则
iptables-restore < /etc/sysconfig/iptables
匹配条件
#示例如下iptables -t filter -I INPUT -s 192.168.1.111,192.168.1.118 -j DROPiptables -t filter -I INPUT -s 192.168.1.0/24 -j ACCEPTiptables -t filter -I INPUT ! -s 192.168.1.0/24 -j ACCEPT
#示例如下iptables -t filter -I OUTPUT -d 192.168.1.111,192.168.1.118 -j DROPiptables -t filter -I INPUT -d 192.168.1.0/24 -j ACCEPTiptables -t filter -I INPUT ! -d 192.168.1.0/24 -j ACCEPT
#示例如下iptables -t filter -I INPUT -p tcp -s 192.168.1.146 -j ACCEPTiptables -t filter -I INPUT ! -p udp -s 192.168.1.146 -j ACCEPT
#示例如下iptables -t filter -I INPUT -p icmp -i eth4 -j DROPiptables -t filter -I INPUT -p icmp ! -i eth4 -j DROP
#示例如下iptables -t filter -I OUTPUT -p icmp -o eth4 -j DROPiptables -t filter -I OUTPUT -p icmp ! -o eth4 -j DROP
扩展匹配条件
tcp扩展模块
–sport:用于匹配 tcp 协议报文的源端口,可以使用冒号指定一个连续的端口范围。 –dport:用于匹配 tcp 协议报文的目标端口,可以使用冒号指定一个连续的端口范围。 –tcp-flags:用于匹配报文的tcp头的标志位。 –syn:用于匹配 tcp 新建连接的请求报文,相当于使用 –tcp-flags SYN,RST,ACK,FIN SYN
。
#示例如下iptables -t filter -I OUTPUT -d 192.168.1.146 -p tcp -m tcp --sport 22 -j REJECTiptables -t filter -I INPUT -s 192.168.1.146 -p tcp -m tcp --dport 22:25 -j REJECTiptables -t filter -I INPUT -s 192.168.1.146 -p tcp -m tcp --dport :22 -j REJECTiptables -t filter -I INPUT -s 192.168.1.146 -p tcp -m tcp --dport 80: -j REJECTiptables -t filter -I OUTPUT -d 192.168.1.146 -p tcp -m tcp ! --sport 22 -j ACCEPTiptables -t filter -I INPUT -p tcp -m tcp --dport 22 --tcp-flags SYN,ACK,FIN,RST,URG,PSH SYN -j REJECTiptables -t filter -I OUTPUT -p tcp -m tcp --sport 22 --tcp-flags SYN,ACK,FIN,RST,URG,PSH SYN,ACK -j REJECTiptables -t filter -I INPUT -p tcp -m tcp --dport 22 --tcp-flags ALL SYN -j REJECTiptables -t filter -I OUTPUT -p tcp -m tcp --sport 22 --tcp-flags ALL SYN,ACK -j REJECTiptables -t filter -I INPUT -p tcp -m tcp --dport 22 --syn -j REJECT
udp 扩展模块
–sport:匹配udp报文的源地址。 –dport:匹配udp报文的目标地址。
#示例iptables -t filter -I INPUT -p udp -m udp --dport 137 -j ACCEPTiptables -t filter -I INPUT -p udp -m udp --dport 137:157 -j ACCEPT
icmp 扩展模块
–icmp-type:匹配icmp报文的具体类型。
#示例iptables -t filter -I INPUT -p icmp -m icmp --icmp-type 8/0 -j REJECTiptables -t filter -I INPUT -p icmp --icmp-type 8 -j REJECTiptables -t filter -I OUTPUT -p icmp -m icmp --icmp-type 0/0 -j REJECTiptables -t filter -I OUTPUT -p icmp --icmp-type 0 -j REJECTiptables -t filter -I INPUT -p icmp --icmp-type "echo-request" -j REJECT
multiport 扩展模块
-p tcp -m multiport –sports 用于匹配报文的源端口,可以指定离散的多个端口号,端口之间用”逗号”隔开。 -p udp -m multiport –dports 用于匹配报文的目标端口,可以指定离散的多个端口号,端口之间用”逗号”隔开。
#示例如下iptables -t filter -I OUTPUT -d 192.168.1.146 -p udp -m multiport --sports 137,138 -j REJECTiptables -t filter -I INPUT -s 192.168.1.146 -p tcp -m multiport --dports 22,80 -j REJECTiptables -t filter -I INPUT -s 192.168.1.146 -p tcp -m multiport ! --dports 22,80 -j REJECTiptables -t filter -I INPUT -s 192.168.1.146 -p tcp -m multiport --dports 80:88 -j REJECTiptables -t filter -I INPUT -s 192.168.1.146 -p tcp -m multiport --dports 22,80:88 -j REJECT
iprange 模块
–src-range:指定连续的源地址范围。 –dst-range:指定连续的目标地址范围。
#示例iptables -t filter -I INPUT -m iprange --src-range 192.168.1.127-192.168.1.146 -j DROPiptables -t filter -I OUTPUT -m iprange --dst-range 192.168.1.127-192.168.1.146 -j DROPiptables -t filter -I INPUT -m iprange ! --src-range 192.168.1.127-192.168.1.146 -j DROP
牛逼啊!接私活必备的 N 个开源项目!赶快收藏
string 模块
–algo:指定对应的匹配算法,可用算法为bm、kmp,此选项为必需选项。 –string:指定需要匹配的字符串
#示例 iptables -t filter -I INPUT -m string --algo bm --string "OOXX" -j REJECT
time 模块
–timestart:用于指定时间范围的开始时间,不可取反。 –timestop:用于指定时间范围的结束时间,不可取反。 –weekdays:用于指定”星期几”,可取反。 –monthdays:用于指定”几号”,可取反。 –datestart:用于指定日期范围的开始日期,不可取反。 –datestop:用于指定日期范围的结束时间,不可取反。
#示例 iptables -t filter -I OUTPUT -p tcp --dport 80 -m time --timestart 09:00:00 --timestop 19:00:00 -j REJECT iptables -t filter -I OUTPUT -p tcp --dport 443 -m time --timestart 09:00:00 --timestop 19:00:00 -j REJECT iptables -t filter -I OUTPUT -p tcp --dport 80 -m time --weekdays 6,7 -j REJECT iptables -t filter -I OUTPUT -p tcp --dport 80 -m time --monthdays 22,23 -j REJECT iptables -t filter -I OUTPUT -p tcp --dport 80 -m time ! --monthdays 22,23 -j REJECT iptables -t filter -I OUTPUT -p tcp --dport 80 -m time --timestart 09:00:00 --timestop 18:00:00 --weekdays 6,7 -j REJECT iptables -t filter -I OUTPUT -p tcp --dport 80 -m time --weekdays 5 --monthdays 22,23,24,25,26,27,28 -j REJECT iptables -t filter -I OUTPUT -p tcp --dport 80 -m time --datestart 2017-12-24 --datestop 2017-12-27 -j REJECT
connlimit 模块
–connlimit-above:单独使用此选项时,表示限制每个IP的链接数量。 –connlimit-mask:此选项不能单独使用,在使用–connlimit-above选项时,配合此选项,则可以针对”某类IP段内的一定数量的IP”进行连接数量的限制,如果不明白可以参考上文的详细解释。
#示例 iptables -I INPUT -p tcp --dport 22 -m connlimit --connlimit-above 2 -j REJECT iptables -I INPUT -p tcp --dport 22 -m connlimit --connlimit-above 20 --connlimit-mask 24 -j REJECT iptables -I INPUT -p tcp --dport 22 -m connlimit --connlimit-above 10 --connlimit-mask 27 -j REJECT
limit 模块
–limit-burst:类比”令牌桶”算法,此选项用于指定令牌桶中令牌的最大数量。 –limit:类比”令牌桶”算法,此选项用于指定令牌桶中生成新令牌的频率,可用时间单位有second、minute 、hour、day。
#示例,注意,如下两条规则需配合使用 #令牌桶中最多能存放3个令牌,每分钟生成10个令牌(即6秒钟生成一个令牌)。 iptables -t filter -I INPUT -p icmp -m limit --limit-burst 3 --limit 10/minute -j ACCEPT #默认将icmp包丢弃 iptables -t filter -A INPUT -p icmp -j REJECT
state 扩展模块
NEW:连接中的第一个包,状态就是 NEW,我们可以理解为新连接的第一个包的状态为 NEW。 ESTABLISHED:我们可以把 NEW 状态包后面的包的状态理解为 ESTABLISHED,表示连接已建立。 RELATED:从字面上理解 RELATED 译为关系,但是这样仍然不容易理解,我们举个例子。比如 FTP 服务,FTP 服务端会建立两个进程,一个命令进程,一个数据进程。命令进程负责服务端与客户端之间的命令传输(我们可以把这个传输过程理解成 state 中所谓的一个”连接”,暂称为”命令连接”)。数据进程负责服务端与客户端之间的数据传输 (我们把这个过程暂称为”数据连接”)。但是具体传输哪些数据,是由命令去控制的,所以,”数据连接”中的报文与”命令连接”是有”关系”的。那么,”数据连接”中的报文可能就是 RELATED 状态,因为这些报文与”命令连接”中的报文有关系。(注:如果想要对ftp进行连接追踪,需要单独加载对应的内核模块 nf_conntrack_ftp,如果想要自动加载,可以配置 /etc/sysconfig/iptables-config 文件) INVALID:如果一个包没有办法被识别,或者这个包没有任何状态,那么这个包的状态就是 INVALID,我们可以主动屏蔽状态为 INVALID 的报文。 UNTRACKED:报文的状态为 untracked 时,表示报文未被追踪,当报文的状态为 Untracked 时通常表示无法找到相关的连接。
iptables -t filter -I INPUT -m state --state ESTABLISHED -j ACCEPT
mangle 表
TOS:用来设置或改变数据包的服务类型域。这常用来设置网络上的数据包如何被路由等策略。注意这个操作并不完善,有时得不所愿。它在Internet 上还不能使用,而且很多路由器不会注意到这个域值。换句话说,不要设置发往 Internet 的包,除非你打算依靠 TOS 来路由,比如用 iproute2。 TTL:用来改变数据包的生存时间域,我们可以让所有数据包只有一个特殊的 TTL。它的存在有 一个很好的理由,那就是我们可以欺骗一些ISP。为什么要欺骗他们呢?因为他们不愿意让我们共享一个连接。那些 ISP 会查找一台单独的计算机是否使用不同的 TTL,并且以此作为判断连接是否被共享的标志。 MARK 用来给包设置特殊的标记。iproute 2能识别这些标记,并根据不同的标记(或没有标记) 决定不同的路由。用这些标记我们可以做带宽限制和基于请求的分类。
iptables -t mangle -A PREROUTING -i eth0 -p tcp --dport 80 -j MARK --set-mark 1; iptables -t mangle -A PREROUTING -i eth0 -p udp --dprot 53 -j MARK --set-mark 2;
ip rule add from all fwmark 1 table 10 ip rule add from all fwmark 2 table 20
ip route add default via 10.10.1.1 dev eth1 table 10 ip route add default via 10.10.2.1 dev eth2 table 20
自定义链
创建自定义链
#在filter表中创建IN_WEB自定义链 iptables -t filter -N IN_WEB
引用自定义链
#在INPUT链中引用刚才创建的自定义链 iptables -t filter -I INPUT -p tcp --dport 80 -j IN_WEB
重命名自定义链
#将IN_WEB自定义链重命名为WEB iptables -E IN_WEB WEB
删除自定义链
1、自定义链没有被引用。 2、自定义链中没有任何规则。
#第一步:清除自定义链中的规则 iptables -t filter -F WEB #第二步:删除自定义链 iptables -t filter -X WEB
LOG 动作
kern.warning /var/log/iptables.log
service rsyslog restart
–log-level 选项可以指定记录日志的日志级别,可用级别有 emerg,alert,crit,error,warning,notice,info,debug。 –log-prefix 选项可以给记录到的相关信息添加”标签”之类的信息,以便区分各种记录到的报文信息,方便在分析时进行过滤。–log-prefix 对应的值不能超过 29 个字符。
iptables -I INPUT -p tcp --dport 22 -m state --state NEW -j LOG --log-prefix "want-in-from-port-22"
参考链接
https://www.zsythink.net/archives/category/%e8%bf%90%e7%bb%b4%e7%9b%b8%e5%85%b3/iptables/ https://my.oschina.net/mojiewhy/blog/3039897 https://www.frozentux.net/iptables-tutorial/cn/iptables-tutorial-cn-1.1.19.html#MARKTARGET https://mp.weixin.qq.com/s/NOxY4ZC7Cay4LCWlMkVx8A
© 版权声明
文章版权归作者所有,未经允许请勿转载。
THE END
暂无评论内容