Filtering
Filtering is an option which can be enabled on the following components:
- dnsdist
- Recursor
When enabled, filtering matches DNS traffic against policy rules to determine whether or not the filtering engine should intervene. Crucial to understanding filtering are the following concepts:
- Feeds: Provides categorized lists of domains which can be referenced in policy rules, deployed as part of Controlplane
- Static Settings: Static set of configuration instructing the filtering engine how to combine the feeds, vHosts, policy rules, etc to create a comprehensive filtering solution
- vHosts: Virtual hosts in dnsdist which can be assigned specific policy rules and/or filter settings
Configuration Reference
Filter Settings
Sets of filter settings can be defined under the root node filterSettings
. Each set of settings should be a key-value pair, with:
- key: Name of the set
- value: Dictionary holding the configuration of filter settings
The configuration can be quite complex, as there are several concepts involved. Make sure you understand the concepts explained in this guide before attempting to configure them.
Parameters which can be used to configure filter settings are shown in the below table.
Parameter | Type | Default | Description |
---|---|---|---|
logFormat |
string |
"human" |
Format of logging. Available options: "human" "json" |
logLevel |
string |
"info" |
Level of logging. Available options: "debug" "info" "warn" "error" |
proxies |
List of string |
IP addresses of proxies to be returned when traffic is filtered, unless overridden at a lower level (vHost for example). Can be a list of both IPv4 and IPv6 addresses |
|
vHosts |
Map of vHost | {} |
vHosts configuration |
vHostService |
dnsdistService | type: ClusterIP |
Default service object used as template for all vHost service objects. Can also be overridden on each vHost configuration |
feeds |
List of Feed | [] |
Feeds to be consumed for use in filtering |
static |
StaticSettings | {} |
Static settings configuration |
Feed configuration
When feeds are configured, the dnsdist or recursor pod which is performing filtering will have an extra container named oxfeedclient
which will be responsible to download the feeds, process them and repeat when it identifies the upstream feeds have been updated. These feeds are provided by the Controlplane Feeds.
Example of a configuration with one feed:
filterSettings:
mysettings:
feeds:
- url: https://commandsource-testcmdsource.controlplane.svc:8443/feed/
namespace: testfeed
username: myUsername
password: myPassword
tlsconfig:
insecure_skip_verify: true
The above configuration will cause the oxfeedclient
container to consume a feed from the url https://commandsource-testcmdsource.controlplane.svc:8443/feed/
and expose the learned categories via the naming convention [NAMESPACE NAME]/[CODE]
. In this example, if the feed contains a category with code 1
, it would be accessible as testfeed/1
.
Additionally, it attempts to authenticate using myUsername
and myPassword
and will not attempt to perform any TLS verification (not recommended).
Parameters which can be used to configure feeds are shown in the below table.
Parameter | Type | Required | Default | Description |
---|---|---|---|---|
loadFirst |
boolean |
false |
If true, prioritize this feed when the oxfeedclient container starts. If multiple feeds are configured this can be used to ensure a specific feed is loaded first. |
|
namespace |
string |
yes |
Namespace to prepend to the codes of the categories learned from this feed | |
password |
string |
Password to use for authentication with the feed. Using secretName is preferred |
||
secretName |
string |
Name of a pre-existing Kubernetes Secret containing a username & password for authentication with the feed | ||
secretPasswordKey |
string |
"password" |
If secretName is specified: name of the item inside the Secret which holds the password |
|
secretUsernameKey |
string |
"username" |
If secretName is specified: name of the item inside the Secret which holds the username |
|
url |
string |
yes |
Full URL of the feed | |
username |
string |
Username to use for authentication with the feed. Using secretName is preferred |
||
tlsconfig |
TLSConfig | {} |
TLS configuration options |
Feed TLS config
Parameter | Type | Required | Default | Description |
---|---|---|---|---|
ca |
string |
CA in PEM format to use for validation. Use of caSecret is recommended for security reasons |
||
caSecret |
string |
Name of a pre-existing Kubernetes Secret with a data item named ca.crt containing the CA in PEM format to use for validation |
||
insecure_skip_verify |
boolean |
false |
Skip validation of the feed's certificate chain and hostname |
Static Settings
Parameters which can be used to configure static filtering settings are shown in the below table.
Parameter | Type | Default | Description |
---|---|---|---|
categories |
List of Category | [] |
Categories to be calculated |
domainlists |
Map of DomainList | {} |
Static domain lists |
filtersettings |
List of UserSettings | [] |
Mapping of users, products, profiles, etc to filtering objects such as domainlists and categories |
ipmappings |
List of IPMapping | [] |
Mapping of IP prefixes to users |
policyrules |
List of PolicyRules | [] |
Filtering policies |
Categories
These calculated categories allow for the combination of categories learned from feeds. For example:
filterSettings:
mysettings:
static:
categories:
- name: calccategory
title: My calculated category
codes:
- myfeed/1
- otherfeed/1
- otherfeed/2
The above will expose a category named calccategory
which will contain the sum of DomainPaths from:
- Category with code
1
in the feed configured withnamespace: myfeed
- Categories with codes
1
and2
in the feed configured withnamespace: otherfeed
Parameters which can be used to configure categories are shown in the below table.
Parameter | Type | Required | Default | Description |
---|---|---|---|---|
codes |
List of string |
yes |
List of codes learned from feed(s) | |
name |
string |
yes |
Name of the category | |
title |
string |
Title of the category. Only used for presentation purposes |
Domain Lists
Domain lists allow for the configuration of static lists of domains to which filtering decisions can be applied. For example:
filterSettings:
mysettings:
static:
domainlists:
global-allow-list:
- powerdns.com
global-block-list:
- evil.example
- malware.example
The above will expose 2 static domain lists:
- Domain list
global-allow-list
containing thepowerdns.com
domain - Domain list
global-block-list
containing 2 example domains that may be desirable to block
These domain lists can be referenced by Setting Mappings and Policy Rules using their names (ie: global-allow-list
and global-block-list
).
User Settings
User Settings allow for defining user settings and mapping them to filtering objects. For example:
filterSettings:
mysettings:
static:
filtersettings:
- username: user1
filter_content: true
named_category_lists:
categories-denylist:
- someCategory
Above mapping will assign the user user1
a user-scoped category list named categories-denylist
which contains the category named someCategory
. This user-scoped category list categories-denylist
can then be referenced in policy rules.
filter_content
The filter_content
parameter must be set to true
to enable the filtering of defined content
such as the members of the someCategory
category in the above example.
Parameters which can be used to configure user settings are shown in the below table.
Parameter | Type | Required | Default | Description |
---|---|---|---|---|
username |
string |
yes |
Username to match against | |
timezone |
string |
Timezone in the format Europe/Amsterdam , local time of the server if unspecified and UTC if configured with an unknown timezone |
||
usertags |
List of string |
[] |
Extra tags for the user which can be referenced in policy rules | |
product |
string |
"" |
Product used by user which can be referenced in policy rules | |
filter_content |
boolean |
false |
If true, apply the filtering of named_category_lists and named_domain_lists |
|
named_category_lists |
Map of UserScopedCategoryList | {} |
Category lists scoped to this user | |
named_domain_lists |
Map of UserScopedDomainList | {} |
Domain lists scoped to this user |
User scoped category list
A user scoped category list allows for configuring category lists which only apply to that specific user. For example:
filterSettings:
mysettings:
static:
filtersettings:
- username: user1
filter_content: true
named_category_lists:
categories-allowlist:
- socialmedia
categories-denylist:
- malware
- botnets
In the above example, this user's scope has the following category lists defined:
- Category list
categories-allowlist
references the categorysocialmedia
with the intention of allowing this user access to social media - Category list
categories-denylist
references the categoriesmalware
andbotnets
with the intention of safeguarding the user against potentially bad actors
Policy Rules
These category lists have only been scoped to the user, they still need to be enforced by a policy rule to become active
User scoped domain list
A user scoped domain list allows for configuring domain lists which only apply to that specific user. For example:
filterSettings:
mysettings:
static:
filtersettings:
- username: user1
filter_content: true
named_domain_lists:
domains-allowlist:
- powerdns.com
domains-denylist:
- malware.example
- botnet.example
In the above example, this user's scope has the following domain lists defined:
- Domain list
domains-allowlist
references the domainpowerdns.com
with the intention of allowing this user access to this domain - Domain list
domains-denylist
references the categoriesmalware.example
andbotnet.example
with the intention of safeguarding the user against resolving these domains
Policy Rules
These domain lists have only been scoped to the user, they still need to be enforced by a policy rule to become active
IP Mapping
IP Mappings allow for mapping of IP prefixes to users. For example:
filterSettings:
mysettings:
static:
ipmappings:
- prefix: 10.0.0.0/8
username: private
- prefix: 172.16.0.0/12
username: private
- prefix: 192.168.0.0/16
username: private
Above mapping will assign the user private
to traffic originating from the 3 IPv4 address ranges allocated for private networks.
Parameters which can be used to configure ip mappings are shown in the below table.
Parameter | Type | Required | Default | Description |
---|---|---|---|---|
prefix |
string |
yes |
Prefix to match against | |
username |
string |
yes |
Username to assign to traffic matched against this prefix |
Policy Rules
Policy rules tie together all the other objects which have been configured and are the glue which enables the actual filtering process. For example:
filterSettings:
mysettings:
static:
domainlists:
global-block-list:
- evil.example
- malware.example
policyrules:
- name: block-domain-list
scope: all
action: blacklist
source: list
source_list: global-block-list
In this example we define a domainlist
named global-block-list
containing 2 domains which we want to globally block for everybody.
We then have a policy rule named block-domain-list
which will perform the action blacklist
(ie: block) for this domainlist by specifying source
to be a list
and refer to the name by setting source_list
to the name of our list: global-block-list
.
Parameters which can be used to configure policy rules are shown in the below table.
Parameter | Type | Required | Default | Description |
---|---|---|---|---|
priority |
integer |
Priority of this rule. If unset the priority is defined by the ordering of the list, where the first entry is first applied, then second, etc. | ||
name |
string |
yes |
Name of the policy rule | |
action |
string |
yes |
Action to be taken when matched. Available options: "whitelist" "blacklist" "monitor" |
|
scope |
string |
yes |
Scope of the rule. Available options: "all" "content" "security" "homework" In the current release only "all" and "content" are applicable and have the same outcome |
|
source |
string |
yes |
Type of object to match against. Available options: "category" "code" "list" |
|
products |
List of string |
Products to match against | ||
category_list |
string |
If source: category and source_category_mode: user , set this to the name of the User scoped category list |
||
usertag |
string |
If set, match against this usertag | ||
source_list |
string |
If source: list , set this to the name of the domain list |
||
source_codes |
List of string |
If source: code , set this to a list of codes to match against.These should be namespaced codes, ie: testfeed/2 and myfeed/3 |
||
source_category_mode |
string |
If source: category , specify whether the category should be fetched from: A statically defined category under categories : set this to static A category list defined as User scoped category list: set this to user |
||
source_category_static |
List of string |
If source: category and source_category_mode: static , set this to a list of names of categories defined under categories |
||
redirect_ips |
List of string |
IP addresses of proxies to be returned when this policy rule is blocking. Can be a list of both IPv4 and IPv6 addresses |
||
redirect_rcode |
integer |
Numerical representation of DNS RCode to be returned when this policy rule is blocking. Available options: NoError: 0 ServFail: 2 NXDomain: 3 |
vHosts
When virtual hosts (vHosts) are defined in a filterSettings
configuration and the settings are applied to a set of dnsdist instances, the following happens:
- Service objects are created for each vHost to expose it users
- vHosts can be referenced in rules to apply different policies to them
To define vHosts, you can use the vHosts
parameter inside your filterSettings
configuration, for example:
Each defined vHost can be further configured using the following parameters:
Parameter | Type | Default | Description |
---|---|---|---|
defaultproduct |
string |
Default product to be assigned to traffic on this vHost which is not matched to a user | |
defaultredirect |
string |
This overrides the global 'defaultredirect' setting for this vhost if set. It only affects the HTTP proxy. | |
defaultuser |
string |
Default user to be assigned to traffic on this vHost when the source IP is not matched | |
forceuser |
string |
User to be forced on all traffic on this vHost | |
metricsname |
string |
Name to be used for this vHost in metrics, if unset this will be derived from the name of the vHost | |
protobuftag |
string |
Additional protobuf tag to set if traffic on this vHost is exported to dstoredist | |
proxies |
List of string |
IP addresses of proxies to be returned when traffic is filtered. Can be a list of both IPv4 and IPv6 addresses |
|
proxydeviceprofile |
integer |
Set a fixed device profile number for traffic on this vHost | |
service |
dnsdistService | Configuration of the dnsdist service object for this vHost | |
unfiltered |
boolean |
false |
If true, no filtering is applied to traffic on this vHost |