Skip to content

宿主机安全隔离方案

适用场景:在 Ubuntu/Debian 宿主机上,把不可信的浏览器、下载器、第三方软件限制在独立的网络命名空间里,确保:

  • 飞书、Kimi Code CLI 等日常工具不受影响
  • Jumpserver SSH/VNC 客户端/服务端正常工作
  • 宿主机 9000–9009 端口服务保持可达
  • 不可信应用只能访问公网,无法访问宿主机本地服务、内网和其他容器网络

1. 设计思路

text
┌─────────────────────────────────────────────────────────────────┐
│                        宿主机默认网络命名空间                      │
│  ┌─────────┐  ┌────────────┐  ┌────────────┐  ┌───────────────┐ │
│  │  飞书   │  │ Kimi Code  │  │ SSH/VNC    │  │ 9000-9009 服务 │ │
│  └────┬────┘  └─────┬──────┘  └─────┬──────┘  └───────┬───────┘ │
│       │             │               │                 │         │
│       └─────────────┴───────────────┴─────────────────┘         │
│                           物理网卡 / 默认路由                     │
└─────────────────────────────────────────────────────────────────┘

        ┌─────────────────────┘  iptables/nftables 转发 + NAT

┌───────┴──────────────────────────────────────────┐
│        独立网络命名空间 untrusted                   │
│   ┌─────────────┐    veth pair                    │
│   │ 不可信浏览器 │ <-> veth-unt-ns  10.200.1.2/24  │
│   │ 下载软件     │                                 │
│   └─────────────┘                                 │
└───────────────────────────────────────────────────┘
  • 网络层隔离:不可信应用运行在 untrusted network namespace,拥有独立的 lo、路由表、iptables/nftables 规则。
  • 访问控制:宿主机 nftables 默认丢弃入站;SSH / VNC 仅允许指定的 Jumpserver 管理 IP;放行 9000–9009;丢弃来自 veth-unt-host 的到宿主机的流量;禁止不可信 netns 访问 RFC1918 私网。
  • NAT 上网:不可信 netns 通过 veth + 宿主机 NAT 访问公网,源地址被伪装成宿主机地址。
  • 可选增强:可叠加 AppArmor/Bubblewrap 做文件系统沙箱、seccomp 做系统调用过滤。

2. 文件说明

文件作用
nftables.conf宿主机防火墙规则(drop 入站/限制转发、放行必要端口、NAT)
untrusted-netns-setup.sh创建并配置 untrusted network namespace 和 veth 对
run-untrusted.sh在隔离 netns 中以当前用户身份启动指定程序
rollback.sh移除 netns、veth 并恢复 nftables 备份
untrusted-netns.servicesystemd 开机自动创建 netns(可选)
change-host-ports.sh修改宿主机 SSH / VNC 监听端口(默认 10822 / 10922)
restrict-admin-ip.sh限制 SSH / VNC 仅允许指定 Jumpserver IP 访问

3. 前置检查

bash
# 1. 确认系统为 Ubuntu/Debian
lsb_release -a

# 2. 确认 nftables 已安装
sudo apt update && sudo apt install -y nftables

# 3. 如果启用了 UFW,建议先停用并记录现有规则,避免与原生 nftables 冲突
sudo ufw status numbered
sudo systemctl disable --now ufw

如果你必须保留 UFW,请改用 iptables 版本实现,或使用 nftables 更高/更低优先级(priority)的 chain,避免同 priority 冲突。

4. 安装步骤

bash
cd /home/xxx/docs/security/host-isolation
sudo ./install.sh

或手动:

bash
cd /home/xxx/docs/security/host-isolation

# 备份原有 nftables 配置
sudo cp /etc/nftables.conf /etc/nftables.conf.bak.$(date +%Y%m%d%H%M%S)

# 安装规则
sudo cp nftables.conf /etc/nftables.conf
sudo chmod 600 /etc/nftables.conf
sudo systemctl enable --now nftables

# 创建隔离网络命名空间
sudo ./untrusted-netns-setup.sh

5. 使用方式

5.1 启动隔离浏览器

bash
# Chrome / Chromium
./run-untrusted.sh google-chrome --incognito

# Firefox
./run-untrusted.sh firefox

# 任意命令行工具
./run-untrusted.sh curl -s https://www.example.org

5.2 创建桌面快捷方式(示例)

ini
# ~/.local/share/applications/untrusted-chrome.desktop
[Desktop Entry]
Name=Chrome (Isolated)
Exec=/home/xxx/docs/security/host-isolation/run-untrusted.sh google-chrome --incognito
Type=Application
Terminal=false

6. 验证清单

bash
# 查看命名空间
ip netns list
# 应输出:untrusted

# 在隔离环境中访问公网
sudo ip netns exec untrusted ping -c 2 1.1.1.1
sudo ip netns exec untrusted curl -sI https://www.example.org

# 验证无法访问宿主机本地 SSH(应失败)
sudo ip netns exec untrusted timeout 2 bash -c '</dev/tcp/127.0.0.1/10822' && echo "FAIL" || echo "OK blocked"

# 验证无法访问宿主机 9000 端口(应失败)
sudo ip netns exec untrusted timeout 2 bash -c '</dev/tcp/127.0.0.1/9000' && echo "FAIL" || echo "OK blocked"

# 从外部或本机默认命名空间确认 9000-9009 可达
curl http://localhost:9000

# 确认飞书/Kimi Code 可正常联网
# (在默认命名空间运行,无需修改)

7. 规则要点

7.1 入站(input)

  • 允许 lo 回环。
  • 丢弃所有来自 veth-unt-host(不可信 netns)到宿主机的包。
  • 允许已建立连接。
  • 允许源 IP 为 ADMIN_IP(默认 192.168.122.250)访问 TCP 10822(SSH)、10922(VNC)。
  • 允许 TCP 9000-9009
  • 允许有限 ICMP echo-request。

7.2 转发(forward)

  • 默认 accept,避免破坏 Docker / K8s / containerd 等已有转发。
  • 禁止不可信 netns 访问 RFC1918 私网(10/8、172.16/12、192.168/16、127/8、169.254/16)。
  • 可选:进一步限制只允许 80/443/53。

7.3 NAT

  • 对源地址为 10.200.1.0/24(不可信 netns 子网)的流量做 masquerade
  • 不影响宿主机其他流量。

7.4 管理入口加固

修改 SSH / VNC 端口:

bash
sudo ./change-host-ports.sh

限制仅允许 Jumpserver IP 访问 SSH / VNC:

bash
# 使用默认 IP 192.168.122.250
sudo ./restrict-admin-ip.sh

# 或指定其他 IP / 子网
sudo ./restrict-admin-ip.sh 192.168.122.250
sudo ./restrict-admin-ip.sh 192.168.122.0/24

修改前请确认当前连接源 IP 正确,否则可能把自己锁在 SSH 外面。

8. 可选增强

层级方案说明
文件系统bubblewrap / firejail限制不可信应用只能访问下载目录、临时目录
系统调用seccomp-bpf禁止不必要的 syscall,如 ptracemount
MACAppArmor profile限制程序读/写/执行路径
资源cgroup v2限制 CPU、内存、IO,防止 DoS
DNS本地 DNS over HTTPS防止 DNS 劫持/泄露

示例 Bubblewrap 叠加(可选):

bash
bwrap \
  --unshare-all --share-net \
  --tmpfs /tmp --bind "$HOME/Downloads/untrusted" "$HOME/Downloads" \
  --ro-bind /etc/resolv.conf /etc/resolv.conf \
  --proc /proc --dev /dev \
  google-chrome --incognito

注意:--share-net 需要配合本方案的 netns 使用;若直接用 bwrap 的 --unshare-net 则无法联网。

9. 开机自启(可选)

bash
sudo cp untrusted-netns.service /etc/systemd/system/
sudo cp untrusted-netns-setup.sh /usr/local/bin/
sudo chmod +x /usr/local/bin/untrusted-netns-setup.sh
sudo systemctl daemon-reload
sudo systemctl enable --now untrusted-netns

10. 回滚

bash
cd /home/xxx/docs/security/host-isolation
sudo ./rollback.sh

回滚后如需恢复 UFW:

bash
sudo systemctl enable --now ufw

11. 注意事项与限制

  1. X11/Wayland:隔离应用仍能连接当前用户的 X/Wayland 服务。如需进一步隔离,使用 firejail --x11=xephyr 或 Wayland 嵌套 compositor。
  2. PulseAudio / PipeWire:隔离应用默认可与本机音频服务通信(通过 socket)。如不需要,可在 run-untrusted.sh 中取消 PULSE_SERVER 等变量。
  3. DNS:不可信 netns 默认使用 1.1.1.18.8.8.8。若网络仅允许内网 DNS,请编辑 /etc/netns/untrusted/resolv.conf 并在 nftables.conf forward 链中放行对应 DNS IP。
  4. IPv6:不可信 netns 中已禁用 IPv6,避免绕过 IPv4 规则。
  5. Docker/K8sforward 默认 accept,不会破坏现有容器/ Pod 转发;但 input 默认 drop,若 K8s NodePort 使用 9000-9009 以外的端口,请补充放行。
  6. 权限run-untrusted.sh 需要 root 来进入 netns,进入后会 runuser 回原用户运行应用,避免应用以 root 运行。

12. 故障排查

现象排查
隔离应用无法联网sudo ip netns exec untrusted ping 1.1.1.1;检查 nft list ruleset 是否有 NAT;检查默认路由 ip netns exec untrusted ip route
宿主机 9000 端口被外部拒绝sudo nft list chain inet filter input;确认 tcp dport 9000-9009 accept 存在;确认服务监听 0.0.0.0127.0.0.1
隔离应用能访问内网检查 forward 链中 ip daddr @private_nets drop 是否生效;nft list ruleset
无法进入 netns检查是否已运行 untrusted-netns-setup.sh,或 systemd 服务状态 systemctl status untrusted-netns