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 |
|---|---|---|
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¶
Added 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), defaultTrue.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_PASSWORD:Password for Redis. Default is
None(ie: no password). If Redis ACLs are used, the username can be supplied as part of the URI described above.ZONECONTROL_CACHE_ZONES_INTERVAL:After
zonecontrol-cachehas added a new list to the cache, this setting controls how long it will wait before starting a new retrieval. Default is60.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¶
Added 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¶
Added 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¶
Added 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_ALGORITHMSlist and isDNSSEC_ALGO_ECDSA256by default.
Default NSEC3PARAM¶
Added 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¶
Added 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¶
Added 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¶
Added 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¶
Added 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¶
Added 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.)
Branding¶
Added in version 1.8.0.
A custom logo can be displayed in place of the default PowerDNS logo by setting
ZONECONTROL_CUSTOM_LOGO_URL.
The SVG (Scalable Vector Graphics) and PNG (Portable Network Graphics) image file formats are recommended. For optimal visual effect, ensure that the image has a transparent background; PNGs should be at least 60 pixels in height.
To serve a custom logo using ZoneControl, place the file under
/etc/zonecontrol/$WHITENOISE_ROOT/images and set
ZONECONTROL_CUSTOM_LOGO_URL to /images/$FILE_NAME. The value of
WHITENOISE_ROOT is declared in /etc/zonecontrol/settings.py.
OpenID Connect (OAuth2)¶
Added in version 1.8.0.
This section describes how to add OpenID Connect support. Usually this should be done by PowerDNS Professional Services.
OIDC support is done through the AllAuth package. While AllAuth supports a lot of different kinds of “social logins” only OIDC is supported and tested by us.
Mapping to ZoneControl Permissions¶
The following roles are expected to exist in ZoneControl when OIDC support is enabled:
oauth_default_readonlyoauth_default_add_zonesoauth_default_delete_zonesoauth_default_change_settingsoauth_default_change_dnssecoauth_default_advanced_dnssecoauth_default_restore_versionoauth_default_all_permissions
They can either be created by hand or will be created on ZoneControl startup when ZONECONTROL_CREATE_OAUTH_DEFAULT_ROLES is set to True in settings.py (see next section).
On the OIDC side the following items need to be put into the roles for the user to map them to ZoneControl:
zc:readonlyzc:add_zoneszc:delete_zoneszc:change_settingszc:change_dnsseczc:change_view_networkszc:advanced_dnsseczc:restore_versionzc:all_permissions
The OIDC group zc:readonly will be mapped to the oauth_default_readonly role in ZoneControl, etc.
The zc: prefix is configurable and can be set in settings.py with:
ZONECONTROL_OAUTH_ROLE_PREFIX = 'another_prefix:'
settings.py¶
AllAuth can be enabled by setting ENABLE_ALLAUTH to True at the top of the settings file.
The ZONECONTROL_CREATE_OAUTH_DEFAULT_ROLES setting determines whether the required roles will be automatically created on ZoneControl startup (but existing ones with the same name will not be changed!):
ZONECONTROL_CREATE_OAUTH_DEFAULT_ROLES = True
The SOCIALACCOUNT_PROVIDERS section needs to be added (see providers). (Where $VALUE needs to be replaced with the relevant IDP settings.)
SOCIALACCOUNT_PROVIDERS = {
"openid_connect": {
"SCOPE": [
"openid", # default scope
"email", # default scope
"profile", # default scope
],
"APPS": [
{
"provider_id": "$PROVIDER_ID",
"name": "$NAME",
"client_id": "$CLIENT_ID",
"secret": "$SECRET",
},
]
}
}
(Please see the “providers” link above for the redirect_url and server_url settings which will possibly be needed.)
ENABLE_ALLAUTH will set the following values:
LOGIN_URL = '/allauth/accounts/login/'LOGOUT_REDIRECT_URL = '/allauth/accounts/login/'
allauth.account.middleware.AccountMiddleware needs to be added after
django.contrib.messages.middleware.MessageMiddleware in MIDDLEWARE:
MIDDLEWARE = [
[...]
'django.contrib.messages.middleware.MessageMiddleware',
'allauth.account.middleware.AccountMiddleware',
[...]
AllAuth apps need to be added to INSTALLED_APPS (put them above project.zonecontrol):
INSTALLED_APPS = [
[...]
'allauth',
'allauth.account',
'allauth.socialaccount',
'allauth.socialaccount.providers.openid_connect',
'project.zonecontrol',
[...]
The AUTHENTICATION_BACKENDS section needs to be either added or updated with the AllAuth item:
AUTHENTICATION_BACKENDS = [
[...]
'allauth.account.auth_backends.AuthenticationBackend',
]