我们有很多使用 Docker 在 Linux 服务器上运行的应用程序。
举个例子,假设我的应用程序运行在服务器A作为容器(Docker)。
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
df68695a00f1 app/myapp:latest "/run.sh" 2 weeks ago Up 2 days 0.0.0.0:50423->3000/tcp reallymyapp
该应用程序正在侦听主机上的端口 50423(映射到容器上的端口 3000)。
用于访问应用程序的 DNS(端点)指向 HAProxy 主机(例如服务器B),将流量路由至服务器A:50423。
到目前为止一切都运转良好。
我们组织中的安全团队提出了一个担忧,即所有外部源 IP 都可能被允许连接到此类 Docker 主机(例如服务器A)并且他们希望我们限制流量以仅允许特定的 IP(服务器B这是一个负载均衡器)来访问容器,反之亦然(服务器A到服务器B)。然后,我们将允许从用户的机器连接到服务器B/仅负载平衡器。
现在,我关注了 Docker文档并尝试使用 iptables 将以下规则插入到 DOCKER-USER 链:
iptables -I DOCKER-USER -i ekf192 -s 10.1.2.10, 10.1.2.11, 10.1.2.12 -j ACCEPT
iptables -I DOCKER-USER -i ekf192 -j DROP
ACCEPT all -- 10.1.2.10 anywhere
ACCEPT all -- 10.1.2.11 anywhere
ACCEPT all -- 10.1.2.12 anywhere
LOG all -- anywhere anywhere LOG level info prefix "IPTables Dropped: "
DROP all -- anywhere anywhere
RETURN all -- anywhere anywhere
请注意,我们需要来自/到这些主机(10.1.2.10、10.1.2.11、10.1.2.12)的传入和传出流量。
现在,根据我对 iptables 的(有限的)了解,这些规则应该删除所有传入请求,除非它源自提到的 IP 地址,反之亦然,即允许传出流量到提到的 IP。
传入流量按预期工作,但到这些主机的传出流量正在下降。
我对此摸不着头脑,不知道出了什么问题……更不用说我完全不了解 iptables 规则的工作原理。
Jan 12 16:24:43 sms100394 kernel: IPTables Dropped: IN=docker0 OUT=ekf192 MAC=02:42:09:37:a0:14:02:42:ac:11:00:02:08:00 SRC=172.17.0.2 DST=10.1.2.10 LEN=40 TOS=0x00 PREC=0x00 TTL=63 ID=40235 DF PROTO=TCP SPT=3000 DPT=42579 WINDOW=242 RES=0x00 ACK FIN URGP=0
Jan 12 16:24:44 sms100394 kernel: IPTables Dropped: IN=docker0 OUT=ekf192 MAC=02:42:09:37:a0:14:02:42:ac:11:00:02:08:00 SRC=172.17.0.2 DST=10.1.2.11 LEN=52 TOS=0x00 PREC=0x00 TTL=63 ID=0 DF PROTO=TCP SPT=3000 DPT=45182 WINDOW=29200 RES=0x00 ACK SYN URGP=0
Jan 12 16:24:45 sms100394 kernel: IPTables Dropped: IN=docker0 OUT=ekf192 MAC=02:42:09:37:a0:14:02:42:ac:11:00:02:08:00 SRC=172.17.0.2 DST=10.1.2.12 LEN=52 TOS=0x00 PREC=0x00 TTL=63 ID=0 DF PROTO=TCP SPT=3000 DPT=45182 WINDOW=29200 RES=0x00 ACK SYN URGP=0
答案1
iptables 默认不了解“流”,只了解单个数据包。因此,对于传出的数据包,需要添加一条单独的规则,例如:
iptables -I DOCKER-USER -i ekf192 -d 10.1.2.10, 10.1.2.11, 10.1.2.12