This script-set was created to facilitate Malware Filtering and Split-DNS support on PowerDNS Recursor Services.
You may include DNSBLs and IPBLs with different formats such as Adblock, REGEX, Wildcard or Plain Domain Lists (hosts format is excluded as that is supported by default by PowerDNS Recursor).
It's especially useful in cases where you might have a Reverse Proxy as a sort of Gateway that handles all your web services, or cases where you might need to replace Internal DNS Zone Records through REGEX Patterns.
Script Repository maintained by Dylan Blanqué. Created January 2024.
You must have lua-rex-pcre
or lua-rex-pcre2
installed (Can be done with
apt
or luarocks
).
E.g.:
apt update -y
apt install lua-rex-pcre -y || apt install lua-rex-pcre2 -y
You must have the dig
command installed as well, for full cname chain
resolution on local domain overrides.
apt update -y
apt install dnsutils
To use this script-set, after you've ensured the requirements are met you can
clone this repository with git
onto your /etc/powerdns
directory and add
or modify the following line in your PowerDNS Recursor Configuration File:
cd /etc/powerdns
git clone https://github.com/dblanque/pdns-recursor-scripts
# /etc/powerdns/recursor.conf (Legacy)
lua-dns-script=/etc/powerdns/pdns-recursor-scripts/hooks.lua
# /etc/powerdns/recursor.conf (YAML)
recursor:
lua_dns_script: /etc/powerdns/pdns-recursor-scripts/hooks.lua
For Split DNS and other magical options (to reduce or remove the usage of NAT Reflection) you may use the following options in the files:
/etc/powerdns/pdns-recursor-scripts/conf.d/settings.lua
/etc/powerdns/pdns-recursor-scripts/conf.d/*.lua
Bear in mind you must also configure your internal domains in the local-domains.list
file for this feature to work properly (See local-domains-example.list)
.
You can override NS Servers for your local zones, as well as standard record types such as CNAME, A, and AAAA, for example.
Generally speaking the application is for when you want to let your internal main domain be resolved by your Domain Controller (e.g. Samba LDAP, Microsoft ADDS, etc.), but you also want other internal domains to resolve to your internal reverse proxy without having to manually administrate each zone.
For that end you may put all your internal domains except for your main domain
in the local-domains.list
file, and define your main domain as main_domain
(For alternative functions like postresolve_binat
to work).
CNAME internal domain replacement has disabled CNAME full chain resolution by default as it's a synchronous operation that uses dig through lua to enable post-resolve functions (PowerDNS does not support executing post-resolve functions after executing FollowCNAMERecords).
You may enable it by setting cname_resolver_enabled
to true (see settings).
-- /etc/powerdns/pdns-recursor-scripts/conf.d/example.lua
-- Beware, this file gets directly included into the hooks.lua file
-- You can load multiple config files, repeated options will be replaced by the last file.
-- Recommended names: overrides.lua || settings.lua || conf_dnsbl.lua || conf_local.lua
return {
-- Local Domain Override Options
main_domain = "example.com",
use_one_to_one = false,
one_to_one_subnets = {
["127.0.0.0/16"]={
["target"]="127.1.0.0/16",
["acl"]={
"100.64.0.0/10",
}
}
},
internal_reverse_proxy_v4 = "YOUR_INTERNAL_WEB_REVERSE_PROXY",
internal_reverse_proxy_v6 = "YOUR_INTERNAL_WEB_REVERSE_PROXY",
use_local_forwarder = false,
exclude_main_domain_from_irp = true,
exclude_local_forwarder_domains = {
"external.example.com"
},
exclude_local_forwarder_domains_re = {
"^(sub1|sub2).example.com$"
},
-- Exact matches have higher priority
override_map = {
{
name="static.example.com",
qtype="CNAME",
content={
"webserver.example.com"
}
}
},
--[[
Regex matches are sequentially checked, so you should keep your higher
specificity patterns on top.
]]
regex_map = {
{
pattern="^(mail|smtp|imap|smtps|smtp)\\..*$",
qtype="CNAME",
content={
"mx.example.com"
}
},
{
pattern="^(a-record)\\..*$",
qtype="A",
content={
"127.0.0.1"
}
},
{
pattern="^(cname-record-1)\\..*$",
qtype="CNAME",
content={
"mail.example.com"
}
},
{
pattern="^.*$",
qtype="NS",
content={"ns1.example.com","ns2.example.com"}
},
},
default_ttl = 900,
-- For local cname chain resolution
cname_resolver_enabled = false
-- Usually you won't need to change the address.
cname_resolver_address = "127.0.0.1"
-- Change this if your PowerDNS Recursor is on a non-standard port.
cname_resolver_port = 53
-- Extra Debug Logging options
debug_pre_override = false,
debug_post_one_to_one = false,
-- Malware Filter Options
use_dnsbl = false, -- If you want to preresolve with DNSBL files (.list|.txt) in the dnsbl.d directory
use_ipbl = false, -- If you want to postresolve with IPBL files (.list|.txt) in the ipbl.d directory
}
For Blocklists and some Malware Filtering DNS you may use the following
options in the /etc/powerdns/pdns-recursor-scripts/conf.d/malware-filter.lua
.
- Adblock: ||example.com^
- PCRE: Assumed if matches special regex chars and not Adblock Syntax
- HOSTS: Entries starting with the following IPs will be ingested/blocked
- 0.0.0.0
- 127.0.0.1
- ::
- 2001:1::1
- Standard: A normal TXT Domain list.
To whitelist domains create a /etc/powerdns/pdns-recursor-scripts/conf.d/whitelist.txt
file with one domain per line.
-- /etc/powerdns/pdns-recursor-scripts/conf.d/malware-filter.lua
return {
use_dnsbl = true, -- If you want to preresolve with DNSBL files (.list|.txt|.hosts) in the dnsbl.d directory
use_ipbl = true, -- If you want to postresolve with IPBL files (.list|.txt|.hosts) in the ipbl.d directory
}
To reload the lists all you need to do is execute the following command:
rec_control reload-lua-script
OR
rec_control reload-lua-script /etc/powerdns/pdns-recursor-scripts/hooks.lua
You may also add this onto a cronjob with the following format to reload every day at 00:00.
00 00 * * * root rec_control reload-lua-script /etc/powerdns/pdns-recursor-scripts/hooks.lua 2&>1 /dev/null
- Blocked IPs: https://rules.emergingthreats.net/fwrules/emerging-Block-IPs.txt
- Compromised IPs: https://rules.emergingthreats.net/blockrules/compromised-ips.txt
- Hagezi DNS Blocklists: https://github.com/hagezi/dns-blocklists
- Steven Black Hosts:
The following PowerDNS Documents were used as reference.
- https://docs.powerdns.com/authoritative/genindex.html
- https://docs.powerdns.com/recursor/lua-scripting/configure.html
- https://docs.powerdns.com/recursor/lua-scripting/index.html
- https://docs.powerdns.com/recursor/lua-scripting/dq.html#dnsrecord-object
- https://docs.powerdns.com/recursor/lua-scripting/netmask.html
Feel free to contribute to the project with fixes or feature ideas you might need!
This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with this program. If not, see https://fsf.org/.
This program comes with ABSOLUTELY NO WARRANTY.