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,整合配置流程
- 先备份原镜像的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
- 删除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 وليد مجاهد
相关产品推荐
相关产品推荐

