8 design views
Daniel Salzman edited this page 2018-09-17 08:54:44 +00:00

This document is not up-to-date!

Design Document: Views

[[TOC]]

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