commit:     20c274b220ba9be18fa465ff03cd9e7b95b1591b
Author:     Sam James <sam <AT> gentoo <DOT> org>
AuthorDate: Wed Mar 16 18:35:50 2022 +0000
Commit:     Sam James <sam <AT> gentoo <DOT> org>
CommitDate: Sat Aug 31 07:10:13 2024 +0000
URL:        https://gitweb.gentoo.org/repo/gentoo.git/commit/?id=20c274b2

net-dns/bind: restore chroot support

Bug: https://bugs.gentoo.org/832218
Bug: https://bugs.gentoo.org/930348
Bug: https://bugs.gentoo.org/936568
Bug: https://bugs.gentoo.org/937907
Bug: https://github.com/gentoo/gentoo/pull/24001
Signed-off-by: Sam James <sam <AT> gentoo.org>

 net-dns/bind/bind-9.18.0.ebuild   |  89 +++++++++++++++++++-
 net-dns/bind/files/named.confd-r8 |  19 +++++
 net-dns/bind/files/named.init-r15 | 170 ++++++++++++++++++++++++++++++++++++--
 3 files changed, 268 insertions(+), 10 deletions(-)

diff --git a/net-dns/bind/bind-9.18.0.ebuild b/net-dns/bind/bind-9.18.0.ebuild
index 7499493af4f4..dd465d39879c 100644
--- a/net-dns/bind/bind-9.18.0.ebuild
+++ b/net-dns/bind/bind-9.18.0.ebuild
@@ -143,9 +143,96 @@ pkg_postinst() {
        tmpfiles_process named.conf
 
        if [[ ! -f '/etc/bind/rndc.key' && ! -f '/etc/bind/rndc.conf' ]]; then
-               einfo "Using /dev/urandom for generating rndc.key"
+               einfo "Generating rndc.key"
                /usr/sbin/rndc-confgen -a
                chown root:named /etc/bind/rndc.key || die
                chmod 0640 /etc/bind/rndc.key || die
        fi
+
+       einfo
+       einfo "You can edit /etc/conf.d/named to customize named settings"
+       einfo
+
+       use mysql || use postgres || use ldap && {
+               elog "If your named depends on MySQL/PostgreSQL or LDAP,"
+               elog "uncomment the specified rc_named_* lines in your"
+               elog "/etc/conf.d/named config to ensure they'll start before 
bind"
+               einfo
+       }
+
+       einfo "If you'd like to run bind in a chroot AND this is a new"
+       einfo "install OR your bind doesn't already run in a chroot:"
+       einfo "1) Uncomment and set the CHROOT variable in /etc/conf.d/named."
+       einfo "2) Run \`emerge --config '=${CATEGORY}/${PF}'\`"
+       einfo
+
+       CHROOT=$(source /etc/conf.d/named 2>/dev/null; echo ${CHROOT})
+       if [[ -n ${CHROOT} ]]; then
+               elog "NOTE: As of net-dns/bind-9.4.3_p5-r1 the chroot part of 
the init-script got some major changes!"
+               elog "To enable the old behaviour (without using mount) 
uncomment the"
+               elog "CHROOT_NOMOUNT option in your /etc/conf.d/named config."
+               elog "If you decide to use the new/default method, ensure to 
make backup"
+               elog "first and merge your existing configs/zones to /etc/bind 
and"
+               elog "/var/bind because bind will now mount the needed 
directories into"
+               elog "the chroot dir."
+       fi
+}
+
+pkg_config() {
+       CHROOT=$(source /etc/conf.d/named; echo ${CHROOT})
+       CHROOT_NOMOUNT=$(source /etc/conf.d/named; echo ${CHROOT_NOMOUNT})
+       CHROOT_GEOIP=$(source /etc/conf.d/named; echo ${CHROOT_GEOIP})
+
+       if [[ -z "${CHROOT}" ]]; then
+               eerror "This config script is designed to automate setting up"
+               eerror "a chrooted bind/named. To do so, please first uncomment"
+               eerror "and set the CHROOT variable in '/etc/conf.d/named'."
+               die "Unset CHROOT"
+       fi
+
+       if [[ -d "${CHROOT}" ]]; then
+               ewarn "NOTE: As of net-dns/bind-9.4.3_p5-r1 the chroot part of 
the init-script got some major changes!"
+               ewarn "To enable the old behaviour (without using mount) 
uncomment the"
+               ewarn "CHROOT_NOMOUNT option in your /etc/conf.d/named config."
+               ewarn
+               ewarn "${CHROOT} already exists... some things might become 
overridden"
+               ewarn "press CTRL+C if you don't want to continue"
+               sleep 10
+       fi
+
+       echo; einfo "Setting up the chroot directory..."
+
+       mkdir -m 0750 -p ${CHROOT} || die
+       mkdir -m 0755 -p ${CHROOT}/{dev,etc,var/log,run} || die
+       mkdir -m 0750 -p ${CHROOT}/etc/bind || die
+       mkdir -m 0770 -p ${CHROOT}/var/{bind,log/named} ${CHROOT}/run/named/ || 
die
+
+       chown root:named \
+               ${CHROOT} \
+               ${CHROOT}/var/{bind,log/named} \
+               ${CHROOT}/run/named/ \
+               ${CHROOT}/etc/bind \
+               || die
+
+       mknod ${CHROOT}/dev/null c 1 3 || die
+       chmod 0666 ${CHROOT}/dev/null || die
+
+       mknod ${CHROOT}/dev/zero c 1 5 || die
+       chmod 0666 ${CHROOT}/dev/zero || die
+
+       if [[ "${CHROOT_NOMOUNT:-0}" -ne 0 ]]; then
+               cp -a /etc/bind ${CHROOT}/etc/ || die
+               cp -a /var/bind ${CHROOT}/var/ || die
+       fi
+
+       if [[ "${CHROOT_GEOIP:-0}" -eq 1 ]]; then
+               if use geoip; then
+                       mkdir -m 0755 -p ${CHROOT}/usr/share/GeoIP || die
+               elif use geoip2; then
+                       mkdir -m 0755 -p ${CHROOT}/usr/share/GeoIP2 || die
+               fi
+       fi
+
+       elog "You may need to add the following line to your syslog-ng.conf:"
+       elog "source jail { unix-stream(\"${CHROOT}/dev/log\"); };"
 }

diff --git a/net-dns/bind/files/named.confd-r8 
b/net-dns/bind/files/named.confd-r8
index 915c51d4f19f..2d2ef4b868f6 100644
--- a/net-dns/bind/files/named.confd-r8
+++ b/net-dns/bind/files/named.confd-r8
@@ -9,6 +9,25 @@ NAMED_CONF="/etc/bind/named.conf"
 # Leave this unchanged if you want bind to automatically detect the number
 #CPU="1"
 
+# If you wish to run bind in a chroot:
+# 1) un-comment the CHROOT= assignment, below. You may use
+#    a different chroot directory but MAKE SURE it's empty.
+# 2) run: emerge --config =<bind-version>
+#
+#CHROOT="/chroot/dns"
+
+# Uncomment to enable binmount of /usr/share/GeoIP
+#CHROOT_GEOIP="1"
+
+# Uncomment the line below to avoid that the init script mounts the needed 
paths
+# into the chroot directory.
+# You have to copy all needed config files by hand if you say 
CHROOT_NOMOUNT="1".
+#CHROOT_NOMOUNT="1"
+
+# Uncomment this option if you have setup your own chroot environment and you
+# don't want/need the chroot consistency check
+#CHROOT_NOCHECK=1
+
 # Default pid file location
 # use named.conf to specify pid-file location
 

diff --git a/net-dns/bind/files/named.init-r15 
b/net-dns/bind/files/named.init-r15
index d5539d9aa854..bdee10cc61e8 100644
--- a/net-dns/bind/files/named.init-r15
+++ b/net-dns/bind/files/named.init-r15
@@ -11,13 +11,83 @@ depend() {
        provide dns
 }
 
-NAMED_CONF=${NAMED_CONF:-/etc/bind/named.conf}
+NAMED_CONF=${NAMED_CONF:-${CHROOT}/etc/bind/named.conf}
+
+OPENSSL_LIBGOST=${OPENSSL_LIBGOST:-0}
+MOUNT_CHECK_TIMEOUT=${MOUNT_CHECK_TIMEOUT:-60}
+
+_mount() {
+       local from
+       local to
+       local opts
+       local ret=0
+
+       if [ "${#}" -lt 3 ]; then
+               eerror "_mount(): to few arguments"
+               return 1
+       fi
+
+       from=$1
+       to=$2
+       shift 2
+
+       opts="${*}"
+       shift $#
+
+       if [ -z "$(awk "\$2 == \"${to}\" { print \$2 }" /proc/mounts)" ]; then
+               einfo "mounting ${from} to ${to}"
+               mount ${from} ${to} ${opts}
+               ret=$?
+
+               eend $ret
+               return $ret
+       fi
+
+       return 0
+}
+
+_umount() {
+       local dir=$1
+       local ret=0
+
+       if [ -n "$(awk "\$2 == \"${dir}\" { print \$2 }" /proc/mounts)" ]; then
+               ebegin "umounting ${dir}"
+               umount ${dir}
+               ret=$?
+
+               eend $ret
+               return $ret
+       fi
+
+       return 0
+}
 
 _get_pidfile() {
        # as suggested in bug #107724, bug 335398#c17
-       [ -n "${PIDFILE}" ] || PIDFILE=$(\
-                       /usr/bin/named-checkconf -p ${NAMED_CONF} | grep 
'pid-file' | cut -d\" -f2)
-       [ -z "${PIDFILE}" ] && PIDFILE="/run/named/named.pid"
+       [ -n "${PIDFILE}" ] || PIDFILE=${CHROOT}$(\
+                       /usr/sbin/named-checkconf -p ${CHROOT:+-t} ${CHROOT} 
${NAMED_CONF#${CHROOT}} | grep 'pid-file' | cut -d\" -f2)
+       [ -z "${PIDFILE}" ] && PIDFILE=${CHROOT}/run/named/named.pid
+}
+
+check_chroot() {
+       if [ -n "${CHROOT}" ]; then
+               [ ! -d "${CHROOT}" ] && return 1
+               [ ! -d "${CHROOT}/dev" ] || [ ! -d "${CHROOT}/etc" ] || [ ! -d 
"${CHROOT}/var" ] && return 1
+               [ ! -d "${CHROOT}/run" ] || [ ! -d "${CHROOT}/var/log" ] && 
return 1
+               [ ! -d "${CHROOT}/etc/bind" ] || [ ! -d "${CHROOT}/var/bind" ] 
&& return 1
+               [ ! -d "${CHROOT}/var/log/named" ] && return 1
+               [ ! -c "${CHROOT}/dev/null" ] || [ ! -c "${CHROOT}/dev/zero" ] 
&& return 1
+               [ "${CHROOT_GEOIP:-0}" -eq 1 ] && [ ! -d 
"${CHROOT}/usr/share/GeoIP" ] && return 1
+               if [ ${OPENSSL_LIBGOST:-0} -eq 1 ]; then
+                       if [ -d "/usr/lib64" ]; then
+                               [ ! -d "${CHROOT}/usr/lib64/engines" ] && 
return 1
+                       elif [ -d "/usr/lib" ]; then
+                               [ ! -d "${CHROOT}/usr/lib/engines" ] && return 1
+                       fi
+               fi
+       fi
+
+       return 0
 }
 
 checkconfig() {
@@ -27,23 +97,65 @@ checkconfig() {
                eerror "No ${NAMED_CONF} file exists!"
                return 1
        fi
-       /usr/bin/named-checkconf ${NAMED_CONF} || {
+
+       /usr/sbin/named-checkconf ${CHROOT:+-t} ${CHROOT} 
${NAMED_CONF#${CHROOT}} || {
                eerror "named-checkconf failed! Please fix your config first."
                return 1
        }
+
        eend 0
+       return 0
 }
 
 checkzones() {
        ebegin "Checking named configuration and zones"
-       /usr/bin/named-checkconf -z ${NAMED_CONF}
+       /usr/sbin/named-checkconf -z -j ${CHROOT:+-t} ${CHROOT} 
${NAMED_CONF#${CHROOT}}
        eend $?
 }
 
 start() {
        local piddir
 
-       ebegin "Starting named"
+       ebegin "Starting ${CHROOT:+chrooted }named"
+
+       if [ -n "${CHROOT}" ]; then
+               if [ ${CHROOT_NOCHECK:-0} -eq 0 ]; then
+                       check_chroot || {
+                               eend 1
+                               eerror "Your chroot dir ${CHROOT} is 
inconsistent, please run 'emerge --config net-dns/bind' first"
+                               return 1
+                       }
+               fi
+
+               if [ ${OPENSSL_LIBGOST:-0} -eq 1 ]; then
+                       if [ ! -e /usr/lib/engines/libgost.so ]; then
+                               eend 1
+                               eerror "Couldn't find 
/usr/lib/engines/libgost.so but bind has been built with openssl and libgost 
support"
+                               return 1
+                       fi
+                       cp -Lp /usr/lib/engines/libgost.so 
"${CHROOT}/usr/lib/engines/libgost.so" || {
+                               eend 1
+                               eerror "Couldn't copy 
/usr/lib/engines/libgost.so into '${CHROOT}/usr/lib/engines/'"
+                               return 1
+                       }
+               fi
+               cp -Lp /etc/localtime "${CHROOT}/etc/localtime"
+
+               if [ "${CHROOT_NOMOUNT:-0}" -eq 0 ]; then
+                       einfo "Mounting chroot dirs"
+                       _mount /etc/bind ${CHROOT}/etc/bind -o bind
+                       _mount /var/bind ${CHROOT}/var/bind -o bind
+                       _mount /var/log/named ${CHROOT}/var/log/named -o bind
+                       if [ "${CHROOT_GEOIP:-0}" -eq 1 ]; then
+                               _mount /usr/share/GeoIP 
${CHROOT}/usr/share/GeoIP -o bind
+                       fi
+               fi
+
+               # On initial startup, if piddir inside the chroot /var/run/named
+               # Then the .../var/run part might not exist yet
+               checkpath -q -d -o root:root -m 0755 "${piddir}/.."
+       fi
+
        checkconfig || { eend 1; return 1; }
 
        # create piddir (usually /run/named) if necessary, bug 334535
@@ -63,16 +175,56 @@ start() {
        start-stop-daemon --start --pidfile ${PIDFILE} \
                --nicelevel ${NAMED_NICELEVEL:-0} \
                --exec /usr/sbin/named \
-               -- -u named ${CPU} ${OPTIONS}
+               -- -u named ${CPU} ${OPTIONS} ${CHROOT:+-t} ${CHROOT}
        eend $?
 }
 
 stop() {
-       ebegin "Stopping named"
+       local reported=0
+
+       ebegin "Stopping ${CHROOT:+chrooted }named"
+
+       # Workaround for now, until openrc's restart has been fixed.
+       # openrc doesn't care about a restart() function in init scripts.
+       if [ "${RC_CMD}" = "restart" ]; then
+               if [ -n "${CHROOT}" -a ${CHROOT_NOCHECK:-0} -eq 0 ]; then
+                       check_chroot || {
+                               eend 1
+                               eerror "Your chroot dir ${CHROOT} is 
inconsistent, please run 'emerge --config net-dns/bind' first"
+                               return 1
+                       }
+               fi
+
+               checkconfig || { eend 1; return 1; }
+       fi
+
        # -R 10, bug 335398
        _get_pidfile
        start-stop-daemon --stop --retry 10 --pidfile $PIDFILE \
                --exec /usr/sbin/named
+
+       if [ -n "${CHROOT}" ] && [ "${CHROOT_NOMOUNT:-0}" -eq 0 ]; then
+               ebegin "Umounting chroot dirs"
+
+               # just to be sure everything gets clean
+               while fuser -s ${CHROOT} 2>/dev/null; do
+                       if [ "${reported}" -eq 0 ]; then
+                               einfo "Waiting until all named processes are 
stopped (max. ${MOUNT_CHECK_TIMEOUT} seconds)"
+                       elif [ "${reported}" -eq "${MOUNT_CHECK_TIMEOUT}" ]; 
then
+                               eerror "Waiting until all named processes are 
stopped failed!"
+                               eend 1
+                               break
+                       fi
+                       sleep 1
+                       reported=$((reported+1))
+               done
+
+               [ "${CHROOT_GEOIP:-0}" -eq 1 ] && _umount 
${CHROOT}/usr/share/GeoIP
+               _umount ${CHROOT}/etc/bind
+               _umount ${CHROOT}/var/log/named
+               _umount ${CHROOT}/var/bind
+       fi
+
        eend $?
 }
 

Reply via email to