1

The Question:

I want to write a function that has the following pseudocode signature:

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

I want to have the following constraints, however:

  • The website/domain can be something like reddit.com, which has multiple IP addresses for its one domain name.
  • The blocking method should be a client side or desktop solution. It should not rely on using your router. The context of this question is not network administration, I want this function to execute on my personal windows machine.

Insights:

Content filtering can happen at different stages of networking. A solution that uses Windows firewall works at layer 4, the transport layer. Other solutions might use layer 7, the application layer. Cold Turkey is a commercial application that works on layer 7 by requiring a plugin to be installed on every browser and filtering content via the plugins.

One challenge that extends the complexity of blocking sites is shared web hosting. Some websites, like youtube.com, for example, shares the same set of IP Addresses with sites like google.com. For the sake of simplicity, satisfying the problem of shared web hosting can be ignored. I just want the site in question blocked, regardless of what other collateral sites get blocked with it.

A solution to the shared web hosting problem is to use DNS based filtering (instead of IP based filtering). A common solution proposed for the task of blocking a site is to make use the hosts file c:\windows\system32\drivers\etc\hosts. Consider the following function, written in powershell, as a solution that does just that:

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"
    }
}

The problem with the solution above is that it has many trivial workarounds. One workaround, for example, is to just google the name of the website and click on the website from Google. As such, I'm not very content with the solution, since it doesn't actually block or firewall off traffic.

Update: I believe the Windows filter platform might be the most comprehensive solution available. I'm investigating its potential, and adding a tag for it.


The Research:

I've checked every relevant stackoverflow and superuser question I could find, but none were sufficient in providing an answer. See:

Stack Overflow:

Super User:

Josh Desmond
  • 640
  • 2
  • 10
  • 19
  • 2
    You're asking how to write a proxy server. They sell those. – Ken White Aug 30 '19 at 18:52
  • @KenWhite, Maybe. I think a content-filtering web proxy can be a solution to my problem. However, I think my function doesn't require a web proxy to act as a solution. Cold Turkey, for example, intercepts and blocks traffic at the application layer by requiring you to have chrome/firefox plugins installed and blocking traffic there. The core of my problem is that layer 3 network filtering is insufficient for blocking modern cloud hosted websites. I want to know what resources/tutorials/tools can help me write code to achieve the desired functionality. – Josh Desmond Aug 30 '19 at 19:56
  • You can't ask here for *resources/tutorials/tools*, according to the [help/on-topic] guidelines. See the section with the numbered list of items. This site is for specific questions related to programming (code) or use of a programmers tool (IDE, compiler, etc.). – Ken White Aug 30 '19 at 20:39
  • Well, the question itself isn't "asking us to recommend or find a book, tool, software library, tutorial or other off-site resource," as is forbidden in the rules. I just realize that content filtering is a high-level task that has many possible answers, and recognize that an answer to this question may fall under the type of, "You can do this using the _foo()_ system call in the _bar_ windows something _baz_ API/library", or, "You can use Powershell's _foo_ module", or "You can do this by doing _foo_ and rerouting traffic into a DNS sinkwhole". Questions of that type are allowed and common. – Josh Desmond Aug 30 '19 at 21:09
  • 1
    No, the question asked is far too broad in scope for this site. The comment regarding asking for resources was based on your response to my comment, and the words I quoted were verbatim from your comment to me, where you said (quote) ***I want to know what resources/tutorials/tools can help me write code to achieve the desired functionality***. This site is for **specific questions** related to programming (code) or use of a programmers tool. Asking a broad question about how to write a web proxy or intercept local traffic to block *modern, cloud hosted websites* isn't appropriate either. – Ken White Aug 30 '19 at 22:02
  • Okay, "modern, cloud hosted websites" was pretty broad, you got me there. I have edited the question to remove constraints regarding the shared web hosting problem (1 -> many mappings of IP -> domain names). In addition, I have a solution I can post as a first answer to the question, which is only ~3 lines of powershell code. (Me having an answer should be proof the question is no longer too broad). – Josh Desmond Sep 03 '19 at 23:07

1 Answers1

2

The following function is written in powershell, and will block a website by creating a Windows Firewall rule that blocks all TCP traffic to the ip addresses found associated with the website.

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
}

The documentation for function calls used are below:

This function was tested and worked for Stackoverflow.com and Reddit.com, both which have multiple IP addresses. The function fails with YouTube.com, however, as calling Resolve-DnsName for YouTube.com returns only a single IP address, but can be a different IP when called multiple times. Likewise, blocking all YouTube IP's would probably result in blocking services like Google Drive and Google.com, which might not be desirable.

Josh Desmond
  • 640
  • 2
  • 10
  • 19