如何利用iptables管理docker开放的端口?
环境准备
操作系统
操作系统使用的ubuntu20.04.3,全新安装的环境
防火墙
ubuntu20使用的ufw,先把这个停止,这次测试主要使用iptables-services和docker,关闭其余防火墙的影响
安装iptables
1 2 3 4
| apt install iptables
yum install iptables-services
|
初始配置iptables
1 2 3 4
| mkdir /etc/sysconfig
vi /etc/sysconfig/iptables
|
初始化配置文件内容如下(顺序有关)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| # 使用filter表 *filter # 下面三条内容定义了内建的INPUT、FORWAARD、ACCEPT链 :INPUT ACCEPT [0:0] :FORWARD ACCEPT [0:0] :OUTPUT ACCEPT [0:0] # 允许本地访问 -A INPUT -i lo -j ACCEPT # 下面这条不配置也可以,因为不限制数据包流出 -A OUTPUT -o lo -j ACCEPT # 禁止icmp探测 -A INPUT -p icmp -j REJECT # -m state --state ESTABLISHED,RELATED这个条件表示所有处于ESTABLISHED或者RELATED状态的包,策略都是接受的。 -A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT # -m state --state NEW 这个条件是当connection的状态为初始连接(NEW)时候的策略。 # 22端口是默认ssh端口,不开启容易无法连接 -A INPUT -p tcp -m state --state NEW -m multiport --dports 22,80 -j ACCEPT
# 禁止其他访问 -A INPUT -j DROP -A FORWARD -j DROP COMMIT
|
docker安装
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| apt update && \ apt install -y \ ca-certificates \ curl \ gnupg \ lsb-release && \ mkdir -p /etc/apt/keyrings && \ curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg && \ apt update && \ apt install -y docker-ce docker-ce-cli containerd.io docker-compose-plugin
yum install -y yum-utils device-mapper-persistent-data lvm2 && \ yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo && \ yum install -y docker-ce docker-ce-cli containerd.io
mkdir -p /etc/docker && touch /etc/docker/daemon.json && \ echo '{"registry-mirrors":["https://hub-mirror.c.163.com"]' > /etc/docker/daemon.json && \ systemctl enable docker && systemctl start docker
|
防火墙与docker配置
使用iptables-save 导出当前防火墙配置
1
| iptables-save > iptables.save
|
内容如下:
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 40 41 42
| *nat :PREROUTING ACCEPT [39:4940] :INPUT ACCEPT [0:0] :OUTPUT ACCEPT [1:40] :POSTROUTING ACCEPT [1:40] :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 DOCKER -i docker0 -j RETURN COMMIT
*filter :INPUT ACCEPT [0:0] :FORWARD DROP [0:0] :OUTPUT ACCEPT [122:19744] :DOCKER - [0:0] :DOCKER-ISOLATION-STAGE-1 - [0:0] :DOCKER-ISOLATION-STAGE-2 - [0:0] :DOCKER-USER - [0:0] -A INPUT -i lo -j ACCEPT -A INPUT -p icmp -j REJECT --reject-with icmp-port-unreachable -A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT -A INPUT -p tcp -m state --state NEW -m multiport --dports 22,80 -j ACCEPT -A INPUT -j DROP -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 FORWARD -j DROP -A OUTPUT -o lo -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
|
可以看到docker在filter表中新增了几个链
使用docker启动nginx
1
| docker run -d -p 8080:80 nginx
|
此时服务可以直接访问
此时防火墙的配置文件如下
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 40 41 42 43 44 45 46 47 48
| *nat :PREROUTING ACCEPT [25:2945] :INPUT ACCEPT [0:0] :OUTPUT ACCEPT [0:0] :POSTROUTING ACCEPT [1:64] :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
*filter :INPUT ACCEPT [0:0] :FORWARD DROP [0:0] :OUTPUT ACCEPT [36:6464] :DOCKER - [0:0] :DOCKER-ISOLATION-STAGE-1 - [0:0] :DOCKER-ISOLATION-STAGE-2 - [0:0] :DOCKER-USER - [0:0] -A INPUT -i lo -j ACCEPT -A INPUT -p icmp -j REJECT --reject-with icmp-port-unreachable -A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT -A INPUT -p tcp -m state --state NEW -m multiport --dports 22,80 -j ACCEPT -A INPUT -j DROP -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 FORWARD -j DROP -A OUTPUT -o lo -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
|
防火墙配置
如果是在本机上的nginx,我们可以直接通过下面的命令进行控制
1
| iptables -I INPUT 4 -p tcp -m tcp --dport 8080 -j DROP
|
但是现在发现,使用docker启动的服务无法这么调整了
如果要对docker中的服务进行限制,需要在docker相关的链中进行操作
数据包流转跟踪
使用docker启动了两个nginx,分别映射宿主机的8080端口和8081端口,下面是配置文件
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 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55
| *nat :PREROUTING ACCEPT [5:636] :INPUT ACCEPT [0:0] :OUTPUT ACCEPT [0:0] :POSTROUTING ACCEPT [1:64] :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 POSTROUTING -s 172.17.0.2/32 -d 172.17.0.2/32 -p tcp -m tcp --dport 80 -j LOG --log-prefix "iptables-postrouting: " -A POSTROUTING -s 172.17.0.3/32 -d 172.17.0.3/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
-A DOCKER ! -i docker0 -p tcp -m tcp --dport 8081 -j LOG --log-prefix "iptables-docker: " -A DOCKER ! -i docker0 -p tcp -m tcp --dport 8081 -j DNAT --to-destination 172.17.0.3:80 COMMIT
*filter :INPUT ACCEPT [0:0] :FORWARD DROP [0:0] :OUTPUT ACCEPT [59:6764] :DOCKER - [0:0] :DOCKER-ISOLATION-STAGE-1 - [0:0] :DOCKER-ISOLATION-STAGE-2 - [0:0] :DOCKER-USER - [0:0] -A INPUT -i lo -j ACCEPT -A INPUT -p icmp -j REJECT --reject-with icmp-port-unreachable -A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT -A INPUT -p tcp -m tcp --dport 8080 -j DROP -A INPUT -p tcp -m state --state NEW -m multiport --dports 22,80 -j ACCEPT -A INPUT -j DROP -A FORWARD -j LOG --log-prefix "iptables-forward: " -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 FORWARD -j DROP -A OUTPUT -o lo -j ACCEPT -A DOCKER -d 172.17.0.2/32 ! -i docker0 -o docker0 -p tcp -m tcp --dport 80 -j ACCEPT -A DOCKER -d 172.17.0.3/32 ! -i docker0 -o docker0 -p tcp -m tcp --dport 80 -j LOG --log-prefix "iptables-filter-docker: " -A DOCKER -d 172.17.0.3/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 LOG --log-prefix "iptables-docker-user: " -A DOCKER-USER -j RETURN COMMIT
|
下面是访问8081端口,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
| Sep 18 09:33:28 server kernel: [ 9650.758973] iptables-docker: IN=ens33 OUT= MAC=00:0c:29:1c:8e:65:b0:be:83:49:90:a2:08:00 SRC=192.168.6.150 DST=192.168.6.110 LEN=64 TOS=0x00 PREC=0x00 TTL=64 ID=0 DF PROTO=TCP SPT=56563 DPT=8081 WINDOW=65535 RES=0x00 SYN URGP=0 Sep 18 09:33:28 server kernel: [ 9650.759027] iptables-forward: IN=ens33 OUT=docker0 MAC=00:0c:29:1c:8e:65:b0:be:83:49:90:a2:08:00 SRC=192.168.6.150 DST=172.17.0.3 LEN=64 TOS=0x00 PREC=0x00 TTL=63 ID=0 DF PROTO=TCP SPT=56563 DPT=80 WINDOW=65535 RES=0x00 SYN URGP=0 Sep 18 09:33:28 server kernel: [ 9650.759031] iptables-docker-user: IN=ens33 OUT=docker0 MAC=00:0c:29:1c:8e:65:b0:be:83:49:90:a2:08:00 SRC=192.168.6.150 DST=172.17.0.3 LEN=64 TOS=0x00 PREC=0x00 TTL=63 ID=0 DF PROTO=TCP SPT=56563 DPT=80 WINDOW=65535 RES=0x00 SYN URGP=0 Sep 18 09:33:28 server kernel: [ 9650.759036] iptables-filter-docker: IN=ens33 OUT=docker0 MAC=00:0c:29:1c:8e:65:b0:be:83:49:90:a2:08:00 SRC=192.168.6.150 DST=172.17.0.3 LEN=64 TOS=0x00 PREC=0x00 TTL=63 ID=0 DF PROTO=TCP SPT=56563 DPT=80 WINDOW=65535 RES=0x00 SYN URGP=0 Sep 18 09:33:28 server kernel: [ 9650.759082] iptables-forward: IN=docker0 OUT=ens33 PHYSIN=vethd96fc82 MAC=02:42:46:22:17:a8:02:42:ac:11:00:03:08:00 SRC=172.17.0.3 DST=192.168.6.150 LEN=60 TOS=0x00 PREC=0x00 TTL=63 ID=0 DF PROTO=TCP SPT=80 DPT=56563 WINDOW=65160 RES=0x00 ACK SYN URGP=0 Sep 18 09:33:28 server kernel: [ 9650.759084] iptables-docker-user: IN=docker0 OUT=ens33 PHYSIN=vethd96fc82 MAC=02:42:46:22:17:a8:02:42:ac:11:00:03:08:00 SRC=172.17.0.3 DST=192.168.6.150 LEN=60 TOS=0x00 PREC=0x00 TTL=63 ID=0 DF PROTO=TCP SPT=80 DPT=56563 WINDOW=65160 RES=0x00 ACK SYN URGP=0 Sep 18 09:33:28 server kernel: [ 9650.766202] iptables-forward: IN=ens33 OUT=docker0 MAC=00:0c:29:1c:8e:65:b0:be:83:49:90:a2:08:00 SRC=192.168.6.150 DST=172.17.0.3 LEN=52 TOS=0x00 PREC=0x00 TTL=63 ID=0 DF PROTO=TCP SPT=56563 DPT=80 WINDOW=2058 RES=0x00 ACK URGP=0 Sep 18 09:33:28 server kernel: [ 9650.766233] iptables-docker-user: IN=ens33 OUT=docker0 MAC=00:0c:29:1c:8e:65:b0:be:83:49:90:a2:08:00 SRC=192.168.6.150 DST=172.17.0.3 LEN=52 TOS=0x00 PREC=0x00 TTL=63 ID=0 DF PROTO=TCP SPT=56563 DPT=80 WINDOW=2058 RES=0x00 ACK URGP=0 Sep 18 09:33:28 server kernel: [ 9650.766920] iptables-forward: IN=ens33 OUT=docker0 MAC=00:0c:29:1c:8e:65:b0:be:83:49:90:a2:08:00 SRC=192.168.6.150 DST=172.17.0.3 LEN=157 TOS=0x00 PREC=0x00 TTL=63 ID=0 DF PROTO=TCP SPT=56563 DPT=80 WINDOW=2058 RES=0x00 ACK PSH URGP=0 Sep 18 09:33:28 server kernel: [ 9650.766943] iptables-docker-user: IN=ens33 OUT=docker0 MAC=00:0c:29:1c:8e:65:b0:be:83:49:90:a2:08:00 SRC=192.168.6.150 DST=172.17.0.3 LEN=157 TOS=0x00 PREC=0x00 TTL=63 ID=0 DF PROTO=TCP SPT=56563 DPT=80 WINDOW=2058 RES=0x00 ACK PSH URGP=0 Sep 18 09:33:28 server kernel: [ 9650.766983] iptables-forward: IN=docker0 OUT=ens33 PHYSIN=vethd96fc82 MAC=02:42:46:22:17:a8:02:42:ac:11:00:03:08:00 SRC=172.17.0.3 DST=192.168.6.150 LEN=52 TOS=0x00 PREC=0x00 TTL=63 ID=46071 DF PROTO=TCP SPT=80 DPT=56563 WINDOW=509 RES=0x00 ACK URGP=0 Sep 18 09:33:28 server kernel: [ 9650.766986] iptables-docker-user: IN=docker0 OUT=ens33 PHYSIN=vethd96fc82 MAC=02:42:46:22:17:a8:02:42:ac:11:00:03:08:00 SRC=172.17.0.3 DST=192.168.6.150 LEN=52 TOS=0x00 PREC=0x00 TTL=63 ID=46071 DF PROTO=TCP SPT=80 DPT=56563 WINDOW=509 RES=0x00 ACK URGP=0 Sep 18 09:33:28 server kernel: [ 9650.767108] iptables-forward: IN=docker0 OUT=ens33 PHYSIN=vethd96fc82 MAC=02:42:46:22:17:a8:02:42:ac:11:00:03:08:00 SRC=172.17.0.3 DST=192.168.6.150 LEN=290 TOS=0x00 PREC=0x00 TTL=63 ID=46072 DF PROTO=TCP SPT=80 DPT=56563 WINDOW=509 RES=0x00 ACK PSH URGP=0 Sep 18 09:33:28 server kernel: [ 9650.767111] iptables-docker-user: IN=docker0 OUT=ens33 PHYSIN=vethd96fc82 MAC=02:42:46:22:17:a8:02:42:ac:11:00:03:08:00 SRC=172.17.0.3 DST=192.168.6.150 LEN=290 TOS=0x00 PREC=0x00 TTL=63 ID=46072 DF PROTO=TCP SPT=80 DPT=56563 WINDOW=509 RES=0x00 ACK PSH URGP=0 Sep 18 09:33:28 server kernel: [ 9650.767237] iptables-forward: IN=docker0 OUT=ens33 PHYSIN=vethd96fc82 MAC=02:42:46:22:17:a8:02:42:ac:11:00:03:08:00 SRC=172.17.0.3 DST=192.168.6.150 LEN=667 TOS=0x00 PREC=0x00 TTL=63 ID=46073 DF PROTO=TCP SPT=80 DPT=56563 WINDOW=509 RES=0x00 ACK PSH URGP=0 Sep 18 09:33:28 server kernel: [ 9650.767239] iptables-docker-user: IN=docker0 OUT=ens33 PHYSIN=vethd96fc82 MAC=02:42:46:22:17:a8:02:42:ac:11:00:03:08:00 SRC=172.17.0.3 DST=192.168.6.150 LEN=667 TOS=0x00 PREC=0x00 TTL=63 ID=46073 DF PROTO=TCP SPT=80 DPT=56563 WINDOW=509 RES=0x00 ACK PSH URGP=0 Sep 18 09:33:28 server kernel: [ 9650.773906] iptables-forward: IN=ens33 OUT=docker0 MAC=00:0c:29:1c:8e:65:b0:be:83:49:90:a2:08:00 SRC=192.168.6.150 DST=172.17.0.3 LEN=52 TOS=0x00 PREC=0x00 TTL=63 ID=0 DF PROTO=TCP SPT=56563 DPT=80 WINDOW=2045 RES=0x00 ACK URGP=0 Sep 18 09:33:28 server kernel: [ 9650.773959] iptables-docker-user: IN=ens33 OUT=docker0 MAC=00:0c:29:1c:8e:65:b0:be:83:49:90:a2:08:00 SRC=192.168.6.150 DST=172.17.0.3 LEN=52 TOS=0x00 PREC=0x00 TTL=63 ID=0 DF PROTO=TCP SPT=56563 DPT=80 WINDOW=2045 RES=0x00 ACK URGP=0 Sep 18 09:33:28 server kernel: [ 9650.774877] iptables-forward: IN=ens33 OUT=docker0 MAC=00:0c:29:1c:8e:65:b0:be:83:49:90:a2:08:00 SRC=192.168.6.150 DST=172.17.0.3 LEN=52 TOS=0x00 PREC=0x00 TTL=63 ID=0 DF PROTO=TCP SPT=56563 DPT=80 WINDOW=2048 RES=0x00 ACK FIN URGP=0 Sep 18 09:33:28 server kernel: [ 9650.774926] iptables-docker-user: IN=ens33 OUT=docker0 MAC=00:0c:29:1c:8e:65:b0:be:83:49:90:a2:08:00 SRC=192.168.6.150 DST=172.17.0.3 LEN=52 TOS=0x00 PREC=0x00 TTL=63 ID=0 DF PROTO=TCP SPT=56563 DPT=80 WINDOW=2048 RES=0x00 ACK FIN URGP=0 Sep 18 09:33:28 server kernel: [ 9650.775065] iptables-forward: IN=docker0 OUT=ens33 PHYSIN=vethd96fc82 MAC=02:42:46:22:17:a8:02:42:ac:11:00:03:08:00 SRC=172.17.0.3 DST=192.168.6.150 LEN=52 TOS=0x00 PREC=0x00 TTL=63 ID=46074 DF PROTO=TCP SPT=80 DPT=56563 WINDOW=509 RES=0x00 ACK FIN URGP=0 Sep 18 09:33:28 server kernel: [ 9650.775069] iptables-docker-user: IN=docker0 OUT=ens33 PHYSIN=vethd96fc82 MAC=02:42:46:22:17:a8:02:42:ac:11:00:03:08:00 SRC=172.17.0.3 DST=192.168.6.150 LEN=52 TOS=0x00 PREC=0x00 TTL=63 ID=46074 DF PROTO=TCP SPT=80 DPT=56563 WINDOW=509 RES=0x00 ACK FIN URGP=0 Sep 18 09:33:28 server kernel: [ 9650.780061] iptables-forward: IN=ens33 OUT=docker0 MAC=00:0c:29:1c:8e:65:b0:be:83:49:90:a2:08:00 SRC=192.168.6.150 DST=172.17.0.3 LEN=52 TOS=0x00 PREC=0x00 TTL=63 ID=0 DF PROTO=TCP SPT=56563 DPT=80 WINDOW=2048 RES=0x00 ACK URGP=0 Sep 18 09:33:28 server kernel: [ 9650.780108] iptables-docker-user: IN=ens33 OUT=docker0 MAC=00:0c:29:1c:8e:65:b0:be:83:49:90:a2:08:00 SRC=192.168.6.150 DST=172.17.0.3 LEN=52 TOS=0x00 PREC=0x00 TTL=63 ID=0 DF PROTO=TCP SPT=56563 DPT=80 WINDOW=2048 RES=0x00 ACK URGP=0
|
这里面值得注意的是:
因为源ip一直不会变化,所以如果要限定源ip访问,直接执行如下命令:
这也是官方建议的方式,编辑DOCKER-USER链
https://docs.docker.com/network/iptables/
1 2
| iptables -I DOCKER-USER ! -s 192.168.6.1 -j DROP
|
但是如果我只想禁止外部的端口访问,则需要操作nat表,在进行地址转换前就进行拦截
只要访问主机docker启动的的8081端口,就会被拦截
1 2
| iptables -t nat -I DOCKER 1 -p tcp -m tcp --dport 8081 -j RETURN
|
最终配置文件:
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 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58
| *mangle :PREROUTING ACCEPT [4907:504306] :INPUT ACCEPT [4826:493232] :FORWARD ACCEPT [81:11074] :OUTPUT ACCEPT [2198:463332] :POSTROUTING ACCEPT [2279:474406] COMMIT
*nat :PREROUTING ACCEPT [1376:178830] :INPUT ACCEPT [2:264] :OUTPUT ACCEPT [3:216] :POSTROUTING ACCEPT [5:344] :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 POSTROUTING -s 172.17.0.3/32 -d 172.17.0.3/32 -p tcp -m tcp --dport 80 -j MASQUERADE -A DOCKER -i docker0 -j RETURN -A DOCKER -p tcp -m tcp --dport 8081 -j RETURN -A DOCKER ! -i docker0 -p tcp -m tcp --dport 8080 -j DNAT --to-destination 172.17.0.2:80 -A DOCKER ! -i docker0 -p tcp -m tcp --dport 8081 -j DNAT --to-destination 172.17.0.3:80 COMMIT
*filter :INPUT ACCEPT [0:0] :FORWARD DROP [0:0] :OUTPUT ACCEPT [32:3760] :DOCKER - [0:0] :DOCKER-ISOLATION-STAGE-1 - [0:0] :DOCKER-ISOLATION-STAGE-2 - [0:0] :DOCKER-USER - [0:0] -A INPUT -i lo -j ACCEPT -A INPUT -p icmp -j REJECT --reject-with icmp-port-unreachable -A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT -A INPUT -p tcp -m state --state NEW -m multiport --dports 22 -j ACCEPT -A INPUT -j DROP -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 FORWARD -j DROP -A OUTPUT -o lo -j ACCEPT -A DOCKER -d 172.17.0.2/32 ! -i docker0 -o docker0 -p tcp -m tcp --dport 80 -j ACCEPT -A DOCKER -d 172.17.0.3/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
|
额外
对于docker服务,如果对外映射的端口与容器内部端口相同的情况下,限制白名单ip访问指定端口,可以如下配置:
1 2
| iptables -I DOCKER-USER ! -s 192.168.6.1 ! -p tcp ! --dport 6379 -j DROP
|
如果要限制外部能够访问的docker服务,即仅开放指定端口的服务(宿主机端口),使用如下命令配置
如果在宿主机上启动nginx,监听8081端口,这种方式不会阻止访问,会根据filter表的INPUT规则进行判断
1 2
| iptables -t nat -I DOCKER 1 -p tcp -m tcp --dport 8081 -j RETURN
|
但是这种方式,重启docker后就会消失,对DOCKER的编辑无法保存,对DOCKER-USER的编辑可以保存
不过根据上面的描述,我们可以在nat表的PREROUTING链增加规则,重启后可以保存,也能达到我们要的目的
这种方式需要配合INPUT链一起使用,确保INPUT链中也禁止访问8081端口才会生效
如果INPUT中允许8081端口是ACCEPT,数据包也会正常到达,只不过此时虽然包中的原IP还是客户端IP,但在nginx中看到的访问ip是docker0这个接口的ip
1 2
| iptables -t nat -I PREROUTING -p tcp -m tcp --dport 8081 -j RETURN
|
因此,按这个思路,如果要允许仅192.168.6.0网段可以访问5000端口(容器内外端口相同),有如下两种配置方式:
使用docker-user链
1
| iptables -I DOCKER-USER ! -s 192.168.6.0/24 -p tcp -m tcp --dport 5000 -j DROP
|
使用nat表prerouting链,此时需要确保filter表的input链禁止访问5000端口
1
| iptables -t nat -I PREROUTING -p tcp -m tpc --dport 5000 -j RETURN
|
如果容器内外映射的端口不同,则使用nat表的prerouting链实现,可以持久化。
或者使用nat表的DOCKER链实现,不能持久化,docker重启后规则会消失
todo
- 重新整理文档逻辑
- docker swarm模式下,对端口或ip的限制
参考资料
- https://www.cnblogs.com/ggjucheng/archive/2012/08/19/2646466.html – iptables简介
- https://blog.csdn.net/wsclinux/article/details/53256494 – return语句
- https://blog.csdn.net/stonesharp/article/details/26495667 –表的优先级
- https://blog.csdn.net/beeworkshop/article/details/114278379 –日志配置(ubuntu20 在/etc/sysctl.d下新建文件,使用systemctl restart syslog使配置生效)
- https://docs.docker.com/network/iptables/ –docker官网说明
- https://www.jianshu.com/p/586da7c8fd42 –iptables常用参数