是否可以阻止单个进程的(传出)网络访问?
localhost
(到同一台计算机)使用网络访问来完成其工作。
是否可以阻止单个进程的(传出)网络访问?
localhost
(到同一台计算机)使用网络访问来完成其工作。
Answers:
使用Linux 2.6.24+(在2.6.29之前被认为是实验性的),您可以为此使用网络名称空间。您需要CONFIG_NET_NS=y
使用该unshare
工具在内核()和util-linux中启用“网络名称空间” 。
然后,启动没有网络访问权限的过程非常简单:
unshare -n program ...
这将为该进程创建一个空的网络名称空间。也就是说,它在没有网络接口的情况下运行,包括没有环回。在下面的示例中,仅在将当前有效用户和组ID映射到超级用户ID后,才添加-r以运行程序(避免使用sudo):
$ unshare -r -n ping 127.0.0.1
connect: Network is unreachable
如果您的应用需要网络接口,则可以设置一个新接口:
$ unshare -n -- sh -c 'ip link set dev lo up; ping 127.0.0.1'
PING 127.0.0.1 (127.0.0.1) 56(84) bytes of data.
64 bytes from 127.0.0.1: icmp_seq=1 ttl=32 time=0.066 ms
请注意,这将创建一个新的本地环回。也就是说,产生的进程将无法访问主机的开放端口127.0.0.1
。
如果需要访问名称空间内的原始网络,则可以使用nsenter
来输入其他名称空间。
以下示例ping
与PID 1使用的网络名称空间一起运行(通过来指定-t 1
):
$ nsenter -n -t 1 -- ping -c4 example.com
PING example.com (93.184.216.119) 56(84) bytes of data.
64 bytes from 93.184.216.119: icmp_seq=1 ttl=50 time=134 ms
64 bytes from 93.184.216.119: icmp_seq=2 ttl=50 time=134 ms
64 bytes from 93.184.216.119: icmp_seq=3 ttl=50 time=134 ms
64 bytes from 93.184.216.119: icmp_seq=4 ttl=50 time=139 ms
--- example.com ping statistics ---
4 packets transmitted, 4 received, 0% packet loss, time 3004ms
rtt min/avg/max/mdev = 134.621/136.028/139.848/2.252 ms
unshare -n
似乎在没有root
特权的情况下抛出“不允许操作” ,我对此有何遗漏?
sudo unshare -n
继承了根权限。因为我需要sudo来调用unshare,所以我想知道如何确保被调用程序没有root权限。
sudo unshare -n sudo -u dude bash -c 'echo Hello, my name is $USER'
@ThorSummoner bbs.archlinux.org/viewtopic.php?id=205240
Linux具有称为网络名称空间的功能,该功能实际上使您可以在同一台计算机上具有多个网络堆栈,并在运行该程序时将其分配给程序。这是通常用于容器的功能,但是您也可以使用它来完成所需的操作。
该ip netns
子命令管理它。创建一个无法访问任何内容的新网络名称空间很容易,这是新名称空间的默认状态:
root@host:~# ip netns add jail
现在,如果您切换到该名称空间,则可以非常轻松地对其进行配置。您可能想要在其中显示lo,就是这样:
root@host:~# ip netns exec jail /bin/bash
root@host:~# ip addr add 127.0.0.1/8 dev lo
root@host:~# ip link set dev lo up
root@host:~# exit
现在,当您想在没有网络的情况下运行命令时,只需在该监狱中运行它即可:
root@host:~# ip netns exec jail su user -c 'ping 8.8.8.8'
connect: Network is unreachable
根据需要,该网络不可访问。(您可以做各种有趣的事情,因为单独的网络堆栈包括iptables
规则等)
sudo ip
执行ip命令,但是一旦我进入bash,我只是执行su someuser
了一个操作,以获取用户'someuser'的无特权外壳。
您可以使用iptables并将该进程移至cgroup中:
mkdir /sys/fs/cgroup/net_cls/block
echo 42 > /sys/fs/cgroup/net_cls/block/net_cls.classid
iptables -A OUTPUT -m cgroup --cgroup 42 -j DROP
echo [pid] > /sys/fs/cgroup/net_cls/block/tasks
/sys/fs/cgroup/net_cls/tasks
(路径中没有“阻止”)
您可以使用firejail沙箱(应在具有seccomp功能的内核上运行)。
要使用它就做
firejail --noprofile --net=none <path to executable>
--noprofile
禁用默认沙箱,
--net=none
禁用网络
我确实相信大多数发行版确实已经提供了软件包,但是即使发行版不发行,除构建工具链和启用了名称空间/ seccomp的内核外,firejail实际上也没有任何依赖性。
firejail还有其他一些不错的功能,可以在firejail --help
联网方面显示出来(例如仅提供回送接口或阻止ip / dns等),但这应该可以完成工作。另外,它doesn't require root
。
您不能仅凭iptables做到这一点。此功能暂时存在,但无法使其可靠运行并被放弃。
如果您可以使用专用用户ID运行该进程,则iptables可以通过以下owner
模块执行该操作:
iptables -A OUTPUT -m owner --uid-owner 1234 -j DROP
请参阅Iptables中的示例:将输出流量与conntrack和owner匹配。使用奇怪的drops,iptables / pf规则仅允许XY应用程序/用户使用?
如果您可以在其自己的容器中运行该进程,则可以独立对该容器进行防火墙保护(甚至使其完全与网络断开连接)。
安全模块可以过滤进程对网络功能的访问。warl0ck的答案给出了AppArmor的示例。
解决方案1:防火墙:
我们可以使用防火墙等Douane或Opensnitch但这些应用程序是不是100%有效的或处于发展的早期阶段(有很多的bug等,2019年的)
解决方案2:内核MAC:
内核MAC可以用作防火墙,其中最著名的是Tomoyo,Selinux和Apparmor。 这种解决方案在稳定性和效率方面是最好的解决方案(防火墙解决方案),但是大多数情况下设置起来有些复杂。
解决方案3:Firejail:
Firejail可用于阻止不需要root用户的应用程序的网络访问,任何用户都可以从中受益
firejail --noprofile --net=none command-application
解决方案4:取消共享
Unshare可以在没有网络的情况下以不同的名称启动应用程序,但这需要root firejail的解决方案可以做几乎完全相同的事情,但不需要root
unshare -r -n application-comand
解决方案5:代理:
一种解决方案是将应用程序代理为空/伪代理。我们可以使用tsocks或proxybound。这是有关设置的一些详细信息
解决方案6:Iptables:
iptables是另一个简单的解决方案,可以将其设置为阻止应用程序
groupadd no-internet
grep no-internet /etc/group
useradd -g no-internet username
usermod -a -G no-internet userName
检查:sudo groups userName
nano /home/username/.local/bin/no-internet
chmod 755 /home/username/.local/bin/no-internet
#!/bin/bash
sg no-internet "$@"
iptables -I OUTPUT 1 -m owner --gid-owner no-internet -j DROP
4.进行检查,例如在Firefox上运行:
no-internet "firefox"
5.万一您想例外并允许程序访问本地网络:
iptables -A OUTPUT -m owner --gid-owner no-internet -d 192.168.1.0/24 -j ACCEPT
iptables -A OUTPUT -m owner --gid-owner no-internet -d 127.0.0.0/8 -j ACCEPT
iptables -A OUTPUT -m owner --gid-owner no-internet -j DROP
6.使其永久化
在启动时应用iptables规则的一种方法是使用systemd将规则添加为服务
cat /usr/lib/systemd/system/nonet.service
[Unit]
Description=Nonet group iptable update
After=network.target
After=xsession.target
After=iptables.service
After=shorewall.service
[Service]
Type=oneshot
RemainAfterExit=true
StandardOutput=journal
ExecStart=/bin/bash /home/user/Scripts/Nonet.iptables.sh
sg no-internet
。
您可以使用seccomp-bpf阻止某些系统调用。例如,可能想阻止socket
系统调用,以防止进程创建套接字FD。
我写了一个此方法的示例,该示例阻止socket
使用libseccomp 进行系统调用。摘要为(不检查错误):
scmp_filter_ctx ctx = seccomp_init(SCMP_ACT_ALLOW);
seccomp_arch_add(ctx, SCMP_ARCH_NATIVE);
seccomp_rule_add(ctx, SCMP_ACT_ERRNO(EACCES), SCMP_SYS(socket), 1, SCMP_CMP(0, SCMP_CMP_EQ, pf));
seccomp_load(ctx);
execvp(argv[1], argv+1);
这不需要root特权。
但是,完整的沙箱要复杂得多,因此您不应使用此un命令来阻止非合作/恶意程序。