# Copyright (C) 2019 Ian Kelling
# SPDX-License-Identifier: AGPL-3.0-or-later
+if [ -z "$BASH_VERSION" ]; then echo "error: shell is not bash" >&2; exit 1; fi
+
+pre="${0##*/}:"
+m() { printf "$pre %s\n" "$*"; "$@"; }
+e() { printf "$pre %s\n" "$*"; }
+err() { echo "[$(date +'%Y-%m-%d %H:%M:%S%z')]: $0: $*" >&2; }
-set -x
# TODO: copy dkim keys from within this file. its now done in conflink.
# TODO: fix dkim key to b chmod 640, group Debian-exim
-set -eE -o pipefail
-trap 'echo "$0:$LINENO:error: \"$BASH_COMMAND\" returned $?" >&2' ERR
+if [[ -s /usr/local/lib/err ]]; then
+ source /usr/local/lib/err
+elif [[ -s /a/bin/errhandle/err ]]; then
+ source /a/bin/errhandle/err
+else
+ err "no err tracing script found"
+ exit 1
+fi
[[ $EUID == 0 ]] || exec sudo -E "${BASH_SOURCE[0]}" "$@"
if [[ ! $SUDO_USER ]]; then
while fuser /var/lib/dpkg/lock &>/dev/null; do sleep 1; done
f=/var/cache/apt/pkgcache.bin;
if [[ ! -r $f ]] || (( $(( $(date +%s) - $(stat -c %Y $f ) )) > 60*60*12 )); then
- apt-get update
+ m apt-get update
fi
- DEBIAN_FRONTEND=noninteractive apt-get -y install --purge --auto-remove "$@"
+ m DEBIAN_FRONTEND=noninteractive apt-get -y install --purge --auto-remove "$@"
}
postmaster=alerts
## * Install packages
# light version of exim does not have sasl auth support.
-pi exim4-daemon-heavy spamassassin spf-tools-perl openvpn
+pi exim4-daemon-heavy spamassassin spf-tools-perl openvpn dnsmasq
# trisquel 8 = openvpn, debian stretch = openvpn-client
vpn_ser=openvpn-client
vpn_ser=openvpn
fi
+uhome=$(eval echo ~$u)
### * user forward file
if [[ $HOSTNAME == "$MAIL_HOST" ]]; then
# afaik, these will get ignored because they are routing to my own
# machine, but rm them is safer
- rm -f $(eval echo ~$u)/.forward /root/.forward
+ rm -fv $uhome/.forward /root/.forward
else
# this can\'t be a symlink and has permission restrictions
# it might work in /etc/aliases, but this seems more proper.
- install -m 644 {-o,-g}$u <(e $forward) $(eval echo ~$u)/.forward
+ e setting $uhome/.forward to $forward
+ install -m 644 {-o,-g}$u <(e $forward) $uhome/.forward
fi
# * Mail clean cronjob
# * spamassassin
if [[ $HOSTNAME != "$MAIL_HOST" ]]; then
- systemctl stop spamassassin
- systemctl disable spamassassin
-
+ m systemctl stop spamassassin
+ m systemctl disable spamassassin
else
# per readme.debian
sed -i '/^\s*NICE\s*=/d' /etc/default/spamassassin
e 'NICE="--nicelevel 15"' >>/etc/default/spamassassin
- systemctl enable spamassassin
- systemctl start spamassassin
- systemctl reload spamassassin
+ m systemctl enable spamassassin
+ m systemctl start spamassassin
+ m systemctl reload spamassassin
cat >/etc/systemd/system/spamddnsfix.service <<'EOF'
[Unit]
[Install]
WantedBy=timers.target
EOF
- systemctl daemon-reload
- systemctl restart spamddnsfix.timer
- systemctl enable spamddnsfix.timer
+ m systemctl daemon-reload
+ m systemctl restart spamddnsfix.timer
+ m systemctl enable spamddnsfix.timer
fi # [[ $HOSTNAME != "$MAIL_HOST" ]]
##### end spamassassin config
# systemd, buuut it can remake the tun device unexpectedly, i got this in the log
# after my internet was down for a bit:
# NOTE: Pulled options changed on restart, will need to close and reopen TUN/TAP device.
- /a/exe/vpn-mk-client-cert -b mail -n mail -s /b/ds/mail-route li.iankelling.org
+ m /a/exe/vpn-mk-client-cert -b mail -n mail -s /b/ds/mail-route li.iankelling.org
fi
fi
fi
exit 0
EOF
-chmod 755 $f
+m chmod 755 $f
cat >/etc/systemd/system/mailcert.service <<'EOF'
[Unit]
[Install]
WantedBy=timers.target
EOF
-systemctl daemon-reload
-systemctl start mailcert
-systemctl restart mailcert.timer
-systemctl enable mailcert.timer
+m systemctl daemon-reload
+m systemctl start mailcert
+m systemctl restart mailcert.timer
+m systemctl enable mailcert.timer
### make local bounces go to normal maildir
# local mail that bounces goes to /Maildir or /root/Maildir
dirs=(/m/md/bounces/{cur,tmp,new})
-mkdir -p ${dirs[@]}
-chown -R $u:Debian-exim /m/md/bounces
-chmod 775 ${dirs[@]}
-usermod -a -G Debian-exim $u
+m mkdir -p ${dirs[@]}
+m chown -R $u:Debian-exim /m/md/bounces
+m chmod 775 ${dirs[@]}
+m usermod -a -G Debian-exim $u
for d in /Maildir /root/Maildir; do
if [[ ! -L $d ]]; then
- rm -rf $d
+ m rm -rf $d
fi
- ln -sf -T /m/md/bounces $d
+ m ln -sf -T /m/md/bounces $d
done
### begin setup passwd.client
f=/etc/exim4/passwd.client
-rm -f /etc/exim4/passwd.client
-install -m 640 -g Debian-exim /dev/null $f
+rm -fv /etc/exim4/passwd.client
+m install -m 640 -g Debian-exim /dev/null $f
while read -r domain _ pass; do
# reference: exim4_passwd_client(5)
printf "%s:%s\n" "$domain" "$pass" >>$f
### end setup passwd.client
# by default, only 10 days of logs are kept. increase that.
-sed -ri 's/^(\s*rotate\s).*/\11000/' /etc/logrotate.d/exim4-base
+m sed -ri 's/^(\s*rotate\s).*/\11000/' /etc/logrotate.d/exim4-base
## https://blog.dhampir.no/content/make-exim4-on-debian-respect-forward-and-etcaliases-when-using-a-smarthost
sed -r s/^\\S+:/$b:/ 600_exim4-config_userforward >175_$b
-rm -f /etc/exim4/conf.d/main/000_localmacros # old filename
+m rm -f /etc/exim4/conf.d/main/000_localmacros # old filename
cat >/etc/exim4/conf.d/main/000_local <<EOF
MAIN_TLS_ENABLE = true
EOF
-rm -f /etc/exim4/rcpt_local_acl # old path
+rm -fv /etc/exim4/rcpt_local_acl # old path
cat >/etc/exim4/conf.d/rcpt_local_acl <<'EOF'
# Only hosts we control send to @mail.iankelling.org, so make sure
# they are all authed.
!authenticated = *
domains = mail.iankelling.org
EOF
-rm -f /etc/exim4/data_local_acl # old path
+rm -fv /etc/exim4/data_local_acl # old path
cat >/etc/exim4/conf.d/data_local_acl <<'EOF'
# Except for the "condition =", this was
# a comment in the check_data acl. The comment about this not
pi dovecot-core dovecot-imapd dovecot-sieve dovecot-lmtpd
for f in /p/c/subdir_files/sieve/*sieve /a/c/subdir_files/sieve/*sieve; do
- sudo -u $u /a/exe/lnf -T $f $(eval echo ~$u)/sieve/${f##*/}
+ m sudo -u $u /a/exe/lnf -T $f $uhome/sieve/${f##*/}
done
# if we changed 90-sieve.conf and removed the active part of the
# sieve option, we wouldn\'t need this, but I\'d rather not modify a
# default config if not needed. This won\'t work as a symlink in /a/c
# unfortunately.
- sudo -u $u /a/exe/lnf -T sieve/main.sieve $(eval echo ~$u)/.dovecot.sieve
+ m sudo -u $u /a/exe/lnf -T sieve/main.sieve $uhome/.dovecot.sieve
# we set this later in local.conf
sed -ri -f - /etc/dovecot/conf.d/10-mail.conf <<'EOF'
server=/mail.iankelling.org/127.0.1.1
EOF
if systemctl is-active dnsmasq >/dev/null; then
- systemctl reload dnsmasq
+ m systemctl reload dnsmasq
fi
# I used to use debconf-set-selections + dpkg-reconfigure,
cd /etc
wget -q -N https://publicsuffix.org/list/public_suffix_list.dat
EOF
- chmod 755 $f
+ m chmod 755 $f
sed -i --follow-symlinks -f - /etc/aliases <<EOF
\$a root: $postmaster
# https://selivan.github.io/2017/12/30/systemd-serice-always-restart.html
d=/etc/systemd/system/openvpn@mail.service.d
- mkdir -p $d
+ m mkdir -p $d
cat >$d/override.conf <<'EOF'
[Service]
Restart=always
EOF
if ! systemctl cat openvpn@mail.service|grep -xF StartLimitInterval=0 &>/dev/null; then
# needed for the above config to go into effect
- systemctl daemon-reexec
+ m systemctl daemon-reexec
fi
- systemctl enable mailclean.timer
- systemctl start mailclean.timer
- systemctl restart $vpn_ser@mail
- systemctl enable $vpn_ser@mail
- systemctl enable dovecot
- systemctl restart dovecot
+ m systemctl enable mailclean.timer
+ m systemctl start mailclean.timer
+ m systemctl restart $vpn_ser@mail
+ m systemctl enable $vpn_ser@mail
+ m systemctl enable dovecot
+ m systemctl restart dovecot
# * not MAIL_HOST
else # $HOSTNAME != $MAIL_HOST
echo | /a/exe/cedit mail /etc/dnsmasq-servers.conf || [[ $? == 1 ]]
if systemctl is-active dnsmasq >/dev/null; then
- systemctl reload dnsmasq
+ m systemctl reload dnsmasq
fi
- systemctl disable mailclean.timer &>/dev/null ||:
- systemctl stop mailclean.timer &>/dev/null ||:
- systemctl disable $vpn_ser@mail
- systemctl stop $vpn_ser@mail
- systemctl disable dovecot ||:
- systemctl stop dovecot ||:
+ m systemctl disable mailclean.timer &>/dev/null ||:
+ m systemctl stop mailclean.timer &>/dev/null ||:
+ m systemctl disable $vpn_ser@mail
+ m systemctl stop $vpn_ser@mail
+ m systemctl disable dovecot ||:
+ m systemctl stop dovecot ||:
#
#
# would only exist because I wrote it i the previous condition,
# it\'s not part of exim
- rm -f /etc/exim4/conf.d/main/000_localmacros
+ rm -fv /etc/exim4/conf.d/main/000_localmacros
cat >>/etc/exim4/update-exim4.conf.conf <<EOF
dc_eximconfig_configtype='smarthost'
dc_smarthost='$smarthost'
dc_localdelivery='maildir_home'
EOF
- hostname -f > /etc/mailname
+ hostname -f >/etc/mailname
# This ends up at alerts mailbox on MAIL_HOST, but using a user that doesn't exist elsewhere
# is no good.
# so, im trying a bind mount to get rid of that.
if [[ -e /nocow ]]; then
if ! grep -Fx "/nocow/exim4 /var/spool/exim4 none bind 0 0" /etc/fstab; then
- echo "/nocow/exim4 /var/spool/exim4 none bind 0 0" >> /etc/fstab
+ echo "/nocow/exim4 /var/spool/exim4 none bind 0 0" >>/etc/fstab
fi
if ! mountpoint -q $sdir; then
- systemctl stop exim4
+ m systemctl stop exim4
if [[ -L $sdir ]]; then
- rm $sdir
+ m rm $sdir
fi
if [[ ! -e $dir && -d $sdir ]]; then
- mv $sdir $dir
+ m mv $sdir $dir
fi
if [[ ! -d $sdir ]]; then
- mkdir $sdir
- chmod 000 $sdir # only want it to be used when its mounted
+ m mkdir $sdir
+ m chmod 000 $sdir # only want it to be used when its mounted
fi
- mount $sdir
+ m mount $sdir
fi
fi
IFS=:; read _ _ gid _ < <(getent group Debian-exim ||:) ||:; unset IFS
if [[ ! $uid ]]; then
# from /var/lib/dpkg/info/exim4-base.postinst, plus uid and gid options
- adduser --uid 608 --system --group --quiet --home /var/spool/exim4 \
+ m adduser --uid 608 --system --group --quiet --home /var/spool/exim4 \
--no-create-home --disabled-login --force-badname Debian-exim
elif [[ $uid != 608 ]]; then
- systemctl stop exim4 ||:
- usermod -u 608 Debian-exim
- groupmod -g 608 Debian-exim
- usermod -g 608 Debian-exim
- find / /nocow -xdev -uid $uid -exec chown -h 608 {} +
- find / /nocow -xdev -gid $gid -exec chgrp -h 608 {} +
+ m systemctl stop exim4 ||:
+ m usermod -u 608 Debian-exim
+ m groupmod -g 608 Debian-exim
+ m usermod -g 608 Debian-exim
+ m find / /nocow -xdev -uid $uid -exec chown -h 608 {} +
+ m find / /nocow -xdev -gid $gid -exec chgrp -h 608 {} +
fi
# * reload exim
if systemctl is-active exim4 >/dev/null; then
- systemctl reload exim4
+ m systemctl reload exim4
else
- systemctl start exim4
+ m systemctl start exim4
fi
eom
EOF
EOFOUTER
- chmod +x $f
+ m chmod +x $f
cat >/etc/cron.d/mailtest <<EOF
SHELL=/bin/bash
*/10 * * * * $u /usr/local/bin/mailtest-check 2>&1 | /usr/local/bin/log-once -1 mailtest-check
*/10 * * * * root chmod -R g+rw /m/md/bounces 2>&1 | /usr/local/bin/log-once -1 bounces-chmod
EOF
- cp /a/bin/distro-setup/filesystem/usr/local/bin/mailtest-check /usr/local/bin
+ m cp /a/bin/distro-setup/filesystem/usr/local/bin/mailtest-check /usr/local/bin
else
- rm -f /etc/cron.d/mailtest
+ rm -fv /etc/cron.d/mailtest
fi
# does not stop us from remounting /o.
if dpkg -s radicale &>/dev/null; then
if [[ $HOSTNAME == "$MAIL_HOST" ]]; then
- systemctl restart radicale
- systemctl enable radicale
+ m systemctl restart radicale
+ m systemctl enable radicale
if [[ -e /etc/logrotate.d/radicale.disabled ]]; then
- mv /etc/logrotate.d/radicale{.disabled,}
+ m mv /etc/logrotate.d/radicale{.disabled,}
fi
else
- systemctl stop radicale
- systemctl disable radicale
+ m systemctl stop radicale
+ m systemctl disable radicale
# weekly logrotate tries to restart radicale even if it's a disabled service in flidas.
if [[ -e /etc/logrotate.d/radicale ]]; then
- mv /etc/logrotate.d/radicale{,.disabled}
+ m mv /etc/logrotate.d/radicale{,.disabled}
fi
fi
fi
# * misc
-sudo -u $u ln -sf -T /m/.mu /home/$u/.mu
+m sudo -u $u ln -sf -T /m/.mu /home/$u/.mu
# /etc/alias setup is debian specific, and exim postinst script sets up