zcbot/core/sandbox/network.py

39 lines
1.4 KiB
Python

"""Sandbox Docker network 管理。
`zcbot-sandbox-net` 是 `--internal` bridge:
- 默认无 outbound(Docker bridge 移除 host NAT 路由)
- 同网络下容器之间默认隔离(Docker bridge 默认行为,internal 也成立)
Step 2 起即用 `--internal`,iptables OUTPUT blocklist(init.sh 里的)作为 defense-in-depth
(网络层已堵死,iptables 仍按 §7.5 #1 协议加规则,任一缺失视为部署未完成)。
Step 4 引入 egress proxy 时:proxy 容器同接 `zcbot-sandbox-net`(从内部网到 proxy 容器
保持联通),proxy 容器再走 host 默认网出网。sandbox 容器 env `HTTP_PROXY` 指向
proxy 容器名 + iptables 加 ACCEPT 例外,实现"默认 deny + 仅经 proxy"
操作幂等:create 前 inspect 探测,已存在直接返。
"""
from __future__ import annotations
import subprocess
NETWORK_NAME = "zcbot-sandbox-net"
def ensure_network() -> None:
"""创建 `zcbot-sandbox-net`(若不存在)。失败 raise。"""
inspect = subprocess.run(
["docker", "network", "inspect", NETWORK_NAME],
capture_output=True, text=True,
)
if inspect.returncode == 0:
return
r = subprocess.run(
["docker", "network", "create", "--internal", NETWORK_NAME],
capture_output=True, text=True,
)
if r.returncode != 0:
raise RuntimeError(
f"docker network create {NETWORK_NAME} failed: {r.stderr.strip()}"
)