git: e183bef6aa47 - 2023Q1 - dns/blocky: Support running daemon as non-root user

From: Nuno Teixeira <eduardo_at_FreeBSD.org>
Date: Tue, 31 Jan 2023 08:52:59 UTC
The branch 2023Q1 has been updated by eduardo:

URL: https://cgit.FreeBSD.org/ports/commit/?id=e183bef6aa4787e2575e0cbe412ef742b8ca5eaf

commit e183bef6aa4787e2575e0cbe412ef742b8ca5eaf
Author:     Benjamin Spiegel <bspiegel100@gmail.com>
AuthorDate: 2023-01-31 08:29:30 +0000
Commit:     Nuno Teixeira <eduardo@FreeBSD.org>
CommitDate: 2023-01-31 08:41:02 +0000

    dns/blocky: Support running daemon as non-root user
    
     Most rc.d scripts support a standard <service name>_user option in
     /etc/rc.conf to run the service as the specified user. The rc.d script
     for dns/blocky doesn't observe this setting. As a result, it's not
     possible to run as a user other than root (blocky documentation
     recommends using a non-privileged user).
    
     Instructions on how to run non-root user daemon have been added to
     pkg-message.
    
    PR:             269198
    MFH:            2023Q1 (security fixes)
    (cherry picked from commit ffd87be94f2c60fb6c8d0434dd9225d7c73b1441)
---
 dns/blocky/Makefile             |  2 +-
 dns/blocky/files/blocky.in      | 36 +++++++++++++++++++++++++++---------
 dns/blocky/files/pkg-message.in | 15 +++++++++++++++
 3 files changed, 43 insertions(+), 10 deletions(-)

diff --git a/dns/blocky/Makefile b/dns/blocky/Makefile
index 81a8c2a548fb..5035aaffca74 100644
--- a/dns/blocky/Makefile
+++ b/dns/blocky/Makefile
@@ -1,7 +1,7 @@
 PORTNAME=	blocky
 DISTVERSIONPREFIX=	v
 DISTVERSION=	0.20
-PORTREVISION=	1
+PORTREVISION=	3
 CATEGORIES=	dns
 MASTER_SITES=	https://raw.githubusercontent.com/${GH_ACCOUNT}/${GH_PROJECT}/${DISTVERSIONFULL}/:gomod
 DISTFILES=	go.mod:gomod
diff --git a/dns/blocky/files/blocky.in b/dns/blocky/files/blocky.in
index 24a92028836a..2b625f8be55d 100644
--- a/dns/blocky/files/blocky.in
+++ b/dns/blocky/files/blocky.in
@@ -7,9 +7,15 @@
 # Add the following to /etc/rc.conf[.local] to enable this service
 #
 # blocky_enable (bool):	Set to NO by default.
-#				Set it to YES to enable blocky.
-# blocky_config (str): Set to /usr/local/etc/blocky/config.yml by default.
-#
+#			Set it to YES to enable blocky.
+# blocky_config (str):	Set to /usr/local/etc/blocky-config.yml by default.
+#			Set it to a path to use that config file.
+# blocky_user (str):	Services run as root by default. Set to a user name
+#			to run blocky as that user. Note: non-root users
+#			might need permission to bind to ports.
+# blocky_group (str):	Set to the user's primary group by default.
+#			Set it to a group name for daemon file ownership.
+# blocky_flags (str):	Enter extra flags to append to the blocky command.
 
 . /etc/rc.subr
 
@@ -20,17 +26,29 @@ load_rc_config ${name}
 
 : ${blocky_enable:=NO}
 : ${blocky_config:="%%PREFIX%%/etc/blocky-config.yml"}
+: ${blocky_group:=}
 : ${blocky_flags:=}
 
-pidfile=/var/run/blocky.pid
-command="%%PREFIX%%/sbin/blocky"
+if [ -n "${blocky_user}" ] && [ -z "${blocky_group}" ]; then
+	# Detect the daemon user's primary group
+	blocky_group=$(id -gn "${blocky_user}")
+fi
+
+pidfile="/var/run/${name}.pid"
+blocky_path="%%PREFIX%%/sbin/blocky"
+
+command="/usr/sbin/daemon"
+procname="/usr/local/sbin/blocky"
+command_args="-c -f -p ${pidfile} ${blocky_path} \
+	-c ${blocky_config} ${blocky_flags}"
 
-start_cmd="${name}_start"
+start_precmd="blocky_precmd"
 
-blocky_start()
+# Sets up a pidfile the daemon user can access
+blocky_precmd()
 {
-	echo -n "Starting ${name}."
-	/usr/sbin/daemon -p ${pidfile} -f ${command} -c ${blocky_config} ${blocky_flags}
+	install -o "${blocky_user:-root}" -g "${blocky_group:-wheel}" \
+		-m 0600 /dev/null "${pidfile}"
 }
 
 run_rc_command "$1"
diff --git a/dns/blocky/files/pkg-message.in b/dns/blocky/files/pkg-message.in
index 953a51c3cce8..70f077c66f2a 100644
--- a/dns/blocky/files/pkg-message.in
+++ b/dns/blocky/files/pkg-message.in
@@ -7,6 +7,21 @@ A sample configuration file is installed at the following location:
 Default location for configuration file when using rc.d script:
 %%PREFIX%%/etc/blocky-config.yml
 
+With the default configuration, blocky listens on port 53 (TCP and UDP).
+If running as a non-root user, use a different port in blocky configuration,
+such as `port: 5053`, or use mac_portacl(4) to allow binding to port 53.
+
+Example setup for mac_portacl(4):
+
+In /boot/loader.conf:
+
+	mac_portacl_load="YES"
+
+In /etc/sysctl.conf (where <ID> is the UID of your user):
+
+	net.inet.ip.portrange.reservedhigh=0
+	security.mac.portacl.rules=uid:<ID>:tcp:53,uid:<ID>:udp:53
+
 Please refer to the documentation located at
 https://0xerr0r.github.io/blocky/ for further information.
 EOM