]> git.ipfire.org Git - thirdparty/knot-resolver.git/commitdiff
systemd: enable multiple processes with socket activation
authorTomas Krizek <tomas.krizek@nic.cz>
Thu, 25 Jan 2018 17:17:09 +0000 (18:17 +0100)
committerTomas Krizek <tomas.krizek@nic.cz>
Tue, 30 Jan 2018 14:44:42 +0000 (15:44 +0100)
In order to be able to spawn multiple processes with socket activation,
systemd template (see systemd.unit(5)) is used. This allows the user to
create any amount of instances by simply providing a unique name for
each of them. The most sensible instance identifiers are natural
numbers, but any convention could be used.

The default recommended service name becomes kresd@1.service, replacing
the older kresd.service. Sockets are renamed in a similar way. Users are
able to take advantage of bash expansion to spawn/control multiple
processes, e.g. "systemctl start kresd@{1..16}.service"

The socket-activated service can now be launched directly with
"systemctl start kresd@1.service", which will request the associated
sockets without the need for any extra priviledges or capabilities.

Stopping the kresd service now also stops the associated sockets.
Stopping any individual socket is an isolated opration now (stopping
kresd@1.socket no longer stop kresd-tls@1.socket and
kresd-control@1.socket).

Users and packagers are also encouraged to use drop-in files for extra
configuration or modifications to ensure compatibility with their
distribution.

16 files changed:
daemon/README.rst
doc/kresd.8.in
doc/kresd.systemd.8 [new file with mode: 0644]
systemd/90-kresd.preset
systemd/README.md
systemd/drop-in/listen-tls.conf [new file with mode: 0644]
systemd/drop-in/listen-udp-tcp.conf [new file with mode: 0644]
systemd/drop-in/manual-activation.conf [new file with mode: 0644]
systemd/drop-in/systemd-compat.conf [new file with mode: 0644]
systemd/kresd-control@.socket [moved from systemd/kresd-control.socket with 61% similarity]
systemd/kresd-control@1.socket [new symlink]
systemd/kresd-tls@.socket [moved from systemd/kresd-tls.socket with 57% similarity]
systemd/kresd-tls@1.socket [new symlink]
systemd/kresd@.service [moved from systemd/kresd.service with 63% similarity]
systemd/kresd@.socket [moved from systemd/kresd.socket with 80% similarity]
systemd/kresd@1.socket [new symlink]

index 902e8ac3c113933572f8b9ef09e5d1a88968c36b..649f1d686ce07a5335d6f662119be30002528b74 100644 (file)
@@ -1012,6 +1012,8 @@ The watchdog process must notify kresd about active file descriptors, and kresd
 
 The daemon also supports `systemd socket activation`_, it is automatically detected and requires no configuration on users's side.
 
+See ``kresd.systemd(8)`` for details.
+
 Enabling DNSSEC
 ===============
 
index eb42bbdd06126822f570f8652e95f4b57d7529c7..fb4784ee434ec21e097fa22a120a3c3188345aa7 100644 (file)
@@ -88,7 +88,7 @@ online documentation.
 .PP
 .nf
 .RS 6n
-# Create a basic forwarder configuration 
+# Create a basic forwarder configuration
 $ cat << EOF > config
 modules = { 'policy' }
 policy.add(policy.all(policy.FORWARD('192.168.1.1')))
@@ -164,7 +164,7 @@ Show short commandline option help.
 .B \-V
 Show the version.
 .SH "SEE ALSO"
-\fIdaemon/README.md\fR,
+\fIkresd.systemd(8)\fR,
 \fIhttps://knot-resolver.readthedocs.io\fR
 .SH "AUTHORS"
 .B kresd
diff --git a/doc/kresd.systemd.8 b/doc/kresd.systemd.8
new file mode 100644 (file)
index 0000000..0eca980
--- /dev/null
@@ -0,0 +1,148 @@
+.TH "kresd.systemd" "8" "2018-01-30" "CZ.NIC" "Knot DNS Resolver Systemd Units"
+.\"
+.\" kresd.systemd.8 -- man page for systemd units for kresd
+.\"
+.\" Copyright (c) 2018, CZ.NIC. All rights reserved.
+.\"
+.\" See COPYING for the license.
+.\"
+.\"
+.SH "NAME"
+kresd.systemd
+\- managing Knot DNS Resolver through systemd.
+
+.SH "SYNOPSIS"
+.nf
+kresd@.service
+kresd@.socket
+kresd-tls@.socket
+kresd-control@.socket
+.fi
+
+.SH "DESCRIPTION"
+.P
+This manual page describes how to manage \fBkresd\fR using \fBsystemd\fR
+units. Depending on your distribution, this can be either be done with
+socket-based activation or without it. The following assumes socket-based activation.
+For differences see \fINOTES\fR below.
+
+\fBkresd\fR daemon can be executed in multiple independent processes, which can be
+managed with \fBsystemd\fR via systemd templates (see \fBsystemd.unit\fR(5)).
+Each \fBsystemd\fR service instance of \fBkresd\fR (\fIkresd@.service\fR) represents a
+single, independent kresd process.
+
+Each instance of \fIkresd@.service\fR has three systemd sockets (see
+\fBsystemd.socket(5)\fR) associated with it:
+
+.nf
+.RS
+\fIkresd@.socket\fR - UDP/TCP network socket (default: localhost:53)
+\fIkresd-tls@.socket\fR - network socket for DNS-over-TLS (default: localhost:853)
+\fIkresd-control@.socket\fR - UNIX socket with control terminal
+.RE
+.fi
+
+.B Configuring network interfaces
+
+When using socket-based activation, the daemon doesn't require root privileges
+nor any capabilities, because the sockets are created by \fBsystemd\fR and
+passed to \fBkresd\fR. This means \fBkresd\fR can't bind to ports below 1024 when
+configured in \fI/etc/knot-resolver/kresd.conf\fR.
+
+To configure \fBkresd\fR to listen on public interfaces, drop-in files (see
+\fBsystemd.unit\fR(5)) should be used. These can be created with:
+
+.nf
+.RS 4n
+.B systemctl edit kresd@.socket
+.B systemctl edit kresd-tls@.socket
+.RE
+.fi
+
+For example, to configure \fBkresd\fR to listen on 192.0.2.115 on ports 53 and
+853, the drop-in files would look like:
+
+.nf
+.RS 4n
+# /etc/systemd/system/kresd@.socket.d/override.conf
+[Socket]
+ListenDatagram=192.0.2.115:53
+ListenStream=192.0.2.115:53
+
+# /etc/systemd/system/kresd-tls@.socket.d/override.conf
+[Socket]
+ListenStream=192.0.2.115:853
+.RE
+.fi
+
+.SH "NOTES"
+
+.IP * 2
+When \fIkresd@.service\fR is started, stopped or restarted, its associated
+sockets are also automatically started, stopped or restarted.
+
+.IP * 2
+If your distribution doesn't use socket-based activation, you can configure the
+network interfaces for \fBkresd\fR in \fI/etc/knot-resolver/kresd.conf\fR.  The
+service can be started or enabled in the same way as in the examples below, but
+it doesn't have any sockets associated with it.
+
+.SH "EXAMPLES"
+
+.B Single instance
+.RS 4n
+
+To start the service:
+.nf
+.RS 4n
+.B systemctl start kresd@1.service
+.RE
+.fi
+
+To start the service at boot:
+.nf
+.RS 4n
+.B systemctl enable kresd@1.service
+.RE
+.fi
+
+To delay the service startup until some traffic arrives, start (or enable) just
+the sockets:
+.nf
+.RS 4n
+.B systemctl start kresd@1.socket
+.B systemctl start kresd-tls@1.socket
+.RE
+.fi
+
+To disable the TLS socket, you can mask it:
+
+.RS 4n
+.B systemctl mask kresd-tls@1.socket
+.RE
+
+.RE
+
+.B Multiple instances
+.RS 4n
+
+Multiple instances can be handled with the use of \fIBrace Expansion\fR (see
+\fBbash\fR(1)).
+
+To start multiple instances, for example 16:
+.nf
+.RS
+.B systemctl start kresd@{1..16}.service
+.RE
+.fi
+
+.RE
+
+.SH "SEE ALSO"
+\fIkresd(8)\fR,
+\fIsystemd.unit(5)\fR,
+\fIsystemd.socket(5)\fR,
+\fIhttps://knot-resolver.readthedocs.io\fR
+
+.SH "AUTHORS"
+.B kresd developers are mentioned in the AUTHORS file in the distribution.
index ee9934054d2a54b5dfaefc22caa742c024b7032f..95acccf491ac47384aec10ca6f06850d24d4b0cd 100644 (file)
@@ -3,4 +3,4 @@
 # associated sockets *are* enabled however, so the kresd service will
 # be started as soon as anything connects to one of the listening
 # sockets.
-disable kresd.service
+disable kresd@1.service
index 0f35cbe386299d5c6a932c1b32bbe9d340d7b449..d44c2bf7a6ec0c2d05de4b51cdf4ca54c5129d69 100644 (file)
@@ -6,36 +6,33 @@ by systemd (or any supervisor that provides equivalent file descriptor
 initialization via the interface supported by
 sd_listen_fds_with_names(3)).
 
-Distributors of systems using systemd may wish to place
-./90-kresd.preset in /lib/systemd/systemd-preset/90-kresd.preset if
-they want to delay daemon launch until it is accessed. (see
-systemd.preset(5)).
+Usage and Configuration
+-----------------------
 
-When run in this configuration:
+See kresd.systemd(8) for details.
 
- * it will be run under a non-privileged user, which means it will not
-   be able to open any new non-privileged ports.
+Manual activation
+-----------------
 
- * it will use a single process (implicitly uses --forks=1, and will
-   fail if that configuration variable is set to a different value).
-   If you want multiple daemons to listen on these ports publicly
-   concurrently, you'll need the supervisor to manage them
-   differently, for example via a systemd generator:
+If you wish to use manual activation without sockets, you have to grant
+the service the capability to bind to well-known ports. You can use a drop-in
+file.
 
-     https://www.freedesktop.org/software/systemd/man/systemd.generator.html
+    # /etc/systemd/system/kresd@.service.d/override.conf
+    [Service]
+    AmbientCapabilities=CAP_NET_BIND_SERVICE
 
-   If you have a useful systemd generator for multiple concurrent
-   processes, please contribute it upstream!
+Notes
+-----
 
-Administrators who wish to make kresd listen on a public network
-interface can use:
+*  If you're using systemd prior to version 227, use a drop-in file to change
+   the service type to simple. See drop-in/systemd-compat.conf.
 
-    systemctl edit kresd.socket
+*  Distributors of systems using systemd may wish to place
+   ./90-kresd.preset in /lib/systemd/systemd-preset/90-kresd.preset if
+   they want to delay daemon launch until it is accessed. (see
+   systemd.preset(5)).
 
-to add an override file that indicates where they want it to listen.
-For example:
-
-    # /etc/systemd/system/kresd.socket.d/override.conf
-    [Socket]
-    ListenDatagram=192.0.2.115:53
-    ListenStream=192.0.2.115:53
+*  Symlinks pointing from @1 to the systemd template are not necessary. They
+   are only useful to provide users unfamiliar with kresd instances a hint
+   when using bash completion.
diff --git a/systemd/drop-in/listen-tls.conf b/systemd/drop-in/listen-tls.conf
new file mode 100644 (file)
index 0000000..b03c425
--- /dev/null
@@ -0,0 +1,7 @@
+# /etc/systemd/system/kresd-tls@.socket.d/override.conf
+
+# Configure which interfaces should kresd listen on.
+# ListenStream can be added multiple times.
+
+[Socket]
+ListenStream=192.0.2.115:853
diff --git a/systemd/drop-in/listen-udp-tcp.conf b/systemd/drop-in/listen-udp-tcp.conf
new file mode 100644 (file)
index 0000000..c45e1ce
--- /dev/null
@@ -0,0 +1,8 @@
+# /etc/systemd/system/kresd@.socket.d/override.conf
+
+# Configure which interfaces should kresd listen on.
+# ListenDatagram and ListenStream can be added multiple times.
+
+[Socket]
+ListenDatagram=192.0.2.115:53
+ListenStream=192.0.2.115:53
diff --git a/systemd/drop-in/manual-activation.conf b/systemd/drop-in/manual-activation.conf
new file mode 100644 (file)
index 0000000..af7e0d3
--- /dev/null
@@ -0,0 +1,7 @@
+# /etc/systemd/system/kresd@.service.d/override.conf
+
+# If socket activation isn't used, the CAP_NET_BIND_SERVICE is necessary
+# to be able to bind to a well-known port as an unprivilidged user.
+
+[Service]
+AmbientCapabilities=CAP_NET_BIND_SERVICE
diff --git a/systemd/drop-in/systemd-compat.conf b/systemd/drop-in/systemd-compat.conf
new file mode 100644 (file)
index 0000000..b33671a
--- /dev/null
@@ -0,0 +1,6 @@
+# /etc/systemd/system/kresd@.service.d/override.conf
+
+# If systemd.227+ isn't available (e.g. CentOS 7), change the service type.
+
+[Service]
+Type=simple
similarity index 61%
rename from systemd/kresd-control.socket
rename to systemd/kresd-control@.socket
index ceba94bafee6a54e69c617934438bc3e23170e7c..c31a6d9c643a620da82713616e3242fac2fe4f53 100644 (file)
@@ -2,13 +2,12 @@
 Description=Knot DNS Resolver control socket
 Documentation=man:kresd(8)
 Before=sockets.target
-PartOf=kresd.socket
-Alias=knot-resolver-control.socket
+Service=kresd@%i.service
+PartOf=kresd@%i.service
 
 [Socket]
-ListenStream=/run/knot-resolver/control
+ListenStream=/run/knot-resolver/control@%i
 FileDescriptorName=control
-Service=kresd.service
 SocketMode=0660
 
 [Install]
diff --git a/systemd/kresd-control@1.socket b/systemd/kresd-control@1.socket
new file mode 120000 (symlink)
index 0000000..4a4b9d6
--- /dev/null
@@ -0,0 +1 @@
+kresd-control@.socket
\ No newline at end of file
similarity index 57%
rename from systemd/kresd-tls.socket
rename to systemd/kresd-tls@.socket
index 328039f5f5c8f293539ca59c3e71a60ab699e1e1..7f1123f5fd31033d3cf6f941b6506efd0395e6eb 100644 (file)
@@ -2,13 +2,15 @@
 Description=Knot DNS Resolver TLS network listener
 Documentation=man:kresd(8)
 Before=sockets.target
-PartOf=kresd.socket
-Alias=knot-resolver-tls.socket
+Service=kresd@%i.service
+PartOf=kresd@%i.service
 
 [Socket]
-ListenStream=853
+ReusePort=true
+FreeBind=true
 FileDescriptorName=tls
-Service=kresd.service
+ListenStream=[::1]:853
+ListenStream=127.0.0.1:853
 
 [Install]
 WantedBy=sockets.target
diff --git a/systemd/kresd-tls@1.socket b/systemd/kresd-tls@1.socket
new file mode 120000 (symlink)
index 0000000..f261c13
--- /dev/null
@@ -0,0 +1 @@
+kresd-tls@.socket
\ No newline at end of file
similarity index 63%
rename from systemd/kresd.service
rename to systemd/kresd@.service
index a08da00d012b6092fded98e39dcd3f205113e00d..864ebe7737138d087ce7b68b5da5e2a187cfdb13 100644 (file)
@@ -1,7 +1,9 @@
 [Unit]
 Description=Knot DNS Resolver daemon
 Documentation=man:kresd(8)
-Alias=knot-resolver.service
+Wants=kresd@%i.socket
+Wants=kresd-control@%i.socket
+Wants=kresd-tls@%i.socket
 
 [Service]
 Type=notify
@@ -10,5 +12,3 @@ EnvironmentFile=-/etc/default/kresd
 ExecStart=/usr/sbin/kresd $KRESD_ARGS
 User=knot-resolver
 Restart=on-failure
-# CAP_NET_BIND_SERVICE capability is needed for manual service activation
-AmbientCapabilities=CAP_NET_BIND_SERVICE
similarity index 80%
rename from systemd/kresd.socket
rename to systemd/kresd@.socket
index ac7dc63739230641f9079dcf730f78f29589e7c2..29b7e0aa6778c1244c8061a40053c55425b1e4d3 100644 (file)
@@ -2,14 +2,16 @@
 Description=Knot DNS Resolver network listeners
 Documentation=man:kresd(8)
 Before=sockets.target
-Alias=knot-resolver.socket
+Service=kresd@%i.service
+PartOf=kresd@%i.service
 
 [Socket]
-ListenStream=[::1]:53
+ReusePort=true
+FreeBind=true
 ListenDatagram=[::1]:53
-ListenStream=127.0.0.1:53
+ListenStream=[::1]:53
 ListenDatagram=127.0.0.1:53
-FreeBind=true
+ListenStream=127.0.0.1:53
 
 [Install]
 WantedBy=sockets.target
diff --git a/systemd/kresd@1.socket b/systemd/kresd@1.socket
new file mode 120000 (symlink)
index 0000000..c0ed9f2
--- /dev/null
@@ -0,0 +1 @@
+kresd@.socket
\ No newline at end of file