How to Configure DNS on Windows

A Step-by-Step Guide for Network Administrators

Illustration Shows Porn Being Blocked in SERPs

Streamline your network management with our comprehensive DNS configuration guide for Windows. Learn best practices, improve security, and boost network efficiency with easy-to-follow steps.

Learn About Pricing

Step 1: The Windows App

We offer a Windows app that can streamline the configuration of the service. It does not have a deployable MSI file for mass deployments, it must be configured on each device separately.


Instructions to configure the Windows App:

  • Install the app
  • Configure custom filter using ID
  • Enable password protection
  • Enable uninstallation protection
  • Blocking internet options setting should not be needed since that is covered through policy management below

A more detail guide on how to configure the Windows app is found here: Setup DNS Filtering on Windows with CleanBrowsing.

Step 2: Configure DNS Through Network Adapter Settings (IPv4 and IPv6)

The Windows app is not required to configure CleanBrowsing on a Windows device. DNS can be configured mannually via the Network Adapter Settings (IPv4 and IPv6). If configuring manually, we recommend configuring both Ethernet and Wi-Fi interfaces by default, and either a) disabling IPv6 or b) configuring both IPv4 and IPv6 on the device.


Instructions to Configure Windows Mannually:

  1. Open Network and Sharing Center > Change adapter settings.
  2. Right-click your network connection > Properties.
  3. Select Internet Protocol Version 4 (TCP/IPv4) or Internet Protocol Version 6 (TCP/IPv6) > Properties.
  4. Set the DNS server addresses to your preferred IPv4 or IPv6 DNS servers.
  5. If there are issues with IPv6, which is common, disable them on Ethernet and Wi-Fi under the adapter properties


Find a detailed guide on how to configure manually here. Configuring IPv4 does requre you to push your public IP to our system so that we know what traffic to filter.



Restrict Access to Network Settings with Group Policy

If you configure the interfaces directly we recommend using Group Policy to restrict access so that your users cannot make local changes.


Instructions to Restrict Access:

  1. Open Group Policy Editor
    • Press Windows Key + R to open the Run dialog.
    • Type gpedit.msc and press Enter to launch the Local Group Policy Editor.
  2. Navigate to Network Connection Settings:
    • Go to User Configuration > Administrative Templates > Network > Network Connections.
  3. Apply Restrictions:
    • Enable the policy Prohibit access to properties of components of a LAN connection. This setting should prevent users from accessing and changing properties of network connections, including DNS settings.
    • Enable Prohibit access to properties of a LAN connection. This might be too restrictive, but see if it works.
    • Enable Prohibit adding and removing components for a LAN or remote access connection
    • Enable Prohibit configuration of VPN connection

Step 3: Account for Dynamic Public IPs

When using IPv4 on your network you need to keep CleanBrowsing aware of the networks public IP. This can be done by querying the Dynamic Device URL issued in the CleanBrowsing dashboard. It looks like this: https://my.cleanbrowsing.org/dynip/[unique ID].

We advise automating the process of keeping the Dynamic Device URL updated.



Part 1: Create PowerShell Script

This will create a script to automatically find the networks public IP using the CleanBrowsing Dynamic Device URL.

  1. Open Notepad or any text editor.
  2. Paste the following PowerShell code:

  3. 
    # Log file path<
    $logFilePath = "C:\Scripts\Logs\DynamicDNS.txt"
    
    # Function to write log messages
          function Write-Log {
              param(
                  [string]$Message
          )
    
    $Timestamp = Get-Date -Format "yyyy-MM-dd HH:mm:ss"
    $LogMessage = "$Timestamp - $Message"
    $LogMessage | Out-File -FilePath $logFilePath -Append
        }
    
    # Write log message indicating script start
    Write-Log "Script started."
    
    try {
        # Invoke web request to retrieve dynamic IP address
        $response = Invoke-WebRequest -Uri "https://my.cleanbrowsing.org/dynip/abc123" -UseBasicParsing
        $ipAddress = $response.Content
    
        # Log the retrieved IP address
        Write-Log "Retrieved IP address: $ipAddress"
    
        # Add your additional logic here if needed
    
        Write-Log "Script completed successfully."
    }
    catch {<
          # Write exception details to log if an error occurs
          Write-Log "Error occurred: $_"
    }
                    

  4. Save the file with a .ps1 extension, e.g., CleanBrowsingDynamicDNS.ps1 , to a known location like C:\Scripts\.
  5. Set permissions on the file to deny standard users access

Part 2: Create a Scheduled Task

This will create a scheduler on your machine to initiate the sript in Part 1.

  1. Open Task Scheduler (taskschd.msc).
  2. Select "Create Task…" and give it a name, e.g., "Dynamic DNS Updates".
  3. Set the trigger as on workstation lock of any user
  4. Make sure it is set to “Run whether user is logged on or not”. You may need to not use the basic task flow for this.
  5. Configure the task for Windows 10 in the dropdown
  6. Set to run with highest privileges
  7. Under Conditions, set it to “Start only if the following network connection is available” and select Any connection
  8. For the action, select "Start a program," then browse to the PowerShell executable (C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe).
  9. In the "Add arguments" field, enter -ExecutionPolicy Bypass -File "C:\Scripts\CleanBrowsingDynamicDNS.ps1".
  10. Complete the wizard.

Step 4: Block Encrypted DNS

Encrypted DNS, such as DNS over HTTPS (DoH) or DNS over TLS (DoT), enhances user privacy by encrypting DNS queries, making it difficult for external parties to monitor web activity. However, this same encryption can pose a threat to networks by bypassing traditional DNS filtering and monitoring tools that organizations use to enforce security policies.

When DNS traffic is encrypted, network administrators lose visibility and control over domain resolutions, potentially allowing malicious sites or content to slip through, increasing the risk of threats like malware, phishing, or unauthorized access.

To help address this you can follow the instructions below to block DOH and DOT on your devices.

Block DOH (DNS over HTTPS)

You can use a scheduled task in Windows to run a PowerShell script that dynamically adds block rules to the firewall based on a public IP blocklist

Part 1: Create PowerShell Script

  1. Open Notepad or any text editor.
  2. Paste the following PowerShell code:
  3. 
    # Define URLs to fetch IP addresses from
    $ipv4Url = "https://raw.githubusercontent.com/dibdot/DoH-IP-blocklists/master/doh-ipv4.txt"
    $ipv6Url = "https://raw.githubusercontent.com/dibdot/DoH-IP-blocklists/master/doh-ipv6.txt"
    $logFile = "C:\Scripts\Logs\BlockDOH.txt"
    
    # Define IP addresses to exclude from blocking so that you can still use CleanBrowsing
    $excludeIPs = @('185.228.168.10')
    
    # Function to fetch and parse IP addresses from URLs
    function Get-IPsFromUrl {
        param (
            [string]$Url
              )
        $content = Invoke-WebRequest -Uri $Url -UseBasicParsing
        $ips = $content.Content -split "`n" | ForEach-Object {
              if ($_ -match '^\s*([0-9a-f:.]+)') { $matches[1] }
                }
                return $ips
        }
    
    # Fetch IP addresses
    $ipv4Addresses = Get-IPsFromUrl -Url $ipv4Url
    $ipv6Addresses = Get-IPsFromUrl -Url $ipv6Url
    
    # Combine IPv4 and IPv6 addresses
    $allIPs = $ipv4Addresses + $ipv6Addresses
    
    # Ensure the log file directory exists
    $dir = Split-Path -Path $logFile
    if (-not (Test-Path -Path $dir)) {
        New-Item -ItemType Directory -Path $dir | Out-Null
        }
    
    # Get existing firewall rules
    $existingRules = Get-NetFirewallRule | Where-Object { $_.DisplayName -like "BlockDoH*" } | Select-Object -ExpandProperty DisplayName
    
    # Add firewall rules for new IP addresses, excluding specified IPs
    foreach ($ip in $allIPs) {
        if ($ip -in $excludeIPs) {
            "Skipping excluded IP $ip" | Out-File -FilePath $logFile -Append
              continue
          }
    
    $ruleName = "BlockDoH_$ip"
    if ($ruleName -notin $existingRules) {
          # Adding rule to block the IP
          New-NetFirewallRule -DisplayName $ruleName -Direction Outbound -Action Block -RemoteAddress $ip -Protocol Any
          "Added firewall rule to block $ip" | Out-File -FilePath $logFile -Append
          }
                else {
                    "Rule for $ip already exists." | Out-File -FilePath $logFile -Append
                    }
                }
    
    "Firewall rules update completed." | Out-File -FilePath $logFile -Append
                  
  4. Save the file with a .ps1 extension, e.g., BlockDOH.ps1, to a known location like C:\Scripts\.
  5. Set permissions on the file to deny standard users access explicitly.

Step 2: Create Scheduled Task

  1. Open Task Scheduler (taskschd.msc).
  2. Select Create Task… and give it a name, e.g., "Block DOH".
  3. Set the trigger as Monthly on the first day or something similar
  4. Make sure it is set to Run whether user is logged on or not. You may need to not use the basic task flow for this.
  5. Configure the task for Windows 10 in the dropdown
  6. Set to run with highest privileges
  7. Under Conditions, set it to Start only if the following network connection is available and select any connection
  8. Under Settings, leave all the defaults, except check Run task as soon as possible after a scheduled start is missed
  9. For the action, select Start a program then browse to the PowerShell executable (C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe)..
  10. In the Add arguments field, enter -ExecutionPolicy Bypass -File "C:\Scripts\BlockDOH.ps1"
  11. Complete the wizard.

Feel free to manually trigger the script on the first run to get the initial IPs blocked.

Block DOT (DNS over TLS)

Create am outbound rule in the Windows Defender Firewall to block port 853 can effectively prevent applications from using DNS over TLS.
Here’s a basic outline of how to do this:

  1. Open Windows Defender Firewall with Advanced Security: Search for it in the Start menu and open it.
  2. Create a New Outbound Rule: Navigate to Outbound Rules and choose New Rule.
  3. Select Rule Type: Choose Port as the rule type and click Next.
  4. Specify Port: Select TCP and specify 853 as the port number to block, then click Next.
  5. Block the Connection: Choose Block the connection and proceed.
  6. Profile Application: Apply the rule to Domain, Private, and Public profiles as necessary.
  7. Name the Rule: Give your rule a meaningful name, such as “Block DNS over TLS”, and finish the wizard.

Step 5: Configure Custom Allow and Blocks with Scripts

With CleanBrowsing you can customize the service to allow and block specific domains. This section will show you how to automate this process using the CleanBrowsing ashboard API (Reserved for Pro100 + accounts). Via this feature an administrator can create an automation task that keeps the CleanBrowsing current with evolving network needs without having to log into the dashboard directly.

CleanBrowsing API Setup for Windows 10

First, create four text files for users to edit and make sure the Users group has permission to edit the files:

  • AddToWhitelist.txt (Delayed)
  • RemoveFromWhitelist.txt (Immediate)
  • AddToBlocklist.txt (Immediate)
  • RemoveFromBlocklist.txt (Delayed)


Second, write two PowerShell scripts that processes these files. The reason for two separate files is because one script will be ran immediately, and the other will be ran on a delay. There is an option to immediately remove certain domains from the blocklist. Currently this is configured to allow removal of google.com from the blocklist immediately because the Captcha service is hosted on google.com and breaks a lot of sites when google.com is blocked. There could be other uses for this as well.

First Script: DNSManagementImmediate.ps1

# Log file path
$logFilePath = "C:\Scripts\Logs\DNSManagement.txt"

# Function to write log messages
function Write-Log {
    param(
          [string]$Message
    )
    $Timestamp = Get-Date -Format "yyyy-MM-dd HH:mm:ss"
    $LogMessage = "$Timestamp - $Message"
    $LogMessage | Out-File -FilePath $logFilePath -Append
    }

Write-Log "Script for immediate actions started."

try {
    # Function to send API requests
    function Send-APIRequest {
        param (
              [string]$Action,
              [string]$Domain
        )
        $apiKey = "***YOUR API KEY HERE***"
        $uri = "https://my.cleanbrowsing.org/api?apikey=$apiKey&action=$Action&domain_name=$Domain"

        Write-Log "Invoking API request: $Action for domain: $Domain"
        $response = Invoke-RestMethod -Uri $uri -Method Get
        Write-Log "API response: $($response | ConvertTo-Json -Depth 5)"
        }

# Function to process actions based on file contents
function Process-Actions {
        param (
            [string]$FilePath,
            [string]$Action
        )
        if (Test-Path $FilePath) {
            $domains = Get-Content $FilePath
            foreach ($domain in $domains) {
            Write-Log "Processing action: $Action for domain: $domain"
            Send-APIRequest -Action $Action -Domain $domain
            }
                # Clear file after processing
                Clear-Content $FilePath
            }
        }

# Function to immediately remove specific domains from the blocklist if listed
function Unblock-SpecificDomains {
    $blockedDomainsPath = "C:\Scripts\RemoveFromBlocklist.txt"
    $permissibleDomains = @("google.com") # Extendable list
    if (Test-Path $blockedDomainsPath) {
        $domainsToUnblock = Get-Content $blockedDomainsPath
        foreach ($domain in $domainsToUnblock) {
          if ($domain -in $permissibleDomains) {
              Write-Log "Approving immediate blocklist removal for domain: $domain"
              Send-APIRequest -Action "blocklist/delete" -Domain $domain
              }
            }
                # Optionally clear file after processing
                Clear-Content $blockedDomainsPath
                }
            }

# Process actions for different files
Process-Actions -FilePath "C:\Scripts\RemoveFromWhitelist.txt" -Action "whitelist/delete"
Process-Actions -FilePath "C:\Scripts\AddToBlocklist.txt" -Action "blocklist/add"

# Check and approve specific domains immediately
Unblock-SpecificDomains

Write-Log "Script for immediate actions completed successfully."
}
catch {
      Write-Log "Error occurred: $_"
}
              

Second Script: DNSManagementDelayed.ps1


# Log file path
$logFilePath = "C:\Scripts\Logs\DNSManagement.txt"

# Function to write log messages
function Write-Log {
    param(
          [string]$Message
    )
      $Timestamp = Get-Date -Format "yyyy-MM-dd HH:mm:ss"
      $LogMessage = "$Timestamp - $Message"
      $LogMessage | Out-File -FilePath $logFilePath -Append
      }

Write-Log "Script for immediate actions started."

try {
    # Function to send API requests
    function Send-APIRequest {
        param (
              [string]$Action,
              [string]$Domain
        )
        $apiKey = "***YOUR API KEY HERE***"
        $uri = "https://my.cleanbrowsing.org/api?apikey=$apiKey&action=$Action&domain_name=$Domain"

        Write-Log "Invoking API request: $Action for domain: $Domain"
        $response = Invoke-RestMethod -Uri $uri -Method Get
        Write-Log "API response: $($response | ConvertTo-Json -Depth 5)"
        }

# Function to process actions based on file contents
function Process-Actions {
    param (
            [string]$FilePath,
            [string]$Action
            )
            if (Test-Path $FilePath) {
              $domains = Get-Content $FilePath
              foreach ($domain in $domains) {
              Write-Log "Processing action: $Action for domain: $domain"
              Send-APIRequest -Action $Action -Domain $domain
            }
            # Clear file after processing
            Clear-Content $FilePath
            }
          }

# Process actions for different files
Process-Actions -FilePath "C:\Scripts\AddToWhitelist.txt" -Action "whitelist/add"
Process-Actions -FilePath "C:\Scripts\RemoveFromBlocklist.txt" -Action "blocklist/delete"

Write-Log "Script for immediate actions completed successfully."
      }
      catch {
        Write-Log "Error occurred: $_"
      }
            


Save the Scripts

Save this scripts to a location accessible by the system (e.g., C:\Scripts\DNSManagementImmediate.ps1 and C:\Scripts\DNSManagementDelayed.ps1 )

Set permissions on the files to deny any standard user accounts Modify and below permissions. This will prevent modification and reading of the API key. It also prevents on demand execution of the file. Admin accounts are part of the Users group, so don’t use that group to deny permissions.



Schedule Immediate Script with Task Scheduler

  1. Open Task Scheduler and create a new task (not basic task).
  2. Set the task to Run whether the user is logged on or not and with highest privileges.
  3. Configure the task for Windows 10 in the dropdown
  4. Trigger: On workstation lock of any user
  5. Conditions: Network ⇒ Start only if the following network connection is available: “Any connection”
  6. Action: Set the action to start the PowerShell script.
    • Program/script: C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe
    • Add arguments: -ExecutionPolicy Bypass -File "C:\Scripts\DNSManagementImmediate.ps1"
  7. Conditions and Settings: Adjust as needed for your environment.

Schedule Delayed Script with Task Scheduler

  1. Open Task Scheduler and create a new task (not basic task).
  2. Set the task to Run whether the user is logged on or not and with highest privileges.
  3. Configure the task for Windows 10 in the dropdown
  4. Trigger: On workstation lock of any user with a 4hr delay
  5. Conditions: Network ⇒ Start only if the following network connection is available: “Any connection”
  6. Action: Set the action to start the PowerShell script.
    • Program/script: C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe
    • Add arguments: -ExecutionPolicy Bypass -File "C:\Scripts\DNSManagementImmediate.ps1"
  7. Conditions and Settings: Adjust as needed for your environment.

Step 6: Install Certificate to fix HTTPS Warnings

When HTTPS enabled domains are blocked by a policy, CleanBrowsing presents a block page to you which is also served over HTTPS. This block page is encrypted with a certificate signed by the CleanBrowsing Root CA. In order to avoid certificate errors when accessing the block page, you must install the CleanBrowsing Root CA in your browser, or if you have a network of computers, in your users’ browsers.

To avoid these errors entirely you must deploy the CleanBrowsing certifiate to the local root store on all devices.

A complete Guide to Installing the CleanBrowsing CA is available.

Step 7: BLock Windows App Store

The Windows App store allows a device user to easily install applications to the device that might otherwise circumvent the network controls (e.g., VPN, Proxy applications). To prevent this, we recommend blocking the Windows App Store.
This is availalbe with Windows 10 Enterprise.

Steps to Block Windows App Store

1. Open Group Policy Editor:

  • Press Windows Key + R to open the Run dialog.
  • Type gpedit.msc and press Enter to launch the Local Group Policy Editor.

2. Navigate to the Windows Store Policy:

  • In the Group Policy Editor, navigate to Computer Configuration > Administrative Templates > Windows Components > Store.

3. Disable the Store Application:

  • Find the setting Turn off the Store application.
  • Double-click on it to open its configuration window.

4. Configure the Setting:

  • Select Enabled to disable access to the Windows Store.
  • Click Apply and then OK to save the changes.

Step 8: Prevent Installation of Unwanted Software Through AppLocker

Note: The reason this is needed is because there are many applications that can be installed to the users local profile without requiring admin permissions. Even though Chrome and Edge are locked down, a user could download an alternate browser to their local profile very easily.

Additionally, there is a more advanced solution called Windows Defender Application Control, and it is more powerful and secure, but it is harder to configure. I may consider using it in the future though.

1. Open the Local Security Policy Editor

  • Press Win + R< to open the Run dialog.
  • Type secpol.msc and press Enter.

2. Navigate to AppLocker

  • In the Local Security Policy window, expand the Application Control Policies node.
  • Click on AppLocker. This displays AppLocker's overview and configuration options.

3. Configure AppLocker Properties (Optional)

  • Right-click on AppLocker, then select Properties.
  • In the AppLocker Properties window, you can configure additional settings, like enforcement settings. These are optional at the start but can be configured as needed.

4. Create Default Rules

For each rule type (Executables, Windows Installer Files, Script, and Packaged app Rules), you'll want to create default rules.

For Executables:
  • Right-click Executable Rules and choose Create Default Rules. Three default rules are created:
    • Allow all users to run executables in the Windows folder.
    • Allow all users to run executables in the Program Files folder.
    • Allow members of the local Administrators group to run all executables.

For Windows Installer Files:

  • Right-click Windows Installer Rules and choose Create Default Rules. Similar default rules are created for installer packages.

For Scripts and Packaged Apps:

  • Repeat the process for Script Rules and Packaged app Rules if you want to control these types of applications as well.

5. Configure Rule Enforcement

  • Once the default rules are created, you need to enable rule enforcement.
  • Right-click on Executable Rules, Windows Installer Rules, Script Rules, or Packaged app Rules, then select Properties.
  • In the Enforcement tab, select Enforce rules for the rule types you want to enforce. You might start with Executables and Windows Installer Files.

6. Configure the Application Identity Service to Start Automatically

Starting with Windows 10, the Application Identity service is now a protected process. As a result, you can no longer manually set the service Startup type to Automatic by using the Services snap-in. Try either of these methods instead:

  • Open an elevated command prompt or PowerShell session and type then run:
  • sc.exe config appidsvc start=auto

7. Test Your Configuration

  • To ensure everything is set up correctly, try running applications as both a standard user and an administrator. Verify that the rules work as expected.

8. Monitor and Adjust Rules

  • Use the AppLocker logs in Event Viewer (Event Viewer > Applications and Services Logs > Microsoft > Windows > AppLocker) to monitor allowed and blocked applications.
  • Adjust your rules based on operational needs and any issues encountered.

Step 9: Harden Browsers

Securing your network requires not just filtering at the DNS level but also hardening browser settings, especially when it comes to Secure DNS (DNS-over-HTTPS). While this feature aims to enhance privacy by encrypting DNS queries, it can inadvertently bypass your network's filtering controls, allowing users to access restricted content or malicious websites. This creates a significant security gap, especially in environments that rely on DNS-based content filtering. To mitigate these risks, it's essential to disable Secure DNS and other related settings in browsers like Microsoft Edge and Google Chrome.

For detailed, step-by-step instructions on hardening these browsers, refer to our dedicated guides for Edge and Chrome.

Step 10: Testing & Verification

Ensuring that your CleanBrowsing DNS resolvers are correctly configured is crucial for maintaining a secure and filtered network. Testing the confgiuration can be achieved by checking what DNS resolver is being used in the browser or in the command line. We offer a comprehensive guide on how to test & verify the configuration<.

Verify Using the Browser

Via the Browser you can verify that your network is routing correctly by using the dnsleaktest.com website.

On this website run the standard test. The output of this test should show CleanBrowsing servers like this:

DNS Leak Test Results Showing CleanBrowsing Configured

Verify Using the Command Prompt

Via the command prompt you can verify that your network is routing correctly by using the nslookup.

nslookup -q=TXT mylocation.whois.dnscontest.cleanbrowsing.org
Server:        185.228.168.10
Address:    185.228.168.10#53

Non-authoritative answer:
mylocation.whois.dnscontest.cleanbrowsing.org    text = "CleanBrowsing: dns-edge-usa-west-la, 185.228.168.10"
                  

This shows you that the network is routing to dns-edge-usa-west-la, 185.228.168.10" and the WAN IP of the network is 185.228.168.10.

CleanBrowsing is a DNS Filtering technology that creates safe browsing experiences on your network.

What is DNS Filtering?