1

问题:

我想编写一个具有以下伪代码签名的函数:

/**
 * Blocks all traffic to the given website.
 * 
 * @param {String} domain The domain name of the site to block
 */
function blockSite (domain) {
  // TODO
}

但是,我希望有以下限制:

  • 网站/域可以类似于 reddit.com,它的一个域名有多个 IP 地址。
  • 阻塞方法应该是客户端或桌面解决方案。它不应该依赖于使用您的路由器。这个问题的上下文不是网络管理,我希望这个功能在我的个人 Windows 机器上执行。

见解:

内容过滤可能发生在网络的不同阶段。使用 Windows 防火墙的解决方案工作在第 4 层,即传输层。其他解决方案可能会使用第 7 层,即应用层。Cold Turkey是一个在第 7 层上工作的商业应用程序,要求在每个浏览器上安装一个插件并通过插件过滤内容。

扩展阻止站点复杂性的一项挑战是共享 Web 托管。例如,某些网站(例如 youtube.com)与 google.com 等网站共享同一组 IP 地址。为了简单起见,满足共享虚拟主机的问题可以忽略。我只是希望有问题的网站被阻止,而不管其他附属网站被它阻止。

共享虚拟主机问题的解决方案是使用基于 DNS 的过滤(而不是基于 IP 的过滤)。为阻止站点的任务提出的常见解决方案是使用 hosts 文件c:\windows\system32\drivers\etc\hosts。考虑以下用 powershell 编写的函数,作为实现此目的的解决方案:

function Block-Site([String] $domain) {
    $hosts = 'C:\Windows\System32\drivers\etc\hosts'
    $isBlocked = Get-Content -Path $hosts | Select-String -Pattern ([regex]::Escape($domain))

    If(-not $isBlocked) {
        Add-Content -Path $hosts -Value "127.0.0.1 $domain"
        Add-Content -Path $hosts -Value "127.0.0.1 www.$domain"
    }
}

上述解决方案的问题在于它有许多简单的解决方法。例如,一种解决方法是只用谷歌搜索网站的名称,然后点击谷歌的网站。因此,我对解决方案不是很满意,因为它实际上并没有阻止或防火墙关闭流量。

更新:我相信Windows 过滤器平台可能是最全面的解决方案。我正在研究它的潜力,并为它添加一个标签。


这项研究:

我已经检查了我能找到的所有相关的 stackoverflow 和超级用户问题,但没有一个足以提供答案。看:

堆栈溢出:

超级用户:

4

1 回答 1

2

以下函数是用 powershell 编写的,它将通过创建一个 Windows 防火墙规则来阻止网站,该规则阻止所有与网站关联的 IP 地址的 TCP 流量。

function Block-TrafficToURL([String] $domain) {
    [System.Collections.ArrayList]$IPs = @()
    Resolve-DnsName -Name $domain -NoHostsFile | Foreach {$IPs.Add("$($_.IPAddress)")}
    New-NetFirewallRule -DisplayName "Block $domain" -Direction Outbound -Protocol TCP -Action Block -RemoteAddress $IPs
}

使用的函数调用的文档如下:

此功能已经过测试并适用于 Stackoverflow.com 和 Reddit.com,它们都有多个 IP 地址。但是,该函数在 YouTube.com 上失败,因为为 YouTube.com 调用 Resolve-DnsName 仅返回一个 IP 地址,但在多次调用时可以是不同的 IP。同样,屏蔽所有 YouTube IP 可能会导致屏蔽 Google Drive 和 Google.com 等服务,这可能是不可取的。

于 2019-09-04T16:15:36.250 回答