init.sh: 覆写 /etc/resolv.conf 绕过 docker embedded DNS
发现 user-defined bridge network 上 docker run --dns 是改 daemon 给 embedded DNS(127.0.0.11)的上游 forward 目标,容器 /etc/resolv.conf 不变(仍是 nameserver 127.0.0.11)。腾讯云轻量等场景 daemon 探测 systemd-resolved 上游 失败 → embedded DNS 自身 forward 也跪 → --dns 8.8.8.8 救不了。 正确解:init.sh 启动时直接覆写 /etc/resolv.conf,完全绕过 embedded DNS。 - pool.py 把 --dns flag 换成 -e ZCBOT_DNS=8.8.8.8,114.114.114.114 - init.sh apply_resolv_conf 函数循环 echo "nameserver $ip" > /etc/resolv.conf - /etc/resolv.conf 是 docker bind mount file(非 rootfs),--read-only 不挡, root 跑 init.sh 可写;--restart=no 容器生命周期内不被 docker 覆盖 iptables 127.0.0.11 ACCEPT 例外保留不动(无副作用,以备未来需要 service discovery 等场景)。 Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
3a3f8d86cc
commit
ae15a36e58
|
|
@ -184,10 +184,13 @@ class SandboxPool:
|
||||||
"-e", f"ZCBOT_PG_IPS={self.pg_ips}",
|
"-e", f"ZCBOT_PG_IPS={self.pg_ips}",
|
||||||
"--restart=no",
|
"--restart=no",
|
||||||
]
|
]
|
||||||
# 显式 DNS(绕过 docker daemon 上游探测,腾讯云轻量等场景下 daemon 探测
|
# 显式 DNS:用 env 传给 init.sh,启动时覆写 /etc/resolv.conf 直接指公网 DNS。
|
||||||
# host systemd-resolved 上游不稳)
|
# 不用 docker `--dns` flag ── user-defined bridge network 上 `--dns` 只改
|
||||||
for dns_ip in self.dns:
|
# docker daemon 给 embedded DNS(127.0.0.11)的上游目标,容器 resolv.conf
|
||||||
cmd += ["--dns", dns_ip]
|
# 不变;daemon 上游探测在腾讯云轻量等场景不稳,embedded DNS 自身 forward
|
||||||
|
# 仍跪。init.sh 直接写 resolv.conf 完全绕过 embedded DNS。
|
||||||
|
if self.dns:
|
||||||
|
cmd += ["-e", f"ZCBOT_DNS={','.join(self.dns)}"]
|
||||||
# repo skills 只读 mount ── fs 工具进容器后(read/glob/grep)能 access
|
# repo skills 只读 mount ── fs 工具进容器后(read/glob/grep)能 access
|
||||||
# SKILL.md 内引用的 references/*.md。host 上 zcbot/skills/ 是项目代码,
|
# SKILL.md 内引用的 references/*.md。host 上 zcbot/skills/ 是项目代码,
|
||||||
# 跟用户 working_dir 正交,只读防容器内进程改 skill 实现。
|
# 跟用户 working_dir 正交,只读防容器内进程改 skill 实现。
|
||||||
|
|
|
||||||
|
|
@ -8,6 +8,26 @@
|
||||||
# 上层 ensure() 会 raise。
|
# 上层 ensure() 会 raise。
|
||||||
set -euo pipefail
|
set -euo pipefail
|
||||||
|
|
||||||
|
apply_resolv_conf() {
|
||||||
|
# 覆写 /etc/resolv.conf 直接指公网 DNS,绕过 docker embedded DNS(127.0.0.11)。
|
||||||
|
# user-defined bridge network 默 resolv.conf = nameserver 127.0.0.11,embedded DNS
|
||||||
|
# 转发给 docker daemon 上游 ── 腾讯云轻量等场景 daemon 探测 systemd-resolved 失败
|
||||||
|
# → embedded DNS 自己 forward 不出去 → 全跪。docker run `--dns` flag 只改 daemon
|
||||||
|
# 上游不动 resolv.conf,在 user-defined network 上无效。
|
||||||
|
# init.sh root 跑可写 /etc/resolv.conf(docker bind mount file 而非 rootfs);
|
||||||
|
# --restart=no 容器整生命周期内不被 docker 覆盖。
|
||||||
|
if [ -n "${ZCBOT_DNS:-}" ]; then
|
||||||
|
{
|
||||||
|
for ip in $(echo "$ZCBOT_DNS" | tr ',' ' '); do
|
||||||
|
[ -z "$ip" ] && continue
|
||||||
|
echo "nameserver $ip"
|
||||||
|
done
|
||||||
|
} > /etc/resolv.conf
|
||||||
|
echo "[init] /etc/resolv.conf set:"
|
||||||
|
cat /etc/resolv.conf
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
apply_blocklist() {
|
apply_blocklist() {
|
||||||
# Docker embedded DNS 例外(必须在 127.0.0.0/8 DROP 前)──
|
# Docker embedded DNS 例外(必须在 127.0.0.0/8 DROP 前)──
|
||||||
# 容器内 /etc/resolv.conf 默写 `nameserver 127.0.0.11`,挡了所有域名解析全跪。
|
# 容器内 /etc/resolv.conf 默写 `nameserver 127.0.0.11`,挡了所有域名解析全跪。
|
||||||
|
|
@ -42,6 +62,7 @@ apply_blocklist() {
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
|
apply_resolv_conf
|
||||||
apply_blocklist
|
apply_blocklist
|
||||||
echo "[init] iptables OUTPUT blocklist applied:"
|
echo "[init] iptables OUTPUT blocklist applied:"
|
||||||
iptables -L OUTPUT -n --line-numbers
|
iptables -L OUTPUT -n --line-numbers
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue