【问题标题】:create iptables rule per process/service为每个进程/服务创建 iptables 规则
【发布时间】:2011-05-17 21:10:39
【问题描述】:

是否可以使用 iptables 来允许由“进程”发起的流量,即使用进程名称?例如,我想允许由 ping 命令启动的所有内容。

【问题讨论】:

    标签: linux iptables


    【解决方案1】:

    看起来 owner iptables 模块就是您想要的。首先,检查它是否在您的系统中可用:

    iptables -m owner --help
    

    您可以在这里阅读更多内容:http://www.frozentux.net/iptables-tutorial/iptables-tutorial.html#OWNERMATCH

    【讨论】:

    • Owner 只允许您匹配拥有该进程的用户或组,而不是进程名称本身。 (cmd-owner 标志似乎已被删除)。
    • @MikeLundy:向您的系统添加一个组(我自己使用nonet),然后向您的输出链添加一条规则,如下所示:-A OUTPUT -m owner --gid-owner nonet -j REJECT --reject-with icmp-net-unreachable 运行您事先知道的程序你想阻止,用 sg (sg nonet "your_prog your_args")。
    • 如果不支持,则control groups 是解决方案。设置起来非常困难,但有标准的内核支持。它需要可以手动构建的 iptables 1.6。我将发布一个关于如何将应用程序设置和标记到 cgroup 并让 iptables 识别它的答案。
    • @Bgs 谢谢你的想法!我注意到你也需要 ip6tables。我发布了我的食谱作为答案。
    【解决方案2】:
    -m owner --pid-owner PID
    

    http://linuxpoison.blogspot.com/2010/11/how-to-limit-network-access-by-user.htmlhttp://linux.die.net/man/8/iptables

    请注意,您需要 ipt_owner 模块,因为 xt_owner 不支持 --pid-owner。

    例如(这只是一个近似值)

    #!/bin/bash
    $@ &
    iptables -m owner --pid-owner %1 -j REJECT
    

    但实际上,您最好使用 --uid-owner 和 --gid-owner。首先,--pid-owner 标准仅匹配确切的 pid,这意味着您的程序可以轻松生成不会被此规则阻止的子进程。 (至少我没有读过其他内容。)其次,iptables(8) 警告 --pid-owner 在 SMP 系统上已损坏(这可能适用于您,也可能不适用于您,但在任何一种情况下都会限制可移植性)。第三,上面的脚本中有一个竞态条件,因为进程在被阻塞之前就已经启动了。 (如果有办法在进程启动之前获取它的 pid,那我从来没有听说过。)

    【讨论】:

      【解决方案3】:

      如果有办法在进程启动之前获取它的 pid,那么我从未听说过。

      您可以编写一个包装器,它首先分叉,然后添加规则并执行进程(假设您正在运行的程序不会再次分叉),因为 exec(3) 调用不会更改 PID。

      /* NOTE this contains zero error checking */
      int main(int argc, char **argv) {
          /* Eat argv[0] the name of the wrapper script */
          argv++;
          argc--;
      
          pid_t my_pid = getpid();
      
          char *iptables_cmd = NULL;
          asprintf(&iptables_cmd, "/sbin/iptables -A INPUT -m owner --pid_owner %d -j ACCEPT", my_pid);
      
          system(iptables_cmd);
      
          execv(argv[0], argv);
      }
      

      【讨论】:

        【解决方案4】:

        基于@Bgs 的回答,我会这样做:

        1. 添加一个新的系统组,例如。 snitch
        sudo addgroup --system snitch
        
        1. 将自己添加到该组,这样您就不会被要求输入密码来运行设置为主要组的进程:
        sudo adduser $USER snitch
        
        1. 添加 IPv4 和 IPv6 规则以记录并拒绝属于该组的进程生成的任何数据包:
        sudo iptables  -A OUTPUT -m owner --gid-owner snitch -j LOG --log-prefix 'Snitch: '
        sudo ip6tables -A OUTPUT -m owner --gid-owner snitch -j LOG --log-prefix 'Snitch: '
        sudo iptables  -A OUTPUT -m owner --gid-owner snitch -j REJECT
        sudo ip6tables -A OUTPUT -m owner --gid-owner snitch -j REJECT
        
        1. 在内核消息上打开一个tail watch:
        dmesg -w
        
        1. 使用sg 或任何其他类似方式启动您的目标进程:
        sg snitch 'your target program'
        

        【讨论】:

        • 按组而不是按用户生成/过滤有什么优势?
        • @fabiomaia 优点是能够运行访问您的文件和主目录的进程,而不是其他用户的进程。您想要控制他们的网络通信以及他们的子进程的网络通信,而不是您启动的其他进程的网络通信。例如,考虑阻止对某个程序的所有网络访问(您可能无权运行 :-) 或将特定浏览器隧道连接到 VPN,同时保持所有其他进程不变。
        • @fabiomaia 请注意,这不是超级安全:如果目标程序知道这个技巧,它可以恢复它自己的主组(使用 sg 使用的相同系统调用),从而得到出狱。但我从未见过这样做的程序。
        【解决方案5】:

        关于 iptables https://fr.wikipedia.org/wiki/Iptables 的法语维基百科页面指出,使用 --pid-owner 或 --cmd-owner 过滤的可能性已从内核 2.6.14 开始删除......并链接到我无法访问的内核更改日志'不要检查这个断言,因为我不是内核内部结构的专家!

        对应的英文页面没有详细说明。

        使用 UID/GID 过滤仍然有效。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2013-09-05
          • 2018-02-20
          • 2014-11-29
          • 1970-01-01
          • 1970-01-01
          • 2012-08-31
          • 1970-01-01
          • 2014-11-13
          相关资源
          最近更新 更多