X-Git-Url: https://iankelling.org/git/?a=blobdiff_plain;f=mail-setup;h=de9db482acad97f7c8cb4b23e4b856c7a8d87994;hb=ea108a03dfa2d7f73447c0b14210d766e5ee5d9b;hp=28e02ce089f63edc39362f7123610f77bc3ad578;hpb=608a1255fc3700611bdabdc9c8635940ac3390af;p=distro-setup diff --git a/mail-setup b/mail-setup index 28e02ce..de9db48 100755 --- a/mail-setup +++ b/mail-setup @@ -3,10 +3,24 @@ # Copyright (C) 2019 Ian Kelling # SPDX-License-Identifier: AGPL-3.0-or-later + +# todo: setup an alert for bouncing test emails. + +# todo: bounces to my fsf mail can come from fsf@iankelling.org, +# think about making bounces go from the original address. + +# 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. +#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 @@ -18,12 +32,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 - # todo: disable postgrey # todo: in testforward-check, we should also look @@ -136,7 +144,7 @@ fi [[ $EUID == 0 ]] || exec sudo -E "${BASH_SOURCE[0]}" "$@" - +# note, this is hardcoded in /etc/exim4/conf.d/main/000_local u=$(id -nu 1000) @@ -165,9 +173,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. ####### @@ -279,7 +288,11 @@ fi i() { # install file local tmp tmpdir dest="$1" local base="${dest##*/}" - mkdir -p ${dest%/*} + local dir="${dest%/*}" + if [[ $dir != "$base" ]]; then + # dest has a directory component + mkdir -p "$dir" + fi ir=false # i result tmpdir=$(mktemp -d) cat >$tmpdir/"$base" @@ -334,7 +347,6 @@ stopifactive() { mxhost=mx.iankelling.org mxport=587 -forward=$u@$mxhost # old setup. left as comment for example # mxhost=mail.messagingengine.com @@ -377,11 +389,17 @@ EOF fi # light version of exim does not have sasl auth support. -pi-nostart exim4 exim4-daemon-heavy spamassassin openvpn unbound clamav-daemon wireguard +# 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 # 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 @@ -476,7 +494,6 @@ case $HOSTNAME in i /etc/systemd/system/wg-quick@wgmail.service.d/override.conf <&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 @@ -930,6 +958,14 @@ enabled = true port = 25,587 filter = exim banaction = iptables-exim + +# 209.51.188.13 = mail.fsf.org +# 2001:470:142::13 = mail.fsf.org +# 209.51.188.92 = eggs.gnu.org +# 2001:470:142:3::10 = eggs.gnu.org +# 72.14.176.105 2600:3c00:e000:280::2 = mail.iankelling.org +# 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 m systemctl restart fail2ban @@ -967,10 +1003,8 @@ awk 'BEGIN { FS = ":" } ; $6 ~ /^\/home/ && $7 !~ /\/nologin$/ { print $1 }' /et 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 @@ -1003,9 +1037,14 @@ if (( ${#files[@]} )); then ${files[@]} /etc/exim4 fi -# by default, only 10 days of logs are kept. increase that. -m sed -ri 's/^(\s*rotate\s).*/\11000/' /etc/logrotate.d/exim4-base - +# By default, only 10 days of logs are kept. increase that. +# And dont compress, I look back at logs too often and +# dont need the annoyance of decompressing them all the time. +m sed -ri '/^\s*compress\s*$/d;s/^(\s*rotate\s).*/\11000/' /etc/logrotate.d/exim4-base +files=(/var/log/exim4/*.gz) +if (( ${#files[@]} )); then + gunzip ${files[@]} +fi ## disabled. not using .forward files, but this is still interesting ## for reference. @@ -1015,6 +1054,7 @@ m sed -ri 's/^(\s*rotate\s).*/\11000/' /etc/logrotate.d/exim4-base # b=userforward_higher_priority # # replace the router name so it is unique # sed -r s/^\\S+:/$b:/ 600_exim4-config_userforward >175_$b +rm -fv /etc/exim4/conf.d/router/175_userforward_higher_priority # todo, consider 'separate' in etc/exim4.conf, could it help on busy systems? @@ -1033,17 +1073,43 @@ 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,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, +# 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 + +# 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 rm -vf /etc/exim4/conf.d/main/000_localmacros # old filename -cat >/etc/exim4/conf.d/main/000_local </etc/exim4/conf.d/main/000_local2 </etc/exim4/conf.d/main/000_local <<'EOF' MAIN_TLS_ENABLE = true # require tls connections for all smarthosts @@ -1065,11 +1131,6 @@ MAIN_LOG_SELECTOR = +all # Based on spec, seems like a good idea to be nice. smtp_return_error_details = true -# normally empty, I set this so I can set the envelope address -# when doing mail redelivery to invoke filters. Also allows -# me exiqgrep and stuff. -MAIN_TRUSTED_GROUPS = $u - # default is 10. when exim has been down for a bit, fsf mailserver # will do a big send in one connection, then exim decides to put # the messages in the queue instead of delivering them, to avoid @@ -1088,10 +1149,10 @@ DKIM_SELECTOR = li # 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:}} +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}} +DKIM_PRIVATE_KEY = ${if exists{/etc/exim4/${dkim_domain}-private.pem} {/etc/exim4/${dkim_domain}-private.pem}} # most of the ones that gmail seems to use. # Exim has horrible default of signing unincluded @@ -1102,19 +1163,43 @@ 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 -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 + + +# this is the default delay_warning_condition, plus matching on local_domains. +# If I have some problem with my local system that causes delayed delivery, +# I dont want to send warnings out to non-local domains. +delay_warning_condition = ${if or {\ + { !eq{$h_list-id:$h_list-post:$h_list-subscribe:}{} }\ + { match{$h_precedence:}{(?i)bulk|list|junk} }\ + { match{$h_auto-submitted:}{(?i)auto-generated|auto-replied} }\ + { match_domain{$domain}{+local_domains} }\ + } {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 rm -fv /etc/exim4/rcpt_local_acl # old path @@ -1135,6 +1220,7 @@ accept EOF rm -fv /etc/exim4/data_local_acl # old path + i /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 @@ -1153,6 +1239,8 @@ warn 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 @@ -1162,6 +1250,8 @@ warn add_header = X-Spam_action: $spam_action 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 @@ -1174,14 +1264,14 @@ warn EOF -i /etc/exim4/conf.d/router/900_exim4-config_local_user <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 @@ -2236,11 +2333,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 <>/etc/exim4/conf.d/main/000_local < /etc/mailname - /a/exe/cedit nn /etc/hosts <<'EOF' || [[ $? == 1 ]] 10.173.8.2 nn.b8.nz EOF @@ -2720,9 +2838,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 <>/etc/myexim4/conf.d/main/000_local-nn <<'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' @@ -2907,6 +3053,9 @@ if [[ -e /nocow ]]; then # 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 After=local-fs.target + +[Service] +ExecStartPre=/usr/local/bin/exim-nn-iptables EOF if ! mountpoint -q $sdir; then stopifactive exim4 exim4in @@ -2941,8 +3090,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 @@ -2953,7 +3102,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) @@ -2968,11 +3118,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 ;;& @@ -2994,7 +3139,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 @@ -3015,7 +3160,7 @@ case $HOSTNAME in $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 ;;& @@ -3026,7 +3171,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 ;; @@ -3058,53 +3206,98 @@ case $HOSTNAME in # 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 <>/etc/cron.d/mailtest <> /etc/exim4/ignore-sent + done + 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=( -$(/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 + + 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 <