如何完全屏蔽像 Facebook 这样的网站?

Jos*_*ohn 5 dns iptables

我试图阻止从我的家庭系统 (Ubuntu) 访问 Facebook。我可以将 facebook.com 添加到/etc/hosts,但这只会阻止访问 facebook.com。我可以通过许多其他方式使用 facebook,例如 mbasic.facebook.com、m.facebook.com、touch.facebook.com、IP 地址等。

我想我可以使用浏览器扩展来阻止它,但我更喜欢系统范围的块。我查看了这个问题该问题试图使用 iptables 解决此问题,但没有解决 - 运行此命令后我仍然可以访问 facebook.com(我从 whois 173.252.120.6 | grep CID 获得范围):

sudo iptables -A OUTPUT -p tcp --destination-port 80 -d 173.252.64.0/18 -j REJECT 
Run Code Online (Sandbox Code Playgroud)

所以我的问题本质上是:我如何阻止一个网站,比如 facebook.com,以各种方式(不必是 100% 万无一失),它不能在系统上以任何方式访问?

use*_*ser 4

这取决于您希望该块的万无一失程度,以及您对系统的控制程度。既然您谈论您的“家庭系统”并修改 /etc/hosts,我假设您具有合法的 root 访问权限,并且不需要完全无懈可击。

阻止对整个域的访问的最简单方法是设置本地 DNS“递归解析器”并专门配置这些域。基本上,您设置一个 DNS 服务器(这当然可以在同一主机上运行),将您的本地系统指向它,并告诉该 DNS 服务器返回精心设计的响应,例如,域facebook.com(或称为zone )在 DNS 中)。对于这些,您没有设置地址记录,这将导致任何解析 facebook.com 下的任何主机名的尝试都会返回“找不到主机”。

您可以设置这样的 DNS 服务器来自行完成所有名称解析,或者将其不知道的任何内容(通过其配置)转发到其他 DNS 服务器;后一种配置通常称为“转发”解析器。

这适用于特定域下的所有名称访问(www.facebook.com、m.facebook.com、touch.facebook.com、whatever.somewhere.facebook.com),但不适用于 DNS 中不相关的名称(www.facebook.com、m.facebook.com、touch.facebook.com、whatever.somewhere.facebook.com)。 facebook.example.com 仍然可以使用,如果它转到 Facebook)。它也不会阻止通过 IP 地址进行访问。然而,它确实使得首先查找 IP 地址变得不太容易(host或者nslookup同样会说“未找到”)。

如果这个想法只是为了避免意外浏览特定的已知域,那么这可能就足够了。如果想法是完全阻止访问,那么它就行不通。


要实际进行设置,您首先需要决定是否需要本地的、完全配置的解析器,或者是否需要转发解析器。两者都有优点和缺点,但现在,我将向您展示如何配置转发解析器,因为这更有可能满足您的用例需求。

有许多不同的 DNS 服务器软件包可供使用,但也许 *nix 世界中最知名的(当然是最知名的之一)是 BIND,目前版本为 9。您没有说明您正在运行的 Ubuntu 的确切版本,所以我会确认您正在运行 14.04/trusty,这是当前的 Ubuntu LTS 版本。其他不应有显着差异。

要安装 BIND,请打开终端窗口并发出命令(出现提示时您需要提供密码)

sudo apt-get update
sudo apt-get install -u bind9
Run Code Online (Sandbox Code Playgroud)

查看第二个命令显示的要安装的软件包列表,确保其看起来合理,然后确认安装。

软件本身现已安装,需要进行配置。主要配置文件是/etc/bind/named.conf;在编辑器中打开它(我gedit在这里使用,但任何文本编辑器都可以):

sudo gedit /etc/bind/named.conf
Run Code Online (Sandbox Code Playgroud)

directory下块中设置的值options。然后,将整个配置文件替换为以下内容:

options {
  directory "** PAST VALUE GOES IN HERE **";
  forwarders { ** YOUR UPSTREAM DNS SERVER IPS HERE, SEE BELOW ** };
  forward only;
  allow-transfer { "none"; };
  allow-query { "localhost"; };
  allow-update { "none"; };
};
Run Code Online (Sandbox Code Playgroud)

对于directory,使用过去的值(所以这很可能是,directory "/etc/bind";但不要相信我的话)。

因为forwarders { }格式稍微复杂一些。在这里,按 IP 地址列出您的 ISP(或其他上游)DNS 服务器,每个 IP 地址后跟一个分号。您可能可以在 /etc/resolv.conf 中找到这些内容。请注意,如果您有 NAT 路由器或类似路由器,它完全有可能也提供 DNS 转发服务,如果是这样,您希望在此处使用路由器的 IP 地址。例如,如果您的上游 DNS 服务器是 192.168.100.1 和 192.168.200.1,那么这将变成forwarders { 192.168.100.1; 192.168.200.1; };在括号内部和外部都包含最后的分号(它们有不同的用途,您现在不需要完全理解;只需相信我,他们都需要在那里)。编辑任何 BIND 相关的配置文件后,执行命令sudo rndc reload以触发配置的重新加载。

如果您有严格配置的防火墙,则需要允许通过 TCPUDP、本地端口 53 传输到系统的本地流量。例如:

sudo iptables -A INPUT -i lo -p udp --dport 53 -j ACCEPT
sudo iptables -A INPUT -i lo -p tcp --dport 53 -j ACCEPT
Run Code Online (Sandbox Code Playgroud)

现在请确保将系统的名称解析器功能指向此 DNS 服务器。这可能可以通过直接编辑 /etc/resolv.conf 将nameserver指令替换为指向 127.0.0.1 的单个指令来实现,但您可能想单独询问这一点,因为我不太熟悉 Ubuntu 的方式做事。他们可能有一个 GUI,并且 /etc/resolv.conf 可能会在启动时自动重写。

这为您提供了非常基本的转发 DNS 解析器设置。要阻止对特定域的访问(在 DNS 术语中,这意味着您为这些名称权威地服务于空区域),请将节添加zone { }到您的 BIND 配置文件中,指向db.empty包为方便起见而提供的文件bind9。例如,要阻止所有内容facebook.com(包括裸名),请添加:

zone "facebook.com" { type master; file "db.empty"; };
Run Code Online (Sandbox Code Playgroud)

再次执行sudo rndc reload来加载它。您现在应该无法访问 facebook.com 下的任何主机名。

如果搞砸了,只需重置网络 DNS 设置以使用上游 DNS 服务器,或撤消对 /etc/bind/named.conf 的最新更改并再次重新加载配置。您可以在一行中的任意位置(引号内除外)书写//,将该行的其余部分变成注释;例如,这是暂时取消更改的好方法。

玩得开心!