You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Docker容器自动配置iptables与redsocks失败,求排查缺失环节

问题描述

我用脚本配置自定义iptables并重启redsocks,手动在运行中的容器内执行该脚本完全正常,但想让容器启动时自动完成配置。原本以为Dockerfile里的CMD指令能实现,但没生效,请问我遗漏了什么?

我的Dockerfile

# Dockerfile
# https://github.com/ultrafunkamsterdam/undetected-chromedriver/discussions/1600
ARG CHROME_VERSION

FROM selenoid/chrome:${CHROME_VERSION:-latest} as selenoid_chrome

FROM python:3.10-bookworm as patcher

RUN pip install undetected-chromedriver

COPY --from=selenoid_chrome /usr/bin/chromedriver /usr/bin/chromedriver

COPY patch_driver.py .

RUN python3 patch_driver.py

FROM selenoid_chrome

USER root

RUN apt-get update
RUN apt-get upgrade -qy
RUN apt-get install iptables redsocks curl wget lynx -qy

COPY --from=patcher /usr/bin/chromedriver /usr/bin/chromedriver

COPY redsocks.conf /etc/redsocks.conf
COPY iptables-config.sh /etc/iptables-config.sh

RUN chmod +x /etc/iptables-config.sh

CMD [ "bash", "/etc/iptables-config.sh" ]

ENV DRIVER_ARGS="--headless=new --start-maximized --window-size=1024,1620 --disable-dev-shm-usage --remote-debugging-pipe --no-sandbox --user-agent='Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/117.0.0.0 Safari/537.36' --verbose"

RUN AAA=$(echo '#!/bin/bash\necho $DRIVER_ARGS' ; cat /entrypoint.sh ; ) && echo "$AAA" > /entrypoint.sh

USER selenium

我的iptables配置脚本

#!/bin/bash
#https://medium.com/@jogarcia/breaking-the-proxy-walls-with-redsocks-in-linux-f4c1bfb6fb6a

# Configura iptables para que todo el trafico local vaya directamente y el resto
# siempre que tenga autorizacion (grupo socksified) vaya a internet a traves de redsocks

# Create new chain
iptables -t nat -N REDSOCKS

# Ignore LANs and some other reserved addresses.
# See http://en.wikipedia.org/wiki/Reserved_IP_addresses#Reserved_IPv4_addresses
# and http://tools.ietf.org/html/rfc5735 for full list of reserved networks.
iptables -t nat -A REDSOCKS -d 0.0.0.0/8 -j RETURN
iptables -t nat -A REDSOCKS -d 10.0.0.0/8 -j RETURN
iptables -t nat -A REDSOCKS -d 100.64.0.0/10 -j RETURN
iptables -t nat -A REDSOCKS -d 127.0.0.0/8 -j RETURN
iptables -t nat -A REDSOCKS -d 169.254.0.0/16 -j RETURN
iptables -t nat -A REDSOCKS -d 172.16.0.0/12 -j RETURN
iptables -t nat -A REDSOCKS -d 192.168.0.0/16 -j RETURN
iptables -t nat -A REDSOCKS -d 198.18.0.0/15 -j RETURN
iptables -t nat -A REDSOCKS -d 224.0.0.0/4 -j RETURN
iptables -t nat -A REDSOCKS -d 240.0.0.0/4 -j RETURN

# Anything else should be redirected to port 12345
#iptables -t nat -A REDSOCKS -p tcp -j REDIRECT --to-ports 12345 and 12346

iptables -t nat -A REDSOCKS -p tcp --dport 80 -j REDIRECT --to-ports 12346
iptables -t nat -A REDSOCKS -p tcp --dport 443 -j REDIRECT --to-ports 12345

iptables -t nat -A REDSOCKS -p tcp -j REDIRECT --to-ports 12345

# Any tcp connection made should be redirected to the REDSOCKS CHAIN.
iptables -t nat -A OUTPUT -p tcp -j REDSOCKS

# Restart Redsocks
/etc/init.d/redsocks restart

我的docker-compose.yml

version: "3.9"

services:
  selenium:
    image: uc_chrome:latest
    build:
      context: .
      dockerfile: Dockerfile.uc
    restart: "no"
    container_name: airflow_uc
    cap_add:
      - NET_ADMIN
    privileged: true
    volumes:
      - /dev/shm:/dev/shm
      - ./proxy_manager:/lpm
    ports:
      - "5900-5999:4444"

问题原因及修复方案

你没生效的核心原因有三个,逐个解决就能搞定:

1. 原镜像ENTRYPOINT覆盖了你的CMD

selenoid/chrome本身自带ENTRYPOINT ["/entrypoint.sh"],Docker规则里,如果容器同时有ENTRYPOINT和CMD,CMD的内容会作为参数传给ENTRYPOINT执行,而不是单独跑你的脚本。你虽然修改了/entrypoint.sh,但你的CMD根本没机会执行——ENTRYPOINT直接接管了启动流程。

2. 脚本执行完容器直接退出

你的iptables-config.sh是一次性脚本,跑完所有命令就会退出,而Docker容器的生命周期和主进程绑定,主进程退了容器就停了,后续的Chrome服务根本起不来。

3. 权限不匹配

Dockerfile最后切换到了selenium用户,但iptables配置、redsocks重启都需要root权限,用普通用户执行会直接失败。


具体修复步骤

方案一:修改ENTRYPOINT,整合配置流程

  1. 先备份原镜像的entrypoint脚本,再新建一个entrypoint,先执行iptables配置,再启动原服务:
# 替换原来修改entrypoint的RUN命令
RUN cp /entrypoint.sh /entrypoint.sh.orig && \
    echo '#!/bin/bash\n/etc/iptables-config.sh\necho $DRIVER_ARGS\n' > /entrypoint.sh && \
    cat /entrypoint.sh.orig >> /entrypoint.sh && \
    chmod +x /entrypoint.sh
  1. 删除Dockerfile里的CMD [ "bash", "/etc/iptables-config.sh" ],让ENTRYPOINT全权处理启动。

方案二:直接用ENTRYPOINT指定复合启动命令

在Dockerfile里替换原CMD,用exec保证原服务进程成为容器主进程:

# 移除原CMD,添加以下ENTRYPOINT
ENTRYPOINT ["/bin/bash", "-c", "/etc/iptables-config.sh && exec su selenium -c '/entrypoint.sh $DRIVER_ARGS'"]

这里exec是关键,能让后续的Chrome服务进程替代当前bash进程,保证容器不会因为脚本执行完就退出;su selenium则是切换回普通用户启动Chrome,符合安全规范。

额外检查

  • 确认docker-compose里的NET_ADMIN和privileged配置保留,这是iptables生效的必要权限。
  • 检查redsocks.conf的端口配置和脚本里的转发端口一致,避免端口不匹配导致代理失效。

内容的提问来源于stack exchange,提问作者Walid Mujahid وليد مجاهد

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.25 20:25:57