From 8b0b340cd6e1499a787cc75e2e6edc7475e3024d Mon Sep 17 00:00:00 2001 From: ninetailedtori Date: Sun, 14 Dec 2025 19:37:45 +0000 Subject: [PATCH 1/5] Add systemd units, patch existing main unit. --- contrib/roothints-sig.sh.in | 10 +++ contrib/unbound-anchor.service.in | 91 ++++++++++++++++++++++++++++ contrib/unbound-anchor.timer.in | 9 +++ contrib/unbound-chown.service.in | 88 +++++++++++++++++++++++++++ contrib/unbound-roothints.service.in | 88 +++++++++++++++++++++++++++ contrib/unbound-roothints.timer.in | 9 +++ contrib/unbound.service.in | 6 ++ 7 files changed, 301 insertions(+) create mode 100644 contrib/roothints-sig.sh.in create mode 100644 contrib/unbound-anchor.service.in create mode 100644 contrib/unbound-anchor.timer.in create mode 100644 contrib/unbound-chown.service.in create mode 100644 contrib/unbound-roothints.service.in create mode 100644 contrib/unbound-roothints.timer.in diff --git a/contrib/roothints-sig.sh.in b/contrib/roothints-sig.sh.in new file mode 100644 index 000000000..b903f795b --- /dev/null +++ b/contrib/roothints-sig.sh.in @@ -0,0 +1,10 @@ +#!/bin/bash + +if [ "$(md5sum '@UNBOUND_RUN_DIR@/root.hints' | cut -d' ' -f1)" = "$(cat '@UNBOUND_RUN_DIR@/root-hints.md5')" ]; then + exit 0 +else + command logger "Error (unbound-roothints): root-hints.md5 does not match root.hint's signature!" + # This line adds a notification when the sigs don't match! + # notify-send "Error (unbound-roothints): root-hints.md5 does not match root.hint's signature!" + exit 1 +fi diff --git a/contrib/unbound-anchor.service.in b/contrib/unbound-anchor.service.in new file mode 100644 index 000000000..36a7c227a --- /dev/null +++ b/contrib/unbound-anchor.service.in @@ -0,0 +1,91 @@ +; For further details about the directives used in this unit file, including +; the below, please refer to systemd's official documentation, available at +; https://www.freedesktop.org/software/systemd/man/systemd.exec.html. +; +; +; - `ProtectSystem=strict` implies we mount the entire file system hierarchy +; read-only for the processes invoked by the unit except for the API file +; system subtrees /dev, /proc and /sys (which are protected by +; PrivateDevices=, ProtectKernelTunables=, ProtectControlGroups=). +; +; - `PrivateTmp=yes` secures access to temporary files of the process, and +; makes sharing between processes via /tmp or /var/tmp impossible. +; +; - `ProtectHome=yes` makes the directories /home, /root, and /run/user +; inaccessible and empty for processes invoked by the unit. +; +; - `ProtectControlGroups=yes` makes the Linux Control Groups hierarchies +; (accessible through /sys/fs/cgroup) read-only to all processes invoked by +; the unit. It also implies `MountAPIVFS=yes`. +; +; - `RuntimeDirectory=unbound` creates a /run/unbound directory, owned by the +; unit User and Group with read-write permissions (0755) as soon as the +; unit starts. This allows unbound to store its pidfile. The directory and +; its content are automatically removed by systemd when the unit stops. +; +; - `NoNewPrivileges=yes` ensures that the service process and all its +; children can never gain new privileges through execve(). +; +; - `RestrictSUIDSGID=yes` ensures that any attempts to set the set-user-ID +; (SUID) or set-group-ID (SGID) bits on files or directories will be denied. +; +; - `RestrictRealTime=yes` ensures that any attempts to enable realtime +; scheduling in a process invoked by the unit will be denied. +; +; - `RestrictNamespaces=yes` ensures that access to any kind of namespacing +; is prohibited. +; +; - `LockPersonality=yes` locks down the personality system call so that the +; kernel execution domain may not be changed from the default. +; +; - With /etc/systemd/network/*.network a setting to make sure the network +; is not considered online too early, can reduce network unreachable +; errors on server start: +; [Link] +; RequiredForOnline=routable +; +[Unit] +Description=unbound-anchor +Documentation=man:unbound-anchor(8) +After=network-online.target +After=unbound-roothints.service +Wants=network-online.target +Wants=unbound-roothints.service +Before=unbound-chown.service +Before=unbound.service +OnFailure=logger "Error (unbound-anchor): Please check root anchor." + +[Install] +WantedBy=multi-user.target + +[Service] +ExecCondition=@UNBOUND_RUN_DIR@/roothints-sig.sh +ExecStart=/bin/cp "/etc/trusted-key.key" @UNBOUND_ROOTKEY_FILE@ +ExecStart=@UNBOUND_SBIN_DIR@/unbound-anchor -f "/etc/resolv.conf" -r @UNBOUND_RUN_DIR@/root.hints -a @UNBOUND_ROOTKEY_FILE@ +NotifyAccess=main +Type=oneshot +# TODO: Needs checking. Does unbound-anchor require net capabilities? +CapabilityBoundingSet=CAP_DAC_OVERRIDE CAP_NET_RAW CAP_NET_OVERRIDE +MemoryDenyWriteExecute=true +NoNewPrivileges=true +PrivateDevices=true +PrivateTmp=true +ProtectHome=true +ProtectClock=true +ProtectControlGroups=true +ProtectKernelLogs=true +ProtectKernelModules=true +ProtectKernelTunables=true +ProtectProc=invisible +ProtectSystem=strict +RuntimeDirectory=unbound +ConfigurationDirectory=unbound +StateDirectory=unbound +RestrictAddressFamilies=AF_INET AF_INET6 +RestrictRealtime=true +SystemCallArchitectures=native +RestrictNamespaces=yes +LockPersonality=yes +RestrictSUIDSGID=yes +ReadWritePaths=@UNBOUND_ROOTKEY_FILE@ +ReadOnlyPaths=/etc/trusted-key.key /etc/resolv.conf @UNBOUND_RUN_DIR@/root.hints \ No newline at end of file diff --git a/contrib/unbound-anchor.timer.in b/contrib/unbound-anchor.timer.in new file mode 100644 index 000000000..85d97f375 --- /dev/null +++ b/contrib/unbound-anchor.timer.in @@ -0,0 +1,9 @@ +[Unit] +Description=Run unbound-anchor monthly + +[Timer] +OnCalendar=monthly +Persistent=true + +[Install] +WantedBy=timers.target diff --git a/contrib/unbound-chown.service.in b/contrib/unbound-chown.service.in new file mode 100644 index 000000000..db2439e6a --- /dev/null +++ b/contrib/unbound-chown.service.in @@ -0,0 +1,88 @@ +; For further details about the directives used in this unit file, including +; the below, please refer to systemd's official documentation, available at +; https://www.freedesktop.org/software/systemd/man/systemd.exec.html. +; +; +; - `ProtectSystem=strict` implies we mount the entire file system hierarchy +; read-only for the processes invoked by the unit except for the API file +; system subtrees /dev, /proc and /sys (which are protected by +; PrivateDevices=, ProtectKernelTunables=, ProtectControlGroups=). +; +; - `PrivateTmp=yes` secures access to temporary files of the process, and +; makes sharing between processes via /tmp or /var/tmp impossible. +; +; - `ProtectHome=yes` makes the directories /home, /root, and /run/user +; inaccessible and empty for processes invoked by the unit. +; +; - `ProtectControlGroups=yes` makes the Linux Control Groups hierarchies +; (accessible through /sys/fs/cgroup) read-only to all processes invoked by +; the unit. It also implies `MountAPIVFS=yes`. +; +; - `RuntimeDirectory=unbound` creates a /run/unbound directory, owned by the +; unit User and Group with read-write permissions (0755) as soon as the +; unit starts. This allows unbound to store its pidfile. The directory and +; its content are automatically removed by systemd when the unit stops. +; +; - `NoNewPrivileges=yes` ensures that the service process and all its +; children can never gain new privileges through execve(). +; +; - `RestrictSUIDSGID=yes` ensures that any attempts to set the set-user-ID +; (SUID) or set-group-ID (SGID) bits on files or directories will be denied. +; +; - `RestrictRealTime=yes` ensures that any attempts to enable realtime +; scheduling in a process invoked by the unit will be denied. +; +; - `RestrictNamespaces=yes` ensures that access to any kind of namespacing +; is prohibited. +; +; - `LockPersonality=yes` locks down the personality system call so that the +; kernel execution domain may not be changed from the default. +; +; - With /etc/systemd/network/*.network a setting to make sure the network +; is not considered online too early, can reduce network unreachable +; errors on server start: +; [Link] +; RequiredForOnline=routable +; +[Unit] +Description=unbound-chown +Documentation=man:chown(1) +After=network-online.target +After=unbound-anchor.service +After=unbound-roothints.service +Wants=network-online.target +Wants=unbound-anchor.service +Wants=unbound-roothints.service +Before=unbound.service +OnFailure=logger "Error (unbound-chown): Please check /etc/unbound ownership." + +[Install] +WantedBy=multi-user.target + +[Service] +ExecStart=/bin/chown -R unbound:unbound @UNBOUND_RUN_DIR@ +ExecStart=/bin/chown unbound:unbound @UNBOUND_ROOTKEY_FILE@ +NotifyAccess=main +Type=oneshot +CapabilityBoundingSet=CAP_CHOWN +MemoryDenyWriteExecute=true +NoNewPrivileges=true +PrivateDevices=true +PrivateTmp=true +ProtectHome=true +ProtectClock=true +ProtectControlGroups=true +ProtectKernelLogs=true +ProtectKernelModules=true +ProtectKernelTunables=true +ProtectProc=invisible +ProtectSystem=strict +RuntimeDirectory=unbound +ConfigurationDirectory=unbound +StateDirectory=unbound +RestrictRealtime=true +SystemCallArchitectures=native +RestrictNamespaces=yes +LockPersonality=yes +RestrictSUIDSGID=yes +ReadWritePaths=@UNBOUND_RUN_DIR@ @UNBOUND_ROOTKEY_FILE@ diff --git a/contrib/unbound-roothints.service.in b/contrib/unbound-roothints.service.in new file mode 100644 index 000000000..d6f22b1f5 --- /dev/null +++ b/contrib/unbound-roothints.service.in @@ -0,0 +1,88 @@ +; For further details about the directives used in this unit file, including +; the below, please refer to systemd's official documentation, available at +; https://www.freedesktop.org/software/systemd/man/systemd.exec.html. +; +; +; - `ProtectSystem=strict` implies we mount the entire file system hierarchy +; read-only for the processes invoked by the unit except for the API file +; system subtrees /dev, /proc and /sys (which are protected by +; PrivateDevices=, ProtectKernelTunables=, ProtectControlGroups=). +; +; - `PrivateTmp=yes` secures access to temporary files of the process, and +; makes sharing between processes via /tmp or /var/tmp impossible. +; +; - `ProtectHome=yes` makes the directories /home, /root, and /run/user +; inaccessible and empty for processes invoked by the unit. +; +; - `ProtectControlGroups=yes` makes the Linux Control Groups hierarchies +; (accessible through /sys/fs/cgroup) read-only to all processes invoked by +; the unit. It also implies `MountAPIVFS=yes`. +; +; - `RuntimeDirectory=unbound` creates a /run/unbound directory, owned by the +; unit User and Group with read-write permissions (0755) as soon as the +; unit starts. This allows unbound to store its pidfile. The directory and +; its content are automatically removed by systemd when the unit stops. +; +; - `NoNewPrivileges=yes` ensures that the service process and all its +; children can never gain new privileges through execve(). +; +; - `RestrictSUIDSGID=yes` ensures that any attempts to set the set-user-ID +; (SUID) or set-group-ID (SGID) bits on files or directories will be denied. +; +; - `RestrictRealTime=yes` ensures that any attempts to enable realtime +; scheduling in a process invoked by the unit will be denied. +; +; - `RestrictNamespaces=yes` ensures that access to any kind of namespacing +; is prohibited. +; +; - `LockPersonality=yes` locks down the personality system call so that the +; kernel execution domain may not be changed from the default. +; +; - With /etc/systemd/network/*.network a setting to make sure the network +; is not considered online too early, can reduce network unreachable +; errors on server start: +; [Link] +; RequiredForOnline=routable +; +[Unit] +Description=unbound-roothints +Documentation=man:unbound(8) +After=network-online.target +Wants=network-online.target +Before=unbound-anchor.service +Before=unbound-chown.service +Before=unbound.service +OnFailure=logger "Error (unbound-roothints): Please check root hints." + +[Install] +WantedBy=multi-user.target + +[Service] +ExecStart=/bin/curl -o @UNBOUND_RUN_DIR@/root.hints https://www.internic.net/domain/named.cache +ExecStart=/bin/curl -o @UNBOUND_RUN_DIR@/root-hints.md5 https://www.internic.net/domain/named.cache.md5 +ExecStart=/bin/curl -o @UNBOUND_RUN_DIR@/icannbundle.pem https://data.iana.org/root-anchors/icannbundle.pem +NotifyAccess=main +Type=oneshot +CapabilityBoundingSet=CAP_NET_RAW CAP_NET_OVERRIDE +MemoryDenyWriteExecute=true +NoNewPrivileges=true +PrivateDevices=true +PrivateTmp=true +ProtectHome=true +ProtectClock=true +ProtectControlGroups=true +ProtectKernelLogs=true +ProtectKernelModules=true +ProtectKernelTunables=false +ProtectProc=invisible +ProtectSystem=strict +RuntimeDirectory=unbound +ConfigurationDirectory=unbound +StateDirectory=unbound +RestrictAddressFamilies=AF_INET AF_INET6 +RestrictRealtime=true +SystemCallArchitectures=native +RestrictNamespaces=yes +LockPersonality=yes +RestrictSUIDSGID=yes +ReadWritePaths=@UNBOUND_RUN_DIR@/root.hints @UNBOUND_RUN_DIR@/root-hints.md5 @UNBOUND_RUN_DIR@/icannbundle.pem \ No newline at end of file diff --git a/contrib/unbound-roothints.timer.in b/contrib/unbound-roothints.timer.in new file mode 100644 index 000000000..b4d4ced8e --- /dev/null +++ b/contrib/unbound-roothints.timer.in @@ -0,0 +1,9 @@ +[Unit] +Description=Run root.hints monthly + +[Timer] +OnCalendar=monthly +Persistent=true + +[Install] +WantedBy=timers.target diff --git a/contrib/unbound.service.in b/contrib/unbound.service.in index b05e2c959..aa5e228a5 100644 --- a/contrib/unbound.service.in +++ b/contrib/unbound.service.in @@ -48,7 +48,13 @@ Description=Validating, recursive, and caching DNS resolver Documentation=man:unbound(8) After=network-online.target +After=unbound-roothints.service +After=unbound-anchor.service +After=unbound-chown.service Wants=network-online.target +Wants=unbound-roothints.service +Wants=unbound-anchor.service +Wants=unbound-chown.service Before=nss-lookup.target [Install] From 87367232cf7750bc96b0244ce4c4416f073b1ebb Mon Sep 17 00:00:00 2001 From: ninetailedtori Date: Sun, 14 Dec 2025 19:42:11 +0000 Subject: [PATCH 2/5] Add UNBOUND_CHROOT_DIR to chown service. --- contrib/unbound-chown.service.in | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/contrib/unbound-chown.service.in b/contrib/unbound-chown.service.in index db2439e6a..a8750f45e 100644 --- a/contrib/unbound-chown.service.in +++ b/contrib/unbound-chown.service.in @@ -61,6 +61,7 @@ WantedBy=multi-user.target [Service] ExecStart=/bin/chown -R unbound:unbound @UNBOUND_RUN_DIR@ +ExecStart=/bin/chown -R unbound:unbound @UNBOUND_CHROOT_DIR@ ExecStart=/bin/chown unbound:unbound @UNBOUND_ROOTKEY_FILE@ NotifyAccess=main Type=oneshot @@ -85,4 +86,4 @@ SystemCallArchitectures=native RestrictNamespaces=yes LockPersonality=yes RestrictSUIDSGID=yes -ReadWritePaths=@UNBOUND_RUN_DIR@ @UNBOUND_ROOTKEY_FILE@ +ReadWritePaths=@UNBOUND_RUN_DIR@ @UNBOUND_CHROOT_DIR@ @UNBOUND_ROOTKEY_FILE@ From 1e48fa4a905c1256b1b36221ece0a4541839fbfa Mon Sep 17 00:00:00 2001 From: Toria Date: Tue, 30 Dec 2025 18:18:09 +0000 Subject: [PATCH 3/5] Move units to their own folder. Comment out additional units in unbound.service.in. Also add reference to icannbundle.pem to unbound-anchor.service.in. Signed-off-by: Toria --- .../{ => systemd}/unbound-anchor.service.in | 7 +- contrib/{ => systemd}/unbound-anchor.timer.in | 0 .../unbound-roothints.service.in | 0 .../{ => systemd}/unbound-roothints.timer.in | 0 contrib/unbound-chown.service.in | 89 ------------------- contrib/unbound.service.in | 11 ++- 6 files changed, 8 insertions(+), 99 deletions(-) rename contrib/{ => systemd}/unbound-anchor.service.in (93%) rename contrib/{ => systemd}/unbound-anchor.timer.in (100%) rename contrib/{ => systemd}/unbound-roothints.service.in (100%) rename contrib/{ => systemd}/unbound-roothints.timer.in (100%) delete mode 100644 contrib/unbound-chown.service.in diff --git a/contrib/unbound-anchor.service.in b/contrib/systemd/unbound-anchor.service.in similarity index 93% rename from contrib/unbound-anchor.service.in rename to contrib/systemd/unbound-anchor.service.in index 36a7c227a..bf46c3f14 100644 --- a/contrib/unbound-anchor.service.in +++ b/contrib/systemd/unbound-anchor.service.in @@ -48,10 +48,9 @@ Description=unbound-anchor Documentation=man:unbound-anchor(8) After=network-online.target -After=unbound-roothints.service Wants=network-online.target +After=unbound-roothints.service Wants=unbound-roothints.service -Before=unbound-chown.service Before=unbound.service OnFailure=logger "Error (unbound-anchor): Please check root anchor." @@ -61,7 +60,7 @@ WantedBy=multi-user.target [Service] ExecCondition=@UNBOUND_RUN_DIR@/roothints-sig.sh ExecStart=/bin/cp "/etc/trusted-key.key" @UNBOUND_ROOTKEY_FILE@ -ExecStart=@UNBOUND_SBIN_DIR@/unbound-anchor -f "/etc/resolv.conf" -r @UNBOUND_RUN_DIR@/root.hints -a @UNBOUND_ROOTKEY_FILE@ +ExecStart=/bin/sudo -u unbound @UNBOUND_SBIN_DIR@/unbound-anchor -f "/etc/resolv.conf" -r @UNBOUND_RUN_DIR@/root.hints -a @UNBOUND_ROOTKEY_FILE@ -c @UNBOUND_RUN_DIR@/icannbundle.pem NotifyAccess=main Type=oneshot # TODO: Needs checking. Does unbound-anchor require net capabilities? @@ -88,4 +87,4 @@ RestrictNamespaces=yes LockPersonality=yes RestrictSUIDSGID=yes ReadWritePaths=@UNBOUND_ROOTKEY_FILE@ -ReadOnlyPaths=/etc/trusted-key.key /etc/resolv.conf @UNBOUND_RUN_DIR@/root.hints \ No newline at end of file +ReadOnlyPaths=/etc/trusted-key.key /etc/resolv.conf @UNBOUND_RUN_DIR@/root.hints @UNBOUND_RUN_DIR@/icannbundle.pem \ No newline at end of file diff --git a/contrib/unbound-anchor.timer.in b/contrib/systemd/unbound-anchor.timer.in similarity index 100% rename from contrib/unbound-anchor.timer.in rename to contrib/systemd/unbound-anchor.timer.in diff --git a/contrib/unbound-roothints.service.in b/contrib/systemd/unbound-roothints.service.in similarity index 100% rename from contrib/unbound-roothints.service.in rename to contrib/systemd/unbound-roothints.service.in diff --git a/contrib/unbound-roothints.timer.in b/contrib/systemd/unbound-roothints.timer.in similarity index 100% rename from contrib/unbound-roothints.timer.in rename to contrib/systemd/unbound-roothints.timer.in diff --git a/contrib/unbound-chown.service.in b/contrib/unbound-chown.service.in deleted file mode 100644 index a8750f45e..000000000 --- a/contrib/unbound-chown.service.in +++ /dev/null @@ -1,89 +0,0 @@ -; For further details about the directives used in this unit file, including -; the below, please refer to systemd's official documentation, available at -; https://www.freedesktop.org/software/systemd/man/systemd.exec.html. -; -; -; - `ProtectSystem=strict` implies we mount the entire file system hierarchy -; read-only for the processes invoked by the unit except for the API file -; system subtrees /dev, /proc and /sys (which are protected by -; PrivateDevices=, ProtectKernelTunables=, ProtectControlGroups=). -; -; - `PrivateTmp=yes` secures access to temporary files of the process, and -; makes sharing between processes via /tmp or /var/tmp impossible. -; -; - `ProtectHome=yes` makes the directories /home, /root, and /run/user -; inaccessible and empty for processes invoked by the unit. -; -; - `ProtectControlGroups=yes` makes the Linux Control Groups hierarchies -; (accessible through /sys/fs/cgroup) read-only to all processes invoked by -; the unit. It also implies `MountAPIVFS=yes`. -; -; - `RuntimeDirectory=unbound` creates a /run/unbound directory, owned by the -; unit User and Group with read-write permissions (0755) as soon as the -; unit starts. This allows unbound to store its pidfile. The directory and -; its content are automatically removed by systemd when the unit stops. -; -; - `NoNewPrivileges=yes` ensures that the service process and all its -; children can never gain new privileges through execve(). -; -; - `RestrictSUIDSGID=yes` ensures that any attempts to set the set-user-ID -; (SUID) or set-group-ID (SGID) bits on files or directories will be denied. -; -; - `RestrictRealTime=yes` ensures that any attempts to enable realtime -; scheduling in a process invoked by the unit will be denied. -; -; - `RestrictNamespaces=yes` ensures that access to any kind of namespacing -; is prohibited. -; -; - `LockPersonality=yes` locks down the personality system call so that the -; kernel execution domain may not be changed from the default. -; -; - With /etc/systemd/network/*.network a setting to make sure the network -; is not considered online too early, can reduce network unreachable -; errors on server start: -; [Link] -; RequiredForOnline=routable -; -[Unit] -Description=unbound-chown -Documentation=man:chown(1) -After=network-online.target -After=unbound-anchor.service -After=unbound-roothints.service -Wants=network-online.target -Wants=unbound-anchor.service -Wants=unbound-roothints.service -Before=unbound.service -OnFailure=logger "Error (unbound-chown): Please check /etc/unbound ownership." - -[Install] -WantedBy=multi-user.target - -[Service] -ExecStart=/bin/chown -R unbound:unbound @UNBOUND_RUN_DIR@ -ExecStart=/bin/chown -R unbound:unbound @UNBOUND_CHROOT_DIR@ -ExecStart=/bin/chown unbound:unbound @UNBOUND_ROOTKEY_FILE@ -NotifyAccess=main -Type=oneshot -CapabilityBoundingSet=CAP_CHOWN -MemoryDenyWriteExecute=true -NoNewPrivileges=true -PrivateDevices=true -PrivateTmp=true -ProtectHome=true -ProtectClock=true -ProtectControlGroups=true -ProtectKernelLogs=true -ProtectKernelModules=true -ProtectKernelTunables=true -ProtectProc=invisible -ProtectSystem=strict -RuntimeDirectory=unbound -ConfigurationDirectory=unbound -StateDirectory=unbound -RestrictRealtime=true -SystemCallArchitectures=native -RestrictNamespaces=yes -LockPersonality=yes -RestrictSUIDSGID=yes -ReadWritePaths=@UNBOUND_RUN_DIR@ @UNBOUND_CHROOT_DIR@ @UNBOUND_ROOTKEY_FILE@ diff --git a/contrib/unbound.service.in b/contrib/unbound.service.in index aa5e228a5..257891043 100644 --- a/contrib/unbound.service.in +++ b/contrib/unbound.service.in @@ -48,14 +48,13 @@ Description=Validating, recursive, and caching DNS resolver Documentation=man:unbound(8) After=network-online.target -After=unbound-roothints.service -After=unbound-anchor.service -After=unbound-chown.service Wants=network-online.target -Wants=unbound-roothints.service -Wants=unbound-anchor.service -Wants=unbound-chown.service Before=nss-lookup.target +# These two are needed for systemd-managed root.hints and trusted-key.key updates. +#After=unbound-roothints.service +#Wants=unbound-roothints.service +#After=unbound-anchor.service +#Wants=unbound-anchor.service [Install] WantedBy=multi-user.target From 85a0ef858a9234efed5b6e756a040f1600297d52 Mon Sep 17 00:00:00 2001 From: Toria Date: Tue, 30 Dec 2025 20:02:28 +0000 Subject: [PATCH 4/5] Refactor roothints-sig as well. --- contrib/{ => systemd}/roothints-sig.sh.in | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename contrib/{ => systemd}/roothints-sig.sh.in (100%) diff --git a/contrib/roothints-sig.sh.in b/contrib/systemd/roothints-sig.sh.in similarity index 100% rename from contrib/roothints-sig.sh.in rename to contrib/systemd/roothints-sig.sh.in From bc31a344163c5039c62ffc661b927ccc629daa29 Mon Sep 17 00:00:00 2001 From: Toria Date: Tue, 30 Dec 2025 20:37:25 +0000 Subject: [PATCH 5/5] Change need for sudo, to use systemd unit ability to run as user:group natively (safer than needing sudoers access AND config). --- contrib/systemd/unbound-anchor.service.in | 4 +++- contrib/systemd/unbound-roothints.service.in | 2 ++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/contrib/systemd/unbound-anchor.service.in b/contrib/systemd/unbound-anchor.service.in index bf46c3f14..1324b4486 100644 --- a/contrib/systemd/unbound-anchor.service.in +++ b/contrib/systemd/unbound-anchor.service.in @@ -58,9 +58,11 @@ OnFailure=logger "Error (unbound-anchor): Please check root anchor." WantedBy=multi-user.target [Service] +User=unbound +Group=unbound ExecCondition=@UNBOUND_RUN_DIR@/roothints-sig.sh ExecStart=/bin/cp "/etc/trusted-key.key" @UNBOUND_ROOTKEY_FILE@ -ExecStart=/bin/sudo -u unbound @UNBOUND_SBIN_DIR@/unbound-anchor -f "/etc/resolv.conf" -r @UNBOUND_RUN_DIR@/root.hints -a @UNBOUND_ROOTKEY_FILE@ -c @UNBOUND_RUN_DIR@/icannbundle.pem +ExecStart=@UNBOUND_SBIN_DIR@/unbound-anchor -f "/etc/resolv.conf" -r @UNBOUND_RUN_DIR@/root.hints -a @UNBOUND_ROOTKEY_FILE@ -c @UNBOUND_RUN_DIR@/icannbundle.pem NotifyAccess=main Type=oneshot # TODO: Needs checking. Does unbound-anchor require net capabilities? diff --git a/contrib/systemd/unbound-roothints.service.in b/contrib/systemd/unbound-roothints.service.in index d6f22b1f5..e0a1de2f5 100644 --- a/contrib/systemd/unbound-roothints.service.in +++ b/contrib/systemd/unbound-roothints.service.in @@ -58,6 +58,8 @@ OnFailure=logger "Error (unbound-roothints): Please check root hints." WantedBy=multi-user.target [Service] +User=unbound +Group=unbound ExecStart=/bin/curl -o @UNBOUND_RUN_DIR@/root.hints https://www.internic.net/domain/named.cache ExecStart=/bin/curl -o @UNBOUND_RUN_DIR@/root-hints.md5 https://www.internic.net/domain/named.cache.md5 ExecStart=/bin/curl -o @UNBOUND_RUN_DIR@/icannbundle.pem https://data.iana.org/root-anchors/icannbundle.pem