调试nftables针对无root权限Podman容器的出站拦截规则失效问题
调试无root Podman容器nftables cgroupv2规则的方法
1. 验证cgroup路径与层级匹配
- 核对层级参数
level 5的准确性:执行stat -c %N /sys/fs/cgroup/user.slice/user-1001.slice/user@1001.service/nomad.slice/libpod-987157aff0dfe097a3fd90f09bd665fff553740c83856d961644224f0f81804d.scope,从根cgroup(level 0)开始数目标cgroup的层级数,确保level 5与实际层级一致。 - 尝试省略层级参数,直接使用完整cgroup路径修改规则:
socket cgroupv2 "user.slice/user-1001.slice/user@1001.service/nomad.slice/libpod-987157aff0dfe097a3fd90f09bd665fff553740c83856d961644224f0f81804d.scope" drop
2. 确认容器进程的cgroup归属
- 主机端执行
podman inspect <容器ID> | grep CgroupPath,获取容器的官方cgroup路径,与规则中的路径完全比对(包括特殊字符、大小写)。 - 进入容器网络命名空间(执行
podman unshare nsenter -t <容器PID> -n),查看进程cgroup:cat /proc/self/cgroup,确认容器内进程的cgroup路径与主机端路径对应一致。
3. 测试规则匹配逻辑
- 在output链最前端添加基础计数规则,验证流量是否经过该链:
观察计数器是否增长,确认数据包流转路径正常。counter accept - 改用cgroup inode替代路径:先获取目标cgroup的inode号
stat -c %i /sys/fs/cgroup/目标路径,修改规则为:socket cgroupv2 inode <inode数值> drop - 检查nftables版本:执行
nft --version,确保版本在0.9.8及以上,老版本对cgroupv2支持存在已知bug。
4. 排查无root用户权限限制
- 检查目标cgroup的访问权限:
ls -ld /sys/fs/cgroup/目标路径,确保当前无root用户拥有读权限。 - 在容器网络命名空间内执行
nft monitor trace,同时添加跟踪规则:
查看是否有数据包匹配该规则的跟踪日志。nft add table ip trace; nft add chain ip trace trace_chain { type filter hook output priority -150; policy accept; } nft add rule ip trace trace_chain socket cgroupv2 "你的cgroup路径" meta nftrace set 1
5. 数据包路径跟踪
- 在容器网络命名空间内用tcpdump抓包:
tcpdump -i eth0 host 8.8.8.8,同时在容器内执行ping 8.8.8.8,对比tcpdump的发包记录与nftables计数器,判断规则是否拦截了数据包。
内容的提问来源于stack exchange,提问作者psbz
相关产品推荐
相关产品推荐

