阻止进程的网络访问?

lar*_*kee 90 linux networking process iptables

是否可以阻止单个进程的(传出)网络访问?

Mic*_*rny 95

对于 Linux 2.6.24+(在 2.6.29 之前被认为是实验性的),您可以为此使用网络命名空间。您需要CONFIG_NET_NS=y使用该unshare工具在内核 ( ) 和 util-linux 中启用“网络名称空间” 。

然后,在没有网络访问权限的情况下启动进程非常简单:

unshare -n program ...
Run Code Online (Sandbox Code Playgroud)

这会为进程创建一个空的网络命名空间。也就是说,它在没有网络接口的情况下运行,包括没有环回。在下面的示例中,我们添加 -r 以仅在当前有效用户和组 ID 映射到超级用户 ID 后才运行程序(避免使用 sudo):

$ unshare -r -n ping 127.0.0.1
connect: Network is unreachable
Run Code Online (Sandbox Code Playgroud)

如果你的应用需要一个网络接口,你可以设置一个新的:

$ 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
Run Code Online (Sandbox Code Playgroud)

请注意,这将创建一个新的本地环回。也就是说,生成的进程将无法访问主机的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
Run Code Online (Sandbox Code Playgroud)

  • `unshare -n` 似乎在没有 `root` 权限的情况下抛出“不允许操作”,我有什么遗漏吗? (8认同)
  • 一个衬里将过程限制为用户。只需 sudo 两次:```sudo unshare -n sudo -u dude bash -c 'echo 你好,我的名字是 $USER'``` @ThorSummoner https://bbs.archlinux.org/viewtopic.php?id=205240 (5认同)
  • 是的。它由切换命名空间后产生的所有子级继承。 (3认同)
  • 我看起来像任何我想取消共享的程序,例如使用`sudo unshare -n` 继承根权限。由于我需要 sudo 来调用 unshare,我想知道如何确保被调用的程序没有 root 权限。 (3认同)

der*_*ert 30

Linux 有一个称为网络命名空间的功能,它允许您在同一台机器上拥有多个网络堆栈,并在运行时将其分配给一个程序。这是通常用于容器的功能,但您也可以使用它来完成您想要的操作。

ip netns子命令管理它。创建一个无法访问任何内容的新网络命名空间很容易,这是新命名空间的默认状态:

root@host:~# ip netns add jail
Run Code Online (Sandbox Code Playgroud)

现在,如果您切换到该命名空间,则可以相当轻松地对其进行配置。你可能想在其中提到 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
Run Code Online (Sandbox Code Playgroud)

现在当你想在没有网络的情况下运行你的命令时,你只需在那个监狱中运行它:

root@host:~# ip netns exec jail su user -c 'ping  8.8.8.8'
connect: Network is unreachable
Run Code Online (Sandbox Code Playgroud)

根据需要,网络无法访问。(您可以做各种有趣的事情,因为单独的网络堆栈包括iptables规则等)


小智 20

您可以使用 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
Run Code Online (Sandbox Code Playgroud)


dai*_*isy 11

是的,使用定制的 apparmor 配置文件,即

/usr/bin/curl {
    ...

    # block ipv4 acces
    deny network inet,
    # ipv6 
    deny network inet6,
    # raw socket
    deny network raw,

}
Run Code Online (Sandbox Code Playgroud)

但是那样的话,您还需要生成一个允许访问的文件列表,整个过程可能有点复杂。并在此处查看帮助文档


Tom*_*ina 10

您可以使用firejail 沙箱(应该适用于具有 seccomp 功能的内核)。

使用它只是做

firejail --noprofile --net=none <path to executable>
Run Code Online (Sandbox Code Playgroud)

--noprofile禁用默认沙箱 --net=none禁用网络

我确实相信大多数发行版确实已经提供了软件包,但即使它们没有 firejail,除了构建工具链和启用命名空间/seccomp 的内核之外,几乎没有任何依赖项。

firejail 还有一些其他不错的功能可以在firejail --help网络方面展示(例如仅提供环回接口或阻止 ip/dns 等),但这应该可以完成工作。还有,它doesn't require root


int*_*ika 9

解决方案 1:防火墙:

我们可以使用防火墙等DouaneOpensnitch但这些应用程序是不是100%有效的或处于发展的早期阶段(有很多的bug等,2019年的)

解决方案 2:内核 MAC:

内核 MAC 可以用作防火墙,最著名的是TomoyoSelinuxApparmor。 这个解决方案在稳定性和效率方面是最好的一个(防火墙解决方案),但大多数时候设置它有点复杂。

解决方案 3:Firejail:

Firejail可用于阻止不需要 root 的应用程序的网络访问任何用户都可以从中受益

firejail --noprofile --net=none command-application
Run Code Online (Sandbox Code Playgroud)

解决方案 4:取消共享

Unshare 可以在没有网络的不同命名空间上启动应用程序,但这需要 root firejail 的解决方案几乎完全相同,但不需要 root

unshare -r -n application-comand
Run Code Online (Sandbox Code Playgroud)

解决方案 5:代理:

一种解决方案是将应用程序代理为空/假代理。我们可以使用tsocksproxybound。这是有关设置的一些详细信息

解决方案 6:Iptables:

另一个简单的解决方案是 iptables,它可以设置为阻止应用程序

  1. 创建、验证新组;将所需用户添加到该组:
    • 创建: groupadd no-internet
    • 证实: grep no-internet /etc/group
    • 添加用户:useradd -g no-internet username

      注意:如果您正在修改已经存在的用户,您应该运行:usermod -a -G no-internet userName 检查:sudo groups userName

  2. 在您的路径中创建一个脚本并使其可执行:
    • 创建: nano /home/username/.local/bin/no-internet
    • 可执行: chmod 755 /home/username/.local/bin/no-internet
    • 内容: #!/bin/bash
                    sg no-internet "$@"

  3. 添加用于删除组no-internet网络活动的iptables 规则
    • iptables -I OUTPUT 1 -m owner --gid-owner no-internet -j DROP

      注意:不要忘记使更改永久化,因此它会在重新启动后自动应用。这样做,取决于您的 Linux 发行版。


   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
Run Code Online (Sandbox Code Playgroud)

  • 这是一本非常出色的指南。谢谢你。尽管对我来说,我的 no-internet 命令似乎从未传递过参数,所以我现在使用的是 `sg no-internet`。 (2认同)

Gil*_*il' 5

单独使用 iptables 是无法做到的。此功能短暂存在,但无法可靠地工作并被放弃。

如果您可以以专用用户 ID 的身份运行该进程,则 iptables 可以使用该owner模块执行此操作:

iptables -A OUTPUT -m owner --uid-owner 1234 -j DROP
Run Code Online (Sandbox Code Playgroud)

请参阅Iptables 中的示例:将传出流量与 conntrack 和所有者匹配。使用奇怪的 dropiptables/pf 规则只允许 XY 应用程序/用户?

如果您可以在其自己的容器中运行该进程,则可以独立地为该容器设置防火墙(甚至使其与网络完全断开连接)。

安全模块可以过滤进程对网络功能的访问。warl0ck 的回答给出了一个 AppArmor 的例子。


归档时间:

查看次数:

56835 次

最近记录:

6 年,1 月 前