我们在 Linux docker 容器上运行我们的 java 软件构建,我修改了我们的集成测试管道以将测试执行包装在 nsjail 内部,它看起来像这样:
nsjail -Mo --chroot / --user root --group root --disable_rlimit -- /bin/sh -c "our integration test execution goes here"
这样做的原因是隔离这些测试的网络,以便它们可以并行运行,并且仍然绑定到可能相同的端口。这种方法效果很好,性能提升也很大。
但是(当然有一个但是)我在被监禁的进程中没有任何传出网络访问权限。我以为被监禁的进程会有某种桥接(不确定这是否是术语)网络,但我似乎错了。
有没有什么办法可以让 nsjailed 进程获得这种网络访问权限?
答案1
这只是一个部分答案因为我不太明白这些选项之间的区别。它概述了选项,但对我来说,只有最后一个有效。
nsjail --help
向我们展示
--macvlan_iface|-I VALUE
Interface which will be cloned (MACVLAN) and put inside the subprocess' namespace as 'vs'
--macvlan_vs_ip VALUE
IP of the 'vs' interface (e.g. "192.168.0.1")
--macvlan_vs_nm VALUE
Netmask of the 'vs' interface (e.g. "255.255.255.0")
--macvlan_vs_gw VALUE
Default GW for the 'vs' interface (e.g. "192.168.0.1")
# I guess that "GW" means Gateway
--macvlan_vs_ma VALUE
MAC-address of the 'vs' interface (e.g. "ba:ad:ba:be:45:00")
您可以找到一个例子在 nsjail github 上。访问链接查看输出。请注意,这“需要 root/setuid”。
sudo ./nsjail --user 9999 --group 9999 --macvlan_iface eth0 --chroot /chroot/ -Mo --macvlan_vs_ip 192.168.0.44 --macvlan_vs_nm 255.255.255.0 --macvlan_vs_gw 192.168.0.1 -- /bin/sh -i
这些参数有一些默认设置:
/* Parameters for the cloned MACVLAN interface inside jail */
optional string macvlan_iface = 83; /* Interface to be cloned, eg 'eth0' */
optional string macvlan_vs_ip = 84 [default = "192.168.0.2"];
optional string macvlan_vs_nm = 85 [default = "255.255.255.0"];
optional string macvlan_vs_gw = 86 [default = "192.168.0.1"];
optional string macvlan_vs_ma = 87 [default = ""];
optional string macvlan_vs_mo = 88 [default = "private"];
因此,我们主要需要关心--macvlan_iface eth0
使用正确的界面来设置eth0
,并修改任何默认值(如果我们关心的话)。
然而,这并不总是有效。特别是有一个目前未解决的问题其中指出
根据我对 macvlan 的粗略理解,如果适配器是虚拟化的或者允许多个 MAC 地址(例如在 VMWare 或云托管提供商上),则似乎不可能使用它。
--privileged --add-cap="NET_ADMIN"
这也许可以解释为什么即使使用docker 标志和keep:caps: true
nsjail 配置,我也无法让它在我的 docker 容器内工作。
在我的docker容器中也有一个--iface_own
以类似方式失败的选项。
输出--help
还显示选项
--disable_clone_newnet|-N
Don't use CLONE_NEWNET. Enable global networking inside the jail
也用于nsjail 示例使用互联网(正如 andref 的仅链接答案所指出的那样)。事实证明,在配置文件中句法只是clone_newnet: false
。
这次启动 nsjail 成功了,但 jail 内部似乎仍没有名称解析。但是,如果我们也/etc/resolv.conf
像链接示例中那样添加挂载,它就可以正常工作了!
clone_newnet: false
mount {
src_content: "nameserver 8.8.8.8"
dst: "/etc/resolv.conf"
}
但是,请注意,在这种情况下,您从不同的 nsjail 实例监听的端口之间将没有任何分离。
答案2
你可以看看https://github.com/google/nsjail/blob/master/configs/firefox-with-net.cfg其中包含允许 Firefox 在监狱内运行但可以访问互联网的配置。