X-Git-Url: https://iankelling.org/git/?a=blobdiff_plain;f=mailtest-check;h=036aeff1a2faf981367d7ff69f9ebb98cff26a58;hb=97c57fc9d533818c47b97e9b46e20a1530eac54c;hp=e28d5ae966750233f5778c20c26a7c1d58be54a6;hpb=da085f71e5ae00a9f78ed903be6ae675f66eacfa;p=distro-setup diff --git a/mailtest-check b/mailtest-check index e28d5ae..036aeff 100755 --- a/mailtest-check +++ b/mailtest-check @@ -29,7 +29,7 @@ getspamdpid() { fi } pr() { - if [[ -e /var/lib/prometheus/node-exporter ]]; then + if $doprom && [[ -e /var/lib/prometheus/node-exporter ]]; then cat >>/var/lib/prometheus/node-exporter/mailtest-check.prom.$$ fi } @@ -57,16 +57,27 @@ if [[ $1 == nonint ]]; then fi #### end arg processing #### - -if ! $int; then - sleep 60 -fi +# we put this in to avoid dns errors that happen on reboot, +# but I want to debug them. +# if ! $int; then +# sleep 60 +# fi # TODO, get je to deliver the local mailbox: /m/md/INBOX # dovecot appears to setup, i can t be sure. +source /a/bin/bash_unpublished/source-state +doprom=false +case $HOSTNAME in + $MAIL_HOST|bk|je) + doprom=true + ;; + *) + rm -f /var/lib/prometheus/node-exporter/mailtest-check.prom* + ;; +esac main() { @@ -76,14 +87,39 @@ main() { froms=(ian@iankelling.org z@zroe.org testignore@je.b8.nz iank@gnu.org) ;; je) - froms=(ian@iankelling.org z@zroe.org testignore@expertpathologyreview.com testignore@amnimal.ninja) + froms=(ian@iankelling.org z@zroe.org iank@gnu.org testignore@amnimal.ninja) folders=(/m/md/je.b8.nz/testignore) ;; *) folders=(/m/md/l/testignore) froms=(testignore@je.b8.nz testignore@expertpathologyreview.com testignore@amnimal.ninja ian@iankelling.org z@zroe.org iank@gnu.org) if ! $int; then - timeout 120 rsync --chown iank:iank -e "ssh -oIdentitiesOnly=yes -F /dev/null -i /root/.ssh/jtuttle" -t --inplace -r 'jtuttle@fencepost.gnu.org:/home/j/jtuttle/Maildir/new/' /m/md/l/testignore/new + ### begin rsyncing fencepost email ### + # We dont want to exit if rsync fails, that will get caught by + # our later test by virtue of not having the latest email. + did_rsync=false + try_start_time=$EPOCHSECONDS + try_limit=140 # somewhat arbitrary value + while ! $did_rsync; do + try_left=$(( try_limit - ( EPOCHSECONDS - try_start_time) )) + timeout=120 # somewhat arbitrary value + if (( try_left < 0 )); then + echo "mailtest-check: failed to rsync fencepost > $try_limit seconds" + break + fi + if (( try_left < timeout )); then + timeout=$try_left + fi + if timeout $timeout rsync --chown iank:iank -e "ssh -oIdentitiesOnly=yes -F /dev/null -i /root/.ssh/jtuttle" -t --inplace -r 'jtuttle@fencepost.gnu.org:/home/j/jtuttle/Maildir/new/' /m/md/l/testignore/new; then + did_rsync=true + else + sleep 4 + fi + done + if ! $did_rsync; then + echo mailtest-check: warning: fencepost rsync failed + fi + ### end rsyncing fencepost email ### fi ;; esac @@ -112,6 +148,9 @@ EOF declare -i unexpected=0 for folder in ${folders[@]}; do for from in ${froms[@]}; do + declare -i missing_dnswl=0 + declare -i dnsfail=0 + declare -i unexpected=0 latest= last_sec=0 @@ -121,13 +160,15 @@ EOF fi # webmail sends them to cur it seems while read -r file; do - if [[ $file -nt $latest ]]; then + file_sec=$(awk '/^Subject: / {print $4}' $file) + if [[ $file_sec ]] && (( file_sec > last_sec )); then latest=$file + last_sec="$file_sec" fi done <$tmpfile + rm -f $tmpfile to=$(awk '/^Envelope-to: / {print $2}' $latest) - last_sec=$(awk '/^Subject: / {print $4}' $latest) if $slow; then if ! $int; then @@ -138,13 +179,18 @@ EOF if [[ $(readlink /proc/$$/ns/net) != "$(readlink /proc/$spamdpid/ns/net)" ]]; then spamcpre="nsenter -t $spamdpid -n -m" fi - + unset results declare -A results # pyzor fails for our test message, so dont put useless load on their # servers. # example line that sed is parsing: # (-0.1 / 5.0 requ) DKIM_SIGNED=0.1,DKIM_VALID=-0.1,DKIM_VALID_AU=-0.1,SPF_HELO_PASS=-0.001,SPF_PASS=-0.001,TVD_SPACE_RATIO=0.001 autolearn=_AUTOLEARN - raw_results="$($spamcpre sudo -u Debian-exim spamassassin -t --cf='score PYZOR_CHECK 0' <"$latest" | tail -n2 | head -n1 | sed -r 's/^\([^)]*\) *//;s/=[^, ]*([, ]|$)/ /g')" + resultfile=$(mktemp) + $spamcpre sudo -u Debian-exim spamassassin -D -t --cf='score PYZOR_CHECK 0' <"$latest" &>$resultfile + + # note: on some mail, its 1 line after the send-test-forward, on others its 2 with a blank inbetween. + # I use the sed -n to filter this. + raw_results="$(tail $resultfile | grep -A2 -Fx /usr/local/bin/send-test-forward | tail -n+2 | sed -nr 's/^\([^)]*\) *//;s/=[^, ]*([, ]|$)/ /gp')" for r in $raw_results; do case $r in # got this in an update 2022-01. dun care @@ -173,8 +219,8 @@ EOF # eggs has RCVD_IN_DNSWL_MED keys+=(RCVD_IN_DNSWL_MED) elif [[ $from == *@gnu.org ]]; then - # eggs has these - keys+=(RCVD_IN_DNSWL_MED DKIMWL_WL_HIGH) + # eggs has this. it used to have DKIMWL_WL_HIGH sometime in 2022 + keys+=(RCVD_IN_DNSWL_MED) fi for t in ${keys[@]}; do @@ -195,7 +241,7 @@ EOF fi done if (( ${#results[@]} || ${#missing[@]} )); then - printf "$HOSTNAME spamtest %s/%s\n" "$latest" + printf "$HOSTNAME spamtest %s\n" "$latest" if (( ${#results[@]} )); then printf "unexpected %s" "${!results[*]} " fi @@ -203,14 +249,52 @@ EOF printf "missing %s" "${missing[*]}" fi echo # ends our printf string buildup - + cat $resultfile + echo mailtest-check: end of spam debug results + # lets just handle 1 failure at a time in interactive mode. if $int; then - echo mailtest-check: cat $latest: - cat $latest - echo mailtest-check: end of cat - echo "$(tput setaf 5 2>/dev/null ||:)█$(tput sgr0 2>/dev/null||:)%.0s" $(eval echo "{1..${COLUMNS:-60}}") + echo mailtest-check: from: $from, to: $to + exit 0 fi + + # less verbose debug output, commented since I might want it another time. + # if $int; then + # echo mailtest-check: cat $latest: + # cat $latest + # echo mailtest-check: end of cat + # echo "$(tput setaf 5 2>/dev/null ||:)█$(tput sgr0 2>/dev/null||:)%.0s" $(eval echo "{1..${COLUMNS:-60}}") + #fi fi + rm -f $resultfile + for r in ${results[@]}; do + case $r in + # iank: for when we want to handle dns errors differently + # DKIM_INVALID|T_SPF_TEMPERROR|T_SPF_HELO_TEMPERROR) + # dnsfail+=1 + # ;; + *) + unexpected=$(( unexpected + 1 )) + ;; + esac + done + for miss in ${missing[@]}; do + # We expect dns failures from time to time, so + # we count them separately and alert differently. + case $miss in + # iank: dns fail + # DKIM_VALID|DKIM_VALID_AU|DKIM_VALID_EF|SPF_HELO_PASS|SPF_PASS| + RCVD_IN_DNSWL_MED|DKIMWL_WL_HIGH) + missing_dnswl+=1 + ;; + *) + unexpected+=1 + ;; + esac + done + pr <