Skip to content

Commit

Permalink
Merge pull request #14055 from fredmorcos/meson-systemd-services
Browse files Browse the repository at this point in the history
Meson: `pdns-auth` and `ixfrdist` systemd service files
  • Loading branch information
fredmorcos committed Apr 11, 2024
2 parents ffee904 + 8f3205d commit a9f4dd7
Show file tree
Hide file tree
Showing 6 changed files with 279 additions and 9 deletions.
44 changes: 44 additions & 0 deletions auth/systemd/ixfrdist.service.in
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
[Unit]
Description=@Description@
Documentation=man:ixfrdist(1)
Documentation=man:ixfrdist.yml(5)
Documentation=https://doc.powerdns.com
Wants=network-online.target
After=network-online.target time-sync.target

[Service]
Type=simple
ExecStart=@BinDir@/ixfrdist @Config@
Restart=on-failure
RestartSec=1
StartLimitInterval=0

# Sandboxing
CapabilityBoundingSet=CAP_NET_BIND_SERVICE CAP_SETGID CAP_SETUID
NoNewPrivileges=true
DevicePolicy=closed
@LockPersonality@
@PrivateDevices@
@PrivateTmp@
@PrivateUsers@
@ProtectClock@
@ProtectControlGroups@
@ProtectHome@
@ProtectHostname@
@ProtectKernelLogs@
@ProtectKernelModules@
@ProtectKernelTunables@
@ProtectSystem@
@RestrictAddressFamilies@
@RestrictNamespaces@
@RestrictRealtime@
@RestrictSUIDSGID@
@SystemCallArchitectures@
@SystemCallFilter@
@ProtectProc@
@PrivateIPC@
@RemoveIPC@
@MemoryDenyWriteExecute@

[Install]
WantedBy=multi-user.target
49 changes: 49 additions & 0 deletions auth/systemd/pdns-auth.service.in
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
[Unit]
Description=@Description@
Documentation=man:pdns-auth(1)
Documentation=man:pdns-auth-control(1)
Documentation=https://doc.powerdns.com
Wants=network-online.target
After=network-online.target mysql.service mysqld.service postgresql.service slapd.service mariadb.service time-sync.target

[Service]
ExecStart=@StaticBinDir@/pdns-auth @ConfigName@ @SocketDir@ --guardian=no --daemon=no --disable-syslog --log-timestamp=no --write-pid=no
SyslogIdentifier=@SyslogIdentifier@
User=@ServiceUser@
Group=@ServiceGroup@
Type=notify
Restart=on-failure
RestartSec=1
StartLimitInterval=0
RuntimeDirectory=@RuntimeDirectory@

# Sandboxing
CapabilityBoundingSet=CAP_NET_BIND_SERVICE CAP_CHOWN
AmbientCapabilities=CAP_NET_BIND_SERVICE CAP_CHOWN
NoNewPrivileges=true
DevicePolicy=closed
@LockPersonality@
@PrivateDevices@
@PrivateTmp@
@PrivateUsers@
@ProtectClock@
@ProtectControlGroups@
@ProtectHome@
@ProtectHostname@
@ProtectKernelLogs@
@ProtectKernelModules@
@ProtectKernelTunables@
@ProtectSystem@
@RestrictAddressFamilies@
@RestrictNamespaces@
@RestrictRealtime@
@RestrictSUIDSGID@
@SystemCallArchitectures@
@SystemCallFilter@
@ProtectProc@
@PrivateIPC@
@RemoveIPC@
@MemoryDenyWriteExecute@

[Install]
WantedBy=multi-user.target
130 changes: 130 additions & 0 deletions meson.build
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ subdir('meson' / 'dlopen') # dlopen
subdir('meson' / 'verbose-logging') # Verbose Logging
subdir('meson' / 'pkcs11') # PKCS11
subdir('meson' / 'gss-tsig') # GSS-TSIG
subdir('meson' / 'libsystemd') # Systemd notification
subdir('meson' / 'systemd') # Systemd and unit file handling
subdir('meson' / 'code-coverage') # Code coverage
subdir('meson' / 'auto-var-init') # Automatic Variable Initialization
Expand Down Expand Up @@ -149,6 +150,135 @@ deps = [
dep_boost_test,
]

if dep_systemd.found()
systemd_service_conf = configuration_data()
systemd_service_conf.set('BinDir', get_option('bindir'))
systemd_service_conf.set('StaticBinDir', get_option('sbindir'))
systemd_service_user = get_option('systemd-service-user')
systemd_service_group = get_option('systemd-service-group')
systemd_service_conf.set('ServiceUser', systemd_service_user)
systemd_service_conf.set('ServiceGroup', systemd_service_group)
summary('Service User', systemd_service_user, section: 'Systemd')
summary('Service Group', systemd_service_group, section: 'Systemd')

# ProtectSystem=full will disallow write access to /etc and /usr, possibly not being
# able to write slaved-zones into sqlite3 or zonefiles.
systemd_service_conf.set(
'ProtectSystem', have_systemd_protect_system ? 'ProtectSystem=full' : '',
)
systemd_service_conf.set(
'SystemCallArchitectures',
have_systemd_system_call_architectures ? 'SystemCallArchitectures=native' : '',
)
systemd_system_call_filter = '~ @clock @debug @module @mount @raw-io @reboot @swap @cpu-emulation @obsolete'
systemd_service_conf.set(
'SystemCallFilter',
have_systemd_system_call_filter ? 'SystemCallFilter=' + systemd_system_call_filter : '',
)
systemd_service_conf.set(
'ProtectProc',
have_systemd_protect_proc ? 'ProtectProc=invisible' : '',
)

systemd_features = {
'LockPersonality': have_systemd_lock_personality,
'PrivateDevices': have_systemd_private_devices,
'PrivateTmp': have_systemd_private_tmp,
'PrivateUsers': false, # Setting it to true prevents us from opening our sockets.
'ProtectClock': have_systemd_protect_clock,
'ProtectControlGroups': have_systemd_protect_control_groups,
'ProtectHome': have_systemd_protect_home,
'ProtectHostname': have_systemd_protect_hostname,
'ProtectKernelLogs': have_systemd_protect_kernel_logs,
'ProtectKernelModules': have_systemd_protect_kernel_modules,
'ProtectKernelTunables': have_systemd_protect_kernel_tunables,
'RestrictNamespaces': have_systemd_restrict_namespaces,
'RestrictRealtime': have_systemd_restrict_realtime,
'RestrictSUIDSGID': have_systemd_restrict_suidsgid,
'PrivateIPC': have_systemd_private_ipc,
'RemoveIPC': have_systemd_remove_ipc,
}

foreach feature, enable_it: systemd_features
systemd_service_conf.set(feature, enable_it ? feature + '=true': '')
endforeach

auth_service_conf = configuration_data()
auth_service_conf.merge_from(systemd_service_conf)
# Disabled, it breaks LuaJIT.
auth_service_conf.set(
'MemoryDenyWriteExecute',
have_systemd_memory_deny_write_execute ? 'MemoryDenyWriteExecute=false' : '',
)
auth_service_conf.set(
'RestrictAddressFamilies',
have_systemd_restrict_address_families ? 'RestrictAddressFamilies=AF_UNIX AF_INET AF_INET6' : '',
)

enable_socket_dir = (not have_systemd_with_runtime_dir_env) and have_systemd_percent_t

auth_service_conf_general = configuration_data()
auth_service_conf_general.merge_from(auth_service_conf)
auth_service_conf_general.set('Description', 'PowerDNS Authoritative Server')
auth_service_conf_general.set('SocketDir', enable_socket_dir ? '--socket-dir=%t/pdns-auth' : '')
auth_service_conf_general.set('SyslogIdentifier', 'pdns-auth')
auth_service_conf_general.set('RuntimeDirectory', 'pdns-auth')

configure_file(
input: 'auth' / 'systemd' / 'pdns-auth.service.in',
output: 'pdns-auth.service',
configuration: auth_service_conf_general,
)

auth_service_conf_instance = configuration_data()
auth_service_conf_instance.merge_from(auth_service_conf)
auth_service_conf_instance.set('Description', 'PowerDNS Authoritative Server %i')
auth_service_conf_instance.set('ConfigName', '--config-name=%i')
auth_service_conf_instance.set('SocketDir', enable_socket_dir ? '--socket-dir=%t/pdns-auth-%i' : '')
auth_service_conf_instance.set('SyslogIdentifier', 'pdns-auth-%i')
auth_service_conf_instance.set('RuntimeDirectory', have_systemd_percent_t ? 'pdns-auth-%i' : 'pdns-auth')

configure_file(
input: 'auth' / 'systemd' / 'pdns-auth.service.in',
output: 'pdns-auth@.service',
configuration: auth_service_conf_instance,
)

if get_option('tools-ixfrdist')
ixfrdist_service_conf = configuration_data()
ixfrdist_service_conf.merge_from(systemd_service_conf)
ixfrdist_service_conf.set(
'MemoryDenyWriteExecute',
have_systemd_memory_deny_write_execute ? 'MemoryDenyWriteExecute=true' : '',
)
ixfrdist_service_conf.set(
'RestrictAddressFamilies',
have_systemd_restrict_address_families ? 'RestrictAddressFamilies=AF_INET AF_INET6' : '',
)

ixfrdist_service_conf_general = configuration_data()
ixfrdist_service_conf_general.merge_from(ixfrdist_service_conf)
ixfrdist_service_conf_general.set('Description', 'PowerDNS IXFR Distributor')

configure_file(
input: 'auth' / 'systemd' / 'ixfrdist.service.in',
output: 'ixfrdist.service',
configuration: ixfrdist_service_conf_general,
)

ixfrdist_service_conf_instance = configuration_data()
ixfrdist_service_conf_instance.merge_from(ixfrdist_service_conf)
ixfrdist_service_conf_instance.set('Description', 'PowerDNS IXFR Distributor %i')
ixfrdist_service_conf_instance.set('Config', '--config=' + get_option('sysconfdir') + '/ixfrdist-%.ymli')

configure_file(
input: 'auth' / 'systemd' / 'ixfrdist.service.in',
output: 'ixfrdist@.service',
configuration: ixfrdist_service_conf_instance,
)
endif
endif

libpdns_bindlexer_source = src_dir / 'bindlexer.l'
libpdns_bindlexer_gen = src_dir / 'bindlexer.c'
if not fs.is_file(libpdns_bindlexer_gen)
Expand Down
9 changes: 9 additions & 0 deletions meson/libsystemd/meson.build
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
opt_systemd = get_option('systemd')

dep_systemd = dependency('libsystemd', required: opt_systemd)
conf.set('HAVE_SYSTEMD', dep_systemd.found(), description: 'libsystemd')
summary('libsystemd', dep_systemd.found(), bool_yn: true, section: 'Configuration')

if dep_systemd.found()
summary('Lib Version', dep_systemd.version(), section: 'Systemd')
endif
55 changes: 46 additions & 9 deletions meson/systemd/meson.build
Original file line number Diff line number Diff line change
@@ -1,13 +1,50 @@
dep_systemd = dependency('libsystemd', required: false)
conf.set('HAVE_SYSTEMD', dep_systemd.found(), description: 'systemd')
summary('Systemd', dep_systemd.found(), bool_yn: true, section: 'Configuration')
dep_systemd_prog = dependency('systemd', required: false)
summary('Systemd', dep_systemd_prog.found(), bool_yn: true, section: 'Configuration')

if dep_systemd.found()
summary('Version', dep_systemd.version(), section: 'Systemd')
# Map systemd features to systemd/systemctl version.
systemd_features = {
'private_tmp': 183,
'system_call_architectures': 209,
'private_devices': 209,
'restrict_address_families': 211,
'protect_system': 214,
'protect_home': 214,
'restrict_realtime': 231,
'memory_deny_write_execute': 231,
'protect_control_groups': 232,
'protect_kernel_modules': 232,
'protect_kernel_tunables': 232,
'remove_ipc': 232,
'dynamic_user': 232,
'private_users': 232,
'protect_system_strict': 232,
'restrict_namespaces': 233,
'lock_personality': 235,
# while SystemCallFilter is technically available starting with 187,
# we use the pre-defined call filter sets that have been introduced later.
# Initial support for these landed in 231
# @filesystem @reboot @swap in 233
# @aio, @sync, @chown, @setuid, @memlock, @signal and @timer in 235
'system_call_filter': 235,
'percent_t': 236,
'private_mounts': 239,
'with_runtime_dir_env': 240,
'protect_hostname': 242,
'restrict_suidsgid': 242,
'protect_kernel_logs': 244,
'protect_clock': 245,
'protect_proc': 247,
'private_ipc': 248,
}

systemd_service_user = get_option('systemd-service-user')
systemd_service_group = get_option('systemd-service-group')
systemd_version = dep_systemd_prog.version()
foreach feature, version: systemd_features
feature_name = 'have_systemd_' + feature
feature_value = systemd_version.version_compare('>=' + version.to_string())
set_variable(feature_name, feature_value)
conf.set(feature_name.to_upper(), feature_value, description: 'systemd feature: ' + feature)
endforeach

summary('Service User', systemd_service_user, section: 'Systemd')
summary('Service Group', systemd_service_group, section: 'Systemd')
if dep_systemd_prog.found()
summary('Version', dep_systemd_prog.version(), section: 'Systemd')
endif
1 change: 1 addition & 0 deletions meson_options.txt
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ option('module-lua2', type: 'combo', choices: ['disabled', 'static', 'dynamic'],
option('tools', type: 'boolean', value: false, description: 'Build extra tools')
option('tools-ixfrdist', type: 'boolean', value: false, description: 'Build ixfrdist')
option('lua-records', type: 'boolean', value: true, description: 'Support Lua records')
option('systemd', type: 'feature', value: 'auto', description: 'Systemd notification (requires libsystemd)')
option('systemd-service-user', type: 'string', value: 'pdns', description: 'Systemd service user (setuid and unit file; user is not created)')
option('systemd-service-group', type: 'string', value: 'pdns', description: 'Systemd service group (setgid and unit file; group is not created)')
option('auto-var-init', type: 'combo', value: 'disabled', choices: ['zero', 'pattern', 'disabled'], description: 'Enable initialization of automatic variables')
Expand Down

0 comments on commit a9f4dd7

Please sign in to comment.