DNS Application Firewall

This module is a high-level interface for other powerful filtering modules and DNS views. It provides an easy interface to apply and monitor DNS filtering rules and a persistent memory for them. It also provides a restful service interface and an HTTP interface.

Example configuration

Firewall rules are declarative and consist of filters and actions. Filters havefieldoperatoroperand notation (e.g.qname=example.com), and may be chained using AND/OR keywords. Actions may or may not have parameters after the action name.

-- Let's write some daft rules!modules={'daf'}-- Block all queries with QNAME = example.comdaf.add'qname = example.com deny'-- Filters can be combined using AND/OR...-- Block all queries with QNAME match regex and coming from given subnetdaf.add'qname ~ %w+.example.com AND src = 192.0.2.0/24 deny'-- We also can reroute addresses in response to alternate target-- This reroutes 1.2.3.4 to localhostdaf.add'src = 127.0.0.0/8 reroute 192.0.2.1-127.0.0.1'-- Subnets work too, this reroutes a whole subnet-- e.g. 192.0.2.55 to 127.0.0.55daf.add'src = 127.0.0.0/8 reroute 192.0.2.0/24-127.0.0.0'-- This rewrites all A answers for 'example.com' from-- whatever the original address was to 127.0.0.2daf.add'src = 127.0.0.0/8 rewrite example.com A 127.0.0.2'-- Mirror queries matching given name to DNS loggerdaf.add'qname ~ %w+.example.com mirror 127.0.0.2'daf.add'qname ~ example-%d.com mirror 127.0.0.3@5353'-- Forward queries from subnetdaf.add'src = 127.0.0.1/8 forward 127.0.0.1@5353'-- Forward to multiple targetsdaf.add'src = 127.0.0.1/8 forward 127.0.0.1@5353,127.0.0.2@5353'-- Truncate queries based on destination IPsdaf.add'dst = 192.0.2.51 truncate'-- Disable a ruledaf.disable2-- Enable a ruledaf.enable2-- Delete a ruledaf.del2

If you’re not sure what firewall rules are in effect, seedaf.rules:

-- Show active rules> daf.rules[1] => {    [rule] => {        [count] => 42        [id] => 1        [cb] => function: 0x1a3eda38    }    [info] => qname = example.com AND src = 127.0.0.1/8 deny    [policy] => function: 0x1a3eda38}[2] => {    [rule] => {        [suspended] => true        [count] => 123522        [id] => 2        [cb] => function: 0x1a3ede88    }    [info] => qname ~ %w+.facebook.com AND src = 127.0.0.1/8 deny...    [policy] => function: 0x1a3ede88}

Web interface

If you haveHTTP/2 loaded, the firewall automatically loads as a snippet.You can create, track, suspend and remove firewall rules from the web interface.If you load both modules, you have to loaddaf afterhttp.

RESTful interface

The module also exports a RESTful API for operations over rule chains.

URLHTTP VerbAction
/dafGETReturn JSON list of active rules.
/dafPOSTInsert new rule, rule string is expected in body. Returns rule information in JSON.
/daf/<id>GETRetrieve a rule matching given ID.
/daf/<id>DELETEDelete a rule matching given ID.
/daf/<id>/<prop>/<val>PATCHModify given rule, for example /daf/3/active/false suspends rule 3.

This interface is used by the web interface for all operations, but you can also use it directlyfor testing.

# Get current rule set$ curl -s -X GET http://localhost:8453/daf| jq .{}# Create new rule$ curl -s -X POST -d"src = 127.0.0.1 pass" http://localhost:8453/daf| jq .{"count":0,"active": true,"info":"src = 127.0.0.1 pass","id":1}# Disable rule$ curl -s -X PATCH http://localhost:8453/daf/1/active/false| jq .true# Retrieve a rule information$ curl -s -X GET http://localhost:8453/daf/1| jq .{"count":4,"active": true,"info":"src = 127.0.0.1 pass","id":1}# Delete a rule$ curl -s -X DELETE http://localhost:8453/daf/1| jq .true