mostly a bunch of fixes
[distro-setup] / mail-setup
index 8283d7c07980a8cbc8d3ad416147103b2afdbe2b..65682c2971f513a64b29c207633ca4888397725c 100755 (executable)
@@ -3,6 +3,27 @@
 # Copyright (C) 2019 Ian Kelling
 # SPDX-License-Identifier: AGPL-3.0-or-later
 
+# Things I tend to forget. on MAIL_HOST, daemon runs with /etc/exim4/my.conf,
+# due to /etc/default/exim4 containing:
+# COMMONOPTIONS='-C /etc/exim4/my.conf'
+# UPEX4OPTS='-o /etc/exim4/my.conf'
+#
+# The non-daemon config
+# gets generated from this script calling update-exim4.conf -d /etc/myexim4
+# which has log path
+# log_file_path = /var/log/exim4/my%s
+#
+# eximbackup folder is /bu/md
+# it is cleaned up by mail-backup-clean, which is run by btrbk-run
+
+# shellcheck disable=SC2254 # makes for a lot of unneeded quotes
+
+
+# perusing through /el/mainlog without test messages:
+# &!testignore|jtuttle|
+#
+#&! testignore|jtuttle|eximbackup|/usr/sbin/exim4 -bpu
+
 # todo: check new macro DKIM_TIMESTAMPS
 
 # todo: check if REMOTE_SMTP_INTERFACE or REMOTE_SMTP_TRANSPORTS_HEADERS_REMOVE can simplify my or fsfs config
@@ -282,7 +303,7 @@ fi
 
 # * functions & constants
 
-pre="${0##*/}:"
+pre="${0##*/}:${SSH_CLIENT:+ $HOSTNAME:}"
 m() { printf "$pre %s\n"  "$*"; "$@"; }
 e() { printf "$pre %s\n"  "$*"; }
 err() { printf "$pre %s\n"  "$*" >&2; exit 1; }
@@ -328,9 +349,19 @@ soff () {
   done
 }
 sre() {
+  local enabled
   for service; do
     m systemctl restart $service
-    m systemctl enable $service;
+    # Optimization for exim,
+    # is-enabled: 0m0.015s
+    # enable: 0m0.748s
+    # It is related to this message:
+    # exim4.service is not a native service, redirecting to systemd-sysv-install.
+    # Executing: /lib/systemd/systemd-sysv-install enable exim4
+    enabled=$(systemctl is-enabled $service 2>/dev/null ||:)
+    if [[ $enabled != enabled ]]; then
+      m systemctl enable $service
+    fi
   done
 }
 mailhost() {
@@ -505,7 +536,7 @@ EOF
 # Aug 02 21:59:27 sy systemd[1]: wg-quick@wgmail.service: Failed with result 'exit-code'.
 # Aug 02 21:59:27 sy systemd[1]: Failed to start WireGuard via wg-quick(8) for wgmail.
 # Aug 02 21:59:47 sy systemd[1]: wg-quick@wgmail.service: Scheduled restart job, restart counter is at 1.
-# Aug 02 21:59:47 sy systemd[1]: Stopped WireGuard via wg-quick(8) for wgmail.
+# Aug 02 21:95:47 sy systemd[1]: Stopped WireGuard via wg-quick(8) for wgmail.
 # Aug 02 21:59:47 sy systemd[1]: Starting WireGuard via wg-quick(8) for wgmail...
 # Aug 02 21:59:47 sy wg-quick[3424]: wg-quick: `wgmail' already exists
 # Aug 02 21:59:47 sy systemd[1]: wg-quick@wgmail.service: Main process exited, code=exited, status=1/FAILURE
@@ -826,6 +857,7 @@ fi
 u /etc/spamassassin/mylocal.cf <<'EOF'
 # this is mylocal.cf because the normal local.cf has a bunch of upstream stuff i dont want to mess with
 
+
 # /usr/share/doc/exim4-base/README.Debian.gz:
 #   SpamAssassin's default report should not be used in a add_header
 #   statement since it contains empty lines. (This triggers e.g. Amavis'
@@ -850,6 +882,35 @@ PIDFILE="/var/run/spamd.pid"
 NICE="--nicelevel 15"
 CRON=1
 EOF
+
+case $HOSTNAME in
+  bk)
+u /etc/spamassassin/my_thishost.cf <<'EOF'
+# note: these are duplicated in exim config
+# veth0/1 # bk bk_ip6
+internal_networks 10.173.8.1/32 10.173.8.2/32 85.119.83.50/32 2001:ba8:1f1:f0c9::2
+trusted_networks 10.173.8.1/32 10.173.8.2/32 85.119.83.50/32 2001:ba8:1f1:f0c9::2
+EOF
+
+    ;;
+  je)
+    u /etc/spamassassin/my_thishost.cf <<'EOF'
+# note: these are duplicated in exim config
+# veth0/1 # je je_ipv6
+internal_networks 10.173.8.1/32 10.173.8.2/32 85.119.82.128/32 2001:ba8:1f1:f09d::2/128
+trusted_networks 10.173.8.1/32 10.173.8.2/32 85.119.82.128/32 2001:ba8:1f1:f09d::2/128
+EOF
+    ;;
+  *)
+    u /etc/spamassassin/my_thishost.cf <<'EOF'
+# note: these are duplicated in exim config
+# veth0/1 # li li_ip6
+internal_networks 10.173.8.1/32 10.173.8.2/32 72.14.176.105/32 2600:3c00::f03c:91ff:fe6d:baf8/128
+trusted_networks 10.173.8.1/32 10.173.8.2/32 72.14.176.105/32 2600:3c00::f03c:91ff:fe6d:baf8/128
+EOF
+;;
+  esac
+
 #####   end spamassassin config
 
 
@@ -918,7 +979,7 @@ fi
 # and see someone is banned.
 
 sed 's/^ *before *= *iptables-common.conf/before = iptables-common-exim.conf/' \
-    /etc/fail2ban/action.d/iptables-multiport.conf| i /etc/fail2ban/action.d/iptables-exim.conf
+    /etc/fail2ban/action.d/iptables-multiport.conf| u /etc/fail2ban/action.d/iptables-exim.conf
 u /etc/fail2ban/action.d/iptables-common-exim.conf <<'EOF'
 # iank: same as iptables-common, except iptables is iptables-exim, ip6tables is ip6tables-exim
 
@@ -1136,26 +1197,26 @@ rm -fv /etc/exim4/conf.d/retry/37_retry
 
 cat >/etc/exim4/conf.d/retry/17_retry <<'EOF'
 # Retry fast for my own domains
-iankelling.org * F,1d,4m;F,14d,1h
-amnimal.ninja * F,1d,4m;F,14d,1h
-expertpathologyreview.com * F,1d,4m;F,14d,1h
-je.b8.nz * F,1d,4m;F,14d,1h
-zroe.org * F,1d,4m;F,14d,1h
-eximbackup.b8.nz * F,1d,4m;F,14d,1h
+iankelling.org * F,1d,1m;F,14d,1h
+amnimal.ninja * F,1d,1m;F,14d,1h
+expertpathologyreview.com * F,1d,1m;F,14d,1h
+je.b8.nz * F,1d,1m;F,14d,1h
+zroe.org * F,1d,1m;F,14d,1h
+eximbackup.b8.nz * F,1d,1m;F,14d,1h
 
 # The spec says the target domain will be used for temporary host errors,
 # but i've found that isn't correct, the hostname is required
 # at least sometimes.
-nn.b8.nz * F,1d,4m;F,14d,1h
-defaultnn.b8.nz * F,1d,4m;F,14d,1h
-mx.iankelling.org * F,1d,4m;F,14d,1h
-bk.b8.nz * F,1d,4m;F,14d,1h
-eggs.gnu.org * F,1d,4m;F,14d,1h
-fencepost.gnu.org * F,1d,4m;F,14d,1h
+nn.b8.nz * F,1d,1m;F,14d,1h
+defaultnn.b8.nz * F,1d,1m;F,14d,1h
+mx.iankelling.org * F,1d,1m;F,14d,1h
+bk.b8.nz * F,1d,1m;F,14d,1h
+eggs.gnu.org * F,1d,1m;F,14d,1h
+fencepost.gnu.org * F,1d,1m;F,14d,1h
 
 # afaik our retry doesnt need this, but just using everything
-mx.amnimal.ninja * F,1d,4m;F,14d,1h
-mx.expertpathologyreview.com * F,1d,4m;F,14d,1h
+mx.amnimal.ninja * F,1d,1m;F,14d,1h
+mx.expertpathologyreview.com * F,1d,1m;F,14d,1h
 
 
 mail.fsf.org * F,1d,15m;F,14d,1h
@@ -1177,27 +1238,16 @@ cd /etc/exim4
   for f in *-private.pem; do
     echo ${f%-private.pem}
   done
-} | i /etc/exim4/conf.d/my-dkim-domains
-
-if grep -Fq REMOTE_SMTP_SMARTHOST_TLS_VERIFY_HOSTS \
-        /etc/exim4/conf.d/transport/10_exim4-config_transport-macros; then
-  cat >/etc/exim4/conf.d/transport/11_iank <<'EOF'
-# This unsets the default macro defined in on t11 in
-# /etc/exim4/conf.d/transport/10_exim4-config_transport-macros
-# It seems like a very odd choice that this has become
-# the default in t11. Normal smarthost clients use username/password
-# auth. Oh well.
-REMOTE_SMTP_SMARTHOST_TLS_VERIFY_HOSTS ==
-EOF
-else
-  rm -f /etc/exim4/conf.d/transport/11_iank
-fi
+} | u /etc/exim4/conf.d/my-dkim-domains
+
+rm -f /etc/exim4/conf.d/transport/11_iank
 
 cat >/etc/exim4/conf.d/main/000_local <<'EOF'
 MAIN_TLS_ENABLE = true
 
 # require tls connections for all smarthosts
-REMOTE_SMTP_SMARTHOST_HOSTS_REQUIRE_TLS = *
+REMOTE_SMTP_SMARTHOST_HOSTS_REQUIRE_TLS = ! nn.b8.nz
+REMOTE_SMTP_SMARTHOST_HOSTS_AVOID_TLS = nn.b8.nz
 
 # debian exim config added this in 2016 or so?
 # it's part of the smtp spec, to limit lines to 998 chars
@@ -1210,7 +1260,7 @@ REMOTE_SMTP_SMARTHOST_HOSTS_REQUIRE_TLS = *
 IGNORE_SMTP_LINE_LENGTH_LIMIT = true
 
 # more verbose logs. used to use +all, but made it less for more efficiency.
-MAIN_LOG_SELECTOR = -tls_cipher -tls_certificate_verified +pid +received_recipients +received_sender +sender_on_delivery +return_path_on_delivery +msg_id_created +subject +address_rewrite +smtp_confirmation
+MAIN_LOG_SELECTOR = -skip_delivery -tls_cipher -tls_certificate_verified +all_parents +address_rewrite +arguments +deliver_time +pid +queue_time +queue_time_overall +received_recipients +received_sender +return_path_on_delivery +sender_on_delivery +smtp_confirmation +subject
 
 # Based on spec, seems like a good idea to be nice.
 smtp_return_error_details = true
@@ -1241,6 +1291,7 @@ DKIM_SIGN_HEADERS = mime-version:in-reply-to:references:from:date:subject:to
 
 domainlist local_hostnames = ! je.b8.nz : ! bk.b8.nz : *.b8.nz : b8.nz
 
+# note: most of these are duplicated in spamassassin config
 hostlist iank_trusted = <; \
 # veth0
 10.173.8.1 ; \
@@ -1269,7 +1320,7 @@ delay_warning_condition = ${if or {\
 
 # enable 587 in addition to the default 25, so that
 # i can send mail where port 25 is firewalled by isp
-daemon_smtp_ports = 25 : 587
+daemon_smtp_ports = 25 : 587 : 10025
 # default of 25, can get stuck when catching up on mail
 smtp_accept_max = 400
 smtp_accept_reserve = 100
@@ -1710,7 +1761,6 @@ EOF
 cat >/etc/exim4/update-exim4.conf.conf  <<'EOF'
 # default stuff, i havent checked if its needed
 dc_minimaldns='false'
-dc_relay_nets=''
 CFILEMODE='644'
 dc_use_split_config='true'
 dc_mailname_in_oh='true'
@@ -1742,6 +1792,7 @@ if mailhost; then
   # # setup chgrp www-data in ./conflink
 
   pi-nostart radicale
+  m usermod -a -G radicale iank
 
   u /etc/systemd/system/radicale.service.d/override.conf <<EOF
 [Unit]
@@ -2196,27 +2247,28 @@ if [[ $HOSTNAME == bk ]]; then
 
   ### begin composer install
   # https://getcomposer.org/doc/faqs/how-to-install-composer-programmatically.md
-  # cd $(mktemp -d)
-  # sum="$(wget -q -O - https://composer.github.io/installer.sig)"
-  # m php -r "copy('https://getcomposer.org/installer', 'composer-setup.php');"
-  # if [[ $sum != $(php -r "echo hash_file('sha384', 'composer-setup.php');") ]]; then
-  #   echo 'ERROR: Invalid composer installer checksum' >&2
-  #   rm -fv composer-setup.php
-  #   exit 1
-  # fi
-  # m php composer-setup.php --quiet
-  # rm -fv composer-setup.php
-  # m mv composer.phar /usr/local/bin
-
-  # the above method gets composer2, carddav plugin at least doesnt work with that
-  # yet, it was just released 10-24-2020.
-  m cd /usr/local/bin
-  m wget -nv -N https://getcomposer.org/composer-1.phar
-  chmod +x composer-1.phar
+  cd /usr/local/bin
+  EXPECTED_CHECKSUM="$(php -r 'copy("https://composer.github.io/installer.sig", "php://stdout");')"
+  php -r "copy('https://getcomposer.org/installer', 'composer-setup.php');"
+  ACTUAL_CHECKSUM="$(php -r "echo hash_file('sha384', 'composer-setup.php');")"
+
+  if [ "$EXPECTED_CHECKSUM" != "$ACTUAL_CHECKSUM" ]
+  then
+    >&2 echo 'ERROR: Invalid installer checksum'
+    rm composer-setup.php
+    exit 1
+  fi
+
+  php composer-setup.php --quiet
+  rm composer-setup.php
+
+  # based on error when running composer
+  mkdir -p /var/www/.composer
+  chown www-data:www-data /var/www/.composer
+
   ### end composer install
 
   rcdirs=(/usr/local/lib/rcexpertpath /usr/local/lib/rcninja)
-  ncdirs=(/var/www/ncninja)
   ncdirs=(/var/www/ncexpertpath /var/www/ncninja)
   # point debian cronjob to our local install, preventing daily cron error
 
@@ -2248,8 +2300,6 @@ if [[ $HOSTNAME == bk ]]; then
     rcdir=${rcdirs[i]}
     rcbase=${rcdir##*/}
     ncdir=${ncdirs[i]}
-    myncdir=/root/${ncdir##*/}
-    mkdir -p $myncdir
 
     # copied from debians cronjob
     u /etc/cron.d/$rcbase <<EOF
@@ -2371,7 +2421,7 @@ EOF
     verf=$rcdir/plugins/carddav/myversion
     upgrade=false
     install=false
-    v=4.0.0
+    v=5.0.1
     if [[ -e $verf ]]; then
       if [[ $(cat $verf) != "$v" ]]; then
         install=true
@@ -2383,16 +2433,16 @@ EOF
     if $install; then
       m rm -rf $rcdir/plugins/carddav
       tmpd=$(mktemp -d)
-      m wget -nv -O $tmpd/t.tgz https://github.com/blind-coder/rcmcarddav/releases/download/v$v/carddav-v$v.tgz
+      m wget -nv -O $tmpd/t.tgz https://github.com/blind-coder/rcmcarddav/releases/download/v$v/carddav-v$v.tar.gz
       cd $rcdir/plugins
       tar xzf $tmpd/t.tgz
       rm -rf $tmpd
       m chown -R www-data:www-data $rcdir/plugins/carddav
       m cd $rcdir/plugins/carddav
       if $upgrade; then
-        m sudo -u www-data composer-1.phar update --no-dev
+        m sudo -u www-data composer.phar update --no-dev
       else
-        m sudo -u www-data composer-1.phar install --no-dev
+        m sudo -u www-data composer.phar install --no-dev
       fi
       m chown -R root:root $rcdir/plugins/carddav
       echo $v >$verf
@@ -2516,7 +2566,9 @@ EOF
   for ((i=0; i < ${#bkdomains[@]}; i++)); do
     domain=${bkdomains[i]}
     ncdir=${ncdirs[i]}
+    myncdir=/var/local/${ncdir##*/}
     ncbase=${ncdir##*/}
+    mkdir -p $myncdir
     m cd /var/www
     if [[ ! -e $ncdir/index.php ]]; then
       # if we wanted to only install a specific version, use something like
@@ -2536,13 +2588,16 @@ EOF
       m touch $myncdir/done-install
     fi
 
-    # note, strange this happend where updater did not increment the version var,
-    # mine was stuck on 20. I manually updated it.
     m cd $ncdir/config
-    if [[ ! -e $myncdir/config.php-orig ]]; then
-      m cp -a config.php $myncdir/config.php-orig
-    fi
-    cat $myncdir/config.php-orig - >$myncdir/tmp.php <<EOF
+    # if we did this more than once, it would revert the
+    # version number to the original.
+    if [[ ! -e $myncdir/config.php-orig || ! -s config.php ]]; then
+      if [[ -s config.php ]]; then
+        m cp -a config.php $myncdir/config.php-orig
+        # keep the file so it keeps the same permissions.
+        truncate -s0 config.php
+      fi
+      cat $myncdir/config.php-orig - >$myncdir/tmp.php <<EOF
 # https://docs.nextcloud.com/server/19/admin_manual/configuration_server/email_configuration.html
 \$CONFIG["mail_smtpmode"] = "sendmail";
 \$CONFIG["mail_smtphost"] = "127.0.0.1";
@@ -2574,9 +2629,11 @@ fwrite(STDOUT, "<?php\n\\\$CONFIG = ");
 var_export(\$CONFIG);
 fwrite(STDOUT, ";\n");
 EOF
-    e running php $myncdir/tmp.php
-    # note: we leave it around place for debugging
-    php $myncdir/tmp.php >config.php
+      e running php $myncdir/tmp.php
+      # note: we leave it around place for debugging
+      # shellcheck disable=SC2024 # intended
+      sudo -u www-data php $myncdir/tmp.php >config.php
+    fi
     cd $ncdir
     m sudo -u www-data php occ maintenance:update:htaccess
     list=$(sudo -u www-data php $ncdir/occ --output=json_pretty app:list)
@@ -2642,7 +2699,13 @@ fi
 ncbase=$1
 cd /var/www/$ncbase
 # https://docs.nextcloud.com/server/22/admin_manual/maintenance/update.html?highlight=updater+phar
+# the docs claim this is all you need, which is not true.
+# You will go to the web ui and it will say that you need to click a button to update,
+# or that you can run occ upgrade
 m php /var/www/$ncbase/updater/updater.phar -n
+# throw a sleep in just because who knows what else is undocumented
+sleep 5
+m php occ upgrade
 EOFOUTER
     chmod +x /usr/local/bin/ncup
 
@@ -2805,7 +2868,7 @@ EOF
       mmm_mail4root
     )
     for f in ${files[@]}; do
-      echo "# iank: removed due to running nonroot"|i /etc/exim4/conf.d/router/$f
+      echo "# iank: removed due to running nonroot"|u /etc/exim4/conf.d/router/$f
     done
     ;;
 esac
@@ -2815,7 +2878,7 @@ case $HOSTNAME in
   # ** $MAIL_HOST|bk|je)
   $MAIL_HOST|bk|je)
 
-    echo|i /etc/exim4/conf.d/router/165_backup_local
+    echo|u /etc/exim4/conf.d/router/165_backup_local
 
     cat >>/etc/exim4/update-exim4.conf.conf <<EOF
 # note: some things we don't set that are here by default because they are unused.
@@ -2845,6 +2908,9 @@ EOF
   # ** $MAIL_HOST|bk)
   $MAIL_HOST|bk)
 
+    cat >>/etc/exim4/update-exim4.conf.conf <<EOF
+dc_relay_nets='defaultnn.b8.nz'
+EOF
 
     # no clamav on je, it has 1.5g memory and clamav uses most of it
     u /etc/exim4/conf.d/clamav_data_acl <<'EOF'
@@ -2896,7 +2962,7 @@ gnusmarthost:
   debug_print = "R: smarthost for $local_part@$domain"
   driver = manualroute
   domains = ! +local_domains
-# send most mail through eggs, helps fsfs sender reputation.
+# comment senders to send most mail through eggs, helps fsfs sender reputation.
 # uncomment and optionally move to 188 file to send through my own servers again
   senders = *@gnu.org
   transport = smarthost_dkim
@@ -2974,7 +3040,7 @@ deny
 #  senders = testlist-bounces+test=zroe.org@fsf.org
 #  message = iank-bounce
 EOF
-    echo|i /etc/exim4/conf.d/router/880_universal_forward
+    echo|u /etc/exim4/conf.d/router/880_universal_forward
 
 
     cat >>/etc/exim4/conf.d/main/000_local <<EOF
@@ -3092,7 +3158,7 @@ EOF
 10.173.8.2 nn.b8.nz
 EOF
 
-    sed -r -f - /etc/init.d/exim4  <<'EOF' | i /etc/init.d/exim4in
+    sed -r -f - /etc/init.d/exim4  <<'EOF' |u /etc/init.d/exim4in
 s,/etc/default/exim4,/etc/default/exim4in,g
 s,/run/exim4/exim.pid,/run/exim4/eximin.pid,g
 s,(^[ #]*Provides:).*,\1 exim4in,
@@ -3135,16 +3201,16 @@ EOF
   *)
     # this one should be removed for all non mail hosts, but
     # bk and je never become mail_host
-    echo|i /etc/exim4/conf.d/router/195_dnslookup_vpn
-    echo|i /etc/exim4/conf.d/router/160_backup_redir
-    echo|i /etc/exim4/conf.d/router/161_backup_redir_nn
-    echo|i /etc/exim4/conf.d/router/185_sentarchive
-    echo|i /etc/exim4/conf.d/router/186_sentarchive_nn
-    echo|i /etc/exim4/conf.d/router/188_exim4-config_smarthost
-    echo|i /etc/exim4/conf.d/router/190_exim4-config_fsfsmarthost
-    echo|i /etc/exim4/conf.d/rcpt_local_acl
-    echo|i /etc/exim4/conf.d/main/000_local-nn
-    echo|i /etc/exim4/conf.d/clamav_data_acl
+    echo|u /etc/exim4/conf.d/router/195_dnslookup_vpn
+    echo|u /etc/exim4/conf.d/router/160_backup_redir
+    echo|u /etc/exim4/conf.d/router/161_backup_redir_nn
+    echo|u /etc/exim4/conf.d/router/185_sentarchive
+    echo|u /etc/exim4/conf.d/router/186_sentarchive_nn
+    echo|u /etc/exim4/conf.d/router/188_exim4-config_smarthost
+    echo|u /etc/exim4/conf.d/router/190_exim4-config_fsfsmarthost
+    echo|u /etc/exim4/conf.d/rcpt_local_acl
+    echo|u /etc/exim4/conf.d/main/000_local-nn
+    echo|u /etc/exim4/conf.d/clamav_data_acl
 
 
     if $bhost_t; then
@@ -3241,7 +3307,7 @@ dc_eximconfig_configtype='smarthost'
 dc_smarthost='$smarthost'
 EOF
 
-    hostname -f |i /etc/mailname
+    hostname -f |u /etc/mailname
     cat >>/etc/exim4/update-exim4.conf.conf <<EOF
 # The manpage incorrectly states this will do header rewriting, but
 # that only happens if we have dc_hide_mailname is set.
@@ -3321,7 +3387,6 @@ sentarchive:
   unseen
 EOF
 
-
     u /etc/myexim4/conf.d/router/160_backup_redir <<'EOF'
 backup_redir:
 driver = redirect
@@ -3338,8 +3403,6 @@ unseen = true
 errors_to = alerts@iankelling.org
 EOF
 
-
-
     # for bk, we have a exim4in.service that will do this for us.
     m update-exim4.conf -d /etc/myexim4
     ;;
@@ -3417,14 +3480,20 @@ if $reload; then
   m systemctl daemon-reload
 fi
 
-# checking bhost_t is redundant, but could help us catch errors.
-if $bhost_t || [[ -e /etc/wireguard/wghole.conf ]]; then
-  # todo: in mail-setup, we have a static list of backup hosts, not *y
-  m systemctl --now enable wg-quick@wghole
+# optimization, this only needs to run once.
+if [[ ! -e /sys/class/net/wghole ]]; then
+  # checking bhost_t is redundant, but could help us catch errors.
+  if $bhost_t || [[ -e /etc/wireguard/wghole.conf ]]; then
+    # todo: in mail-setup, we have a static list of backup hosts, not *y
+    m systemctl --now enable wg-quick@wghole
+  fi
 fi
 
-sysd-prom-fail-install epanicclean
-m systemctl --now enable epanicclean
+# optimization, this only needs to be run once
+if [[ ! -e /var/lib/prometheus/node-exporter/exim_paniclog.prom ]]; then
+  sysd-prom-fail-install epanicclean
+  m systemctl --now enable epanicclean
+fi
 
 case $HOSTNAME in
   je)
@@ -3435,8 +3504,11 @@ case $HOSTNAME in
     ;;
 esac
 
-m /a/bin/ds/mail-cert-cron -1
-sre mailcert.timer
+# optimization, this only needs to run once.
+if [[ ! -e /etc/exim4/fullchain.pem ]]; then
+  m /a/bin/ds/mail-cert-cron -1
+  m systemctl --now enable mailcert.timer
+fi
 
 case $HOSTNAME in
   $MAIL_HOST|bk)
@@ -3473,9 +3545,11 @@ case $HOSTNAME in
   $MAIL_HOST|bk|je)
     # start spamassassin/dovecot before exim.
     sre dovecot spamassassin
-    # need to wait a bit before restarting exim, else I
-    # get a paniclog entry like: spam acl condition: all spamd servers failed
-    sleep 3
+    # Wait a bit before restarting exim, else I get a paniclog entry
+    # like: spam acl condition: all spamd servers failed. But I'm tired
+    # of waiting. I'll deal with this some other way.
+    #
+    # sleep 3
     m systemctl --now enable mailclean.timer
     ;;&
   $MAIL_HOST)