lots of fixes, automation for bitfolk
[distro-setup] / mail-setup
index 46933160539e29a67fbc258a3c5ae0c208268d82..5166faa3a44e1a9009368ee48d9a989cfe3272d2 100755 (executable)
@@ -3,6 +3,13 @@
 # Copyright (C) 2019 Ian Kelling
 # SPDX-License-Identifier: AGPL-3.0-or-later
 
+
+# todo: add a prometheus alert for dovecot.
+
+# todo: handle errors like this:
+# Mar 02 12:44:26 kw systemd[1]: exim4.service: Found left-over process 68210 (exim4) in control group while starting unit. Ignoring.
+# Mar 02 12:44:26 kw systemd[1]: This usually indicates unclean termination of a previous run, or service implementation deficiencies.
+
 #  todo: harden dovecot. need to do some research. one way is for it to only listen on a wireguard vpn interface, so only clients that are on the vpn can access it.
 #  todo: consider hardening cups listening on 0.0.0.0
 #  todo: stop/disable local apache, and rpc.mountd, and kdeconnect when not in use.
@@ -18,8 +25,6 @@
 # todo: run mailping test after running, or otherwise
 # clear out terminal alert
 
-# todo: reinstall bk with bigger filesystem
-
 # todo: on bk, dont send email if mailvpn is not up
 
 # todo: mailtest-check should check on bk too
@@ -165,9 +170,10 @@ fi
 # background: dovecot does not yet have ocsp stapling support
 # reference: https://community.letsencrypt.org/t/simple-guide-using-lets-encrypt-ssl-certs-with-dovecot/2921
 #
-# for phone, k9mail, same thing but username alerts, pass in ivy-pass.
+# for phone, k9mail, fdroid, same thing but username alerts, pass in ivy-pass.
 # also, bk.b8.nz for secondary alerts, username is iank. same alerts pass.
-# fetching mail settings: folder poll frequency 10 minutes
+# fetching mail settings: folder poll frequency 10 minutes.
+# account settings, fetching mail, push folders: All. Then disable the persistent notification.
 #######
 
 
@@ -380,11 +386,16 @@ EOF
 fi
 
 # light version of exim does not have sasl auth support.
-pi-nostart exim4 exim4-daemon-heavy spamassassin openvpn unbound clamav-daemon wireguard
+pi-nostart exim4 exim4-daemon-heavy spamassassin unbound clamav-daemon wireguard
 
 # note: pyzor debian readme says you need to run some initialization command
 # but its outdated.
 pi spf-tools-perl p0f postgrey pyzor razor jq moreutils certbot fail2ban
+case $HOSTNAME in
+  je) : ;;
+  # not included due to using wireguard: openvpn
+  *) pi wget git unzip iptables ;;
+esac
 # bad packages that sometimes get automatically installed
 pu openresolv resolvconf
 
@@ -479,7 +490,6 @@ case $HOSTNAME in
     i /etc/systemd/system/wg-quick@wgmail.service.d/override.conf <<EOF
 [Unit]
 Requires=mailnn.service
-After=network.target mailnn.service
 JoinsNamespaceOf=mailnn.service
 BindsTo=mailnn.service
 StartLimitIntervalSec=0
@@ -655,6 +665,7 @@ fi
 
 case $HOSTNAME in
   $MAIL_HOST)
+    # todo, should this be after vpn service
     i /etc/systemd/system/unbound.service.d/nn.conf <<EOF
 [Unit]
 After=mailnn.service
@@ -782,14 +793,20 @@ if [[ -e /p/c/filesystem ]]; then
   # NOTE: Pulled options changed on restart, will need to close and reopen TUN/TAP device.
   m /a/exe/vpn-mk-client-cert -b mailclient -n mail li.iankelling.org
 fi
-case $HOSTNAME in
-  bk)
-    if [[ ! -e /etc/openvpn/client/mail.conf ]]; then
-      echo "$0: error: first, on a system with /p/c/filesystem, run mail-setup, or the vpn-mk-client-cert line above this err" 2>&2
-      exit 1
-    fi
-    ;;
-esac
+
+# With openvpn, I didn't get around to persisting the openvpn
+# cert/configs into /p/c/machine_specific/bk, so I had this case to
+# manually get the cert. However, we aren't using openvpn anymore, so it
+# is commented out.
+#
+# case $HOSTNAME in
+#   bk)
+#     if [[ ! -e /etc/openvpn/client/mail.conf ]]; then
+#       echo "$0: error: first, on a system with /p/c/filesystem, run mail-setup, or the vpn-mk-client-cert line above this err" 2>&2
+#       exit 1
+#     fi
+#     ;;
+# esac
 
 m rsync -aiSAX --chown=root:root --chmod=g-s /a/bin/ds/mail-cert-cron /usr/local/bin
 
@@ -1048,6 +1065,16 @@ expertpathologyreview.com * F,1d,10m;F,14d,1h
 je.b8.nz * F,1d,10m;F,14d,1h
 zroe.org * F,1d,10m;F,14d,1h
 eximbackup.b8.nz * F,1d,4m;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
+mail.fsf.org * F,1d,15m;F,14d,1h
 EOF
 
 
@@ -1516,7 +1543,7 @@ case $HOSTNAME in
     # sieve has the benefit of being supported in postfix and
     # proprietary/weird environments, so there is more examples on the
     # internet.
-    pi dovecot-core dovecot-imapd dovecot-sieve dovecot-lmtpd dovecot-sqlite sqlite3
+    pi-nostart dovecot-core dovecot-imapd dovecot-sieve dovecot-lmtpd dovecot-sqlite sqlite3
 
     for f in /p/c{/machine_specific/$HOSTNAME,}/filesystem/etc/dovecot/users; do
       if [[ -e $f ]]; then
@@ -1540,17 +1567,23 @@ xioE3sYKdjOt+p6mlg3l8+OLtODEFPHDqwIBAg==
 -----END DH PARAMETERS-----
 EOF
     {
+
       if [[ $HOSTNAME == "$MAIL_HOST" ]]; then
         cat <<'EOF'
 ssl_cert = </etc/exim4/fullchain.pem
 ssl_key = </etc/exim4/privkey.pem
 EOF
       else
+        # We have a lets encrypt hooks that puts things here.
+        # This is just for bk, which uses the vpn cert in exim
+        # for sending mail, but the local hostname cert for
+        # dovecot.
         cat <<'EOF'
 ssl_cert = </etc/exim4/exim.crt
 ssl_key = </etc/exim4/exim.key
 EOF
       fi
+
       cat <<'EOF'
 # https://ssl-config.mozilla.org
 ssl = required
@@ -1861,6 +1894,7 @@ if [[ $HOSTNAME == bk ]]; then
   ### 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
 
@@ -1870,7 +1904,7 @@ if [[ $HOSTNAME == bk ]]; then
   #### begin dl roundcube
   # note, im r2e subbed to https://github.com/roundcube/roundcubemail/releases.atom
   v=1.4.13; f=roundcubemail-$v-complete.tar.gz
-  cd /a/opt
+  cd /root
   if [[ -e $f ]]; then
     timestamp=$(stat -c %Y $f)
   else
@@ -2211,7 +2245,7 @@ var_export(\$CONFIG);
 fwrite(STDOUT, ";\n");
 EOF
     m php tmp.php >config.php
-    m rm tmp.php
+    m rm -f tmp.php
     m sudo -u www-data php $ncdir/occ maintenance:update:htaccess
     list=$(sudo -u www-data php $ncdir/occ --output=json_pretty app:list)
     # user_external not compaible with nc 23
@@ -2262,11 +2296,12 @@ For logs, run: jr -u $ncbase
 EOF
 fi
 EOFOUTER
+    chmod +x /usr/local/bin/ncup
 
     mkdir -p /var/www/cron-errors
     chown www-data.www-data /var/www/cron-errors
     i /etc/cron.d/$ncbase <<EOF
-PATH=/sbin:/usr/sbin:/usr/bin:/bin:/usr/local/bin
+PATH=/usr/sbin:/sbin:/usr/bin:/bin:/usr/local/bin
 SHELL=/bin/bash
 # https://docs.nextcloud.com/server/20/admin_manual/configuration_server/background_jobs_configuration.html
 */5  *  *  *  * www-data php -f $ncdir/cron.php --define apc.enable_cli=1 |& log-once nccron
@@ -2374,7 +2409,13 @@ case $HOSTNAME in
     rm -fv /etc/systemd/system/exim4.service.d/nonroot.conf
     ;;
   *)
-    i /etc/systemd/system/exim4.service.d/nonroot.conf <<'EOF'
+    dirs=()
+    for d in /a /d /m /media /mnt /nocow /o /p /q; do
+      if [[ -d $d ]]; then
+        dirs+=($d)
+      fi
+    done
+    i /etc/systemd/system/exim4.service.d/nonroot.conf <<EOF
 [Service]
 # see 56.2 Root privilege in exim spec
 AmbientCapabilities=CAP_NET_BIND_SERVICE
@@ -2385,7 +2426,7 @@ ProtectHome=yes
 # note, in t10 systemd, if one of these is an sshfs mountpoint,
 # this whole setting doesnt work. tried it with a newer systemd 250 though
 # an nspawn, and it worked there.
-InaccessiblePaths=d m media mnt nocow o p q
+InaccessiblePaths=${dirs[@]}
 NoNewPrivileges=yes
 ProtectSystem=yes
 
@@ -2721,8 +2762,6 @@ EOF
     echo|i /etc/exim4/conf.d/rcpt_local_acl
     echo|i /etc/exim4/conf.d/router/880_universal_forward
 
-    echo amnimal.ninja > /etc/mailname
-
     /a/exe/cedit nn /etc/hosts <<'EOF' || [[ $? == 1 ]]
 10.173.8.2 nn.b8.nz
 EOF
@@ -2752,9 +2791,10 @@ COMMONOPTIONS='-oP /run/exim4/eximin.pid'
 UPEX4OPTS='-d /etc/myexim4'
 EOF
 
+    echo bk.b8.nz > /etc/mailname
     cat >>/etc/exim4/update-exim4.conf.conf <<EOF
 # man page: is used to build the local_domains list, together with "localhost"
-dc_other_hostnames='amnimal.ninja;expertpathologyreview.com'
+dc_other_hostnames='amnimal.ninja;expertpathologyreview.com;bk.b8.nz'
 EOF
 
     ;;
@@ -2817,7 +2857,10 @@ EOF
 
     if $bhost_t; then
       install -d /bu
-      install -d -g $u -o $u -m 771 /bu/md
+      install -d -g Debian-exim -o Debian-exim -m 771 /bu/md
+      if [[ -e /bu/md/cur && $(stat -c %u /bu/md/cur) == 1000 ]]; then
+        chown -R Debian-exim:Debian-exim /bu/md
+      fi
       i /etc/exim4/conf.d/transport/30_backup_maildir <<EOF
 # modified debian maildir transport
 backup_maildir:
@@ -2829,7 +2872,6 @@ backup_maildir:
   directory_mode = 0700
   mode = 0644
   mode_fail_narrower = false
-  user = $u
 EOF
 
       i /etc/exim4/conf.d/router/870_backup_local <<'EOF'
@@ -2973,8 +3015,8 @@ elif [[ $uid != 608 ]]; then
   m usermod -u 608 Debian-exim
   m groupmod -g 608 Debian-exim
   m usermod -g 608 Debian-exim
-  m find / /nocow -path ./var/tmp -prune -o -xdev -uid $uid -execdir chown -h 608 {} +
-  m find / /nocow -path ./var/tmp -prune -o -xdev -gid $gid -execdir chgrp -h 608 {} +
+  m find / /nocow -xdev -path ./var/tmp -prune -o -uid $uid -execdir chown -h 608 {} +
+  m find / /nocow -xdev -path ./var/tmp -prune -o -gid $gid -execdir chgrp -h 608 {} +
 fi
 
 # * start / stop services
@@ -2985,7 +3027,8 @@ if $reload; then
   m systemctl daemon-reload
 fi
 
-m systemctl --now enable epanicclean.timer
+sysd-prom-fail-install epanicclean
+m systemctl --now enable epanicclean
 
 case $HOSTNAME in
   je)
@@ -3000,11 +3043,6 @@ m /a/bin/ds/mail-cert-cron -1
 sre mailcert.timer
 
 case $HOSTNAME in
-  bk)
-    # todo, this should be done in distro-begin
-    soff systemd-resolved
-    ln -sf 127.0.0.1-resolv/stub-resolv.conf /etc/resolv.conf
-    ;;&
   $MAIL_HOST|bk)
     m systemctl --now enable mailnn mailnnroute
     ;;&
@@ -3026,7 +3064,7 @@ case $HOSTNAME in
     fi
     if ! systemctl is-active clamav-daemon >/dev/null; then
       m systemctl --now enable clamav-daemon
-      out=$(rsync -aiSAX --chown=root:root --chmod=g-s /a/bin/ds/filesystem/etc/systemd/system/epanicclean.{timer,service} /etc/systemd/system)
+      out=$(rsync -aiSAX --chown=root:root --chmod=g-s /a/bin/ds/filesystem/etc/systemd/system/epanicclean.service /etc/systemd/system)
       if [[ $out ]]; then
         reload=true
       fi
@@ -3058,7 +3096,10 @@ rm -f /var/local/mail-setup-reload
 
 
 case $HOSTNAME in
-  $MAIL_HOST|bk|je) : ;;
+  $MAIL_HOST|bk|je|li)
+    # on li, these are never started, except $vpnser
+    :
+    ;;
   *)
     soff radicale mailclean.timer dovecot spamassassin $vpnser mailnn clamav-daemon
     ;;
@@ -3093,16 +3134,12 @@ case $HOSTNAME in
     cat >/etc/cron.d/mailtest <<EOF
 SHELL=/bin/bash
 PATH=/usr/bin:/bin:/usr/local/bin
-MAILTO=alerts@iankelling.org
-*/5 * * * *   $u send-test-forward |& log-once send-test-forward
+MAILTO=daylert@iankelling.org
+*/5  * * * *   $u send-test-forward |& log-once send-test-forward
 */10 * * * *   root chmod -R g+rw /m/md/bounces |& log-once -1 bounces-chmod
-# im seeing some intermittent failures on the slow check, do it all the time
-# for now. It looks like a dns failure.
-#5-59/5 * * * *   root mailtest-check |& log-once -1 mailtest-check
-#0 * * * *   root mailtest-check slow |& log-once -1 mailtest-slow
-*/5 * * * *   root timeout 290 mailtest-check slow |& log-once -12 mailtest-check
+*/5  * * * *   root timeout 290 mailtest-check slow |& log-once -4 mailtest-check
 # if a bounce happened yesterday, dont let it slip through the cracks
-8   1 * * *   root awk '$5 == "**"' /var/log/exim4/mainlog.1
+8   1 * * *   root export MAILTO=alerts@iankelling.org; [[ -s /var/log/exim4/mainlog.1 ]] && awk '\$5 == "**"' /var/log/exim4/mainlog.1
 EOF
     m sudo rsync -ahhi --chown=root:root --chmod=0755 \
       /b/ds/mailtest-check /b/ds/check-remote-mailqs /usr/local/bin/
@@ -3112,6 +3149,7 @@ EOF
     test_to="testignore@expertpathologyreview.com, testignore@je.b8.nz, testignore@amnimal.ninja, jtuttle@gnu.org"
 
     cat >>/etc/cron.d/mailtest <<EOF
+0   13 * * *  root echo "1pm alert. You are not in the matrix."
 2   * * * *   root check-remote-mailqs |& log-once check-remote-mailqs
 EOF
     ;;&
@@ -3127,10 +3165,10 @@ EOF
     cat >/usr/local/bin/send-test-forward <<'EOF'
 #!/bin/bash
 olds=(
-$(/sbin/exiqgrep -o 260 -i -r '^(testignore@(iankelling\.org|zroe\.org|expertpathologyreview\.com|amnimal\.ninja|je\.b8\.nz)|jtuttle@gnu\.org)$')
+$(/usr/sbin/exiqgrep -o 260 -i -r '^(testignore@(iankelling\.org|zroe\.org|expertpathologyreview\.com|amnimal\.ninja|je\.b8\.nz)|jtuttle@gnu\.org)$')
 )
 if (( ${#olds[@]} )); then
-  /sbin/exim -Mrm "${olds[@]}" >/dev/null
+  /usr/sbin/exim -Mrm "${olds[@]}" >/dev/null
 fi
 EOF
     for test_from in ${test_froms[@]}; do