如何控制每个程序的互联网访问?

我想使用一款软件来控制哪些程序可以连接到互联网。我知道这种行为与"防火墙"这个词有关,但是一些Linux用户如果有人要求个人防火墙会非常不高兴。我不想通过要求这样的程序来让你不高兴。
我不想要在Windows上使用"安全端口"或者其他个人防火墙承诺的功能。我查看了iptables,但它不符合我的要求。

我在这里看到了一个很好的答案("如何阻止Wine应用程序访问互联网"),但设置起来非常不方便。

是否有一款软件可以询问每个程序是否可以访问互联网?


在Mac上有一个叫做Little Snitch的软件可以做到这一点。我想Windows版本也是有的... - Alvar
12个回答

我找到了一个方便的解决方案来解决这个问题。你可以创建一个永远不能使用互联网的组,并将程序作为该组的成员启动。
  1. 创建一个名为no-internet的组。请不要加入该组。

    sudo addgroup no-internet
    
  2. 向iptables添加规则,阻止属于no-internet组的所有进程使用网络(使用ip6tables还可以阻止IPv6流量)

    sudo iptables -A OUTPUT -m owner --gid-owner no-internet -j DROP
    
  3. 执行sudo -g no-internet YOURCOMMAND而不是YOURCOMMAND
你可以轻松地编写一个使用sudo的包装脚本。通过添加一行代码,你可以摆脱密码提示。
%sudo     ALL=(:no-internet)      NOPASSWD: ALL

或者,类似于sudo visudo的东西
使用iptables-saveiptables-restore来持久化防火墙规则。

1我尝试了你的指南,sudo -g no-internet firefox 比默认的连接速度更快。但是它并没有起作用。 - kenn
2@kenn 我只能说在这里它运行得很好。我猜你在创建规则时可能做错了什么。可能是没有保存规则,没有将脚本设置为可执行,或者类似的问题。 - Tim
我重新启动并再次应用了上述规则,但没有成功。 - kenn
对我来说,这是sudo iptables -A OUTPUT -m owner --gid-owner no-internet -j DROP,需要使用sudo - Klesun
2对我来说非常完美,甚至在Firefox上也能使用。谢谢! - Kostanos
太好了。我讨厌那些需要安装额外软件等解决方案。 - callmebob
2这对我来说似乎也不起作用,在Ubuntu 19.04上。为了允许更改在重新启动之间保存,我确实需要安装iptables-persistent。(所以你可能想把这个添加到上面的解决方案中)。然而,sudo -g no-internet firefox并不能限制Firefox访问互联网。从概念上讲,这个解决方案似乎应该有效。有没有什么基本的东西被忽视了?例如,我们需要设置ipv4和ipv6两者才能使其工作吗? - Enterprise
更好的选择是在您的iptables规则中将gid更改为root,然后设置一个允许规则,可以使用sudo来允许访问或定期将该组应用于进程的文件(如果需要)。考虑将其默认设置为黑名单,并将允许的进程列入白名单,而不是选择加入黑名单。 - Dwight Spencer
有没有等价的nftables? - Pedro Gimeno
根据iptables-translate的说法,NFTables的等效命令是:nft add rule ip filter OUTPUT skgid "$(getent group no-internet|cut -f3 -d:)" counter drop - Pedro Gimeno
еҰӮд»ҠпјҢдҪ еҸҜиғҪиҝҳйңҖиҰҒдҪҝз”Ёзұ»дјјsudo ip6tables -A OUTPUT -m owner --gid-owner no-internet -j DROPзҡ„е‘Ҫд»ӨжқҘдёәIPv6жү§иЎҢжӯӨж“ҚдҪңпјҢ并дҪҝз”Ёsudo service netfilter-persistent saveдҪҝе…¶жҢҒд№…еҢ–пјҲеңЁе®үиЈ…netfilter-persistentиҪҜ件еҢ…еҗҺпјүгҖӮ - Tey'
嗨!如果我只想允许具有互联网权限的组,我应该这样做:sudo iptables -A OUTPUT -m owner !--gid-owner has-internet -j DROP,当我执行sudo -g has-internet YOURCOMMAND(例如sudo -g has-internet ping somerandomsite.com)时无法连接...为什么?我应该加入has-internet组吗?在规则中是否应该使用--suppl-groups选项?谢谢!!!! - codeispoetry
PS我创建了一个新问题:https://askubuntu.com/posts/1458243/edit - codeispoetry

注意:Douane已不再积极开发,并据报道在较新的Ubuntu版本中无法正常工作。出于历史原因,此解决方案可能无效,但答案保持不变。
如果您仍在寻找这种类型的应用程序,我目前正在开发完全符合您需求的应用程序:http://douaneapp.com/ https://gitlab.com/douaneapp/Douane 我的应用程序会阻止任何未知应用程序(授权应用程序的新版本将被阻止),并询问您是否允许或拒绝其流量。
请查看网站;-)

screen shot


酷!我还看了ppa,但是没有找到包,尽管应用程序在那里创建了。 另外,我想知道它是否能显示将IP解析为可读的网站名称? 而且,我打算按照编译说明进行操作,我在那里看到了很多针对Ubuntu依赖包的提示,我将使用checkinstall来创建我本地的.deb包副本,以便轻松管理升级(删除/安装)。 或许checkinstall也可以用来创建你的发行版本,我认为。 - Aquarius Power
你可以在Github上提出功能请求(https://github.com/Douane/Douane/issues):) - ZedTuX
2嗯,看起来正是我需要的!但是我在Ubuntu上找不到安装它的软件包。 - azerafati
还没有Ubuntu的软件包吗? - Anwar
没有人向我咨询Ubuntu的问题,真是遗憾啊 :( - ZedTuX
@ZedTuX,你能制作一个Ubuntu软件包吗? - user595510
抱歉,@MarkYisri,我不是一个打包者,但我非常乐意帮助任何人在任何类型的软件包管理器中打包Douane。 - ZedTuX
@ZedTuX 给我一点时间来处理这个,如果将其转换为可构建的软件包不太复杂,我会在 PPA 上自动运行一些测试编译;如果一切都符合您的要求,那么您可以直接指向该 PPA。 (我有几种不同程序的工作流程,因此开发自动化工作流程不是问题呵呵)。 - Thomas Ward
@ThomasWard 嗨,很高兴看到你的消息!请随意在 Github 上开一个问题,这样我就可以更好地跟踪你的进展。 - ZedTuX
@ZedTuX 我离准备好的包裹还有很远的距离,毕竟我还有很多事情要处理呢。 - Thomas Ward
@ZedTuX是Douane被放弃了吗?网站返回5xx的http状态码,在Gitlab上所有东西(如安装文档)都指向不存在的github链接。顺便说一下,如果deb包太麻烦的话,可以考虑打包成appimage/flatpack/snap格式。 - Pablo Bianchi
你好 @PabloBianchi。很抱歉出现了这些问题。我以一种相当快速和简单的方式迁移到了Gitlab。此外,我所有的网站都已经关闭,因为我需要一些时间来修复它们,但Douane并没有被放弃,只是我没有足够的时间(要照顾孩子;)但如果有人开放PR或问题,我会随时提供帮助!感谢您的评论和对Douane的关注!!;-) - ZedTuX
我修复了README.md文件中的损坏链接。 - ZedTuX
1Douaneapp.com又回来了! :) - ZedTuX
尽管如此,我仍然需要在网站上更新一个链接,以便指向Gitlab。 - ZedTuX
新的网站已经上线,所有链接都已修复,还新增了一个“路线图”部分。此外,我还推出了全新的安装程序,只需点击一次(下一步按钮),就可以自动完成Douane的安装。 - ZedTuX
@ZedTuX 关于冻结错误,已经解决了吗?我打算在Ubuntu 18.04上安装它。 - darksoulsong
1嘿 @darksoulsong,我还在努力工作,但时间非常有限,很不幸。加入我们的 https://gitter.im/Douane/General?utm_source=share-link&utm_medium=link&utm_campaign=share-link 以获取最新信息! - ZedTuX

另一个选择是firejail。它在沙盒中运行应用程序,您可以控制应用程序是否能够访问网络。
firejail --net=none firefox

这个命令将启动没有网络访问的Firefox浏览器。 请注意,Ubuntu软件源中的firejail发行版已经过时了 - 最好从firejail官方网站下载最新的LTS版本。

1非常轻巧且非常实用。感谢分享! - Exterminator13

在德国Ubuntu论坛上有一个Perl脚本通过Google翻译成英文),似乎可以实现这个功能。我从未尝试过,也没有仔细查看过脚本,但也许对你有用。描述只有德文,所以你可能需要一个翻译服务(比如Google翻译;见上文)。

我会看一下。这很有趣,可能是合适的工具。不幸的是,没有图形用户界面,但这不应该阻止我 :) - guerda

在另一个用户下运行程序将使用该用户的配置文件而不是您自己的。
以下是一种解决方案,不需要修改防火墙规则,并在相同的用户下(通过sudo)以修改后的环境运行,其中您的用户是my_user,您想要运行的应用程序是my_app:
# run app without access to internet
sudo unshare -n sudo -u my_user my_app

更多详细信息请参见man unsharethis answer

Linux图形界面防火墙

如果你正在寻找一个图形界面防火墙,我在OpenSnitch上取得了良好的结果——它尚未在Ubuntu软件仓库中,并且我不会称其为生产级别,但是按照github页面上的构建步骤对我有效。


Ubuntu已经有一个防火墙ufw,但默认情况下是禁用的。您可以通过命令行或其前端gufw启用和使用它,该前端可以直接从Ubuntu软件中心安装。

如果您需要阻止特定应用程序的互联网访问,您可以尝试LeopardFlower,它仍处于测试版,并且不在Ubuntu软件中心提供:


@psusi: 我真的希望人们不要散布错误和无用的信息。IPTables可以做到这一点,所以我不认为这是“鲁莽”的。只是因为不理解使用情况而说“不行”有点狭隘。http://www.debian-administration.org/article/120/Application_level_firewalling 编辑 bodhi.zazen
注意 - 这个选项在2005年从IPTABLES中删除,比这个回答发布的时间早了8年。http://www.spinics.net/lists/netfilter/msg49716.html

commit 34b4a4a624bafe089107966a6c56d2a1aca026d4 Author: Christoph Hellwig Date: Sun Aug 14 17:33:59 2005 -0700

[NETFILTER]: Remove tasklist_lock abuse in ipt{,6}owner

Rip out cmd/sid/pid matching since its unfixable broken and stands in the way of locking changes to tasklist_lock.

Signed-off-by: Christoph Hellwig <hch@xxxxxx>
Signed-off-by: Patrick McHardy <kaber@xxxxxxxxx>
Signed-off-by: David S. Miller <davem@xxxxxxxxxxxxx>

2对于考虑举报此事的任何人:这不应该是一条评论,而是回答了提出的问题。@user141987我确实建议您扩展一下,提供有关如何设置iptables以实现每个应用程序限制的更多信息。然而,我建议在您的回答中包含重要信息(并仍然提供链接供参考)。 - Eliah Kagan
2iptables 不通过应用程序进行过滤。 - Panther
那篇文章似乎是错误信息,因为没有这样的选项。过去要求创建这样一个选项的请求被拒绝的原因是因为它本质上是不可靠的;一个应用程序可以简单地更改其名称。 - psusi
3@psusi你是说“如果你的内核是使用CONFIG_IP_NF_MATCH_OWNER编译的,那么你可以配置你的iptables防火墙以允许或拒绝基于每个命令的数据包”这是不正确的吗?还是只是大多数内核不包含这个选项?如果这是不正确的,是否有相关信息的来源来驳斥它?(请注意,针对应用程序的防火墙限制的主要目的并不是为了使运行不受信任的应用程序变得完全安全。主要目的是给用户提供除应用程序内置配置选项之外的一定程度的控制。) - Eliah Kagan
这个选项在2005年从内核中移除,比这个回答给出的时间早了8年 - http://www.spinics.net/lists/netfilter/msg49716.html,并且尽管有相反的说法,但是不准确,你不能使用iptables进行应用程序过滤。 - Panther

我发现这里发布的解决方案非常好。它涉及创建一个允许互联网访问的用户组,并设置防火墙规则,只允许该组成员访问。应用程序要想访问互联网,唯一的方式就是由该组的成员运行。你可以通过使用sudo -g internet -s命令在该组下运行程序。

简要总结上述链接中的帖子内容:

  1. 在终端中键入以下命令来创建“internet”组:sudo groupadd internet
  2. 确保将要运行下面脚本的用户已添加到/etc/group文件的sudo组中。如果您修改了该文件,则需要注销并重新登录,然后下面的脚本才能正常工作。
  3. 创建一个包含以下内容的脚本,并运行它:
    #!/bin/sh
    # 防火墙应用程序 - 仅允许从“internet”组运行的应用程序运行
    
    # 清除先前的规则
    sudo iptables -F
    
    # 接受internet组的数据包
    sudo iptables -A OUTPUT -p tcp -m owner --gid-owner internet -j ACCEPT
    
    # 还要允许本地连接
    sudo iptables -A OUTPUT -p tcp -d 127.0.0.1 -j ACCEPT
    sudo iptables -A OUTPUT -p tcp -d 192.168.0.1/24 -j ACCEPT
    
    # 拒绝其他用户的数据包
    sudo iptables -A OUTPUT -p tcp -j REJECT
    
    # 开启带有internet访问权限的终端
    sudo -g internet -s
    
  4. 通过运行上述脚本,您将获得一个可以运行具有互联网访问权限的应用程序的终端。
请注意,此脚本不会保存和恢复您的防火墙规则。您可能希望修改脚本以使用iptables-saveiptables-restore shell命令。

无论好坏,Linux采用了一种不同的方法。没有简单的图形界面来提供这个功能。关于这个话题在互联网上有很多讨论,如果你谷歌搜索,你可以找到一些有趣的讨论。虽然辩论很有趣,但迄今为止还没有一个专门的程序员团队愿意编写和维护这个功能。
在Linux中提供这个功能的工具有Apparmor、Selinux和Tomoyo。
这些工具都不是特别容易学习,而且都有优点和缺点。个人而言,我更喜欢SELinux,尽管SELinux的学习曲线较陡。
参见:

http://www.linuxbsdos.com/2011/12/06/3-application-level-firewalls-for-linux-distributions/

有一个应用程序已经被提及过了,叫做leopardflower。我不确定它的状态/维护情况。

试试豹花吧。它有图形用户界面和应用程序限制。