This document is not up-to-date!
Design Document: Views
Purpose of Views
Views allow the server to expose the same zone with different content to different clients. This functionality has been available in BIND for years and although it brings some operational problems, quite a lot of users are brave enough to request this functionality to be added into Knot DNS.
Proposed implementation
The proposed implementation utilizes existing ACLs to build matching rules for views. The views are defined in a new configuration section view. Each view has two attributes: The priority attribute to control order of evaluation and the acl attribute carrying a list of ACLs to match.
The views are sorted by a compound key (priority, id) in ascending order and evaluated sequentially. The first matching ACL determines the view, any ACL in a view can match.
The new syntax is as follows:
view:
- id: STR
priority: NUM
acl: acl_id ...
A view can be then assigned to a template or a zone using the view attribute. This attribute
is multi-valued and the zone can be thus assigned into multiple views. Also, in order to be able
to identify multiple zones with the same name but a different template, a domain attribute of
a zone is optionally suffixed with the at sign (@
) and an arbitrary alias. The whole attribute
must be unique.
The template and zone syntax is modified as follows:
template:
- id: STR
view: view_id ...
# existing options
zone:
- domain: DNAME[@STR]
view: view_id ...
# existing options
For backward compatibility, the defaults are defined as follows:
view:
- id: default
priority: 0
acl: []
template:
- id: default
view: default
# existing defaults
Use Cases
This section describes a few basic uses of the proposed functionality with configuration file examples.
Public domain split-view
A company has a public domain acme.test. The zone visible to the world is different from the zone visible to clients inside an internal network. In addition, there is an internal subdomain int.acme.test visible only for the internal clients.
acl:
- id: internal_clients
address: [192.168.0.0/16]
action: query
view:
- id: internal
priority: 1
acl: interal_clients
- id: external
priority: 2
zone:
- domain: acme.test
view: external
file: acme.test.zone
- domain: acme.test@internal
view: internal
file: int/acme.test.zone
- domain: int.acme.test
view: internal
file: int/int.acme.test.zone
Zone in multiple views
A zone can be exposed via multiple views. Let's have an external network, an office network, and a lab network. Again, the parent zone acme.test exists in two variants (one for the world, one internal for the company) and again the int.acme.test child zone is available to all internal clients. In addition, there is a builds.acme.test zone visible only within the lab network. In addition, a system administrator can use their TSIG key and access that zone from anywhere.
key:
- id: alice.admin
algorithm: hmac-sha256
secret: ffObJdpfV2AiY7qHQgLFbk0mOzaGfyKQFmx/kpg2lE8=
acl:
- id: office
address: 192.168.1.0/24
action: query
- id: lab
address: [192.168.2.0/24, 10.0.0.0/8]
action: query
- id: admins
key: alice.admin
action: query
view:
- id: admin
priority: 0
acl: admins
- id: office
priority: 1
acl: office
- id: lab
priority: 2
acl: lab
- id: external
priority: 100
zone:
- domain: acme.test
view: external
file: acme.test.zone
- domain: acme.test@internal
view: [admin, office, lab]
file: int/acme.test.zone
- domain: int.acme.test
view: [admin, office, lab]
file: int/acme.test.zone
- domain: builds.acme.test
view: [admin, lab]
file: builds.acme.test.zone
Zone transfers with views
To differentiate a view for the purpose of zone transfer, a different TSIG key can be used. Let's limit the configuration to two views only, and share the common configuration between zones using templates.
Master server configuration:
key:
- id: int.slaves
algorithm: hmac-sha256
secret: vZNKk2r/iuybafZ1mjpEHnzaThr/xcTSBLtOmOHVtbo=
- id: ext.slaves
algorithm: hmac-sha256
secret: HVo02ON60KDJneMIpKksSqCWa4w5CwE44U45aIpGfv8=
acl:
- id: transfer_to_slave
key: [int.slaves, ext.slaves]
address: 172.16.100.0/8
action: transfer
- id: query_from_slave_internal
address: 172.16.100.0/8
key: int.slaves
action: query
- id: query_from_slave_external
address: 172.16.100.0/8
key: ext.slaves
action: query
- id: query_from_internal_client
address: [ 192.168.0.0/16, 10.0.0.0/8 ]
action: query
view:
- id: internal
priority: 1
acl: [query_from_internal_client, query_from_slave_internal]
- id: external
priority: 2
template:
- id: default
view: internal
file: "/var/lib/knot/int_%s.zone"
acl: [transfer_to_slave]
- id: external
view: external
file: "/var/lib/knot/ext_%s.zone"
acl: [transfer_to_slave]
zone:
- domain: acme.test@ext
template: external
- domain: acme.test
- domain: int.acme.test
Matching slave server configuration:
# key: ...
# view: ...
remote:
- id: master_as_internal
address: 172.16.100.1
key: int.slaves
- id: master_as_external
address: 172.16.100.1
key: ext.slaves
template:
- id: default
view: internal
file: "/var/lib/knot/int_%s.zone"
master: master_as_internal
- id: external
view: external
file: "/var/lib/knot/ext_%s.zone"
master: master_as_external
# zone: ...
Zone transfers with views (another variant)
Master server configuration:
key:
- id: int_key
algorithm: hmac-sha256
secret: vZNKk2r/iuybafZ1mjpEHnzaThr/xcTSBLtOmOHVtbo=
- id: ext_key
algorithm: hmac-sha256
secret: HVo02ON60KDJneMIpKksSqCWa4w5CwE44U45aIpGfv8=
acl:
- id: int_xfr
key: int_key
address: 172.16.100.0/8
action: transfer
- id: ext_xfr
key: ext_key
address: 172.16.100.0/8
action: transfer
- id: int_query
address: [ 192.168.0.0/16, 10.0.0.0/8 ]
action: query # The 'query' action is default just for zone acl if no views are configured.
view:
- id: internal
priority: 0
acl: [ int_query, int_xfr ]
- id: external
priority: 99
acl: [ ext_xfr ]
template:
- id: default
file: "/var/lib/knot/int_%s.zone"
view: [ internal ]
- id: external
file: "/var/lib/knot/ext_%s.zone"
view: [ external ]
zone:
- domain: acme.test@ext
template: external
- domain: acme.test
- domain: int.acme.test