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.
| URL | HTTP Verb | Action |
|---|---|---|
| /daf | GET | Return JSON list of active rules. |
| /daf | POST | Insert new rule, rule string is expected in body. Returns rule information in JSON. |
| /daf/<id> | GET | Retrieve a rule matching given ID. |
| /daf/<id> | DELETE | Delete a rule matching given ID. |
| /daf/<id>/<prop>/<val> | PATCH | Modify 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