# Copyright (C) 2019 Ian Kelling
# SPDX-License-Identifier: AGPL-3.0-or-later
-# todo: setup a logrotate for /var/log/mymain and mypanic
+# todo: check new macro DKIM_TIMESTAMPS
+
+# todo: check if REMOTE_SMTP_INTERFACE or REMOTE_SMTP_TRANSPORTS_HEADERS_REMOVE can simplify my or fsfs config
+
+# todo: max line length macro changed in t11. look into it
+# todo: check that all macros we use are still valid in t11
# todo: setup an alert for bouncing test emails.
# 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.
+#eg: on eggs, on may 1st, ps grep for exim, 2 daemons running. 1 leftover from a month ago
+#Debian-+ 1954 1 0 36231 11560 4 Apr02 ? 00:40:25 /usr/sbin/exim4 -bd -q30m
+#Debian-+ 23058 1954 0 36821 10564 0 20:38 ? 00:00:00 /usr/sbin/exim4 -bd -q30m
# 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.
-# todo: check that spamd and unbound only listen locally.
# todo: hosts should only allow external mail that is authed and
# destined for backup route. it is a minor issue since traffic is
# todo: run mailping test after running, or otherwise
# clear out terminal alert
-# todo: on bk, dont send email if mailvpn is not up
-
-# todo: mailtest-check should check on bk too
-
# todo: disable postgrey
# todo: in testforward-check, we should also look
elif [[ -s /a/bin/errhandle/err ]]; then
source /a/bin/errhandle/err
else
- err "no err tracing script found"
+ echo "no err tracing script found"
+ exit 1
fi
source /a/bin/distro-functions/src/identify-distros
source /a/bin/distro-functions/src/package-manager-abstractions
if [[ -e /var/local/mail-setup-reload ]]; then
reload=true
fi
-i() { # install file
+u() { # update file. note: duplicated in brc
local tmp tmpdir dest="$1"
local base="${dest##*/}"
local dir="${dest%/*}"
if [[ $dir != "$base" ]]; then
- mkdir -p ${dest%/*}
+ # dest has a directory component
+ mkdir -p "$dir"
fi
- ir=false # i result
+ ur=false # u result
tmpdir=$(mktemp -d)
cat >$tmpdir/"$base"
tmp=$(rsync -ic $tmpdir/"$base" "$dest")
if [[ $tmp ]]; then
printf "%s\n" "$tmp"
- ir=true
+ ur=true
if [[ $dest == /etc/systemd/system/* ]]; then
touch /var/local/mail-setup-reload
reload=true
mxhost=mx.iankelling.org
mxport=587
-forward=$u@$mxhost
# old setup. left as comment for example
# mxhost=mail.messagingengine.com
fi
# light version of exim does not have sasl auth support.
+# note: for bitfolk hosts, unbound has important config with conflink.
pi-nostart exim4 exim4-daemon-heavy spamassassin unbound clamav-daemon wireguard
# note: pyzor debian readme says you need to run some initialization command
# * Mail clean cronjob
-i /etc/systemd/system/mailclean.timer <<'EOF'
+u /etc/systemd/system/mailclean.timer <<'EOF'
[Unit]
Description=Run mailclean daily
WantedBy=timers.target
EOF
-i /etc/systemd/system/mailclean.service <<EOF
+u /etc/systemd/system/mailclean.service <<EOF
[Unit]
Description=Delete and archive old mail files
After=multi-user.target
# * postgrey
-i /etc/default/postgrey <<'EOF'
+u /etc/default/postgrey <<'EOF'
POSTGREY_OPTS="--exim --unix=/var/run/postgrey/postgrey.sock --retry-window=4 --max-age=60"
EOF
m usermod -a -G Debian-exim clamav
-i /etc/systemd/system/clamav-daemon.service.d/fix.conf <<EOF
+u /etc/systemd/system/clamav-daemon.service.d/fix.conf <<EOF
[Service]
-ExecStartPre=-/bin/mkdir /var/run/clamav
+ExecStartPre=-/bin/mkdir -p /var/run/clamav
ExecStartPre=/bin/chown clamav /var/run/clamav
EOF
# old.
#vpnser=mailvpn.service
-# todo: this hangs if it cant resolv the endpoint. we
-# want it to just retry in the background.
+# note: this hangs if it cant resolv the endpoint. we
+# want it to just retry in the background. i just use a static ip instead.
+#
+# Note: at least on t10, on reboot, the service fails to come up according to systemd, but
+# in reality it is up and working, then it tries to restart infinitely, and fails
+# because it detects that the interface exists.
+#
+# failing output:
+#
+# Aug 02 21:59:27 sy wg-quick[2092]: [#] sysctl -q net.ipv4.conf.all.src_valid_mark=1
+# Aug 02 21:59:27 sy wg-quick[2248]: [#] iptables-restore -n
+# Aug 02 21:59:27 sy wg-quick[2249]: Another app is currently holding the xtables lock. Perhaps you want to use the -w option?
+# Aug 02 21:59:27 sy wg-quick[2259]: [#] iptables-restore -n
+# Aug 02 21:59:27 sy wg-quick[2260]: Another app is currently holding the xtables lock. Perhaps you want to use the -w option?
+# Aug 02 21:59:27 sy systemd[1]: wg-quick@wgmail.service: Main process exited, code=exited, status=4/NOPERMISSION
+
+
+# successful output.
+# Aug 03 14:12:47 sy wg-quick[711336]: [#] sysctl -q net.ipv4.conf.all.src_valid_mark=1
+# Aug 03 14:12:47 sy wg-quick[711384]: [#] iptables-restore -n
+# Aug 03 14:12:47 sy wg-quick[711336]: [#] ping -w10 -c1 10.8.0.1 ||:
+# Aug 03 14:12:47 sy wg-quick[711389]: PING 10.8.0.1 (10.8.0.1) 56(84) bytes of data.
+# Aug 03 14:12:47 sy wg-quick[711389]: 64 bytes from 10.8.0.1: icmp_seq=1 ttl=64 time=73.0 ms
+# Aug 03 14:12:47 sy wg-quick[711389]: --- 10.8.0.1 ping statistics ---
+# Aug 03 14:12:47 sy wg-quick[711389]: 1 packets transmitted, 1 received, 0% packet loss, time 0ms
+# Aug 03 14:12:47 sy wg-quick[711389]: rtt min/avg/max/mdev = 72.993/72.993/72.993/0.000 ms
+# Aug 03 14:12:47 sy systemd[1]: Finished WireGuard via wg-quick(8) for wgmail.
+# 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: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
+# Aug 02 21:59:47 sy systemd[1]: wg-quick@wgmail.service: Failed with result 'exit-code'.
+# Aug 02 21:59:47 sy systemd[1]: Failed to start WireGuard via wg-quick(8) for wgmail.
+
+
+# According to iptables -S and iptables -t nat -S,
+# there are no modifications to iptables rules on a succsfull run,
+# and
+
vpnser=wg-quick@wgmail.service
case $HOSTNAME in
case $HOSTNAME in
li) : ;;
*)
- i /etc/systemd/system/wg-quick@wgmail.service.d/override.conf <<EOF
+ u /etc/systemd/system/wg-quick@wgmail.service.d/override.conf <<EOF
[Unit]
Requires=mailnn.service
JoinsNamespaceOf=mailnn.service
# https://selivan.github.io/2017/12/30/systemd-serice-always-restart.html
-i /etc/systemd/system/mailvpn.service <<EOF
+u /etc/systemd/system/mailvpn.service <<EOF
[Unit]
Description=OpenVPN tunnel for mail
After=syslog.target network-online.target mailnn.service
WantedBy=multi-user.target
EOF
-i /etc/systemd/system/mailnnroute.service <<'EOF'
+u /etc/systemd/system/mailnnroute.service <<'EOF'
[Unit]
Description=Network routing for mailnn
After=syslog.target network-online.target mailnn.service
EOF
#
-i /etc/systemd/system/mailnn.service <<'EOF'
+u /etc/systemd/system/mailnn.service <<'EOF'
[Unit]
Description=Network Namespace for mail vpn service that will live forever and cant fail
After=syslog.target network-online.target
WantedBy=multi-user.target
EOF
-i /etc/systemd/system/mailbindwatchdog.service <<EOF
+u /etc/systemd/system/mailbindwatchdog.service <<EOF
[Unit]
Description=Watchdog to restart services relying on systemd-resolved dir
After=syslog.target network-online.target
# If we ever notice this change, chattr +i on it
# trust-ad is used in t10+, glibc 2.31
-i /etc/127.0.0.1-resolv/stub-resolv.conf <<'EOF'
+u /etc/127.0.0.1-resolv/stub-resolv.conf <<'EOF'
nameserver 127.0.0.1
options edns0 trust-ad
EOF
-i /etc/127.0.0.53-resolv/stub-resolv.conf <<'EOF'
+u /etc/127.0.0.53-resolv/stub-resolv.conf <<'EOF'
nameserver 127.0.0.53
options edns0 trust-ad
EOF
-i /etc/10.173.8.1-resolv/stub-resolv.conf <<'EOF'
+u /etc/10.173.8.1-resolv/stub-resolv.conf <<'EOF'
nameserver 10.173.8.1
options edns0 trust-ad
EOF
case $HOSTNAME in
$MAIL_HOST)
# todo, should this be after vpn service
- i /etc/systemd/system/unbound.service.d/nn.conf <<EOF
+ u /etc/systemd/system/unbound.service.d/nn.conf <<EOF
[Unit]
After=mailnn.service
JoinsNamespaceOf=mailnn.service
;;&
$MAIL_HOST|bk)
for unit in ${nn_progs[@]}; do
- i /etc/systemd/system/$unit.service.d/nn.conf <<EOF
+ u /etc/systemd/system/$unit.service.d/nn.conf <<EOF
[Unit]
# Wants appears better than requires because with requires,
;;
esac
+# * wghole (another mail vpn)
+
+if $bhost_t; then
+ u /etc/systemd/system/wg-quick@wghole.service.d/override.conf <<'EOF'
+[Unit]
+StartLimitIntervalSec=0
+
+[Service]
+Restart=on-failure
+RestartSec=20
+EOF
+fi
+
# * spamassassin config
-i /etc/sysctl.d/80-iank-mail.conf <<'EOF'
+u /etc/sysctl.d/80-iank-mail.conf <<'EOF'
# see exim spec
net.netfilter.nf_conntrack_tcp_timeout_close_wait = 120
EOF
-if $ir; then
+if $ur; then
m sysctl -p
fi
-i /etc/spamassassin/mylocal.cf <<'EOF'
+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:
# 2020-10-19 remove old file. remove this when all hosts updated
rm -fv /etc/systemd/system/spamddnsfix.{timer,service}
-i /etc/default/spamassassin <<'EOF'
+u /etc/default/spamassassin <<'EOF'
# defaults plus debugging flags for an issue im having
OPTIONS="--create-prefs --max-children 5 --helper-home-dir"
PIDFILE="/var/run/spamd.pid"
# * Update mail cert
-if [[ -e /p/c/filesystem ]]; then
- # note, man openvpn implies we could just call mail-route on vpn startup/shutdown with
- # 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.
- m /a/exe/vpn-mk-client-cert -b mailclient -n mail li.iankelling.org
-fi
+
+
+## needed only for openvpn mail vpn.
+# if [[ -e /p/c/filesystem ]]; then
+# # note, man openvpn implies we could just call mail-route on vpn startup/shutdown with
+# # 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.
+# m /a/exe/vpn-mk-client-cert -b mailclient -n mail li.iankelling.org
+# fi
# 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
m rsync -aiSAX --chown=root:root --chmod=g-s /a/bin/ds/mail-cert-cron /usr/local/bin
-i /etc/systemd/system/mailcert.service <<'EOF'
+u /etc/systemd/system/mailcert.service <<'EOF'
[Unit]
Description=Mail cert rsync
After=multi-user.target
Type=oneshot
ExecStart=/usr/local/bin/sysd-mail-once mailcert /usr/local/bin/mail-cert-cron
EOF
-i /etc/systemd/system/mailcert.timer <<'EOF'
+u /etc/systemd/system/mailcert.timer <<'EOF'
[Unit]
Description=Run mail-cert once a day
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
-i /etc/fail2ban/action.d/iptables-common-exim.conf <<'EOF'
+u /etc/fail2ban/action.d/iptables-common-exim.conf <<'EOF'
# iank: same as iptables-common, except iptables is iptables-exim, ip6tables is ip6tables-exim
# Fail2Ban configuration file
iptables = /usr/local/bin/ip6tables-exim <lockingopt>
EOF
-i /etc/fail2ban/jail.d/exim.local <<'EOF'
+u /etc/fail2ban/jail.d/exim.local <<'EOF'
[exim]
enabled = true
port = 25,587
# 10.173.8.1 = non-nn net
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 $ir; then
+if $ur; then
m systemctl restart fail2ban
fi
esac
done
-if ! grep -q "^ncsoft:" /etc/aliases; then
- echo "ncsoft: graceq2323@gmail.com" |m tee -a /etc/aliases
-fi
+. /a/bin/bash_unpublished/priv-mail-setup
m gpasswd -a iank adm #needed for reading logs
cat >/etc/exim4/conf.d/retry/17_retry <<'EOF'
# Retry fast for my own domains
-iankelling.org * F,1d,10m;F,14d,1h
-amnimal.ninja * F,1d,10m;F,14d,1h
-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
+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
# The spec says the target domain will be used for temporary host errors,
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
+
+# 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
+
+
mail.fsf.org * F,1d,15m;F,14d,1h
EOF
MAIN_TRUSTED_GROUPS = $u
EOF
+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
+
cat >/etc/exim4/conf.d/main/000_local <<'EOF'
MAIN_TLS_ENABLE = true
# other says gmail does not reject. figure out and open a new bug.
IGNORE_SMTP_LINE_LENGTH_LIMIT = true
-# more verbose logs
-MAIN_LOG_SELECTOR = +all
+# 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
# Based on spec, seems like a good idea to be nice.
smtp_return_error_details = true
DKIM_CANON = relaxed
DKIM_SELECTOR = li
-# from comments in
-# https://debian-administration.org/article/718/DKIM-signing_outgoing_mail_with_exim4
-# and its best for this to align https://tools.ietf.org/html/rfc7489#page-8
-# There could be some circumstance when the
-# from: isnt our domain, but the envelope sender is
-# and so still want to sign, but I cant think of any case.
-DKIM_DOMAIN = ${lc:${domain:$rh_from:}}
+
# The file is based on the outgoing domain-name in the from-header.
# sign if key exists
DKIM_PRIVATE_KEY = ${if exists{/etc/exim4/${dkim_domain}-private.pem} {/etc/exim4/${dkim_domain}-private.pem}}
domainlist local_hostnames = ! je.b8.nz : ! bk.b8.nz : *.b8.nz : b8.nz
-hostlist iank_trusted = <; \\
+hostlist iank_trusted = <; \
# veth0
-10.173.8.1 ; \\
+10.173.8.1 ; \
# li li_ip6
-72.14.176.105 ; 2600:3c00::f03c:91ff:fe6d:baf8 ; \\
+72.14.176.105 ; 2600:3c00::f03c:91ff:fe6d:baf8 ; \
# li_vpn_net li_vpn_net_ip6s
-10.8.0.0/24; 2600:3c00:e000:280::/64 ; 2600:3c00:e002:3800::/56 ; \\
+10.8.0.0/24; 2600:3c00:e000:280::/64 ; 2600:3c00:e002:3800::/56 ; \
# bk bk_ip6
-85.119.83.50 ; 2001:ba8:1f1:f0c9::2 ; \\
+85.119.83.50 ; 2001:ba8:1f1:f0c9::2 ; \
# je je_ipv6
-85.119.82.128 ; 2001:ba8:1f1:f09d::2 ; \\
+85.119.82.128 ; 2001:ba8:1f1:f09d::2 ; \
# fsf_mit_net fsf_mit_net_ip6 fsf_net fsf_net_ip6 fsf_office_net
18.4.89.0/24 ; 2603:3005:71a:2e00::/64 ; 209.51.188.0/24 ; 2001:470:142::/48 ; 74.94.156.208/28
} {no}{yes}}
+# 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
+# default of 25, can get stuck when catching up on mail
+smtp_accept_max = 400
+smtp_accept_reserve = 100
+smtp_reserve_hosts = +iank_trusted
+
+# Rules that make receiving more liberal should be on backup hosts
+# so that we dont reject mail accepted by MAIL_HOST
+LOCAL_DENY_EXCEPTIONS_LOCAL_ACL_FILE = /etc/exim4/conf.d/local_deny_exceptions_acl
EOF
+if dpkg --compare-versions "$(dpkg-query -f='${Version}\n' --show exim4)" ge 4.94; then
+ cat >>/etc/exim4/conf.d/main/000_local <<'EOF'
+# In t11, we cant do the old anymore because this is tainted data used in a file lookup.
+# /usr/share/doc/exim4/NEWS.Debian.gz suggests to use lookups to untaint data.
+DKIM_DOMAIN = ${lookup {${domain:$rh_from:}}lsearch,ret=key{/etc/exim4/conf.d/my-dkim-domains}}
+EOF
+else
+ cat >>/etc/exim4/conf.d/main/000_local <<'EOF'
+# From comments in
+# https://debian-administration.org/article/718/DKIM-signing_outgoing_mail_with_exim4
+# and its best for this to align https://tools.ietf.org/html/rfc7489#page-8
+# There could be some circumstance when the
+# from: isnt our domain, but the envelope sender is
+# and so still want to sign, but I cant think of any case.
+DKIM_DOMAIN = ${lc:${domain:$rh_from:}}
+EOF
+fi
+
rm -fv /etc/exim4/rcpt_local_acl # old path
-i /etc/exim4/conf.d/local_deny_exceptions_acl <<'EOF'
+u /etc/exim4/conf.d/local_deny_exceptions_acl <<'EOF'
# This acl already exists in rcpt, this just makes it more widespread.
# See the comment there for its rationale. The reason it needs to be
# more widespread is that I've turned on sender verification, but cron
EOF
rm -fv /etc/exim4/data_local_acl # old path
-i /etc/exim4/conf.d/data_local_acl <<'EOF'
+
+u /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
# being suitable has been changed in newer exim versions. The only thing
warn
!hosts = +iank_trusted
+ # Smarthosts connect with residential ips and thus get flagged as spam if we do a spam check.
+ !authenticated = plain_server:login_server
condition = ${if < {$message_size}{5000K}}
spam = Debian-exim:true
add_header = X-Spam_score_int: $spam_score_int
add_header = X-Spam_report: $spam_report
add_header = X-Spam_action: $spam_action
-warn
- condition = ${if def:malware_name}
- remove_header = Subject:
- add_header = Subject: [Clamav warning: $malware_name] $h_subject
- log_message = heuristic malware warning: $malware_name
#accept
# spf = pass:fail:softfail:none:neutral:permerror:temperror
EOF
-i /etc/exim4/conf.d/router/900_exim4-config_local_user <<'EOF'
+
+# old file
+rm -fv /etc/exim4/conf.d/router/8{8,9}0_backup_copy \
+ /etc/exim4/conf.d/router/865_backup_redir \
+ /etc/exim4/conf.d/router/870_backup_local
+
+# It is important for this to exist everywhere except in MAIL_HOST
+# non-nn config. Previously, just had it in the nn-config on MAIL_HOST,
+# but that is a problem if we change mail host and still have something
+# in the queue which was destined for this router, but hosts were
+# unreachable, the routers will be reevaluated on the next retry.
+u /etc/exim4/conf.d/router/170_backup_copy <<EOF
+### router/900_exim4-config_local_user
+#################################
+
+backup_copy:
+driver = manualroute
+domains = eximbackup.b8.nz
+transport = backup_remote
+ignore_target_hosts = ${HOSTNAME}wg.b8.nz
+# note changes here also require change in passwd.client
+route_list = * eximbackup.b8.nz
+same_domain_copy_routing = yes
+errors_to = alerts@iankelling.org
+no_more
+EOF
+
+
+# exim4-config transports are the same as default except for
+# message_linelength_limit = 2097152
+#
+# TODO: copy the defaults into their own file, and setup a cronjob so
+# that if file.dpkg-dist shows up, and it is different, we get an alert.
+
+u /etc/exim4/conf.d/transport/30_exim4-config_remote_smtp_smarthost <<'EOF'
+### transport/30_exim4-config_remote_smtp_smarthost
+#################################
+
+# This transport is used for delivering messages over SMTP connections
+# to a smarthost. The local host tries to authenticate.
+# This transport is used for smarthost and satellite configurations.
+
+remote_smtp_smarthost:
+ debug_print = "T: remote_smtp_smarthost for $local_part@$domain"
+ driver = smtp
+ message_linelength_limit = 2097152
+ multi_domain
+ hosts_try_auth = <; ${if exists{CONFDIR/passwd.client} \
+ {\
+ ${lookup{$host}nwildlsearch{CONFDIR/passwd.client}{$host_address}}\
+ }\
+ {} \
+ }
+.ifdef REMOTE_SMTP_SMARTHOST_HOSTS_AVOID_TLS
+ hosts_avoid_tls = REMOTE_SMTP_SMARTHOST_HOSTS_AVOID_TLS
+.endif
+.ifdef REMOTE_SMTP_SMARTHOST_HOSTS_REQUIRE_TLS
+ hosts_require_tls = REMOTE_SMTP_SMARTHOST_HOSTS_REQUIRE_TLS
+.endif
+.ifdef REMOTE_SMTP_SMARTHOST_TLS_VERIFY_CERTIFICATES
+ tls_verify_certificates = REMOTE_SMTP_SMARTHOST_TLS_VERIFY_CERTIFICATES
+.endif
+.ifdef REMOTE_SMTP_SMARTHOST_TLS_VERIFY_HOSTS
+ tls_verify_hosts = REMOTE_SMTP_SMARTHOST_TLS_VERIFY_HOSTS
+.endif
+.ifdef REMOTE_SMTP_HEADERS_REWRITE
+ headers_rewrite = REMOTE_SMTP_HEADERS_REWRITE
+.endif
+.ifdef REMOTE_SMTP_RETURN_PATH
+ return_path = REMOTE_SMTP_RETURN_PATH
+.endif
+.ifdef REMOTE_SMTP_HELO_DATA
+ helo_data=REMOTE_SMTP_HELO_DATA
+.endif
+.ifdef TLS_DH_MIN_BITS
+tls_dh_min_bits = TLS_DH_MIN_BITS
+.endif
+.ifdef REMOTE_SMTP_SMARTHOST_TLS_CERTIFICATE
+tls_certificate = REMOTE_SMTP_SMARTHOST_TLS_CERTIFICATE
+.endif
+.ifdef REMOTE_SMTP_SMARTHOST_PRIVATEKEY
+tls_privatekey = REMOTE_SMTP_SMARTHOST_PRIVATEKEY
+.endif
+.ifdef REMOTE_SMTP_TRANSPORTS_HEADERS_REMOVE
+ headers_remove = REMOTE_SMTP_TRANSPORTS_HEADERS_REMOVE
+.endif
+.ifdef REMOTE_SMTP_SMARTHOST_PROTOCOL
+ protocol = REMOTE_SMTP_SMARTHOST_PROTOCOL
+.endif
+EOF
+
+u /etc/exim4/conf.d/transport/30_exim4-config_remote_smtp <<'EOF'
+### transport/30_exim4-config_remote_smtp
+#################################
+# This transport is used for delivering messages over SMTP connections.
+
+remote_smtp:
+ debug_print = "T: remote_smtp for $local_part@$domain"
+ driver = smtp
+ message_linelength_limit = 2097152
+.ifdef REMOTE_SMTP_HOSTS_AVOID_TLS
+ hosts_avoid_tls = REMOTE_SMTP_HOSTS_AVOID_TLS
+.endif
+.ifdef REMOTE_SMTP_HEADERS_REWRITE
+ headers_rewrite = REMOTE_SMTP_HEADERS_REWRITE
+.endif
+.ifdef REMOTE_SMTP_RETURN_PATH
+ return_path = REMOTE_SMTP_RETURN_PATH
+.endif
+.ifdef REMOTE_SMTP_HELO_DATA
+ helo_data=REMOTE_SMTP_HELO_DATA
+.endif
+.ifdef REMOTE_SMTP_INTERFACE
+ interface = REMOTE_SMTP_INTERFACE
+.endif
+.ifdef DKIM_DOMAIN
+dkim_domain = DKIM_DOMAIN
+.endif
+.ifdef DKIM_IDENTITY
+dkim_identity = DKIM_IDENTITY
+.endif
+.ifdef DKIM_SELECTOR
+dkim_selector = DKIM_SELECTOR
+.endif
+.ifdef DKIM_PRIVATE_KEY
+dkim_private_key = DKIM_PRIVATE_KEY
+.endif
+.ifdef DKIM_CANON
+dkim_canon = DKIM_CANON
+.endif
+.ifdef DKIM_STRICT
+dkim_strict = DKIM_STRICT
+.endif
+.ifdef DKIM_SIGN_HEADERS
+dkim_sign_headers = DKIM_SIGN_HEADERS
+.endif
+.ifdef DKIM_TIMESTAMPS
+dkim_timestamps = DKIM_TIMESTAMPS
+.endif
+.ifdef TLS_DH_MIN_BITS
+tls_dh_min_bits = TLS_DH_MIN_BITS
+.endif
+.ifdef REMOTE_SMTP_TLS_CERTIFICATE
+tls_certificate = REMOTE_SMTP_TLS_CERTIFICATE
+.endif
+.ifdef REMOTE_SMTP_PRIVATEKEY
+tls_privatekey = REMOTE_SMTP_PRIVATEKEY
+.endif
+.ifdef REMOTE_SMTP_HOSTS_REQUIRE_TLS
+ hosts_require_tls = REMOTE_SMTP_HOSTS_REQUIRE_TLS
+.endif
+.ifdef REMOTE_SMTP_TRANSPORTS_HEADERS_REMOVE
+ headers_remove = REMOTE_SMTP_TRANSPORTS_HEADERS_REMOVE
+.endif
+
+EOF
+
+u /etc/exim4/conf.d/transport/30_backup_remote <<'EOF'
+backup_remote:
+ driver = smtp
+ multi_domain
+ message_linelength_limit = 2097152
+ hosts_require_auth = *
+ hosts_try_auth = *
+ envelope_to_add
+ # manual return path because we want it to be the envelope sender
+ # we got not the one we are using in this smtp transport
+ headers_add = "Return-path: $sender_address"
+.ifdef REMOTE_SMTP_SMARTHOST_HOSTS_AVOID_TLS
+ hosts_avoid_tls = REMOTE_SMTP_SMARTHOST_HOSTS_AVOID_TLS
+.endif
+.ifdef REMOTE_SMTP_SMARTHOST_HOSTS_REQUIRE_TLS
+ hosts_require_tls = REMOTE_SMTP_SMARTHOST_HOSTS_REQUIRE_TLS
+.endif
+.ifdef REMOTE_SMTP_SMARTHOST_TLS_VERIFY_CERTIFICATES
+ tls_verify_certificates = REMOTE_SMTP_SMARTHOST_TLS_VERIFY_CERTIFICATES
+.endif
+.ifdef REMOTE_SMTP_SMARTHOST_TLS_VERIFY_HOSTS
+ tls_verify_hosts = REMOTE_SMTP_SMARTHOST_TLS_VERIFY_HOST
+.endif
+.ifdef REMOTE_SMTP_HEADERS_REWRITE
+ headers_rewrite = REMOTE_SMTP_HEADERS_REWRITE
+.endif
+.ifdef REMOTE_SMTP_HELO_DATA
+ helo_data=REMOTE_SMTP_HELO_DATA
+.endif
+.ifdef TLS_DH_MIN_BITS
+tls_dh_min_bits = TLS_DH_MIN_BITS
+.endif
+.ifdef REMOTE_SMTP_SMARTHOST_TLS_CERTIFICATE
+tls_certificate = REMOTE_SMTP_SMARTHOST_TLS_CERTIFICATE
+.endif
+.ifdef REMOTE_SMTP_SMARTHOST_PRIVATEKEY
+tls_privatekey = REMOTE_SMTP_SMARTHOST_PRIVATEKEY
+.endif
+.ifdef REMOTE_SMTP_TRANSPORTS_HEADERS_REMOVE
+ headers_remove = REMOTE_SMTP_TRANSPORTS_HEADERS_REMOVE
+.endif
+EOF
+
+u /etc/exim4/conf.d/router/900_exim4-config_local_user <<'EOF'
### router/900_exim4-config_local_user
#################################
local_part_suffix = +*
local_part_suffix_optional
EOF
-i /etc/exim4/conf.d/transport/30_exim4-config_dovecot_lmtp <<'EOF'
+u /etc/exim4/conf.d/transport/30_exim4-config_dovecot_lmtp <<'EOF'
dovecot_lmtp:
driver = lmtp
socket = /var/run/dovecot/lmtp
envelope_to_add
EOF
-i /etc/exim4/conf.d/transport/30_remote_smtp_vpn <<'EOF'
+u /etc/exim4/conf.d/transport/30_remote_smtp_vpn <<'EOF'
# same as debians 30_exim4-config_remote_smtp, but
# with interface added at the end.
remote_smtp_vpn:
debug_print = "T: remote_smtp_vpn for $local_part@$domain"
driver = smtp
-.ifndef IGNORE_SMTP_LINE_LENGTH_LIMIT
- message_size_limit = ${if > {$max_received_linelength}{998} {1}{0}}
-.endif
+ message_linelength_limit = 2097152
.ifdef REMOTE_SMTP_HOSTS_AVOID_TLS
hosts_avoid_tls = REMOTE_SMTP_HOSTS_AVOID_TLS
.endif
interface = <; 10.8.0.4 ; 2600:3c00:e002:3800::4
EOF
-i /etc/exim4/conf.d/transport/30_smarthost_dkim <<'EOF'
+u /etc/exim4/conf.d/transport/30_smarthost_dkim <<'EOF'
# ian: this is remote_smtp_smarthost plus the dkim parts from remote_smtp
smarthost_dkim:
debug_print = "T: remote_smtp_smarthost for $local_part@$domain"
driver = smtp
+ message_linelength_limit = 2097152
multi_domain
-.ifndef IGNORE_SMTP_LINE_LENGTH_LIMIT
- message_size_limit = ${if > {$max_received_linelength}{998} {1}{0}}
-.endif
hosts_try_auth = <; ${if exists{CONFDIR/passwd.client} \
{\
${lookup{$host}nwildlsearch{CONFDIR/passwd.client}{$host_address}}\
# in the log it just says "Starting Radicale". If you run
# it in the foreground, it will give more info. Background
# plus debug does not help.
- # sudo -u radicale radicale -D -f
+ # sudo -u radicale radicale -D
# created password file with:
# htpasswd -c /p/c/machine_specific/li/filesystem/etc/caldav-htpasswd
pi-nostart radicale
- i /etc/systemd/system/radicale.service.d/override.conf <<EOF
+ u /etc/systemd/system/radicale.service.d/override.conf <<EOF
[Unit]
After=network.target network-online.target mailnn.service $vpnser
# disable power management feature, set to 240 min sync interval,
# so it shouldn't be bad.
- # davdroid from f-druid.
+ # davx^5 from f-droid
# login with url and user name
# url https://cal.iankelling.org/ian
# username ian
done
# https://wiki.dovecot.org/SSL/DovecotConfiguration
- i /etc/dovecot/dhparam <<'EOF'
+ u /etc/dovecot/dhparam <<'EOF'
-----BEGIN DH PARAMETERS-----
MIIBCAKCAQEAoleil6SBxGqQKk7j0y2vV3Oklv6XupZKn7PkPv485QuFeFagifeS
A+Jz6Wquqk5zhGyCu63Hp4wzGs4TyQqoLjkaWL6Ra/Bw3g3ofPEzMGEsV1Qdqde4
cat <<'EOF'
# https://ssl-config.mozilla.org
ssl = required
-# this is the same as the certbot list, in my cert cronjob, I check if that has changed upstream.
+# 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_prefer_server_ciphers = no
mail_plugins = $mail_plugins sieve
}
EOF
- if dpkg --compare-versions $(dpkg-query -f='${Version}\n' --show dovecot-core) ge 1:2.3; then
+ if dpkg --compare-versions "$(dpkg-query -f='${Version}\n' --show dovecot-core)" ge 1:2.3; then
cat <<EOF
ssl_dh = </etc/dovecot/dhparam
EOF
auth_mechanisms = plain login
EOF
- i /etc/dovecot/sieve-spam.sieve <<'EOF'
+ u /etc/dovecot/sieve-spam.sieve <<'EOF'
require ["regex", "fileinto", "imap4flags"];
if allof (header :regex "X-Spam-Status" "^Yes") {
}
EOF
- i /etc/dovecot/local.conf.ext <<'EOF'
+ u /etc/dovecot/local.conf.ext <<'EOF'
passdb {
driver = sql
args = /etc/dovecot/dovecot-sql.conf.ext
EOF
- i /etc/dovecot/dovecot-sql.conf.ext <<'EOF'
+ u /etc/dovecot/dovecot-sql.conf.ext <<'EOF'
# from mailinabox
driver = sqlite
# for je and bk, populated the testignore users for the relevant domains
dir=/var/www/autoconfig.$domain/html/mail
m mkdir -p $dir
# taken from mailinabox
- i $dir/config-v1.1.xml <<EOF
+ u $dir/config-v1.1.xml <<EOF
<?xml version="1.0" encoding="UTF-8"?>
<clientConfig version="1.1">
<emailProvider id="$domain">
rcdir=${rcdirs[i]}
rcbase=${rcdir##*/}
ncdir=${ncdirs[i]}
+ myncdir=/root/${ncdir##*/}
+ mkdir -p $myncdir
# copied from debians cronjob
- i /etc/cron.d/$rcbase <<EOF
+ u /etc/cron.d/$rcbase <<EOF
# Roundcube database cleaning: finally removes all records that are
# marked as deleted.
0 5 * * * www-data $rcdir/bin/cleandb.sh >/dev/null
rctmpdir=/var/tmp/$rcbase
rcdb=/m/rc/$rcbase.sqlite
# config from mailinabox
- i $rcdir/config/config.inc.php <<EOF
+ u $rcdir/config/config.inc.php <<EOF
<?php
\$config = array();
# debian creates this for us
# About categories, see https://www.davx5.com/tested-with/nextcloud
# https://github.com/blind-coder/rcmcarddav/blob/master/doc/GROUPS.md
- i $rcdir/plugins/carddav/config.inc.php <<EOF;
+ u $rcdir/plugins/carddav/config.inc.php <<EOF;
<?php
\$prefs['_GLOBAL']['hide_preferences'] = false;
\$prefs['davserver'] = array(
### begin php setup for rc ###
# Enable PHP modules.
m phpenmod -v php mcrypt imap
- # dpkg says this is required
+ # dpkg says this is required.
+ # nextcloud needs these too
m a2enmod proxy_fcgi setenvif
fpm=$(dpkg-query -s php-fpm | sed -nr 's/^Depends:.* (php[^ ]*-fpm)( .*|$)/\1/p') # eg: php7.4-fpm
phpver=$(dpkg-query -s php-fpm | sed -nr 's/^Depends:.* php([^ ]*)-fpm( .*|$)/\1/p')
# $rclogdir/errors.log
# todo: consider other settings in
# /a/opt/mailinabox/setup/nextcloud.sh
- i /etc/php/$phpver/cli/conf.d/30-local.ini <<'EOF'
+ u /etc/php/$phpver/cli/conf.d/30-local.ini <<'EOF'
apc.enable_cli = 1
EOF
- i /etc/php/$phpver/fpm/conf.d/30-local.ini <<'EOF'
+ u /etc/php/$phpver/fpm/conf.d/30-local.ini <<'EOF'
date.timezone = "America/New_York"
# for nextcloud
upload_max_filesize = 2000M
m rm -f $file
m chown -R www-data.www-data nextcloud
m mv nextcloud $ncdir
+ fi
+
+ if [[ ! -e $myncdir/done-install ]]; then
m cd $ncdir
m sudo -u www-data php occ maintenance:install --database sqlite --admin-user iank --admin-pass $nextcloud_admin_pass
+ 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 config.php-orig ]]; then
- m cp -a config.php config.php-orig
+ if [[ ! -e $myncdir/config.php-orig ]]; then
+ m cp -a config.php $myncdir/config.php-orig
fi
- cat config.php-orig - >tmp.php <<EOF
+ 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";
var_export(\$CONFIG);
fwrite(STDOUT, ";\n");
EOF
- m php tmp.php >config.php
- m rm -f tmp.php
- m sudo -u www-data php $ncdir/occ maintenance:update:htaccess
+ e running php $myncdir/tmp.php
+ # note: we leave it around place for debugging
+ php $myncdir/tmp.php >config.php
+ 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)
# user_external not compaible with nc 23
for app in contacts calendar; do
if [[ $(printf "%s\n" "$list"| jq ".enabled.$app") == null ]]; then
- m sudo -u www-data php $ncdir/occ app:install $app
+ cd $ncdir
+ m sudo -u www-data php occ app:install $app
fi
done
- i /etc/systemd/system/$ncbase.service <<EOF
+ u /etc/systemd/system/$ncbase.service <<EOF
[Unit]
Description=ncup $ncbase
After=multi-user.target
IOSchedulingClass=idle
CPUSchedulingPolicy=idle
EOF
- i /etc/systemd/system/$ncbase.timer <<EOF
+ u /etc/systemd/system/$ncbase.timer <<EOF
[Unit]
Description=ncup $ncbase timer
WantedBy=timers.target
EOF
systemctl enable --now $ncbase.timer
- i /usr/local/bin/ncup <<'EOFOUTER'
+ u /usr/local/bin/ncup <<'EOFOUTER'
#!/bin/bash
-if ! test "$BASH_VERSION"; then echo "error: shell is not bash" >&2; exit 1; fi
-shopt -s inherit_errexit 2>/dev/null ||: # ignore fail in bash < 4.4
-set -eE -o pipefail
-trap 'echo "$0:$LINENO:error: \"$BASH_COMMAND\" exit status: $?, PIPESTATUS: ${PIPESTATUS[*]}" >&2' ERR
-ncbase=$1
-if ! php /var/www/$ncbase/updater/updater.phar -n; then
+source /usr/local/lib/err
+
+m() { printf "%s\n" "$*"; "$@"; }
+err-cleanup() {
echo failed nextcloud update for $ncbase >&2
- /sbin/exim -t <<EOF
+ # -odf or else systemd will kill the background delivery process
+ # and the message will sit in the queue until the next queue run.
+ exim -odf -t <<EOF
To: alerts@iankelling.org
-From: root@$(hostname -f)
+From: www-data@$(hostname -f)
Subject: failed nextcloud update for $ncbase
For logs, run: jr -u $ncbase
EOF
+}
+
+if [[ $(id -u -n) != www-data ]]; then
+ echo error: running as wrong user: $(id -u -n), expected www-data
+ exit 1
+fi
+
+if [[ ! $1 ]]; then
+ echo error: expected an arg, nextcloud relative base dir
+ exit 1
fi
+
+ncbase=$1
+cd /var/www/$ncbase
+# https://docs.nextcloud.com/server/22/admin_manual/maintenance/update.html?highlight=updater+phar
+m php /var/www/$ncbase/updater/updater.phar -n
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
+ u /etc/cron.d/$ncbase <<EOF
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
domains = +local_domains
!verify = recipient/callout=no_cache
EOF
- i /etc/exim4/conf.d/auth/29_exim4-config_auth <<'EOF'
+ u /etc/exim4/conf.d/auth/29_exim4-config_auth <<'EOF'
dovecot_plain:
driver = dovecot
public_name = PLAIN
;;
esac
if $bhost_t; then
- i /etc/exim4/conf.d/auth/29_exim4-config_auth <<'EOF'
+ u /etc/exim4/conf.d/auth/29_exim4-config_auth <<'EOF'
# from 30_exim4-config_examples
plain_server:
driver = plaintext
# to see the default comments in /etc/default/exim4:
# s update-exim4defaults --force --init
# which will overwrite any existing file
- i /etc/default/exim4 <<'EOF'
+ u /etc/default/exim4 <<'EOF'
QUEUERUNNER='combined'
QUEUEINTERVAL='30m'
COMMONOPTIONS='-C /etc/exim4/my.conf'
# i use epanic-clean for alerting if there are bad paniclog entries
E4BCD_WATCH_PANICLOG='no'
EOF
+ # make exim be a nonroot setuid program.
chown Debian-exim:Debian-exim /usr/sbin/exim4
# needs guid set in order to become Debian-exim
chmod g+s,u+s /usr/sbin/exim4
- i /etc/exim4/trusted_configs <<'EOF'
+ # need this to avoid error on service reload:
+ # 2022-08-07 18:44:34.005 [892491] pid 892491: SIGHUP received: re-exec daemon
+ # 2022-08-07 18:44:34.036 [892491] cwd=/var/spool/exim4 5 args: /usr/sbin/exim4 -bd -q30m -C /etc/exim4/my.conf
+ # 2022-08-07 18:44:34.043 [892491] socket bind() to port 25 for address (any IPv6) failed: Permission denied: waiting 30s before trying again (9 more tries)
+ # note: the daemon gives up and dies after retrying those 9 times.
+ # I came upon this by guessing and trial and error.
+ setcap CAP_NET_BIND_SERVICE+ei /usr/sbin/exim4
+ u /etc/exim4/trusted_configs <<'EOF'
/etc/exim4/my.conf
EOF
;;
*)
# default file
- i /etc/default/exim4 <<'EOF'
+ u /etc/default/exim4 <<'EOF'
QUEUERUNNER='combined'
QUEUEINTERVAL='30m'
EOF
dirs+=($d)
fi
done
- i /etc/systemd/system/exim4.service.d/nonroot.conf <<EOF
+ u /etc/systemd/system/exim4.service.d/nonroot.conf <<EOF
[Service]
# see 56.2 Root privilege in exim spec
AmbientCapabilities=CAP_NET_BIND_SERVICE
# this whole setting doesnt work. tried it with a newer systemd 250 though
# an nspawn, and it worked there.
InaccessiblePaths=${dirs[@]}
-NoNewPrivileges=yes
+# this gives us the permission denied error:
+# socket bind() to port 25 for address (any IPv6) failed: Permission denied
+# but we also have to set the file capabilities to avoid the error.
+#NoNewPrivileges=yes
ProtectSystem=yes
# when we get newer systemd
#ProtectDevices=yes
EOF
- i /etc/exim4/conf.d/main/000_local-noroot <<'EOF'
+ u /etc/exim4/conf.d/main/000_local-noroot <<'EOF'
# see 56.2 Root privilege in exim spec
deliver_drop_privilege = true
EOF
# ** $MAIL_HOST|bk|je)
$MAIL_HOST|bk|je)
- echo|i /etc/exim4/conf.d/router/870_backup_local
+ echo|i /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.
CHECK_RCPT_REVERSE_DNS = true
CHECK_MAIL_HELO_ISSUED = true
-# 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
-# default of 25, can get stuck when catching up on mail
-smtp_accept_max = 400
-smtp_accept_reserve = 100
-smtp_reserve_hosts = +iank_trusted
-# options exim has to avoid having to alter the default config files
-CHECK_RCPT_LOCAL_ACL_FILE = /etc/exim4/conf.d/rcpt_local_acl
CHECK_DATA_LOCAL_ACL_FILE = /etc/exim4/conf.d/data_local_acl
-LOCAL_DENY_EXCEPTIONS_LOCAL_ACL_FILE = /etc/exim4/conf.d/local_deny_exceptions_acl
+CHECK_RCPT_LOCAL_ACL_FILE = /etc/exim4/conf.d/rcpt_local_acl
+
# testing dmarc
#dmarc_tld_file = /etc/public_suffix_list.dat
+
EOF
;;&
# ** $MAIL_HOST|bk)
$MAIL_HOST|bk)
+
+ # no clamav on je, it has 1.5g memory and clamav uses most of it
+ u /etc/exim4/conf.d/clamav_data_acl <<'EOF'
+warn
+!hosts = +iank_trusted
+!authenticated = plain_server:login_server
+condition = ${if def:malware_name}
+remove_header = Subject:
+add_header = Subject: [Clamav warning: $malware_name] $h_subject
+log_message = heuristic malware warning: $malware_name
+EOF
+
cat >>/etc/exim4/conf.d/main/000_local <<EOF
# je.b8.nz will run out of memory with freshclam
av_scanner = clamd:/var/run/clamav/clamd.ctl
MAIN_TLS_PRIVATEKEY = /etc/exim4/privkey.pem
EOF
- i /etc/exim4/conf.d/router/190_exim4-config_fsfsmarthost <<'EOF'
+ u /etc/exim4/conf.d/router/190_exim4-config_fsfsmarthost <<'EOF'
gnusmarthost:
debug_print = "R: smarthost for $local_part@$domain"
driver = manualroute
# ** $MAIL_HOST)
$MAIL_HOST)
- i /etc/exim4/conf.d/router/195_dnslookup_vpn <<'EOF'
+ u /etc/exim4/conf.d/router/195_dnslookup_vpn <<'EOF'
# copied from /etc/exim4/conf.d/router/200_exim4-config_primary, but
# use vpn transport. lower priority so it overrides the default route.
# Use this in case our vpn fails, we dont send anything without it.
# which required using a dedicated user, but realized smtp will be
# more reliable and less fuss. If I ever need that again, see the
# history of this file, and bum in brc2.
-
- i /etc/exim4/conf.d/router/890_backup_copy <<EOF
-### router/900_exim4-config_local_user
-#################################
-
-# todo, it would be nice to save sent email too,
-# but its not so important, they still exist in my head
-
-backup_redir:
+ u /etc/exim4/conf.d/router/161_backup_redir_nn <<'EOF'
+backup_redir_nn:
driver = redirect
-domains = +local_domains
# b is just an arbirary short string
data = b@eximbackup.b8.nz
+condition = ${if !bool{${lookup{$local_part@$domain}lsearch{/etc/exim4/ignore-sent}{true}}}}
# note, to test this, i could temporarily allow testignore.
# alerts avoids potential mail loop. root is already
# redirected earlier, so that is just being overly cautious.
local_parts = ! root : ! testignore : ! alerts
unseen = true
-
-backup_copy:
-driver = manualroute
-domains = eximbackup.b8.nz
-transport = backup_remote
-ignore_target_hosts = ${HOSTNAME}wg.b8.nz
-# note changes here also require change in passwd.client
-route_list = * eximbackup.b8.nz
-same_domain_copy_routing = yes
errors_to = alerts@iankelling.org
-no_more
EOF
- i /etc/exim4/conf.d/transport/30_backup_remote <<'EOF'
-backup_remote:
- driver = smtp
- multi_domain
-.ifndef IGNORE_SMTP_LINE_LENGTH_LIMIT
- message_size_limit = ${if > {$max_received_linelength}{998} {1}{0}}
-.endif
- hosts_require_auth = *
- hosts_try_auth = *
- envelope_to_add
- # manual return path because we want it to be the envelope sender
- # we got not the one we are using in this smtp transport
- headers_add = "Return-path: $sender_address"
-.ifdef REMOTE_SMTP_SMARTHOST_HOSTS_AVOID_TLS
- hosts_avoid_tls = REMOTE_SMTP_SMARTHOST_HOSTS_AVOID_TLS
-.endif
-.ifdef REMOTE_SMTP_SMARTHOST_HOSTS_REQUIRE_TLS
- hosts_require_tls = REMOTE_SMTP_SMARTHOST_HOSTS_REQUIRE_TLS
-.endif
-.ifdef REMOTE_SMTP_SMARTHOST_TLS_VERIFY_CERTIFICATES
- tls_verify_certificates = REMOTE_SMTP_SMARTHOST_TLS_VERIFY_CERTIFICATES
-.endif
-.ifdef REMOTE_SMTP_SMARTHOST_TLS_VERIFY_HOSTS
- tls_verify_hosts = REMOTE_SMTP_SMARTHOST_TLS_VERIFY_HOST
-.endif
-.ifdef REMOTE_SMTP_HEADERS_REWRITE
- headers_rewrite = REMOTE_SMTP_HEADERS_REWRITE
-.endif
-.ifdef REMOTE_SMTP_HELO_DATA
- helo_data=REMOTE_SMTP_HELO_DATA
-.endif
-.ifdef TLS_DH_MIN_BITS
-tls_dh_min_bits = TLS_DH_MIN_BITS
-.endif
-.ifdef REMOTE_SMTP_SMARTHOST_TLS_CERTIFICATE
-tls_certificate = REMOTE_SMTP_SMARTHOST_TLS_CERTIFICATE
-.endif
-.ifdef REMOTE_SMTP_SMARTHOST_PRIVATEKEY
-tls_privatekey = REMOTE_SMTP_SMARTHOST_PRIVATEKEY
-.endif
-.ifdef REMOTE_SMTP_TRANSPORTS_HEADERS_REMOVE
- headers_remove = REMOTE_SMTP_TRANSPORTS_HEADERS_REMOVE
-.endif
-EOF
-
- # this avoids some error. i cant remember what. todo:
- # test it out and document why/if its needed.
- # i /etc/exim4/host_local_deny_exceptions <<'EOF'
- # mail.fsf.org
- # *.posteo.de
- # EOF
+ # This allows for forwarded mail to not get most rcpt checks, especially SPF,
+ # which would incorrectly get denied.
+ u /etc/exim4/host_local_deny_exceptions <<'EOF'
+mail.fsf.org
+*.posteo.de
+EOF
# cron email from smarthost hosts will automatically be to
# USER@FQDN. I redirect that to alerts@, on the smarthosts, but in
# case that doesn't work, we still want to accept that mail, but not
# from any host except the smarthosts. local_hostnames and this rule
# is for that purpose.
- i /etc/exim4/conf.d/rcpt_local_acl <<'EOF'
+ u /etc/exim4/conf.d/rcpt_local_acl <<'EOF'
deny
!authenticated = *
domains = +local_hostnames
message = no relay
+
+# for testing bounce behavior
+#deny
+# senders = testlist-bounces+test=zroe.org@fsf.org
+# message = iank-bounce
EOF
echo|i /etc/exim4/conf.d/router/880_universal_forward
MAILDIR_HOME_MAILDIR_LOCATION = /m/md/Sent
EOF
- # for iank@fsf.org, i have mail.fsf.org forward it to fsf@iankelling.org.
- # and also have mail.iankelling.org whitelisted as a relay domain.
- # I could avoid that if I changed this to submit to 587 with a
- # password like a standard mua.
- i /etc/exim4/conf.d/router/188_exim4-config_smarthost <<'EOF'
+
+ 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:
+sentarchive_nn:
driver = redirect
domains = ! +local_domains
condition = ${if !bool{${lookup{$local_part@$domain}lsearch{/etc/exim4/ignore-sent}{true}}}}
data = vojdedIdNejyebni@b8.nz
unseen
+EOF
+
+ # for iank@fsf.org, i have mail.fsf.org forward it to fsf@iankelling.org.
+ # and also have mail.iankelling.org whitelisted as a relay domain.
+ # I could avoid that if I changed this to submit to 587 with a
+ # password like a standard mua.
+ u /etc/exim4/conf.d/router/188_exim4-config_smarthost <<'EOF'
# ian: copied from /etc/exim4/conf.d/router/200_exim4-config_primary, and added senders = and
# replaced DCsmarthost with hostname
fsfsmarthost:
## we use this host to monitor MAIL_HOST and host a mail server for someone
bk)
- echo|i /etc/exim4/conf.d/rcpt_local_acl
- echo|i /etc/exim4/conf.d/router/880_universal_forward
/a/exe/cedit nn /etc/hosts <<'EOF' || [[ $? == 1 ]]
10.173.8.2 nn.b8.nz
s,(^[ #]*NAME=).*,\1"exim4in",
EOF
chmod +x /etc/init.d/exim4in
- i /etc/systemd/system/exim4in.service.d/alwaysrestart.conf <<'EOF'
+ u /etc/systemd/system/exim4in.service.d/alwaysrestart.conf <<'EOF'
[Unit]
# needed to continually restart
StartLimitIntervalSec=0
RestartSec=20
EOF
- i /etc/default/exim4in <<'EOF'
+ u /etc/default/exim4in <<'EOF'
# defaults but no queue runner and alternate config dir
QUEUERUNNER='no'
COMMONOPTIONS='-oP /run/exim4/eximin.pid'
cat >>/etc/exim4/update-exim4.conf.conf <<EOF
dc_other_hostnames='je.b8.nz'
EOF
- 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/router/880_universal_forward
;;
# ** not MAIL_HOST|bk|je
*)
# 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/router/890_backup_copy
echo|i /etc/exim4/conf.d/main/000_local-nn
+ echo|i /etc/exim4/conf.d/clamav_data_acl
if $bhost_t; then
fi
# catches things like cronjob email
- i /etc/exim4/conf.d/router/880_universal_forward <<'EOF'
+ u /etc/exim4/conf.d/router/880_universal_forward <<'EOF'
universal_forward:
driver = redirect
domains = +local_domains
echo | /a/exe/cedit nn /etc/hosts || [[ $? == 1 ]]
echo | /a/exe/cedit mail /etc/dnsmasq-servers.conf || [[ $? == 1 ]]
-
+ # note: condition duplicated at else
if $bhost_t; then
install -d /bu
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
+ u /etc/exim4/conf.d/transport/30_backup_maildir <<EOF
# modified debian maildir transport
backup_maildir:
driver = appendfile
mode_fail_narrower = false
EOF
- i /etc/exim4/conf.d/router/870_backup_local <<'EOF'
+ u /etc/exim4/conf.d/router/165_backup_local <<'EOF'
### router/900_exim4-config_local_user
#################################
EOF
# wghole & thus exim will fail to start without internet connectivity.
- i /etc/systemd/system/exim4.service.d/backup.conf <<'EOF'
+ u /etc/systemd/system/exim4.service.d/backup.conf <<'EOF'
[Unit]
StartLimitIntervalSec=0
RestartSec=20
EOF
- else
+ else # if $bhost_t; then
cat >>/etc/exim4/update-exim4.conf.conf <<EOF
# Note: If theres like a temporary problem where mail gets sent to
# one of these hosts, if exim isnt listening, it will be a temporary error
# ** $MAILHOST|bk, things that belong at the end
case $HOSTNAME in
$MAIL_HOST|bk)
- # config for the non-nn exim
- m rsync -ra --delete /etc/exim4/ /etc/myexim4
- cat >>/etc/myexim4/conf.d/main/000_local-nn <<'EOF'
+ # config for the non-nn exim. note, it uses not default dir, but we
+ # generate that into the default config file
+ m rsync -ra --delete --delete-excluded \
+ --exclude=/conf.d/router/161_backup_redir_nn \
+ --exclude=/conf.d/router/186_sentarchive_nn \
+ --exclude=/conf.d/main/000_local-nn /etc/exim4/ /etc/myexim4
+ cat >>/etc/myexim4/conf.d/main/000_local <<'EOF'
# this makes it easier to see which exim is doing what
log_file_path = /var/log/exim4/my%s
EOF
+
+
+
+ cat >/etc/logrotate.d/myexim <<'EOF'
+/var/log/exim4/mymain /var/log/exim4/myreject {
+ daily
+ missingok
+ rotate 1000
+ delaycompress
+ notifempty
+ nocreate
+}
+/var/log/exim4/mypanic {
+ size 10M
+ missingok
+ rotate 10
+ compress
+ delaycompress
+ notifempty
+ nocreate
+}
+EOF
+
# If we ever wanted to have a separate spool,
# we could do it like this.
# cat >>/etc/exim4/conf.d/main/000_local-nn <<'EOF'
bk)
# config for the non-nn exim
- cat >/etc/myexim4/conf.d/main/000_local-nn <<'EOF'
+ cat >>/etc/myexim4/conf.d/main/000_local <<'EOF'
MAIN_HARDCODE_PRIMARY_HOSTNAME = mail2.iankelling.org
EOF
;;
$MAIL_HOST)
+
+
+ u /etc/myexim4/conf.d/router/185_sentarchive <<'EOF'
+sentarchive:
+ driver = redirect
+ domains = ! +local_domains
+ senders = <; *@fsf.org ; *@posteo.net
+ condition = ${if !bool{${lookup{$local_part@$domain}lsearch{/etc/exim4/ignore-sent}{true}}}}
+ 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
+EOF
+
+
+
# for bk, we have a exim4in.service that will do this for us.
m update-exim4.conf -d /etc/myexim4
;;
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
fi
- i /etc/systemd/system/exim4.service.d/override.conf <<'EOF'
+ u /etc/systemd/system/exim4.service.d/override.conf <<'EOF'
[Unit]
# without local-fs on exim, we get these kind of errors in paniclog on shutdown:
# Failed to create spool file /var/spool/exim4//input//1jCLxz-0008V4-V9-D: Permission denied
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
+fi
+
sysd-prom-fail-install epanicclean
m systemctl --now enable epanicclean
$MAIL_HOST)
# < 2.1 (eg: in t9), uses a different data format which required manual
# migration. dont start if we are running an old version.
- if dpkg --compare-versions $(dpkg -s radicale | awk '$1 == "Version:" { print $2 }') ge 2.1; then
+ if dpkg --compare-versions "$(dpkg -s radicale | awk '$1 == "Version:" { print $2 }')" ge 2.1; then
m systemctl --now enable radicale
fi
;;&
esac
+# for debugging dns issues
+case $HOSTNAME in
+ je|bk)
+ systemctl enable --now logrotate-fast.timer
+ ;;
+esac
+
# last use of $reload happens in previous block
rm -f /var/local/mail-setup-reload
# note: cronjob "ian" also does some important monitoring
# todo: this will sometimes cause an alert because mailtest-check will run
# before we have setup network namespace and spamassassin
- cat >/etc/cron.d/mailtest <<EOF
+ u /etc/cron.d/mailtest <<EOF
SHELL=/bin/bash
PATH=/usr/bin:/bin:/usr/local/bin
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
-*/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 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/
+ u /etc/systemd/system/mailtest-check.service <<'EOF'
+[Unit]
+Description=mailtest-check
+After=local-fs.target
+StartLimitIntervalSec=0
+
+[Service]
+Type=simple
+ExecStart=/usr/local/bin/mailtest-check slow
+Restart=always
+RestartSec=60
+
+[Install]
+WantedBy=graphical.target
+EOF
+ sysd-prom-fail-install mailtest-check
+ sre mailtest-check
;;&
$MAIL_HOST)
test_froms=(ian@iankelling.org z@zroe.org iank@gnu.org)
test_tos=(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."
+# 10 am friday
+0 10 * * 5 root echo "weekly alert. You are not in the matrix."
2 * * * * root check-remote-mailqs |& log-once check-remote-mailqs
EOF
;;&
bk)
- test_froms=(testignore@expertpathologyreview.com testignore@amnimal.ninja)
- test_tos=(testignore@iankelling.org testignore@zroe.org testignore@je.b8.nz)
+ test_froms=(testignore@amnimal.ninja testignore@expertpathologyreview.com)
+ test_tos=(testignore@iankelling.org testignore@je.b8.nz)
+ # We dont need to send from different addresses to the same
+ # address. this breaks down our nice elegant logic of building up
+ # froms and tos , so I just handle expertpath in a special case
+ # below and set the to: to be testignore@zroe.org. If we did sent
+ # that way, it would also mess up our mailtest-check logic that
+ # finds which messages to check.
+ # for example: from testignore@amnimal.ninja to: testignore@iankelling.org testignore@zroe.org
+ # that would become 2 messages and we'd only check 1.
;;&
je)
test_froms=(testignore@je.b8.nz)
test_tos=(testignore@iankelling.org testignore@zroe.org testignore@expertpathologyreview.com testignore@amnimal.ninja)
;;&
$MAIL_HOST|bk|je)
- test_to=${test_tos[0]}
- # dont put these test messages into the sent folder or else it will
+
+ # Dont put these test messages into the sent folder or else it will
# overwhelm it, plus i dont want to save a copy at all.
- echo $test_to > /etc/exim4/ignore-sent
- for t in ${test_tos[@]:1}; do
- test_to+=", $t"
- echo $t >> /etc/exim4/ignore-sent
- done
+ # Plus addresses we generally want to ignore.
+ u /etc/exim4/ignore-sent <<EOF
+$(printf "%s\n" ${test_tos[@]})
+vojdedIdNejyebni@b8.nz
+b@eximbackup.b8.nz
+EOF
+
cat >/usr/local/bin/send-test-forward <<'EOF'
#!/bin/bash
+# we remove from the queue older than 4.3 minutes since we send every 5 minutes.
olds=(
$(/usr/sbin/exiqgrep -o 260 -i -r '^(testignore@(iankelling\.org|zroe\.org|expertpathologyreview\.com|amnimal\.ninja|je\.b8\.nz)|jtuttle@gnu\.org)$')
)
fi
EOF
for test_from in ${test_froms[@]}; do
+
+ test_to=${test_tos[0]}
+ for t in ${test_tos[@]:1}; do
+ test_to+=", $t"
+ done
+ case $test_from in
+ testignore@expertpathologyreview.com)
+ test_to=testignore@zroe.org
+ ;;
+ esac
+
cat >>/usr/local/bin/send-test-forward <<EOFOUTER
-/usr/sbin/exim -f $test_from -t <<EOF
+/usr/sbin/exim -odf -f $test_from -t <<EOF
From: $test_from
To: $test_to
Subject: test \$(date +%Y-%m-%dT%H:%M:%S%z) \$EPOCHSECONDS
m chmod +x /usr/local/bin/send-test-forward
;;
*)
- rm -fv /etc/cron.d/mailtest
+ soff mailtest-check.service
+ rm -fv /etc/cron.d/mailtest \
+ /var/lib/prometheus/node-exporter/mailtest-check.prom* \
+ /var/local/cron-errors/check-remote-mailqs*
;;
esac