#!/bin/bash
# * intro
-# Copyright (C) 2019 Ian Kelling
-# SPDX-License-Identifier: AGPL-3.0-or-later
+
+# Program to install and configure Ian's email related programs
+# Copyright (C) 2024 Ian Kelling
+
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+# SPDX-License-Identifier: GPL-3.0-or-later
# todo:
# on bk (and fsf servers that run multiple exim4 daemons, eg eximfsf2 and eximfsf3),
shopt -s nullglob
-if [[ -s /usr/local/lib/err ]]; then
- source /usr/local/lib/err
-elif [[ -s /a/bin/errhandle/err ]]; then
- source /a/bin/errhandle/err
+if [[ -s /usr/local/lib/bash-bear ]]; then
+ source /usr/local/lib/bash-bear
+elif [[ -s /a/bin/bash-bear-trap/bash-bear ]]; then
+ source /a/bin/bash-bear-trap/bash-bear
else
echo "no err tracing script found"
exit 1
bhost_t=false
case $HOSTNAME in
$MAIL_HOST) : ;;
- kd|frodo|x2|x3|kw|sy|bo)
+ kd|x2|x3|kw|sy|bo|so)
bhost_t=true
;;
esac
ignoreip = 209.51.188.13 2001:470:142::13 209.51.188.92 2001:470:142:3::10 72.14.176.105 2600:3c00:e000:280::2 10.173.8.1
EOF
if $ur; then
+ # Ensure the log file monitored by fail2ban exists, or else fail2ban can't start.
+ if [[ ! -e /var/log/exim4/mainlog ]]; then
+ install -m 640 -o Debian-exim -g adm /dev/null /var/log/exim4/mainlog
+ fi
m systemctl restart fail2ban
fi
ssl = required
# this is the same as the certbot list, i check changes in /a/bin/ds/filesystem/usr/local/bin/check-lets-encrypt-ssl-settings
ssl_cipher_list = ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384
-ssl_protocols = TLSv1.2
+ssl_min_protocol = TLSv1.2
ssl_prefer_server_ciphers = no
protocol lmtp {
# default is just $mail_plugins
mail_plugins = $mail_plugins sieve
}
+
+# /etc/dovecot/conf.d/10-master.conf says the default is 256M.
+# but I started getting oom errors in the syslog
+# Mar 27 15:10:04 sy dovecot[330088]: lmtp(iank)<3839880><gO/BDwtvBGaIlzoA7AdaJQ>: Fatal: master: service(lmtp): child 3839880 returned error 83 (Out of memory (service lmtp { vsz_limit=256 MB }, you may need to increase it) - set CORE_OUTOFMEM=1 environment to get core dump)
+# exim would just queue mail until it eventually succeeded.
+# Deciding what to increase it to, I found this
+# https://dovecot.org/list/dovecot/2011-December/080056.html
+# which suggests 3x the largest dovecot.index.cache file
+# and then I found that
+# md/l/testignore/dovecot.index.cache is 429M, my largest cache file,
+# but that folder only has 2k messages.
+# next biggest is md/l/qemu-devel/dovecot.index.cache 236M
+# which lead to me a search https://doc.dovecot.org/admin_manual/known_issues/large_cache/
+# which suggests 1.5x the maximum cache file size 1G, and
+# that I can safely rm the index.
+default_vsz_limit = 1500M
+
EOF
if dpkg --compare-versions "$(dpkg-query -f='${Version}\n' --show dovecot-core)" ge 1:2.3; then
cat <<EOF
fi
rm -fv /etc/dovecot/conf.d/20-lmtp.conf # file from prev version
+
+ # Having backups of indexes is a waste of space. This also means we
+ # don't send them around with btrbk, I think it is probably
+ # preferable use a bit more cpu to recalculate indexes.
+ install -d -m 700 -o iank -g iank /var/dovecot-indexes
cat >>/etc/dovecot/local.conf <<EOF
+
+
+# This will decrease memory use, and seems likely to decrease cpu & disk
+# use since I rarely use dovecot for most folders.
+mail_cache_max_size = 50M
+
+
# simple password file based login
!include conf.d/auth-passwdfile.conf.ext
# ian: %u is used for alerts user vs iank
-mail_location = maildir:/m/%u:LAYOUT=fs:INBOX=/m/%u/INBOX
-mail_uid = $u
-mail_gid = $u
+# https://doc.dovecot.org/configuration_manual/mail_location/Maildir/
+mail_location = maildir:/m/%u:LAYOUT=fs:INBOX=/m/%u/INBOX:INDEX=/var/dovecot-indexes/%u
+# note: i don't know if these need to be set, but this seems fine.
+mail_uid = iank
+mail_gid = iank
protocol lmtp {
# For a normal setup with exim, we need something like this, which
m mkdir -p $rctmpdir /m/rc
m chown -R www-data.www-data $rctmpdir /m/rc
m chmod 750 $rctmpdir
- # Ensure the log file monitored by fail2ban exists, or else fail2ban can't start.
# todo: check for other mailinabox things
+ # Ensure the log file monitored by fail2ban exists, or else fail2ban can't start.
m sudo -u www-data touch $rclogdir/errors.log
#### begin carddav install
u /usr/local/bin/ncup <<'EOFOUTER'
#!/bin/bash
-source /usr/local/lib/err
+source /usr/local/lib/bash-bear
m() { printf "%s\n" "$*"; "$@"; }
err-cleanup() {
# ld for local debbugs
-/a/exe/web-conf -t -a 127.0.1.1 -p 80 -r /var/lib/debbugs/www - apache2 ld <<'EOF'
+/a/exe/web-conf -l -t -a 127.0.1.1 -p 80 -r /var/lib/debbugs/www - apache2 ld <<'EOF'
# copied from debbugs upstream example
<Directory /var/lib/debbugs/www>
Options Indexes SymLinksIfOwnerMatch MultiViews
EOF
+ # ian: save a copy of sent mail. i thought of other ways to do this,
+ # for example, to only save sent mail that is not sent from my mail
+ # client which saves a copy by default, but in the end, it seems
+ # simplest to turn that off. We want to save external mail sent by
+ # smarthosts. However, there is one complication: encrypted
+ # mail. Saving it here just gets us an encrypted copy that we can't
+ # read. Soo, we could bcc ourselves: then we still have the
+ # annoyance that it is encrypted so we can't grep it. Or, we could
+ # hack emacs so that it sends us an unencrypted copy. Turns out that
+ # the emacs function which saves sent email can also send us a
+ # copy. But, then we have 3 copies: the encrypted copy exim saves,
+ # the unencrypted copy exim saves, and the copy emacs saves. Soo,
+ # we can emacs send a copy directly to the sent alias but only when
+ # it is not mail_host, and have the exim condition for redirecting a
+ # copy to the sent alias avoid doing it if it has an emacs user
+ # agent header.
u /etc/exim4/conf.d/router/186_sentarchive_nn <<'EOF'
-# ian: save a copy of sent mail. i thought of other ways to
-# do this, for example, to only save sent mail that is not sent
-# from my mail client which saves a copy by default, but in the
-# end, it seems simplest to turn that off. We want to save
-# external mail sent by smarthosts.
sentarchive_nn:
driver = redirect
domains = ! +local_domains
- condition = ${if !bool{${lookup{$local_part@$domain}lsearch{/etc/exim4/ignore-sent}{true}}}}
+ condition = ${if and {{!bool{${lookup{$local_part@$domain}lsearch{/etc/exim4/ignore-sent}{true}}}} {!match {$h_user-agent:}{emacs}}}}
data = vojdedIdNejyebni@b8.nz
unseen
EOF
# This name won\'t appear on From: lines of outgoing messages if rewriting is enabled.
echo iankelling.org > /etc/mailname
+ # mail default domain.
+ u /etc/mailutils.conf <<'EOF'
+address {
+ email-domain iankelling.org;
+};
+EOF
# mail.iankelling.org so local imap clients can connect with tls and
# when they happen to not be local.
EOF
# Bind to wghole to receive mailbackup.
- wgholeip=$(sed -rn 's/^ *Address *= *([^/]+).*/\1/p' /etc/wireguard/wghole.conf)
- cat >>/etc/exim4/update-exim4.conf.conf <<EOF
+ if [[ -e /etc/wireguard/wghole.conf ]]; then
+ wgholeip=$(sed -rn 's/^ *Address *= *([^/]+).*/\1/p' /etc/wireguard/wghole.conf)
+ cat >>/etc/exim4/update-exim4.conf.conf <<EOF
dc_other_hostnames='eximbackup.b8.nz'
dc_local_interfaces='127.0.0.1;::1;$wgholeip'
EOF
+ fi
# wghole & thus exim will fail to start without internet connectivity.
u /etc/systemd/system/exim4.service.d/backup.conf <<'EOF'
driver = redirect
domains = ! +local_domains
senders = <; *@fsf.org ; *@posteo.net
- condition = ${if !bool{${lookup{$local_part@$domain}lsearch{/etc/exim4/ignore-sent}{true}}}}
+ condition = ${if and {{!bool{${lookup{$local_part@$domain}lsearch{/etc/exim4/ignore-sent}{true}}}} {!match {$h_user-agent:}{emacs}}}}
data = vojdedIdNejyebni@b8.nz
unseen
EOF
u /etc/myexim4/conf.d/router/160_backup_redir <<'EOF'
backup_redir:
-driver = redirect
-# i dont email myself from my own machine much, so lets ignore that.
-domains = ! +local_domains
-senders = <; *@fsf.org ; *@posteo.net
-condition = ${if !bool{${lookup{$local_part@$domain}lsearch{/etc/exim4/ignore-sent}{true}}}}
-# b is just an arbirary short string
-data = b@eximbackup.b8.nz
-# note, to test this, i could temporarily allow testignore.
-# alerts avoids potential mail loop.
-local_parts = ! root : ! testignore : ! alerts : ! daylert
-unseen = true
-errors_to = alerts@iankelling.org
+ driver = redirect
+ # i dont email myself from my own machine much, so lets ignore that.
+ domains = ! +local_domains
+ senders = <; *@fsf.org ; *@posteo.net
+ condition = ${if and {{!bool{${lookup{$local_part@$domain}lsearch{/etc/exim4/ignore-sent}{true}}}} {!match {$h_user-agent:}{emacs}}}}
+ # b is just an arbirary short string
+ data = b@eximbackup.b8.nz
+ # note, to test this, i could temporarily allow testignore.
+ # alerts avoids potential mail loop.
+ local_parts = ! root : ! testignore : ! alerts : ! daylert
+ unseen = true
+ errors_to = alerts@iankelling.org
EOF
# for bk, we have a exim4in.service that will do this for us.
# if [[ ! $uid ]]; then
# # /a/opt/debbugs/debian/README.mail
# adduser --uid 610 --system --group --home /o/debbugs \
-# --no-create-home --disabled-login --force-badname debbugs
+ # --no-create-home --disabled-login --force-badname debbugs
# m find /o/debbugs -xdev -path ./var/tmp -prune -o -uid $uid -execdir chown -h 610 {} +
# m find /o/debbugs -xdev -path ./var/tmp -prune -o -gid $gid -execdir chgrp -h 610 {} +
# elif [[ $uid != 610 ]]; then
;;
esac
-# optimization, this only needs to run once.
-if [[ ! -e /etc/exim4/fullchain.pem ]]; then
- m /a/bin/ds/mail-cert-cron -1
+# optimization, this only needs to run once. But, if we move to a
+# computer we haven't used much, we need to fetch a fresh cert.
+# Existence check is just to avoid ugly error message from openssl.
+if [[ ! -e /etc/exim4/fullchain.pem ]] || ! openssl x509 -checkend $(( 60 * 60 * 24 * 3 )) -noout -in /etc/exim4/fullchain.pem; then
+ m /a/bin/ds/mail-cert-cron -1 -i
m systemctl --now enable mailcert.timer
fi