You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

如何在Docker容器内为DOCKER-USER链配置IpTables规则以管控自定义网桥中的微服务

如何在Docker容器内将IpTables规则应用到DOCKER-USER链?

核心问题分析

首先得明确一个关键点:每个Docker容器都有自己独立的网络命名空间和iptables规则栈。你在容器A里看到的空iptables链,是容器A自身的网络规则,而DOCKER-USER链是宿主机iptables的一部分——Docker守护进程在宿主机上维护这个链,专门用来过滤进出Docker容器的转发流量。所以容器A默认看不到这个链,也没法直接用自身的iptables操作它。

另外,你之前尝试在容器A的INPUT/OUTPUT链加规则无效,是因为这些链只管控容器A自己的进出流量,而微服务A/B的流量是通过宿主机的FORWARD链(DOCKER-USERFORWARD的前置钩子链)处理的,完全不在容器A的网络栈范围内。


解决方案:让容器A操作宿主机的iptables

既然你的部署要求必须在容器A内管理规则,我们可以通过两种方式让容器A直接操作宿主机的iptables栈:

方案1:挂载宿主机资源,直接调用iptables

启动容器A时,除了已有的NET_ADMIN权限,还要挂载宿主机的/proc目录和xtables.lock文件,同时加上NET_RAW权限(操作iptables需要):

docker run -it -p 8080:8080 \
  --add-cap=NET_ADMIN \
  --add-cap=NET_RAW \
  -v /var/run/docker.sock:/var/run/docker.sock \
  -v /proc:/host/proc \
  -v /run/xtables.lock:/run/xtables.lock \
  containera

在容器A内执行iptables命令时,指定使用宿主机的proc路径,这样就会直接操作宿主机的iptables规则:

iptables --proc-path /host/proc -I DOCKER-USER -i testnet -s xxx.xx.xxx -j REJECT

执行后,你可以在宿主机上运行iptables -L DOCKER-USER -v,就能看到这条规则已经生效了。

方案2:用nsenter进入宿主机网络命名空间

如果挂载/proc有安全顾虑,可以用nsenter工具进入宿主机的网络命名空间执行命令:

  1. 先修改容器A的Dockerfile,安装util-linux(包含nsenter):
FROM node:14
RUN apt-get update
RUN apt-get install -y iptables build-essential util-linux
# Create app directory
WORKDIR /usr/src/app
COPY package*.json ./
RUN npm install
COPY . .
EXPOSE 8080
CMD [ "node", "index.js" ]
  1. 在容器A内,通过nsenter切换到宿主机的网络命名空间执行iptables命令:
nsenter -t 1 -n iptables -I DOCKER-USER -i testnet -s xxx.xx.xxx -j REJECT

这里-t 1指定宿主机的init进程PID(几乎所有系统都是1),-n表示进入网络命名空间,这样执行的命令就会直接作用于宿主机的iptables。


验证规则生效

  1. 在宿主机上执行iptables -L DOCKER-USER -v,确认规则已添加。
  2. 测试从xxx.xx.xxx访问微服务A/B,应该被拒绝;而容器B/C的正常访问不受影响,符合你的需求。

注意事项

  • 必须给容器A分配NET_ADMINNET_RAW权限,否则无法操作iptables。
  • 两种方案本质都是让容器A操作宿主机的iptables,所以要确保容器A的信任度,避免恶意操作。
  • DOCKER-USER链的规则会优先于Docker默认的转发规则,正好适合你限制testnet微服务访问的场景——-i testnet指定了流量来源是testnet网桥,精准管控微服务的入站流量。

内容的提问来源于stack exchange,提问作者nphi

火山引擎 最新活动