This PowerShell module was created to automate the aggregation of DNS blocklists for the creation of Query Resolution Policies (QRP) on a Microsoft DNS server.
The DnsBlockList module first reads and validates the provided configuration file. Then the Query Resolution Policies (QRP) are processed to get domains currently loaded. Next, each BlockListUrl
is queried for changes and updated files are downloaded to the WorkingDirectory
as a .DnsBlockListCache
file. All files are processed and the aggregated list of domains get compared with those currently loaded to produce the add/remove commands in Update-DnsServerQRP.ps1
.
Microsoft DNS Policies Overview
The following are prerequisites for this module.
This module is hard coded to use TLS 1.2 for all secure communications which impacts the following:
- HTTPS communications to a blocklist URL.
- Secure communication to the SMTP server (e.g. STARTTLS) if using SMTP for alerts.
This module must run on a DNS server since it queries the Query Resolution Policies (QRP) currently in use.
The user account running this script must be a DNS server administrator.
This module should be launched via Task Scheduler on a reoccurring schedule that works best for your environment.
The DnsBlockList module uses a configuration file. Each setting is described in detail below.
There are two functions in this module used for working with the default configuration file.
Get-DnsBlockListDefaultConfiguration
- returns the content of the default configuration file to standard out.Copy-DnsBlockListDefaultConfiguration
- copies the default configuration file to the destination folder.
Directory for storing the following files:
CacheConfig.xml
- Stores HTTP response headers ETag and/or Last-Modified timestamp for DnsBlockList files.Update-DnsServerQRP.ps1
- File containing PowerShell QRP Add/Remove commands.*.DnsBlockListCache
- DnsBlockList files are stored using this extension with it'sKey
as the name.
Example of naming a downloaded file:
SansHigh = https://isc.sans.edu/feeds/suspiciousdomains_High.txt
Cached Filename = SansHigh.DnsBlockListCache
Action when a Query Resolution Policy is matched:
Allow
Deny
Respond with SERV_FAIL.Ignore
Do not respond.
Unique prefix to distinguished DnsBlockList rules from all other QRP rules.
Example of how a QRP name is created:
RuleNamePrefix = DBL-
Blocked Domain = bad.contoso.com
Resulting QRP Name = DBL-bad.contoso.com
Specifies whether the module will add/remove QRPs.
False
- add/remove domains as they're processed.True
- no changes are made to QRPs via this script.
Update-DnsServerQRP.ps1
is updated with change commands regardless of this setting.
If the WorkingDirectory
has been setup for git, enabling this setting will commit and push any changes.
False
- Does not run the git commands.True
- The following git commands will be launched in the working directory.
git add -A
git commit -m "DnsBlockList-PowerShell-Module"
git push origin master
Each blocklist must be listed as a key=value
pair where:
Key
= Unique identifier for the blocklist.Value
= blocklist URL
[BlockListUrl]
SansHigh = https://isc.sans.edu/feeds/suspiciousdomains_High.txt
ZeusTracker = https://zeustracker.abuse.ch/blocklist.php?download=domainblocklist
MalwareDomains = https://mirror1.malwaredomains.com/files/domains.txt
NOTE: this script is hard-coded to use
TLS1.2
when communicating with web servers.
LENNY ZELTSER - Blocklists of Suspected Malicious IPs and URLs
Domains that should never be block must be listed here as a key=value
pair where:
Key
= Unique identifier for the allowed domain.Value
= domain name
[AllowDomains]
CompanyEmail = mail.domain.com
CompanyWebsite = www.domain.com
Individual domains to be blocked must be listed here as a key=value
pair where:
Key
= Unique identifier for the blocked domain.Value
= domain name
[BlockDomains]
PhishingEmail01 = foo.evil.com
NOTE: if your implementation requires frequent edits to this section consider hosting a BlockListUrl
internally.
Not all blocklists are structured as having one domain per line. For those occasions additional parsing logic is needed which is handled by the private function Get-DomainFromLine
. For a line to be handed off to this function, it must meet the following criteria:
- Cannot start with a
#
(hash sign) - Must contain a
.
(period) - Length > 2
If there's a BlockList requiring an additional parse method and the line meets the above requirements, do the following:
- Add the appropriate parsing logic to the switch statement in the
Get-DomainFromLine
private function. - Update this configuration section with the
Key
of theBlockListUrl
and theValue
newly added to the switch statement.
MalwareDomains requires alternate parsing and thus uses the following configuration. Note how the same Key
is used to associate the ParseMethod
with the BlockListUrl
.
[BlockListUrl]
MalwareDomains = https://mirror1.malwaredomains.com/files/domains.txt
[ParseMethod]
MalwareDomains = 1
Standard out will always be used even if no value is specified. Choosing both Smtp and WinEvent will enable both methods or just include one.
- Standard Out - Always enabled. Will return any alerts to the prompt.
- Smtp - Send an email based on the
[SMTP]
settings. - WinEvent - Write an event based on the
[WinEvent]
settings.
Recipient email address for the alert.
Sender's email address for the alert.
Email subject for the alert.
DNS name of SMTP server.
NOTE: this script is hard-coded to use
TLS1.2
when communicating with this server.
SMTP server port to connect to.
Optional setting. XML file containing PSCredential for SMTP authentication. Leave blank if no credentials are to be used.
To create this file run the following command using the account that will be launching this module.
Get-Credential | Export-Clixml -Path <CredentialXmlPath>
Ensure NTFS permissions on the PSCredential xml file are tuned to only allow access to SYSTEM, any backup accounts, and the user running this module.
The target event log to write an event to.
Name of the application that generated this event.
By default, DnsBlockList
will not be registered. Doing so requires Administrative permission and can be achieved via the following command.
New-EventLog -LogName Application -Source DnsBlockList
Event Id used when writing an Information event.
Event Id used when writing an Error event.