# Configuration

This chapter describes how to configure the ZoneControl service.

After changing settings, do not forget to restart the service.

## Database configuration

ZoneControl, by default, uses an SQLite database located at `/var/lib/zonecontrol/zonecontrol.db`. Should another database be needed, it needs to be configured in `/etc/zonecontrol/settings.py`.

Django offers connectors for many types of database servers, described in its online documentation.

To enable support for databases other than SQLite, the package with the database driver must be installed. These packages are named “zonecontrol-<database>”. The following databases are supported:

Database | Package-suffix | Engine in `DATABASES`
--- | --- | ---
MySQL | `mysql` | django.db.backends.mysql

Now configure the database in `/etc/zonecontrol/settings.py`, set the ENGINE to the Engine from the table. The rest of the settings are self-explanatory:

    DATABASES = {
        'default': {
            'ENGINE': '$ENGINE',
            'NAME': 'mydatabase',
            'USER': 'mydatabaseuser',
            'PASSWORD': 'mypassword',
            'HOST': '127.0.0.1',
            'PORT': '',
        }
    }

After setting up a new database, it need to be populated with database tables. Run the following command as the `zonecontrol` user:

    zonecontrol-manage migrate

## Secret configuration

The Django web framework relies on a “secret key” for encrypting cookies, password reset tokens and other uses (see the online documentation for more).

This key is generated upon package installation in `/var/lib/zonecontrol/secret_key`.

Should this key not be set or if it is too short, ZoneControl will not start. Generate a new key and add it to the configuration file:

    /usr/share/zonecontrol/bin/python3 -c 'import random; import string; print("".join([random.SystemRandom().choice("{}{}{}".format(string.ascii_letters, string.digits, string.punctuation)) for i in range(50)]))' > /var/lib/zonecontrol/secret_key

## HTTP Service configuration

The Gunicorn HTTP server is configured in the `/etc/zonecontrol/gunicorn_config.py` file. By default, it will listen for HTTP connections on `127.0.0.1:8083`.

A sane configuration is below:

    # Config file for the gunicorn HTTP server
    # See: http://docs.gunicorn.org/en/stable/settings.html
    import multiprocessing
    import os

    # This only has an effect if setproctitle is installed.
    proc_name = 'zonecontrol'

    raw_env = ['DJANGO_SETTINGS_MODULE=project.settings', 'GUNICORN=1']
    bind = ['127.0.0.1:8053']
    workers = multiprocessing.cpu_count() * 2
    threads = 8 # per worker
    timeout = 30 # sec

    chdir = '/usr/share/zonecontrol'

    accesslog = '/var/log/zonecontrol/access.log'
    access_log_format = '%(h)s (%({X-Forwarded-For}i)s) %(l)s %(u)s %(t)s "%(r)s" %(s)s %(b)s "%(f)s" "%(a)s"'
    errorlog = '/var/log/zonecontrol/error.log'
    loglevel = 'info'
    # syslog = True

For more settings, please consult the online documentation.

## Scheduled Changes Deployment

In order to deploy scheduled changes, ZoneControl comes with a small service called `zonecontrol-scheduler.service`. This service reads the Scheduled Changes from the database and applies them when needed.

## Zones List Caching

New in version 1.2.0.

ZoneControl can cache the zones-list in redis to speed up calls from the frontend.

Note

Only the list of zones is cached, not the zone contents.

When changes are made, ZoneControl also stores these mutations in the cache after they have been accepted by PowerDNS. A seperate service called `zonecontrol-cache` loads the list of zones into redis and prunes the mutations at regular intervals. The zones-list is stored wih an expiry time so the cache is either empty or recent.

ZoneControl will always attempt to load the zones-list from the cache, if it cannot find the list or caching is explicitly disabled, it will fall back to loading the list from PowerDNS.

### Enabling Caching

On installations on CentOS, install the `zonecontrol-cache` package, this will also install `redis`. For Debian installations, install the `redis` package.

Then start and enable both redis and the zonecontrol-cache services:

    systemctl enable redis.service
    systemctl start redis.service
    systemctl enable zonecontrol-cache.service
    systemctl start zonecontrol-cache.service

### Cache configuration

The caching behaviour is controlled by several options in `/etc/zonecontrol/settings.py`.

`ZONECONTROL_CACHE_ZONES`:

  Whether or not to cache zones lists (for `zonecontrol-cache`) and to attempt to retrieve them (for ZoneControl), default `True`.

`ZONECONTROL_CACHE_ZONES_LOCATION`:

  Connection URL for Redis. By default database 1 on localhost without authentication and encryption. is used. The redis-py documentation describes this URI in detail. Default is `"redis://127.0.0.1:6379/1"`.

`ZONECONTROL_CACHE_ZONES_INTERVAL`:

  After `zonecontrol-cache` has added a new list to the cache, this setting controls how long it will wait before starting a new retrieval. Default is `60`.

`ZONECONTROL_CACHE_ZONES_EXPIRE_TTL`:

  How long a zones-list is cached in redis before automatically removed, in seconds. Default is `300`.

After changing the settings, restart `zonecontrol-cache.service`.

## Zones Overview DNSSEC Retrieval

New in version 1.2.0.

By default, the PowerDNS API includes the `dnssec` field when the list of zones is retrieved. Generating this field takes 5 queries to the database per zone in the list. When the database is slow, has high latency or the list of zones is huge, this can severely impact the performance of the zones overview in the ZoneControl frontend.

PowerDNS Authoritative Server 4.2.1 introduced the possiblity to request the zones-list without dnssec information. ZoneControl takea advantage of this API feature by default. To have ZoneControl request DNSSEC information from PowerDNS, set `ZONECONTROL_ZONE_OVERVIEW_DNSSEC` to `True` in `/etc/zonecontrol/settings.py`.

The downside of this feature is the loss of the “DNSSEC” column on the overview page of ZoneControl.

## Restriction of Zone Kinds

New in version 1.1.0.

Operators might want to limit the kind of zones that can be created through ZoneControl. This can be done using the `ZONECONTROL_ALLOW_ZONE_KINDS` list in `/etc/zonecontrol/settings.py`.

By default, all kinds are allowed. To only allow Native zones:

    from project.zonecontrol import ZONE_KIND_NATIVE
    ZONECONTROL_ALLOW_ZONE_ACTIONS = [ZONE_KIND_NATIVE]

Note: while in the UI for the user the Master & Slave kinds have been renamed to Primary & Secondary, this is not the case for the config settings. One should still use `ZONE_KIND_MASTER` and `ZONE_KIND_SLAVE` for restricting zone kinds.

## Advanced DNSSEC

New in version 1.1.0.

When a user has the “Advanced DNSSEC” permissions, they can manipulate single DNSSEC keys for zones. The ZoneControl configuration can limit the DNSSEC algorithms that are allowed to be created. There are two settings related to this.

`ZONECONTROL_ADVANCED_DNSSEC_ALGORITHMS`:

  This is the list of algorithms that is shown in the selection box and that are allowed when keys are created through the ZoneControl API. By default, these are `[DNSSEC_ALGO_ECDSA256, DNSSEC_ALGO_ECDSA384, DNSSEC_ALGO_ED25519]`.

`ZONECONTROL_ADVANCED_DNSSEC_DEFAULT_ALGORITHM`:

  This is the algorithm that is set in the Advanced DNSSEC views’ selection box by default. This algorithm must be in the `ZONECONTROL_ADVANCED_DNSSEC_ALGORITHMS` list and is `DNSSEC_ALGO_ECDSA256` by default.

## Default NSEC3PARAM

New in version 1.4.2.

The default `NSEC3PARAM` is set to `1 0 0 -` in `/etc/zonecontrol/settings.py` and can be changed there. These parameters are recommended by RFC9276.

## Automatic PTR Creation

New in version 1.1.0.

ZoneControl can create PTR records for A and AAAA records that are created or modified. This can be disabled in the configuration by setting `ZONECONTROL_ALLOW_AUTOMATIC_PTR` to `False` in `/etc/zonecontrol/settings.py`.

## Zone Actions

New in version 1.1.0.

Users with permissions to access zones can force actions like queuing NOTIFY messages to secondaries or (re-)retrieving a secondary zone. The allowed actions are specified in `ZONECONTROL_ALLOW_ZONE_ACTIONS`. By default this is set to `[ZONE_ACTION_NOTIFY, ZONE_ACTION_AXFR_RETRIEVE]`.

## Prometheus Metrics

New in version 1.5.1.

Prometheus metrics will be exported on the `/metrics` URL path. This is the default path for Prometheus so just pointing your Prometheus configuration at the `host:port` target should be enough.

The metrics are disabled by default and can be enabled by setting `ZONECONTROL_METRICS_ENABLED` to `True` in `/etc/zonecontrol/settings.py`.

The metric for the number of zones (`zonecontrol_zones`) is only available when the caching of zones is enabled. See Zones List Caching.

## Catalog Zone Support

New in version 1.6.0.

Note: Catalog zone support in ZoneControl will only work for PowerDNS Authoritative Server v4.9 and higher versions.

Support for Catalog Zones is disabled by default (see the note above) and can be enabled by setting `ZONECONTROL_CATALOG_ZONE_SUPPORT` to `True` in `/etc/zonecontrol/settings.py`.

When viewing a catalog zone there will be a new section where zones can be added and removed from the catalog.

## Audit Logging to Standard Out or File

New in version 1.6.0.

Audit logging can be echoed to standard out or a file by setting `ZONECONTROL_AUDITLOG_STDOUT` to `True` in `/etc/zonecontrol/settings.py`. It is disabled by default.

These audit log lines are in JSON format but it is also possible to have plain text output; this is done by setting `ZONECONTROL_JSON_LOGGING` to `False` in the same settings file.

(The `ZONECONTROL_JSON_LOGGING` setting only applies to the audit logging at the moment, but it is the intention to do all ZoneControl logging in JSON format in some future ZoneControl major release at which point this setting will apply to all logging.)