From 32a1673064cfd9eaa165b4ea62fa416f02f3dfd2 Mon Sep 17 00:00:00 2001 From: Ian Kelling Date: Mon, 4 Nov 2019 16:02:05 -0500 Subject: [PATCH] Mainly add external monitoring of mail server Various fixes and features along with it. --- brc | 12 +- brc2 | 77 ++- check-mailq | 4 +- check-remote-mailqs | 2 +- conflink | 8 +- distro-begin | 5 +- distro-end | 95 ++-- filesystem/etc/cron.d/ian | 5 +- filesystem/usr/local/bin/mailtest-check | 41 -- filesystem/usr/local/bin/mycheckrestart | 2 - filesystem/usr/local/bin/myupgrade | 39 +- fsf-vpn-dns-cleanup | 1 + gitslink | 42 +- install-my-scripts | 2 +- .../filesystem/etc/systemd/system/znc.service | 10 + mail-setup | 444 ++++++++++-------- mailtest-check | 49 ++ mount-latest-subvol | 2 +- primary-setup | 20 + subdir_files/.gnupg/gpg.conf | 1 + subdir_files/sieve/lists.sieve | 1 + subdir_files/sieve/liststest.sieve | 1 + switch-mail-host | 65 ++- switch-primary-host | 49 -- system-status | 31 +- trusted-network | 7 +- untrusted-network | 7 +- 27 files changed, 594 insertions(+), 428 deletions(-) delete mode 100755 filesystem/usr/local/bin/mailtest-check create mode 100644 machine_specific/li/filesystem/etc/systemd/system/znc.service create mode 100755 mailtest-check delete mode 100755 switch-primary-host mode change 100755 => 100644 system-status diff --git a/brc b/brc index 37e09a0..e8737aa 100644 --- a/brc +++ b/brc @@ -3,11 +3,7 @@ # SPDX-License-Identifier: AGPL-3.0-or-later # this gets sourced. shebang is just for file mode detection -# note, to catch errors in functions but not outside, do: -# set -E -o pipefail -# trap return ERR -# trap 'trap ERR' RETURN - +source /a/bin/errhandle/err # * settings @@ -62,7 +58,7 @@ if [[ $RLC_INSIDE_EMACS ]]; then export PAGER=cat export MANPAGER=cat # scp completion does not work, but this doesnt fix it. todo, figure this out - complete -r scp &> /dev/null + #complete -r scp &> /dev/null # todo, remote file completion fails, figure out how to turn it off export NODE_DISABLE_COLORS=1 # This gets rid of ugly terminal escape chars in node repl @@ -639,7 +635,8 @@ rg() { } hr() { # horizontal row. used to break up output - printf "$(tput setaf 5)█$(tput sgr0)%.0s" $(seq ${COLUMNS:-60}) + + printf "$(tput setaf 5)█$(tput sgr0)%.0s" $(eval echo {1..${COLUMNS:-60}}) echo } @@ -1245,6 +1242,7 @@ if [[ $- == *i* ]]; then local return=$? # this MUST COME FIRST local ps_char ps_color unset IFS + history -a # save history case $return in diff --git a/brc2 b/brc2 index 75ed2bc..959e892 100644 --- a/brc2 +++ b/brc2 @@ -122,8 +122,10 @@ bbk() { # btrbk wrapper fi # run latest install-my-scripts - btrbk-run "$@" | pee cat "systemd-cat -t btrbk-run" - $active && ser enable btrbk.timer + btrbk-run "$@" |& pee cat "systemd-cat -t btrbk-run" + if $active; then + ser enable btrbk.timer + fi } bfg() { java -jar /a/opt/bfg-1.12.14.jar "$@"; } @@ -137,14 +139,14 @@ bpull() { c / # run latest install-my-scripts - switch-mail-host $1 $HOSTNAME | pee cat "systemd-cat -t switch-mail-host" + switch-mail-host pull $1 |& pee cat "systemd-cat -t switch-mail-host" } bpush() { [[ $1 ]] || return 1 c / # run latest install-my-scripts - switch-mail-host $HOSTNAME $1 | pee cat "systemd-cat -t switch-mail-host" + switch-mail-host push $1 |& pee cat "systemd-cat -t switch-mail-host" } lipush() { # note, i had --delete-excluded, but that deletes all files in --exclude-from on @@ -153,13 +155,13 @@ lipush() { p=(/a/bin /a/exe /a/h /a/c /p/c/machine_specific/linode{,.hosts} /a/opt/{emacs,emacs-debianstable,mu}) a="-ahviSAXPH --specials --devices --delete --relative --exclude-from=/p/c/li-rsync-excludes" ret=0 - m rsync $@ $a ${p[@]} /p/c/machine_specific/l2 root@l2.b8.nz:/ || ret=$? - m rsync $@ $a ${p[@]} /p/c/machine_specific/li root@li.b8.nz:/ || ret=$? - m rsync $@ -ahviSAXPH root@iankelling.org:/a/h/proposed-comments/ /a/h/proposed-comments || ret=$? + m rsync "$@" $a ${p[@]} /p/c/machine_specific/l2 root@l2.b8.nz:/ || ret=$? + m rsync "$@" $a ${p[@]} /p/c/machine_specific/li root@li.b8.nz:/ || ret=$? + m rsync "$@" -ahviSAXPH root@iankelling.org:/a/h/proposed-comments/ /a/h/proposed-comments || ret=$? return $ret } lipushnoe() { # noe = noemacs. for running faster. - rsync $@ --delete-excluded -ahviSAXPH --specials --devices --delete --relative \ + rsync "$@" --delete-excluded -ahviSAXPH --specials --devices --delete --relative \ --exclude-from=/p/c/li-rsync-excludes /a/bin /a/exe /a/h /a/c /p/c/machine_specific/li root@li:/ } @@ -272,13 +274,18 @@ digme() { dup() { local ran_d ran_d=false + system-status _ case $PS1 in *DISTRO-BEGIN!*|*DISTRO!*) + pushd / /b/ds/distro-begin || return $? + popd ran_d=true ;;& *DISTRO-END!*|*DISTRO!*) + pushd /b/ds/distro-end || return $? + popd ran_d=true ;;& *CONFLINK*) @@ -512,12 +519,10 @@ fw() { firefox -P default "$@" >/dev/null 2>&1 } - gitian() { git config user.email ian@iankelling.org } - # at least in flidas, things rely on gpg being gpg1 gpg() { command gpg2 "$@" @@ -532,7 +537,6 @@ gse() { --suppress-cc=self "$@" } - hstatus() { # do git status on published repos. c /a/bin/githtml @@ -548,11 +552,16 @@ hstatus() { done } - idea() { /a/opt/idea-IC-163.7743.44/bin/idea.sh "$@" &r } +ilog() { + chan=${1:-#fsfsys} + # use * instead of -r since that does sorted order + ssh root@iankelling.org "cd /var/lib/znc/moddata/log/iank/freenode/$chan && hr && for x in *; do echo \$x; cat \$x; hr; done" | less +G +} + o() { if type gvfs-open &> /dev/null ; then gvfs-open "$@" @@ -570,7 +579,7 @@ jtail() { journalctl -n 10000 -f "$@" | jfilter } jr() { journalctl "$@" | jfilter | less ; } -jrf() { journalctl -f "$@" | jfilter; } +jrf() { journalctl -n 200 -f "$@" | jfilter; } kff() { # keyboardio firmware flash @@ -636,10 +645,14 @@ mdt() { firefox /tmp/mdtest.html } - - mo() { xset dpms force off; } # monitor off +myirc() { + chan=${1:-fsf-office} + # use * instead of -r since that does sorted order + ssh root@iankelling.org "cd /var/lib/znc/moddata/log/iank/freenode/#$chan; grep '\/dev/null; then + if s tar --anchored \ + --exclude etc/dovecot/users \ + --exclude etc/exim4/passwd \ + --exclude etc/exim4/*.pem \ + --mode=g-s --owner=0 --group=0 -cz -C $fs . | s tar -dz -C / | grep /etc/systemd &>/dev/null; then systemd_reload=true fi - s tar --mode=g-s --owner=0 --group=0 -cz -C $fs . | s tar -xz -C / fi if [[ -e $dir/subdir_files ]]; then diff --git a/distro-begin b/distro-begin index 89a09ba..0377b1c 100755 --- a/distro-begin +++ b/distro-begin @@ -236,7 +236,7 @@ done ###### do conflink # linode needs bind group before conflink -if $linode; then +if linode; then pi-nostart bind9 fi # this needs to be before installing pacserve so we have gpg conf. @@ -246,6 +246,7 @@ conflink set +x err-allow source /etc/profile.d/environment.sh +export BRC=t # shellcheck source=./.bashrc source ~/.bashrc err-catch @@ -335,7 +336,7 @@ case $distro in sudo rmmod evbug ||: # might not be loaded yet file=/etc/modprobe.d/evbug.conf line="blacklist evbug" - if ! grep -xFq "$line" $file; then + if [[ $(cat $file) != $line ]]; then sudo dd of=$file 2>/dev/null <<<"$line" sudo depmod -a sudo update-initramfs -u diff --git a/distro-end b/distro-end index 87a54e3..f8419aa 100755 --- a/distro-end +++ b/distro-end @@ -382,7 +382,7 @@ Unattended-Upgrade::MailOnlyOnError "true"; Unattended-Upgrade::Remove-Unused-Dependencies "true"; Unattended-Upgrade::Origins-Pattern { # default is just security updates. this list found from reading - # match_whitelist_string() in `which unattended-upgrades` + # match_whitelist_string() in $(which unattended-upgrades) "o=*,l=*,a=*,c=*,site=*,n=*"; }; EOF @@ -408,6 +408,7 @@ EOF ###### begin website setup case $HOSTNAME in li|l2) + pi bind9 f=/var/lib/bind/db.b8.nz if [[ ! -e $f ]]; then ser stop bind9 @@ -417,14 +418,28 @@ case $HOSTNAME in fi ;;& l2) + # setup let's encrypt cert + m web-conf apache2 l2.b8.nz + s rm -fv /etc/apache2/sites-enabled/l2.b8.nz{,-redir}.conf + ser reload apache2 + s lnf -T /etc/letsencrypt/live/l2.b8.nz/fullchain.pem /etc/exim4/exim.crt + if [[ ! -L /etc/exim4/exim.key ]]; then + s lnf -T /etc/letsencrypt/live/l2.b8.nz/privkey.pem /etc/exim4/exim.key + mail-setup + fi end ;; li) case $HOSTNAME in - li) domain=iankelling.org ;; + li) + m /a/h/setup.sh iankelling.org + ;; + *) + # allow symlinks on other hosts so i can host files in arbitrary paths + m /a/h/setup.sh -s + ;; esac - m /a/h/setup.sh $domain m /a/h/build.rb # start mumble only when im going to use it, since i dont use it much @@ -553,20 +568,8 @@ EOF s useradd --create-home -d /var/lib/znc --system --shell /sbin/nologin --comment "Account to run ZNC daemon" --user-group znc || [[ $? == 9 ]] # 9 if it exists already s chmod 700 /var/lib/znc s chown -R znc:znc /var/lib/znc - sd /etc/systemd/system/znc.service 2>/dev/null <<'EOF' -[Unit] -Description=ZNC, an advanced IRC bouncer -After=network-online.target - -[Service] -ExecStart=/usr/bin/znc -f --datadir=/var/lib/znc -User=znc - -[Install] -WantedBy=multi-user.target -EOF - ser daemon-reload - # avoid restarting if possible, reconnecting to irc is annoying. + # Avoid restarting if possible, reconnecting to irc is annoying. + # The unit file was made active with conflink. if [[ $(ser is-active znc) != active ]]; then m sgo znc fi @@ -1029,6 +1032,15 @@ pi anki ####### begin transmission +case $HOSTNAME in + frodo) + tdir=/i/k + ;; + *) + tdir=/nocow/user + ;; +esac + # adapted from /var/lib/dpkg/info/transmission-daemon.postinst # 450 seems likely to be unused. we need to specify one or else # it won't be stable across installs. @@ -1073,12 +1085,12 @@ ser stop transmission-daemon # plus a simple symlink to the config file which it\'s # not worth separating out. # between comps, the uid can change -f=/i/transmission-daemon +f=$tdir/transmission-daemon +mkdir -p $f s lnf -T $f /var/lib/transmission-daemon/.config/transmission-daemon -if [[ -e $f ]]; then - s chown -R debian-transmission:debian-transmission $f -fi -for f in /i/k/partial-torrents /i/k/torrents; do +s lnf -T /etc/transmission-daemon/settings.json $f/settings.json +s chown -R debian-transmission:debian-transmission $f +for f in $tdir/partial-torrents $tdir/torrents; do if [[ -e $f ]]; then s chown -R debian-transmission:user2 $f fi @@ -1095,16 +1107,15 @@ s chown -R debian-transmission:debian-transmission /var/lib/transmission-daemon # # Changed the cache-size to 256 mb, reduces disk use. # It is a read & write cache. -# -s ruby <<'EOF' +s ruby < false, 'rpc-authentication-required' => false, -'incomplete-dir' => '/i/k/partial-torrents', +'incomplete-dir' => '$tdir/partial-torrents', 'incomplete-dir-enabled' => true, -'download-dir' => '/i/k/torrents', +'download-dir' => '$tdir/torrents', "speed-limit-up" => 800, "speed-limit-up-enabled" => true, "peer-port" => 61486, @@ -1188,9 +1199,10 @@ EOF s -u $u dd of=$d/config.json <&2' ERR - -if [[ $EUID != 1000 ]]; then - echo "$0: error run as normal user" >&2 - exit 1 -fi - -cd /m/md/l/testignore/new -shopt -s nullglob - -# we run this cronjob along with sending the test email every 10 -# minutes, so give it 2 minutes to arrive, then if there is an email at -# least 23 minutes old, the last 2 test emails have failed. -if [[ ! $1 && $- != *i* ]]; then - sleep 120 -fi - -last_sec=0 -for file in *; do - if [[ $file -nt $latest ]]; then - latest=$file - fi -done - -if [[ $latest ]]; then - last_sec=$(awk '/^Subject: / {print $3}' $latest) -fi - -now=$(date +%s) -limit=$(( now - 60 * 23 )) - -if (( last_sec <= limit )); then - echo $HOSTNAME mailtest failure - touch /nocow/user/mailtest-failure -else - rm -f /nocow/user/mailtest-failure -fi - -find . -type f -mtime +1 -delete diff --git a/filesystem/usr/local/bin/mycheckrestart b/filesystem/usr/local/bin/mycheckrestart index eec8584..1d4bdaa 100755 --- a/filesystem/usr/local/bin/mycheckrestart +++ b/filesystem/usr/local/bin/mycheckrestart @@ -17,6 +17,4 @@ fi cmd="$s /usr/sbin/checkrestart -p" if [[ $($cmd | sed '/^Found 0 processes using old versions of upgraded files$/d' | wc -l) != 0 ]]; then $cmd - echo "with -v:" - $cmd -v fi diff --git a/filesystem/usr/local/bin/myupgrade b/filesystem/usr/local/bin/myupgrade index e762246..eedc62d 100755 --- a/filesystem/usr/local/bin/myupgrade +++ b/filesystem/usr/local/bin/myupgrade @@ -17,17 +17,31 @@ fi hn=$(hostname -f) source /a/bin/bash_unpublished/source-state -if [[ $HOSTNAME == "$MAIL_HOST" || $hn == li.b8.nz ]]; then - exit 0 -fi l() { "$@" |& systemd-cat -t myupgrade } -l /a/bin/buildscripts/tor-browser -l /a/bin/buildscripts/go l /a/bin/buildscripts/rust -l /a/bin/buildscripts/misc + +has_x=false +for pkg in xorg wayland; do + if dpkg -s -- $x |& grep -Fx "Status: install ok installed" &> /dev/null; then + has_x=true + break + fi +done + +if $has_x; then + l /a/bin/buildscripts/tor-browser + l /a/bin/buildscripts/misc +fi + + +source /a/bin/distro-setup/path-add-function +export GOPATH=$HOME/go +path-add $GOPATH/bin +path-add /usr/local/go/bin +l /a/bin/buildscripts/go l go get -u mvdan.cc/fdroidcl cmd="sudo /usr/sbin/checkrestart -p" @@ -35,19 +49,24 @@ if [[ $($cmd | sed '/^Found 0 processes using old versions of upgraded files$/d' $cmd -v | pee cat "wall -n" fi +# no automatic reboot for these hosts +if [[ $HOSTNAME == "$MAIL_HOST" || $hn == li.b8.nz ]]; then + exit 0 +fi + if [[ -s /var/log/checkrestart.log ]]; then for x in {30..1}; do - echo "pid $PID. unattended upgrade, rebooting in $((x*10)) seconds" | wall -n + echo "pid $PID. unattended upgrade, rebooting in $((x*10)) seconds" | sudo wall -n sleep 10 done for x in {30..1}; do if ! fuser /var/lib/dpkg/lock &> /dev/null; then - echo "pid $PID. unattended upgrade, rebooting now" | pee cat "wall -n" + echo "pid $PID. unattended upgrade, rebooting now" | pee cat "sudo wall -n" sudo /sbin/reboot exit 0 fi - echo "pid $PID. unattended upgrade reboot waiting 10 seconds for dpkg lock" | wall -n + echo "pid $PID. unattended upgrade reboot waiting 10 seconds for dpkg lock" | sudo wall -n sleep 10 done - echo "pid $PID. dpkg locked for 5 minutes, automatic reboot failed" | pee cat "wall -n" + echo "pid $PID. dpkg locked for 5 minutes, automatic reboot failed" | pee cat "sudo wall -n" fi diff --git a/fsf-vpn-dns-cleanup b/fsf-vpn-dns-cleanup index cf3420b..be7fb58 100755 --- a/fsf-vpn-dns-cleanup +++ b/fsf-vpn-dns-cleanup @@ -5,6 +5,7 @@ trap 'echo "$0:$LINENO:error: \"$BASH_COMMAND\" returned $?" >&2' ERR if ! echo | /a/exe/cedit fsf /etc/dnsmasq-servers.conf; then if systemctl is-active dnsmasq >/dev/null; then + nscd -i hosts systemctl reload dnsmasq fi fi diff --git a/gitslink b/gitslink index 1352ecd..99ef892 100755 --- a/gitslink +++ b/gitslink @@ -8,31 +8,41 @@ lnf() { /a/bin/lnf/lnf "$@"; } shopt -s nullglob shopt -s extglob +cd /a/exe +declare -A existing +for f in *; do + existing[$f]=t +done cd /a/bin -# if we didn't have just automated files, we could cleanup -# links to not executable files. -e rm -rf /a/exe # sourcing instead of calling script changes runtime from .47s to .36s source /a/bin/lnf/lnf >/dev/null ||: -for x in !(unused|unfinished|queue|bash-template|buildscripts|crons|data|examples|log-quiet); do - [[ -e $x/.git ]] || continue - for y in $x/*; do - if [[ -x $y && ! -d $y ]]; then - lnf -v /a/bin/$y /a/exe - fi - done +for x in !(unused|distro-setup|unfinished|queue|bash-template|buildscripts|crons|data|examples|log-quiet); do + [[ -e $x/.git ]] || continue + for y in $x/*; do + f=${y##*/} + if [[ -x $y && ! -d $y ]]; then + unset "existing[$f]" + lnf -v /a/bin/$y /a/exe + fi + done done - for x in *; do - if [[ ! -d $x && -x $x ]]; then - lnf -v /a/bin/$x /a/exe - fi + if [[ ! -d $x && -x $x ]]; then + unset "existing[$x]" + lnf -v /a/bin/$x /a/exe + fi done +cd /a/exe +for f in ${!existing[@]}; do + echo want to do rm -fv $f +done + + + # things we don't want to run in /a, because # they are long running and could get in the way of # btrfs remounting -/a/bin/distro-setup/install-my-scripts -/a/bin/log-quiet/setup +e /a/bin/distro-setup/install-my-scripts diff --git a/install-my-scripts b/install-my-scripts index 63084ee..6a763ef 100755 --- a/install-my-scripts +++ b/install-my-scripts @@ -35,5 +35,5 @@ x="$(readlink -f -- "${BASH_SOURCE[0]}")"; cd ${x%/*} # directory of this file # ran. Very strange, dunno why, but rsync won't do anything unless these # changed, so that should fix it. rsync -t --chmod=755 --chown=root:root /a/bin/log-quiet/log-once switch-mail-host btrbk-run mount-latest-subvol \ - check-subvol-stale /usr/local/bin + check-subvol-stale system-status /usr/local/bin rsync -t --chmod=755 --chown=root:root /a/bin/errhandle/err /usr/local/lib diff --git a/machine_specific/li/filesystem/etc/systemd/system/znc.service b/machine_specific/li/filesystem/etc/systemd/system/znc.service new file mode 100644 index 0000000..31c2a4a --- /dev/null +++ b/machine_specific/li/filesystem/etc/systemd/system/znc.service @@ -0,0 +1,10 @@ +[Unit] +Description=ZNC, an advanced IRC bouncer +After=network-online.target + +[Service] +ExecStart=/usr/bin/znc -f --datadir=/var/lib/znc +User=znc + +[Install] +WantedBy=multi-user.target diff --git a/mail-setup b/mail-setup index ee8482d..68478be 100755 --- a/mail-setup +++ b/mail-setup @@ -11,9 +11,7 @@ m() { printf "$pre %s\n" "$*"; "$@"; } e() { printf "$pre %s\n" "$*"; } err() { echo "[$(date +'%Y-%m-%d %H:%M:%S%z')]: $0: $*" >&2; } - -# TODO: copy dkim keys from within this file. its now done in conflink. -# TODO: fix dkim key to b chmod 640, group Debian-exim +shopt -s nullglob if [[ -s /usr/local/lib/err ]]; then source /usr/local/lib/err @@ -37,9 +35,6 @@ usage() { Usage: ${0##*/} Setup exim4 & dovecot & related things -The minimal assumption we have is that /etc/mailpass exists - - -h|--help Print help and exit. EOF exit $1 @@ -55,7 +50,9 @@ EOF # background: ovecot 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, same thing but username alerts, pass in ivy-pass. +# for phone, k9mail, same thing but username alerts, pass in ivy-pass. +# also, l2.b8.nz for secondary alerts +# fetching mail settings: folder poll frequency 10 minutes ####### @@ -64,30 +61,19 @@ EOF # # for hosts which have all private files I just use the same user # # for other hosts, each one get\'s their own password. # # for generating secure pass, and storing for server too: -# # user=USUALLY_SAME_AS_HOSTNAME -# user=li # f=$(mktemp) +# I use $HOSTNAME as username # apg -m 50 -x 70 -n 1 -a 1 -M CLN >$f -# s sed -i "/^$user:/d" /p/c/filesystem/etc/exim4/passwd -# echo "$user:$(mkpasswd -m sha-512 -s <$f)" >>/p/c/filesystem/etc/exim4/passwd -# # todo: port is no longer used in mailpass, remove it. -# echo "mail.iankelling.org 587 $user:$(<$f)" >> /p/c/machine_specific/$user/filesystem/etc/mailpass -# # then run this script, or part of it which uses /etc/mailpass +# s sed -i "/^$HOSTNAME:/d" /p/c/filesystem/etc/exim4/passwd +# echo "$HOSTNAME:$(mkpasswd -m sha-512 -s <$f)" >>/p/c/filesystem/etc/exim4/passwd +# reference: exim4_passwd_client(5) +# echo "mail.iankelling.org:$HOSTNAME:$(<$f)" > /p/c/machine_specific/$HOSTNAME/filesystem/etc/exim4/passwd.client +# # then run this script # # dovecot password, i just need 1 as I\'m the only user # mkdir /p/c/filesystem/etc/dovecot # echo "iank:$(doveadm pw -s ssha256)::::::" >>/p/c/filesystem/etc/dovecot/users -# conflink - - -# # for ad-hoc testing of some random new host sending mail: -# user=li # client host username & hostname -# f=$(mktemp) -# apg -m 50 -x 70 -n 1 -a 1 -M CLN >$f -# s sed -i "/^$user:/d" /etc/exim4/passwd -# echo "$user:$(mkpasswd -m sha-512 -s <$f)" | s tee -a /etc/exim4/passwd -# echo "mail.iankelling.org:$user:$(<$f)" | ssh root@$user dd of=/etc/exim4/passwd.client ####### end perstent password instructions ###### @@ -113,12 +99,7 @@ EOF # # lines 2+: append to hold space # echo "txt record contents:" # echo "v=DKIM1; k=rsa; p=$(sed -n '${x;s/\n//gp};2,$H' $domain.pem)" -# chmod 644 $domain.pem -# chmod 640 $domain-private.pem -# # in conflink, we chown these to group debian -# conflink # # selector was also put into /etc/exim4/conf.d/main/000_local, -# # via the mail-setup scripts # # 2017-02 dmarc policies: # # host -t txt _dmarc.gmail.com @@ -152,7 +133,7 @@ EOF # * functions constants e() { printf "%s\n" "$*"; } -pi() { # package install +pi() { # package install without starting daemons local f if dpkg -s -- "$@" &> /dev/null; then return 0; @@ -162,7 +143,18 @@ pi() { # package install if [[ ! -r $f ]] || (( $(( $(date +%s) - $(stat -c %Y $f ) )) > 60*60*12 )); then m apt-get update fi - DEBIAN_FRONTEND=noninteractive m apt-get -y install --purge --auto-remove "$@" + f=/usr/sbin/policy-rc.d + dd of=$f 2>/dev/null <>$f -done /dev/null; then - m systemctl reload dnsmasq - fi + if systemctl is-active dnsmasq >/dev/null; then + m systemctl reload dnsmasq + m nscd -i hosts + fi - # I used to use debconf-set-selections + dpkg-reconfigure, - # which then updates this file - # but the process is slower than updating it directly and then I want to set other things in - # update-exim4.conf.conf, so there's no point. - # The file is documented in man update-exim4.conf, - # except the man page is not perfect, read the bash script to be sure about things. + # I used to use debconf-set-selections + dpkg-reconfigure, + # which then updates this file + # but the process is slower than updating it directly and then I want to set other things in + # update-exim4.conf.conf, so there's no point. + # The file is documented in man update-exim4.conf, + # except the man page is not perfect, read the bash script to be sure about things. - # The debconf questions output is additional documentation that is not - # easily accessible, but super long, along with the initial default comment in this - # file, so I've saved that into ./mail-notes.conf. + # The debconf questions output is additional documentation that is not + # easily accessible, but super long, along with the initial default comment in this + # file, so I've saved that into ./mail-notes.conf. - cat >>/etc/exim4/update-exim4.conf.conf <>/etc/exim4/update-exim4.conf.conf < /etc/mailname + echo mail.iankelling.org > /etc/mailname - # MAIN_HARDCODE_PRIMARY_HOSTNAME might mess up the - # smarthost config type, not sure. all other settings - # would be unused in that config type. - cat >>/etc/exim4/conf.d/main/000_local <>/etc/exim4/conf.d/main/000_local <$f <<'EOF' + f=/etc/cron.daily/refresh-dmarc-tld-file + cat >$f <<'EOF' #!/bin/bash cd /etc wget -q -N https://publicsuffix.org/list/public_suffix_list.dat EOF - m chmod 755 $f + m chmod 755 $f - sed -i --follow-symlinks -f - /etc/aliases <$d/override.conf <<'EOF' + # https://selivan.github.io/2017/12/30/systemd-serice-always-restart.html + d=/etc/systemd/system/openvpn@mail.service.d + m mkdir -p $d + cat >$d/override.conf <<'EOF' [Service] Restart=always # time to sleep before restarting a service @@ -767,63 +786,93 @@ RestartSec=1 # StartLimitIntervalSec in recent systemd versions StartLimitInterval=0 EOF - if ! systemctl cat openvpn@mail.service|grep -xF StartLimitInterval=0 &>/dev/null; then - # needed for the above config to go into effect - m systemctl daemon-reexec - fi - + if ! systemctl cat openvpn@mail.service|grep -xF StartLimitInterval=0 &>/dev/null; then + # needed for the above config to go into effect + m systemctl daemon-reexec + fi - 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 + 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 - # remove mail. 2 lines to properly remove whitespace - sed -ri -f - /etc/hosts <<'EOF' + *) # $HOSTNAME != $MAIL_HOST + # remove mail. 2 lines to properly remove whitespace + sed -ri -f - /etc/hosts <<'EOF' s#^(127\.0\.1\.1 .*) +mail\.iankelling\.org$#\1# s#^(127\.0\.1\.1 .*)mail\.iankelling\.org +(.*)#\1\2# EOF - echo | /a/exe/cedit mail /etc/dnsmasq-servers.conf || [[ $? == 1 ]] - if systemctl is-active dnsmasq >/dev/null; then - m systemctl reload dnsmasq - fi + echo | /a/exe/cedit mail /etc/dnsmasq-servers.conf || [[ $? == 1 ]] + if systemctl is-active dnsmasq >/dev/null; then + m nscd -i hosts + m systemctl reload dnsmasq + fi - 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 -fv /etc/exim4/conf.d/main/000_localmacros - cat >>/etc/exim4/update-exim4.conf.conf </dev/null ||: + m systemctl stop mailclean.timer &>/dev/null ||: + m systemctl disable $vpn_ser@mail + m systemctl stop $vpn_ser@mail + # + # + # would only exist because I wrote it i the previous condition, + # it\'s not part of exim + rm -fv /etc/exim4/conf.d/main/000_localmacros + cat >>/etc/exim4/update-exim4.conf.conf </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. - sed -i --follow-symlinks -f - /etc/aliases <>/etc/exim4/update-exim4.conf.conf <>/etc/exim4/update-exim4.conf.conf <$f <<'EOFOUTER' -#!/bin/bash -/usr/sbin/exim -t </etc/cron.d/mailtest </etc/cron.d/mailtest <>/etc/cron.d/mailtest </usr/local/bin/send-test-forward </dev/null; then - if [[ $HOSTNAME == "$MAIL_HOST" ]]; then - m systemctl restart radicale - m systemctl enable radicale - if [[ -e /etc/logrotate.d/radicale.disabled ]]; then - m mv /etc/logrotate.d/radicale{.disabled,} - fi - else - 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 - m mv /etc/logrotate.d/radicale{,.disabled} - fi - fi -fi # * misc m sudo -u $u ln -sf -T /m/.mu /home/$u/.mu diff --git a/mailtest-check b/mailtest-check new file mode 100755 index 0000000..91cf8cd --- /dev/null +++ b/mailtest-check @@ -0,0 +1,49 @@ +#!/bin/bash +set -eE -o pipefail +trap 'echo "$0:$LINENO:error: \"$BASH_COMMAND\" returned $?" >&2' ERR + +if [[ $EUID != 1000 ]]; then + echo "$0: error run as normal user" >&2 + exit 1 +fi + +shopt -s nullglob + + +# We run this cronjob along with sending the test email every 5 minutes, +# so give it 1 minute to arrive, then if the latest email is older than +# 7 minutes, the last 2 haven't arrived in a reasonable amount of time. +min_limit=7 + +if [[ ! $1 && $- != *i* ]]; then + sleep 60 +fi + + +folders=(/m/md/l/testignore{,2}/new) +find ${folders[@]} -type f -mtime +1 -delete + +for folder in ${folders[@]}; do + cd $folder + last_sec=0 + for file in *; do + if [[ $file -nt $latest ]]; then + latest=$file + fi + done + + if [[ $latest ]]; then + last_sec=$(awk '/^Subject: / {print $3}' $latest) + fi + + now=$(date +%s) + limit=$(( now - 60 * min_limit )) + + if (( last_sec <= limit )); then + echo $HOSTNAME mailtest failure + touch /nocow/user/mailtest-failure + break + else + rm -f /nocow/user/mailtest-failure + fi +done diff --git a/mount-latest-subvol b/mount-latest-subvol index f9bc2de..026f490 100644 --- a/mount-latest-subvol +++ b/mount-latest-subvol @@ -242,7 +242,7 @@ for vol in q a o i; do if m umount -R $dir; then unmounted+=($dir) else - if ! kill-dir TERM TERM TERM INT INT HUP HUP; then + if ! kill-dir TERM TERM TERM INT INT HUP HUP TERM TERM TERM INT INT HUP HUP; then if $force; then kill-dir KILL; fi fi diff --git a/primary-setup b/primary-setup index cc335d1..df30f29 100755 --- a/primary-setup +++ b/primary-setup @@ -18,6 +18,9 @@ fi if [[ $1 ]]; then new_host=$1 + if [[ $new_host == localhost ]]; then + new_host=$HOSTNAME + fi m sed -ri "s/MAIL_HOST=.*/MAIL_HOST=$new_host/" /a/bin/bash_unpublished/source-state source /a/bin/bash_unpublished/source-state fi @@ -44,6 +47,23 @@ else # done fi +if dpkg -s radicale &>/dev/null; then + if [[ $HOSTNAME == "$MAIL_HOST" ]]; then + m sudo systemctl restart radicale + m sudo systemctl enable radicale + if [[ -e /etc/logrotate.d/radicale.disabled ]]; then + m sudo mv /etc/logrotate.d/radicale{.disabled,} + fi + else + m sudo systemctl stop radicale + m sudo 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 + m sudo mv /etc/logrotate.d/radicale{,.disabled} + fi + fi +fi + m /a/exe/mail-setup exit 0 : diff --git a/subdir_files/.gnupg/gpg.conf b/subdir_files/.gnupg/gpg.conf index 7ab724c..21955c4 100644 --- a/subdir_files/.gnupg/gpg.conf +++ b/subdir_files/.gnupg/gpg.conf @@ -46,6 +46,7 @@ default-key B125F60B7B287FF6A2B7DF8F170AF0E2954295DF keyserver hkp://keys.gnupg.net #keyserver hkp://keyserver.ubuntu.com #keyserver hkp://keyring.debian.org +keyserver keyserver.ubuntu.com # more secure hkps, but had problems with my gpg version #keyserver hkps://hkps.pool.sks-keyservers.net diff --git a/subdir_files/sieve/lists.sieve b/subdir_files/sieve/lists.sieve index 4fa0016..54f617f 100644 --- a/subdir_files/sieve/lists.sieve +++ b/subdir_files/sieve/lists.sieve @@ -100,6 +100,7 @@ if anyof ( header :contains "list-id" "", header :contains "list-id" "", header :contains "list-id" "", + header :contains "list-id" "", header :contains "list-id" "", header :contains "list-id" "", header :contains "from" "", diff --git a/subdir_files/sieve/liststest.sieve b/subdir_files/sieve/liststest.sieve index 4fa0016..54f617f 100644 --- a/subdir_files/sieve/liststest.sieve +++ b/subdir_files/sieve/liststest.sieve @@ -100,6 +100,7 @@ if anyof ( header :contains "list-id" "", header :contains "list-id" "", header :contains "list-id" "", + header :contains "list-id" "", header :contains "list-id" "", header :contains "list-id" "", header :contains "from" "", diff --git a/switch-mail-host b/switch-mail-host index 11c0f40..a0c590d 100755 --- a/switch-mail-host +++ b/switch-mail-host @@ -4,7 +4,7 @@ source /usr/local/lib/err usage() { cat <&2; } ##### begin command line parsing ######## @@ -55,8 +57,28 @@ done (( $# == 2 )) || usage 1 -old_host=$1 -new_host=$2 + +case $1 in + push) + new_host=$2 + bbk_args="-s $old_host" + new_shell="ssh $new_host" + old_host=$HOSTNAME + ;; + pull) + old_host=$2 + bbk_args="-t $new_host" + bbk_args="-s $old_host" + new_host=$HOSTNAME + old_shell="ssh $old_host" + ;; + *) + err invalid first argument + exit 1 + ;; +esac + + source /a/bin/bash_unpublished/source-state if [[ $old_host != "$MAIL_HOST" ]]; then @@ -66,19 +88,6 @@ if [[ $old_host != "$MAIL_HOST" ]]; then fi fi -if [[ $new_host == "$HOSTNAME" ]]; then - localhost_new=true - new_shell= -else - localhost_new=false - new_shell="ssh $new_host" -fi - -old_shell="ssh $old_host" -if [[ $old_host == "$HOSTNAME" ]]; then - old_shell= -fi - if [[ ! $new_host || ! $old_host ]]; then echo "$0: bad args. see script" exit 1 @@ -91,10 +100,12 @@ new_hostname=$($new_shell hostname) if $new_shell systemctl is-active btrbk.timer; then m $new_shell sudo systemctl stop btrbk.timer + _errcatch_cleanup=cleanup restore_new_btrbk=true fi if $old_shell systemctl is-active btrbk.timer; then m $old_shell sudo systemctl stop btrbk.timer + _errcatch_cleanup=cleanup restore_old_btrbk=true fi @@ -138,12 +149,16 @@ EOF # I think exim will try ipv6 first, so no need to disable # ipv6 i think. + + m $old_shell /a/exe/primary-setup $new_hostname -if $localhost_new; then - m btrbk-run -v -s $old_host $mp_args -else - m btrbk-run -v -t $new_host $mp_args +if ! m btrbk-run -v $bbk_args $mp_args; then + ret=$? + bang="$(printf "$(tput setaf 5)█$(tput sgr0)%.0s" 1 2 3 4 5 6 7)" + e $bang failed btrbk. restoring old host as primary + m $old_shell /a/exe/primary-setup localhost + exit $ret fi -m $new_shell /a/exe/primary-setup $new_hostname +m $new_shell /a/exe/primary-setup localhost diff --git a/switch-primary-host b/switch-primary-host deleted file mode 100755 index 7be327e..0000000 --- a/switch-primary-host +++ /dev/null @@ -1,49 +0,0 @@ -#!/bin/bash - -# this pulls from host $1 to the current host. -# not currently used, but it might be useful at some point - -source /a/bin/errhandle/err - -cd / - -old=$1 -new=$HOSTNAME - -if [[ ! $old ]]; then - echo "$0: error: no \$1 given, should be old host" - exit 1 -fi - -if ! timeout -s 9 2 ssh $old : ; then - echo "$0: error: can't ssh to $old" -fi - -for p in emacs firefox pidgin; do - ssh $old killall $p ||: -done - -# note: duplicated in check-subvol-stale -last_a=$( - vol=a - for s in /mnt/root/btrbk/$vol.*; do - f=${s##*/} - unix_time=$(date -d $(sed -r 's/(.{4})(..)(.{5})(..)(.*)/\1-\2-\3:\4:\5/' <<<${f#$vol.}) +%s) - printf "%s\n" $unix_time - done | sort -r | head -n 1 - ) - -if [[ $last_a != [0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9] ]]; then - echo "$0: error: last_a bad value: $last_a" - exit 1 -fi - -# if last_a is recent enough, skip doing btrbk -if (( last_a < $(date +%s) - 60*60 )); then - if ! ssh $old btrbk-run -pvt $new; then - echo "$0: error: failed btrbk-run" - exit 1 - fi -fi - -switch-mail-host $old $new diff --git a/system-status b/system-status old mode 100755 new mode 100644 index 12621cc..747e2a6 --- a/system-status +++ b/system-status @@ -31,6 +31,10 @@ write-status() { if [[ -e ${glob[0]} ]]; then chars+=("STALE!") fi + if [[ $(find /var/mail -type f \! -empty -print -quit) ]]; then + var_mail_msg="message in /var/mail" + fi + lo -1 var_mail $var_mail_msg glob=(/m/md/bounces/new/*) if [[ -e ${glob[0]} ]]; then chars+=("BOUNCE!") @@ -50,17 +54,24 @@ write-status() { qlen=$(sudo /usr/sbin/exiqgrep -o 60 -c -b | awk '{print $1}') fi if ((qlen)); then + qmsg="queue length $qlen" chars+=("q $qlen") fi + case $HOSTNAME in + # No point in emailing about the mailq on a host where we don't + # check email. + $MAIL_HOST|l2) + lo -1 qlen $qmsg + ;; + esac begin=false - cd /b/ds - if ! make -q ~/.local/distro-begin || [[ $(<~/.local/distro-begin) != 0 ]]; then + if ! make -C /b/ds -q ~/.local/distro-begin || [[ $(<~/.local/distro-begin) != 0 ]]; then begin=true fi end=false - if ! make -q ~/.local/distro-end || [[ $(<~/.local/distro-end) != 0 ]]; then + if ! make -C /b/ds -q ~/.local/distro-end || [[ $(<~/.local/distro-end) != 0 ]]; then end=true fi @@ -94,9 +105,8 @@ write-status() { done # just because i forget a lot, -mmin -NUM means files modified <= NUM minutes ago - if (( $(date -d "$(git log --diff-filter=ACR --format=%aD -1)" +%s) > fsec )) || \ - [[ $(find ${all_dirs[@]} -mmin $fmin -type f -print -quit 2>/dev/null) ]]; then - v conflink newer git or newer filesystem files + if [[ $(find ${all_dirs[@]} -mmin $fmin -type f -print -quit 2>/dev/null) ]]; then + v conflink newer filesystem files chars+=("CONFLINK!") break fi @@ -107,6 +117,12 @@ write-status() { # some hosts i dont push all of /p/c continue fi + if (( $(date -d "$(git log --diff-filter=ACR --format=%aD -1)" +%s) > fsec )); then + v conflink: newer files checked in to git + chars+=("CONFLINK!") + break + fi + untracked=$(git ls-files -o --exclude-standard) if [[ $untracked && $(find $untracked -mmin $fminplus -type f -print -quit) ]]; then v conflink: untracked in $d @@ -114,6 +130,7 @@ write-status() { break fi done + cd / fi if [[ ! -e $f || $(<$f) != 0 ]]; then @@ -164,7 +181,7 @@ write-status() { # Profiled it using time and also adding to the top of the file: # set -x # PS4='+ $(date "+%2N") ' - snaps=($(ls -1avdr /mnt/root/btrbk/$vol.20*|head -n1)) + snaps=($(ls -1avdr /mnt/root/btrbk/$vol.20*|head -n1 || [[ $? == 141 ]] )) now=$(date +%s) maxtime=0 for s in ${snaps[@]}; do diff --git a/trusted-network b/trusted-network index d227137..220c963 100755 --- a/trusted-network +++ b/trusted-network @@ -8,6 +8,9 @@ trap 'echo "$0:$LINENO:error: \"$BASH_COMMAND\" returned $?" >&2' ERR # Usage: run when switching from an untrusted network like public wifi # to a trusted one. -rm -f /etc/dnsmasq.d/untrusted-network.conf +if [[ -e /etc/dnsmasq.d/untrusted-network.conf ]]; then + rm -f /etc/dnsmasq.d/untrusted-network.conf -systemctl reload dnsmasq + nscd -i hosts + systemctl reload dnsmasq +fi diff --git a/untrusted-network b/untrusted-network index 3d8ac97..9cbf4ab 100755 --- a/untrusted-network +++ b/untrusted-network @@ -8,7 +8,8 @@ trap 'echo "$0:$LINENO:error: \"$BASH_COMMAND\" returned $?" >&2' ERR # Usage: use when switching from a trusted network to an untrusted one, # like public wifi. -cat >/etc/dnsmasq.d/untrusted-network.conf <<'EOF' +if [[ ! -s /etc/dnsmasq.d/untrusted-network.conf ]]; then + cat >/etc/dnsmasq.d/untrusted-network.conf <<'EOF' server=8.8.4.4 server=8.8.8.8 server=2001:4860:4860::8844 @@ -18,4 +19,6 @@ no-resolv stop-dns-rebind EOF -systemctl reload dnsmasq + nscd -i hosts + systemctl reload dnsmasq +fi -- 2.30.2