发布于 

iptables入门笔记

iptables是基于Linux内核模块Netfilter的防火墙工具,可以按照一定的规则对ip packet执行监控、修改、转发、重定向、丢弃等操作;ipv6版本的是ip6talblesnftables则是iptables的新实现。目前,iptables还是使用最广泛的Linux防火墙模块,本文也聚焦于iptables的入门使用。

关键概念

iptables的操作对象是ip包。Tables --> Chains --> Rules --> IP Packets,可以按照这样的层级来理解iptables的组织逻辑

flow chart

IP packet IP包

对于ip包的详细讲解可以参考这篇博客

ip packet

部分iptables的功能需要修改ip包的内容,例如通过修改ip包的源地址实现、目的地址实现SNAT、DNAT、包FORWARD等等功能。

Tables 表

iptables共有5张表,分别是:

  1. raw表,只用于一种场景:修改ip包以逃过连接跟踪;
  2. filter表,顾名思义——过滤,是默认表,大多数防火墙功能都和filter表有关;
  3. nat表,用作网络地址转换,例如端口转发功能(后面会讲到);
  4. mangle表,用于修改特殊包;
  5. security表,MAC相关的规则,典型的应用是SELinux

大多数情况下,我们只会用到filternat表,本文也围绕这两个表展开

Chains 链

表是由链(Chain)组成的,有5个默认链,用户也可以自定义链,例如Docker就是使用了iptables自定义链来实现了网络隔离。默认链有默认的策略ACCEPT,可以修改成DROP;每条链上会有n个规则,规则可以定义自己的策略。

链的名称都比较清晰明了,可顾名思义,具体如下:

  1. PREROUTING,ip包被路由前(进来或发送前)相关操作,例如DNAT
  2. INPUT,入包相关操作
  3. FORWARD,包转发相关操作
  4. OUTPUT,出包相关操作
  5. POSTROUTING,路由后修改包相关操作,例如SNAT
  6. 自定义链

上面的iptables流程图可能比较难以理解,它实际上是将入包、出包、转发的流程画到了一张图里面,如果将这三个流程分别标记出来就能够比较清晰地知道在入包、出包、转发过程中iptables做了哪些操作

iptables-summary

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

参考文献

  1. iptables - ArchWiKi
  2. iptables(8) - Arch manual pages
  3. 小菜学网络
  4. nftables - ArchWiKi
  5. Iptables Tutorial 1.2.2
  6. Docker and iptables