Here's a little change for the `postfix' command I'd love to have
in Debian, - to assist its 25 years history of running postfix
chrooted and to have an easier alternative, one way or the other.

It's just a proof of concept, but it is easy enough.  Not yet written
in a style of other code in this script (like using logging functions
which is a good idea in this case for sure.

The "idea" is to have

   postfix chroot [-n] on|off
     - to run services chrooted (on) or non-chrooted (off)
       (-n to show what would be done instead of actual modifications)
   postfix chroot query
     - to query and return the current status (on|off|mixed).

It has a list of known postfix daemons of 2 categories.  These are
the daemons who should never run chrooted (these are always skipped),
and all the other known ones who can run chrooted.  The code skips
daemons which it does not know about (might be an option to turn this
off).

The main motivation for sending this to the list is to ask the question, -
if such *approach* (patching postfix-script to add custom subcommands)
is a considered a good way, or should I use entirely external commands?
Using `postfix' command seems to be the right way, but I'm not sure it's
okay with Wietse.  Or maybe emphasis this is a custom command, and rename
it to, say, `postfix debian-chroot' or something like this?

Either way, before actually shipping it to the users, I want to complete
it so it adheres to the established standards, and add the documentation.

There are some more special options - the -S option omits known simpler
services, for which no complex chroot setup is necessary (so that it's
possible to go with "advanced" chroot setup - with tls certs, sockets, etc,
only if it is actually in use - this is another PoC, I dislike the current
way it is done - it should distinguish between different complex cases,
like for smtp and smtpd, different things might be needed.

Thanks,

/mjt

--------------------------
From: Michael Tokarev <m...@tls.msk.ru
Date: Thu, 19 Dec 2024 20:32:43 +0300
Subject: implement "postfix chroot" command
Forwarded: no

Implement `postfix chroot' command to assist chrooting and un-chrooting
postfix services in master.cf.  The command ignores postfix services which
should never be chrooted, and also custom services.  For all other known
services:

  postfix chroot [-S][-X] query - print on|off|mixed
  postfix chroot - the same as query
  postfix chroot [-n][-S][-X] on - set all supported services to chroot
  postfix chroot [-n][-S][-X] off - set all supported services to no chroot

  -n - do not make actual changes, only show what would be done
  -S - omit known to be simple/safe services (most internal postfix)
  -X - omit known to be complex/unsafe services (needing more complex
       chroot setup)

The more complex ones are basically lmtp, smtp, smtpd, which might need
TLS certificates, access to additional SASL data and the like.  Some
"safe" ones might include a few files in chroot, like /etc/hosts,
/etc/localtime, etc.

diff --git a/conf/postfix-script b/conf/postfix-script
index c43d764f..daf0af77 100755
--- a/conf/postfix-script
+++ b/conf/postfix-script
@@ -408,6 +408,63 @@ post-install)
        $daemon_directory/post-install "$@"
        ;;

+chroot) # debian-specific
+       shift
+       c=$($command_directory/postconf -h compatibility_level) || exit
+       if [ 3 -le ${c%%.*} ]; then yes='[y]' no='[-n]'
+       else yes='[-y]' no='[n]'
+       fi
+       while [ $# -gt 0 ]; do case "$1" in
+           -n) show=echo; shift;; # do not make changes, only show
+           -S) nosimple=y; shift;; # omit known simple/safe services
+           -X) nocomplex=y; shift;; # omit known complex/unsafe services
+           *) break;;
+       esac; done
+       case "$1" in
+           on | y) verify="$yes" set=y ;;
+           off | n) verify="$no"  set=n ;;
+           query | q | "") verify="$yes" set= ;;
+           *) echo "E: chroot: unknown arg $1 (expected [-n][-S][-X] on|off|query)" 
>&2
+              exit 1
+           ;;
+       esac
+       r=$($command_directory/postconf -M |
+         { while read name type x x chroot x x cmd x; do
+               case $cmd in
+                   local|pipe|postlogd|proxymap|spawn|virtual)
+                       continue ;; # ignore non-chrootable ones
+                   anvil|bounce|cleanup|discard|dnsblog|error|flush|pickup| \
+                   postscreen|scache|showq|tlsmgr|tlsproxy|trivial-rewrite| \
+                   verify|nqmgr|oqmgr|qmgr)
+                       [ -n "$nosimple" ] && continue;;
+                   (lmtp|smtp|smtpd|qmqpd)
+                       [ -n "$nocomplex" ] && continue;;
+                   *) echo "W: custom service $name/$type/command=$cmd (ignored)" 
>&2
+                      continue;;
+               esac
+               case "$chroot" in
+                   $verify) match=y ;;
+                   *) nomatch=y; [ "$set" ] && echo $name/$type ;;
+               esac
+           done
+           if [ ! "$set" ]; then
+               case "$match:$nomatch" in
+                   y:)  echo on ;;
+                   :y)  echo off ;;
+                   y:y) echo mixed ;;
+                   :)   echo off ;;
+               esac
+           fi
+         }
+       )
+       if [ ! "$set" ]; then
+           echo $r
+       elif [ -n "$r" ]; then
+           $show $command_directory/postconf -c $config_directory -F \
+               $(for x in $r; do echo $x/chroot=$set; done)
+       fi
+       ;;
+
 tls)
        shift
        $daemon_directory/postfix-tls-script "$@"

_______________________________________________
Postfix-users mailing list -- postfix-users@postfix.org
To unsubscribe send an email to postfix-users-le...@postfix.org

Reply via email to