linux网络命名空间(netns)提供进程级网络协议栈隔离,含独立lo设备、ip、路由表、iptables规则等;默认仅含未启用的lo,需veth pair桥接宿主机并配置ip和路由方可通信。

Linux 命名空间(Namespace)是实现进程级资源隔离的核心机制,其中 network namespace(netns) 可以让不同服务拥有完全独立的网络协议栈——包括独立的回环设备、IP 地址、路由表、iptables 规则、socket 接口和网络设备列表。这比仅靠防火墙或端口绑定更彻底,真正达成“网络不可见、不可连、不可干扰”。
创建并进入独立网络命名空间
使用 unshare 创建干净的 netns,并在其中启动 shell:
sudo unshare --net --uts --ipc --pid --mount --fork --user --rslave bash
注意:--net 是关键;--user 需配合 /proc/sys/user/max_user_namespaces 开启(默认可能关闭);--fork 和 --pid 确保后续进程在新 PID 空间中运行,避免与 host 进程混杂。
进入后执行 ip link 会只看到 lo(未启用),无 eth0 等外部接口,证明网络栈已清空。
为 netns 配置可通信的网络环境
纯 netns 默认无外部连通能力。需通过虚拟以太网对(veth pair)桥接到宿主机或其他网络:
- 在 host 中创建 veth 对:
sudo ip link add veth-host type veth peer name veth-guest - 将
veth-guest移入目标 netns(假设其 PID 为 1234):sudo ip link set veth-guest netns 1234 - 为 host 端配置 IP 并启用:
sudo ip addr add 192.168.100.1/24 dev veth-host && sudo ip link set veth-host up - 在 netns 内配置另一端:
ip addr add 192.168.100.2/24 dev veth-guest && ip link set veth-guest up && ip link set lo up - 添加默认路由:
ip route add default via 192.168.100.1
此时 netns 已具备完整三层网络能力,且与 host 及其他 netns 的网络完全隔离——除非显式桥接或路由转发开启。
绑定服务到指定 netns 并验证隔离性
有两种常用方式启动服务:
-
启动时指定 netns:用
nsenter进入已有 netns 后执行服务命令,例如:sudo nsenter -t 1234 -n --preserve-credentials /usr/bin/python3 -m http.server 8000 -
启动后迁移进程:先启动服务(如 systemd 服务),再用
sudo nsenter -t $PID -n -U --preserve-credentials -r /bin/bash进入其 netns 调试,确认ss -tln仅显示该 netns 内监听地址
验证隔离:从 host 执行 curl http://192.168.100.2:8000 可通;但换一个 netns(如 unshare --net bash)后执行同样 curl 会失败——因两个 netns 的地址空间、路由、ARP 表全不共享。
持久化与生产注意事项
临时 netns 随进程退出而销毁。生产中建议:
- 用
ip netns管理命名 netns(需创建/etc/netns/NAME/下的 resolv.conf 等配置) - 配合
systemd --scope或systemd-run --scope --scope-netns启动服务,支持自动清理与资源追踪 - 禁用跨 netns 转发:
echo 0 | sudo tee /proc/sys/net/ipv4/conf/all/forwarding(默认即关,但需确认) - 避免容器运行时(如 Docker)干扰:Docker 默认每个容器一个 netns,若手动管理,应避开
docker0网桥和相关 iptables 链
不复杂但容易忽略:netns 本身不提供安全边界,仍需配合 cgroups 限流、seccomp 过滤系统调用、用户命名空间降权,才能构成完整服务隔离方案。











