iptables入门笔记
iptables
是基于Linux内核模块Netfilter 的防火墙工具,可以按照一定的规则对ip packet执行监控、修改、转发、重定向、丢弃等操作;ipv6版本的是ip6talbles
;nftables
则是iptables的新实现。目前,iptables还是使用最广泛的Linux防火墙模块,本文也聚焦于iptables的入门使用。
关键概念 iptables的操作对象是ip包。Tables --> Chains --> Rules --> IP Packets
,可以按照这样的层级来理解iptables的组织逻辑
IP packet IP包 对于ip包的详细讲解可以参考这篇博客
部分iptables的功能需要修改ip包的内容,例如通过修改ip包的源地址实现、目的地址实现SNAT、DNAT、包FORWARD等等功能。
Tables 表 iptables共有5张表,分别是:
raw
表,只用于一种场景:修改ip包以逃过连接跟踪;
filter
表,顾名思义——过滤,是默认表,大多数防火墙功能都和filter表有关;
nat
表,用作网络地址转换,例如端口转发功能(后面会讲到);
mangle
表,用于修改特殊包;
security
表,MAC相关的规则,典型的应用是SELinux
大多数情况下,我们只会用到filter 和nat 表,本文也围绕这两个表展开
Chains 链 表是由链(Chain)组成的,有5个默认链,用户也可以自定义链,例如Docker就是使用了iptables自定义链来实现了网络隔离。默认链有默认的策略ACCEPT ,可以修改成DROP ;每条链上会有n个规则,规则可以定义自己的策略。
链的名称都比较清晰明了,可顾名思义,具体如下:
PREROUTING
,ip包被路由前(进来或发送前)相关操作,例如DNAT
INPUT
,入包相关操作
FORWARD
,包转发相关操作
OUTPUT
,出包相关操作
POSTROUTING
,路由后修改包相关操作,例如SNAT
自定义链
上面的iptables流程图可能比较难以理解,它实际上是将入包、出包、转发的流程画到了一张图里面,如果将这三个流程分别标记出来就能够比较清晰地知道在入包、出包、转发过程中iptables做了哪些操作
Rules 规则 常见用途 1. 网络防火墙 1 2 3 4 5 6 # 封禁dockerd默认端口2375的外部访问 iptables -A INPUT -p tcp --dport 2375 -j REJECT # 允许192.168.64.2访问本机2375端口 iptables -I INPUT -p tcp --dport 2375 -s 192.168.64.2 -j ACCEPT
2. docker-proxy网络代理 运行nginx测试容器,并添加端口映射。看出容器之间的通信走docker0网桥,端口映射则是通过docker-proxy转发
1 2 3 4 5 6 7 8 9 10 11 12 root@ubuntu2204:/home/ubuntu# docker run -dit --name nginx -p 8080:80 nginx root@ubuntu2204:/home/ubuntu# ip route default via 192.168.64.1 dev enp0s1 proto dhcp src 192.168.64.5 metric 100 172.17.0.0/16 dev docker0 proto kernel scope link src 172.17.0.1 192.168.64.0/24 dev enp0s1 proto kernel scope link src 192.168.64.5 metric 100 192.168.64.1 dev enp0s1 proto dhcp scope link src 192.168.64.5 metric 100 root@ubuntu2204:/home/ubuntu# lsof -i:8080 COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME docker-pr 1488 root 4u IPv4 20593 0t0 TCP *:http-alt (LISTEN) docker-pr 1493 root 4u IPv6 20599 0t0 TCP *:http-alt (LISTEN)
具体的转发是通过iptables规则实现的
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 root@ubuntu2204:/home/ubuntu# iptables-save # Generated by iptables-save v1.8.7 on Fri May 6 00:18:54 2022 *filter :INPUT ACCEPT [0:0] :FORWARD DROP [0:0] :OUTPUT ACCEPT [0:0] :DOCKER - [0:0] :DOCKER-ISOLATION-STAGE-1 - [0:0] :DOCKER-ISOLATION-STAGE-2 - [0:0] :DOCKER-USER - [0:0] -A FORWARD -j DOCKER-USER -A FORWARD -j DOCKER-ISOLATION-STAGE-1 -A FORWARD -o docker0 -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT -A FORWARD -o docker0 -j DOCKER -A FORWARD -i docker0 ! -o docker0 -j ACCEPT -A FORWARD -i docker0 -o docker0 -j ACCEPT -A DOCKER -d 172.17.0.2/32 ! -i docker0 -o docker0 -p tcp -m tcp --dport 80 -j ACCEPT -A DOCKER-ISOLATION-STAGE-1 -i docker0 ! -o docker0 -j DOCKER-ISOLATION-STAGE-2 -A DOCKER-ISOLATION-STAGE-1 -j RETURN -A DOCKER-ISOLATION-STAGE-2 -o docker0 -j DROP -A DOCKER-ISOLATION-STAGE-2 -j RETURN -A DOCKER-USER -j RETURN COMMIT # Completed on Fri May 6 00:18:54 2022 # Generated by iptables-save v1.8.7 on Fri May 6 00:18:54 2022 *nat :PREROUTING ACCEPT [0:0] :INPUT ACCEPT [0:0] :OUTPUT ACCEPT [0:0] :POSTROUTING ACCEPT [0:0] :DOCKER - [0:0] -A PREROUTING -m addrtype --dst-type LOCAL -j DOCKER -A OUTPUT ! -d 127.0.0.0/8 -m addrtype --dst-type LOCAL -j DOCKER -A POSTROUTING -s 172.17.0.0/16 ! -o docker0 -j MASQUERADE -A POSTROUTING -s 172.17.0.2/32 -d 172.17.0.2/32 -p tcp -m tcp --dport 80 -j MASQUERADE -A DOCKER -i docker0 -j RETURN -A DOCKER ! -i docker0 -p tcp -m tcp --dport 8080 -j DNAT --to-destination 172.17.0.2:80 COMMIT # Completed on Fri May 6 00:18:54 2022
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 root@ubuntu2204:/home/ubuntu# iptables -nvL Chain INPUT (policy ACCEPT 0 packets, 0 bytes) pkts bytes target prot opt in out source destination Chain FORWARD (policy DROP 0 packets, 0 bytes) pkts bytes target prot opt in out source destination 0 0 DOCKER-USER all -- * * 0.0.0.0/0 0.0.0.0/0 0 0 DOCKER-ISOLATION-STAGE-1 all -- * * 0.0.0.0/0 0.0.0.0/0 0 0 ACCEPT all -- * docker0 0.0.0.0/0 0.0.0.0/0 ctstate RELATED,ESTABLISHED 0 0 DOCKER all -- * docker0 0.0.0.0/0 0.0.0.0/0 0 0 ACCEPT all -- docker0 !docker0 0.0.0.0/0 0.0.0.0/0 0 0 ACCEPT all -- docker0 docker0 0.0.0.0/0 0.0.0.0/0 Chain OUTPUT (policy ACCEPT 0 packets, 0 bytes) pkts bytes target prot opt in out source destination Chain DOCKER (1 references) pkts bytes target prot opt in out source destination 0 0 ACCEPT tcp -- !docker0 docker0 0.0.0.0/0 172.17.0.2 tcp dpt:80 Chain DOCKER-ISOLATION-STAGE-1 (1 references) pkts bytes target prot opt in out source destination 0 0 DOCKER-ISOLATION-STAGE-2 all -- docker0 !docker0 0.0.0.0/0 0.0.0.0/0 0 0 RETURN all -- * * 0.0.0.0/0 0.0.0.0/0 Chain DOCKER-ISOLATION-STAGE-2 (1 references) pkts bytes target prot opt in out source destination 0 0 DROP all -- * docker0 0.0.0.0/0 0.0.0.0/0 0 0 RETURN all -- * * 0.0.0.0/0 0.0.0.0/0 Chain DOCKER-USER (1 references) pkts bytes target prot opt in out source destination 0 0 RETURN all -- * * 0.0.0.0/0 0.0.0.0/0
3. cni
To Be Continued
参考文献
iptables - ArchWiKi
iptables(8) - Arch manual pages
小菜学网络
nftables - ArchWiKi
Iptables Tutorial 1.2.2
Docker and iptables