#! /bin/bash -e # postinst script for zdkimfilter # (use bash for arithmetic expantion) # use dbconfig-common; see: # https://www.debian.org/doc/manuals/dbconfig-common/ch-develguide.html # The relevant install and upgrade files are created by the # rule 'override_dh_auto_install' in debian/rules. . /usr/share/debconf/confmodule . /usr/share/dbconfig-common/dpkg/postinst.mysql # debconf protocol 2.0 db_version 2.0 dbc_go zdkimfilter "$@" # sysconfdir --courier-config must exist! eval $(courier-config | grep -E '^(sysconfdir|libexecdir)') # mail user and group (should use courier-config?) mailuser="$(source ${sysconfdir}/esmtpd; echo "$MAILUSER")" mailgroup="$(source ${sysconfdir}/esmtpd; echo "$MAILGROUP")" CONFIGFILE=${sysconfdir}/filters/zdkimfilter.conf # Write to stderr (not to confuse debconf) OUTPUT="&2" echo "zdkimfilter.postinst:" > $OUTPUT db_get zdkimfilter/install-setuid if [ "$RET" = true ]; then chown $mailuser:$mailgroup /usr/bin/zdkimsign chmod u+s /usr/bin/zdkimsign echo "setuid zdkimsign" >> $OUTPUT fi chown $mailuser:$mailgroup ${libexecdir}/filters/zdkimfilter if [ "$1" = "configure" ]; then ## List of files to be prepared under this condition: ## * a config file in /usr/share/zdkimfilter, ## * a script to trim database entries, ## * a script to send DMARC reports, ## * a DKIM signing key for the domain, and ## * a cron snippet to call dmarc_send. ## -- ## a config file in /usr/share/zdkimfilter USRCONFIG=/usr/share/zdkimfilter/zdkimfilter.conf cat /usr/share/zdkimfilter/zdkimfilter.conf.orig.dist > $USRCONFIG # there are less pitfalls with relaxed canonicalization echo "header_canon_relaxed" >> $USRCONFIG echo "body_canon_relaxed" >> $USRCONFIG echo "" >> $USRCONFIG if [ "$dbc_install" = "true" ]; then echo "# DB" >> $USRCONFIG echo "#" >> $USRCONFIG # DB access, and prepare mysql args echo "db_backend mysql" >> $USRCONFIG chown $mailuser:$mailgroup $USRCONFIG chmod u=rw,go= $USRCONFIG if [ -z "$dbc_dbserver" ]; then dbc_dbserver=127.0.0.1 mysql_args="" elif [ -s "$dbc_dbserver" ]; then # FIXME: does dbconfig support this? (OpenDBX does) mysql_args="--socket=$dbc_dbserver" else mysql_args="--host=$dbc_dbserver" fi echo "db_host $dbc_dbserver" >> $USRCONFIG if [ -n "$dbc_dbport" ]; then echo "db_port $dbc_dbport" >> $USRCONFIG mysql_args="$mysql_args --port=$dbc_dbport" fi echo "db_user $dbc_dbuser" >> $USRCONFIG mysql_args="$mysql_args --user=$dbc_dbuser" if [ -n "$dbc_dbpass" ]; then echo "db_password $dbc_dbpass" >> $USRCONFIG mysql_args="$mysql_args --password=$dbc_dbpass" fi echo "db_database $dbc_dbname" >> $USRCONFIG mysql_args="$mysql_args $dbc_dbname" # db_opt_multi_statements seems to be needed because of db_sql_insert_message echo "db_opt_multi_statements" >> $USRCONFIG fi # public suffix list echo "" >> $USRCONFIG echo "publicsuffix /usr/share/publicsuffix/effective_tld_names.dat" >> $USRCONFIG echo "psddmarc /usr/share/zdkimfilter/tentative-psddmarc-list.txt" >> $USRCONFIG # mixed options not already present in the example echo "" >> $USRCONFIG echo "no_signlen" >> $USRCONFIG echo "key_choice_header from *" >> $USRCONFIG echo "" >> $USRCONFIG if [ "$dbc_install" = "true" ]; then echo "# DB SQL" >> $USRCONFIG echo "#" >> $USRCONFIG cat /usr/share/zdkimfilter/db_sql.conf >> $USRCONFIG fi ucf --debconf-ok --three-way $USRCONFIG $CONFIGFILE ucfr zdkimfilter $CONFIGFILE if [ "$dbc_install" = "true" ]; then ## a script to trim database entries DELOLDSCRIPT=/etc/cron.daily/zdkimfilter echo "#! /bin/sh" > $DELOLDSCRIPT chown root:root $DELOLDSCRIPT chmod u=rw,go= $DELOLDSCRIPT echo "# delete old messages (not domains) from the database" >> $DELOLDSCRIPT echo "# incoming" >> $DELOLDSCRIPT echo "mysql $mysql_args <> $DELOLDSCRIPT echo " DELETE r, m FROM msg_ref AS r, message_in AS m" >> $DELOLDSCRIPT echo " WHERE r.message_in = m.id AND" >> $DELOLDSCRIPT echo " m.mtime < UNIX_TIMESTAMP(NOW() - INTERVAL 1 MONTH);" >> $DELOLDSCRIPT echo "EOQUERY" >> $DELOLDSCRIPT echo "" >> $DELOLDSCRIPT echo "# outgoing" >> $DELOLDSCRIPT echo "mysql $mysql_args <> $DELOLDSCRIPT echo " DELETE r, m FROM msg_out_ref AS r, message_out AS m" >> $DELOLDSCRIPT echo " WHERE r.message_out = m.id AND" >> $DELOLDSCRIPT echo " m.mtime < UNIX_TIMESTAMP(NOW() - INTERVAL 1 MONTH);" >> $DELOLDSCRIPT echo "EOQUERY" >> $DELOLDSCRIPT chmod u=rx,go= $DELOLDSCRIPT echo "Installed $DELOLDSCRIPT" >> $OUTPUT ## a script to send DMARC reports DMARC_SEND=/usr/share/zdkimfilter/dmarc_send if [ -s ${sysconfdir}/defaultdomain ]; then org_domain=$(<${sysconfdir}/defaultdomain) elif [ -s ${sysconfdir}/dsnfrom ]; then org_domain=$(sed -nr 's/[^@]*@([^>]*).*/\1/p' ${sysconfdir}/dsnfrom) fi chmod a+x $DMARC_SEND if [ -n "$org_domain" ]; then # The "organization" item is usually set to the domain name # see https://us.dmarcian.com/dmarc-data-providers/ sed -ri -e "s/example\.com/$org_domain/" \ -e "s/This is an example/$org_domain/" $DMARC_SEND chown $mailuser:$mailgroup $DMARC_SEND chmod a+x $DMARC_SEND ## a DKIM signing key for the domain # let size=1148 so that the whole string will be less than 256 bytes # a string length believed to be supported by all DNS tools. # if [ ! -f ${sysconfdir}/filters/keys/deb.private ]; then zdkimgenkey -D /usr/share/zdkimfilter -s deb -d $org_domain -b 1148 mkdir -p ${sysconfdir}/filters/keys mv /usr/share/zdkimfilter/deb.private ${sysconfdir}/filters/keys chown $mailuser:$mailgroup ${sysconfdir}/filters/keys/deb.private if [ ! -f ${sysconfdir}/filters/keys/$org_domain ]; then ln -n -s -T deb.private "${sysconfdir}/filters/keys/$org_domain" unset unlinked else unlinked=" (not linked)" fi echo "Created DKIM signing key pair$unlinked in ${sysconfdir}/filters/keys" >> $OUTPUT echo "public key in /usr/share/zdkimfilter/deb.txt" >> $OUTPUT fi ## a cron snippet to call dmarc_send DMARCFILE=/etc/cron.d/zdkimfilter echo "# crontab fragment to send DMARC aggregate reports" > $DMARCFILE echo "# send reports once a day, somewhere after midnight UTC" >> $DMARCFILE echo "# if sending more often, set honored_report_interval in" >> $DMARCFILE echo "# $CONFIGFILE" >> $DMARCFILE echo "#" >> $DMARCFILE # compute a suitable time for a cron job after midnight UTC # check DST and use largest offset typeset -i summer winter after hour minute summer=$(date --date '2022/07/10' +%z |sed -rn 's/([-+])0{0,3}([0-9]*)/\1\2/p') winter=$(date --date '2022/01/10' +%z |sed -rn 's/([-+])0{0,3}([0-9]*)/\1\2/p') if test $summer -gt $winter ; then after=$summer else after=$winter fi # map [-1200, +1200] to [0, 2400] hour=$(($after/100)) minute=$(($after%100)) if test $after -lt 0 ; then let $((hour+=24)) || true if test $minute -lt 0 ; then let $((minute+=60)) || true let $((hour-=1)) || true fi fi # add some 15~45 minutes let RANDOM=$(($(date +%s)%32767)) || true let minute+=$((15+$RANDOM%32767*30/32767)) || true if test $minute -ge 60 ; then let $((minute-=60)) || true let $((hour+=1)) || true if test $hour -ge 24; then hour=0 fi fi echo "$minute $hour * * * $mailuser test ! -x $DMARC_SEND || $DMARC_SEND" >> $DMARCFILE echo "Installed $DMARCFILE" >> $OUTPUT fi fi fi # It would seem to be a neat idea to enable filtering, since we're installing one. # Is there a Debian policy about this? if [ ! -e ${sysconfdir}/enablefiltering ]; then echo "esmtp" > ${sysconfdir}/enablefiltering chown $mailuser:$mailgroup ${sysconfdir}/enablefiltering echo "Mail filtering enabled" >> $OUTPUT fi # if we stopped filters, then restart them, otherwise run zdkimfilter anew if [ -e ${sysconfdir}/filters/active/zdkimfilter ]; then courierfilter start echo "Courier filter started" >> $OUTPUT else filterctl start zdkimfilter echo "Zdkimfilter enabled" >> $OUTPUT fi # dh_installdeb will replace this with shell code automatically # generated by other debhelper scripts. #DEBHELPER# exit 0