From 19a6358fe743ee28411d0474ca6b66b0c542ed0c Mon Sep 17 00:00:00 2001 From: Ian Kelling Date: Mon, 5 Oct 2020 15:49:45 -0400 Subject: [PATCH] lots of improvements --- .bashrc | 1 - .inputrc | 4 - aresolv.conf | 1 + brc | 102 ++- brc2 | 17 +- btrbk-run | 3 +- certbot-renew-hook | 33 +- check-stale-alerts | 13 +- distro-begin | 139 ++-- distro-end | 63 +- .../check-lets-encrypt-ssl-settings | 8 +- filesystem/etc/cups/client.conf | 2 +- .../systemd/system/openvpn-client-nn@.service | 4 +- .../etc/systemd/system/openvpn-nn@.service | 3 +- i3-sway/common.conf | 3 +- .../vps/filesystem/etc/bind/named.conf.local | 10 + mail-route | 7 +- mail-setup | 726 ++++++++++++++---- pkgs | 2 + subdir_files/.config/i3/config | 2 +- subdir_files/.config/mpv/mpv.conf | 2 +- subdir_files/.config/sway/config | 2 +- subdir_files/sieve/main.sieve | 5 +- 23 files changed, 836 insertions(+), 316 deletions(-) create mode 100644 aresolv.conf diff --git a/.bashrc b/.bashrc index 2bb1722..b9c560c 100644 --- a/.bashrc +++ b/.bashrc @@ -31,7 +31,6 @@ HISTCONTROL=ignoredups # but meh. dunno why, but just " *" does glob expansion, so use [ ] to avoid it. HISTIGNORE='pass *:[ ]*:otp *:oathtool *' - #### begin section that works with sl() function to return from #### noninteractive ssh shells if [[ $SSH_CONNECTION ]] \ diff --git a/.inputrc b/.inputrc index 7518b31..c54a4c6 100644 --- a/.inputrc +++ b/.inputrc @@ -97,10 +97,6 @@ Control-Space: set-mark - - - - ####### commented out stuff ########### # vi mode settings and observatoins diff --git a/aresolv.conf b/aresolv.conf new file mode 100644 index 0000000..cae093a --- /dev/null +++ b/aresolv.conf @@ -0,0 +1 @@ +nameserver 8.8.8.8 diff --git a/brc b/brc index 2ce4471..f30cffa 100644 --- a/brc +++ b/brc @@ -201,12 +201,10 @@ export SL_INFO_DIR=/p/sshinfo if [[ -s $bashrc_dir/path-add-function ]]; then source $bashrc_dir/path-add-function if [[ $SSH_CLIENT ]]; then - if [[ -d /home/iank/.iank/e/e ]]; then + # [[ -d /home/iank/.iank/e/e ]] mounts it unnecessarily, so use this. + if grep -qF /home/iank/.iank/e/e /etc/auto.iank /etc/exports &>/dev/null; then export EMACSDIR=/home/iank/.iank/e/e fi - if [[ $EMACSDIR ]]; then - path-add "$EMACSDIR/lib-src" "$EMACSDIR/src" - fi fi fi @@ -241,14 +239,18 @@ fi # * functions -# when testing for completions, uncomment this -# cm() { _completion_loader $1 &>/dev/null ||:; complete -p $1; } -ccomp() { +ccomp() { # copy completion local src=$1 + local c shift - _completion_loader $src &>/dev/null ||: - complete -p $src &>/dev/null || return 0 - eval $(complete -p $src | sed -r "s/ $src($| )/ $*\1/") + if ! c=$(complete -p $src 2>/dev/null); then + _completion_loader $src &>/dev/null ||: + c=$(complete -p $src 2>/dev/null) || return 0 + fi + # remove $src( .*|$) + c=${c% $src} + c=${c%% $src *} + eval $c $* } @@ -258,6 +260,17 @@ ccomp() { .....() { c ../../../..; } ......() { c ../../../../..; } +chere() { + local f path + for f; do + path=$(readlink -e "$f") + echo "cat >$path <<'EOF'" + cat "$f" + echo EOF + done +} + + # file cut copy and paste, like the text buffers :) # I havnt tested these. _fbufferinit() { # internal use @@ -279,9 +292,8 @@ fpst() { # file paste } _khfix_common() { - local host=${1##*@} - local ip port - read -r ip port < <(timeout 1 ssh -oBatchMode=yes -oControlMaster=no -oControlPath=/ -v $1 |& sed -rn "s/debug1: Connecting to $host \[([^\]*)] port ([0-9]+).*/\1 \2/p" || [[ $? == 124 ]]) + local host ip port + read -r host ip port < <(timeout 1 ssh -oBatchMode=yes -oControlMaster=no -oControlPath=/ -v $1 |& sed -rn "s/debug1: Connecting to ([^ ]+) \[([^\]*)] port ([0-9]+).*/\1 \2 \3/p" || [[ $? == 124 ]]) if [[ ! $ip ]]; then echo "khfix: ssh failed" return 1 @@ -293,7 +305,9 @@ _khfix_common() { ip_entry=$ip host_entry=$host fi - ssh-keygen -R "$host_entry" -f $(readlink -f ~/.ssh/known_hosts) + if [[ $host != $ip ]]; then + ssh-keygen -R "$host_entry" -f $(readlink -f ~/.ssh/known_hosts) + fi echo "khfix: removing key for $ip_entry" ssh-keygen -R "$ip_entry" -f $(readlink -f ~/.ssh/known_hosts) } @@ -731,18 +745,44 @@ g() { # todo: patch emacs so it will look elsewhere. this is kinda sad: # https://emacs.stackexchange.com/questions/4253/how-to-start-emacs-with-a-custom-user-emacs-directory - local args + local args gdb=false + + if [[ $EMACSDIR ]]; then + path-add "$EMACSDIR/lib-src" "$EMACSDIR/src" + fi + if [[ $DISPLAY ]]; then args=-n fi - if ! pgrep -u $EUID emacsclient || (( $# == 0 )); then + if (( $# == 0 )); then args+=" -c" fi + # duplicate -c, but oh well + if ! pgrep -u $EUID emacsclient; then + if (( $# == 0 )) && type -p gdb &>/dev/null; then + gdb=true + else + args+=" -c" + fi + fi if [[ $EMACSDIR ]]; then - EHOME=$HOME HOME=$EMACSDIR m emacsclient -a "" $args "$@" + # Alter the path here, otherwise the nfs mount gets triggered on the + # first path lookup when emacs is not being used. + PATH="$EMACSDIR/lib-src:$EMACSDIR/src:$PATH" EHOME=$HOME HOME=$EMACSDIR m emacsclient -a "" $args "$@" else - m emacsclient -a "" $args "$@" + if $gdb; then + # due to a bug, we cant debug from the start unless we get a new gdb + # https://sourceware.org/bugzilla/show_bug.cgi?id=24454 + # m gdb -ex="set follow-fork-mode child" -ex=r -ex=quit --args emacs --daemon + m emacsclient -a "" $args "$@" + sleep 1 + cd /a/opt/emacs-$(distro-name)$(distro-num) + s gdb -p $(pgrep -f 'emacs --daemon') -ex c + cd - + else + m emacsclient -a "" $args "$@" + fi fi } @@ -783,9 +823,12 @@ grr() { # grep recursive } ccomp grep gr grr -rg() { - command rg -i -M 200 "$@" -} +if type -P rg &>/dev/null; then + rg() { command rg -i -M 200 "$@"; } +else + rg() { grr "$@"; } + ccomp grep rg +fi hr() { # horizontal row. used to break up output printf "$(tput setaf 5 2>/dev/null ||:)█$(tput sgr0 2>/dev/null||:)%.0s" $(eval echo "{1..${COLUMNS:-60}}") @@ -1089,7 +1132,14 @@ s() { "$@" fi } -ccomp sudo s +sb() { # sudo bash -c + # use sb instead of s is for sudo redirections, + # eg. sb 'echo "ok fine" > /etc/file' + # shellcheck disable=SC2034 + local SUDOD="$PWD" + sudo -i bash -c "$@" +} +ccomp sudo s sb safe_rename() { # warn and dont rename if file exists. # mv -n exists, but it\'s silent @@ -1107,14 +1157,6 @@ safe_rename() { # warn and dont rename if file exists. } -sb() { # sudo bash -c - # use sb instead of s is for sudo redirections, - # eg. sb 'echo "ok fine" > /etc/file' - # shellcheck disable=SC2034 - local SUDOD="$PWD" - sudo -i bash -c "$@" -} -complete -F _root_command s sb sd() { sudo dd of="$1" 2>/dev/null diff --git a/brc2 b/brc2 index 92f55ec..b9f0c3f 100644 --- a/brc2 +++ b/brc2 @@ -319,7 +319,7 @@ lipush() { # note, i had --delete-excluded, but that deletes all files in --exclude-from on # the remote site, which doesn't make sense, so not sure why i had it. local p a - p=(/a/bin /a/exe /a/h /a/c /p/c/machine_specific/vps{,.hosts} /a/opt/{emacs-debianstable,mu}) + p=(/a/bin /a/exe /a/h /a/c /p/c/machine_specific/vps{,.hosts} /a/opt/{emacs-debian10,mu}) a="-ahviSAXPH --specials --devices --delete --relative --exclude-from=/p/c/li-rsync-excludes" ret=0 m rsync "$@" $a ${p[@]} /p/c/machine_specific/bk root@bk.b8.nz:/ || ret=$? @@ -514,6 +514,11 @@ kdecd() { /usr/lib/x86_64-linux-gnu/libexec/kdeconnectd; } #net.sourceforge.opencamera # fdroid_pkgs=( + net.mullvad.mullvadvpn + org.schabi.newpipe + io.github.subhamtyagi.lastlauncher + io.anuke.mindustry + com.biglybt.android.client de.marmaro.krt.ffupdater me.ccrama.redditslide org.fedorahosted.freeotp @@ -699,9 +704,6 @@ gpg() { gse() { local email=ian@iankelling.org - if readlink ~/.mu | grep fsf &>/dev/null; then - email=iank@fsf.org - fi git send-email --notes "--envelope-sender=<$email>" \ --suppress-cc=self "$@" } @@ -815,18 +817,18 @@ lom() { fi } -# mu personality. for origina, just run mp. for 2, run mp 2. +# mu personality. for original, just run mp. for 2, run mp 2. # this is partly duplicated in mail-setup mp() { killall mu ||: suf=$1 - set -- /m/mucache ~/.cache/mu /m/.mu ~/.mu + set -- /m/mucache ~/.cache/mu /m/.mu ~/.config/mu while (($#)); do target=$1$suf f=$2 shift 2 if [[ -e $f && ! -L $f ]]; then - rm -rf $f + m rm -rf $f fi m ln -sf -T $target $f done @@ -839,7 +841,6 @@ mbenable() { [[ -e $src ]] || { echo "src:$src does not exist"; return 1; } m mv -T $src $dst m ln -s -T $dst $src - m /a/exe/lnf /m/.mu ~ mu index --maildir=/m/4e } mb2enable() { diff --git a/btrbk-run b/btrbk-run index 00052da..ec0e377 100644 --- a/btrbk-run +++ b/btrbk-run @@ -180,7 +180,8 @@ if [[ ! -v targets && ! $source ]]; then targets=($home kw.office.fsf.org) ;; kd) - targets=(frodo x2.b8.nz) + # todo: add frodo when it comes back online + targets=(x2.b8.nz) # might not be connected to the vpn if timeout -s 9 6 ssh kw.office.fsf.org :; then targets+=(kw.office.fsf.org) diff --git a/certbot-renew-hook b/certbot-renew-hook index ba1e68d..120420a 100755 --- a/certbot-renew-hook +++ b/certbot-renew-hook @@ -16,22 +16,17 @@ set -eE -o pipefail trap 'echo "$0:$LINENO:error: \"$BASH_COMMAND\" returned $?" >&2' ERR -domain_user=( - pump.iankelling.org pumpio - mumble.iankelling.org mumble-server -) - -for ((i=0; i<${#domain_user[@]}; i+=2)); do - domain=${domain_user[i]} - user=${domain_user[i+1]} - - d=/etc/letsencrypt/live/$domain - if [[ $RENEWED_LINEAGE == "$d" ]]; then - install -m 640 -g $user $d/{privkey.pem,fullchain.pem} $(eval echo ~$user) - exit 0 - fi -done - -if [[ $RENEWED_LINEAGE == /etc/letsencrypt/live/iankelling.org ]]; then - cat /etc/letsencrypt/live/iankelling.org/{privkey,cert,chain}.pem > /var/lib/znc/znc.pem -fi +dir=$RENEWED_LINEAGE # long caps vars just bother me + +case $dir in + /etc/letsencrypt/live/iankelling.org) + cat $dir/{privkey,cert,chain}.pem > /var/lib/znc/znc.pem + ;; + /etc/letsencrypt/live/mumble.iankelling.org) + install -m 640 -g mumble-server $dir/{privkey,fullchain}.pem /var/lib/mumble-server + ;; + /etc/letsencrypt/live/mail2.iankelling.org) + install -m 644 $dir/fullchain.pem /etc/exim4/exim.crt + install -m 640 -g Debian-exim $dir/privkey.pem /etc/exim4/exim.key + ;; +esac diff --git a/check-stale-alerts b/check-stale-alerts index 1bb73e5..93eaf4f 100755 --- a/check-stale-alerts +++ b/check-stale-alerts @@ -1,3 +1,4 @@ + #!/bin/bash if [[ ! -e /dev/shm/iank-status ]]; then exit 0 @@ -7,5 +8,13 @@ eval $(< /dev/shm/iank-status) if [[ $HOSTNAME != "$MAIL_HOST" ]]; then exit 0 fi -find /var/local/cron-errors /home/iank/cron-errors /sysd-mail-once-state -type f -mtime +4 -ssh bk.b8.nz find /m/md/INBOX/new /var/local/cron-errors /home/iank/cron-errors /sysd-mail-once-state -type f -mtime +1 +out=$(find /var/local/cron-errors /home/iank/cron-errors /sysd-mail-once-state -type f -mtime +4) +if [[ $out ]]; then + echo HOSTNAME: $HOSTNAME + printf "%s\n" "$out" +fi +out=$(ssh bk.b8.nz find /m/md/INBOX/new /var/local/cron-errors /home/iank/cron-errors /sysd-mail-once-state -type f -mtime +1) +fi [[ $out ]]; then + echo bk.b8.nz: + printf "%s\n" "$out" +fi diff --git a/distro-begin b/distro-begin index 63f01f7..ce37ed2 100755 --- a/distro-begin +++ b/distro-begin @@ -409,76 +409,77 @@ sudo mkdir -p "${dirs[@]}" # allow to fail because they could have read-only mounts on them sudo chown $USER:$USER "${dirs[@]}" ||: +# disabled temporarily ###### setup /i -if home_network; then - tu /etc/fstab <<'EOF' -/i/w /w none bind,noauto 0 0 -/i/k /k none bind,noauto 0 0 -EOF - if ! mountpoint /kr; then - sudo mkdir -p /kr - sudo chown $USER:user2 /kr - fi - if [[ $HOSTNAME == frodo ]]; then - tu /etc/fstab <<'EOF' -/k /kr none bind,noauto 0 0 -EOF - else - tu /etc/fstab <<'EOF' -frodo:/k /kr nfs noauto 0 0 -EOF - fi - sudo mkdir -p /i/{w,k} - for dir in /{i,w,k}; do - if mountpoint $dir; then continue; fi # already mounted - sudo mkdir -p $dir - sudo chown $USER:$USER $dir - done - # debian auto mounting of multi-disk encrypted btrfs is busted. It is - # in jessie, and in stretch as of 11/26/2016 I have 4 disks in cryptab, - # based on 3 of those, it creates .device units for /dev/mapper/dev... - # then waits endlessly for them on bootup, after the /dev/mapper disks - # have already been created and exist. todo: create a simple repro - # for this in a vm and report it upstream. - pi nfs-common - sudo dd of=/root/imount <<'EOF' -#!/bin/bash -[[ $EUID == 0 ]] || exec sudo -E "${BASH_SOURCE[0]}" "$@" -set -eE -o pipefail -trap 'echo "$0:$LINENO:error: \"$BASH_COMMAND\" returned $?" >&2' ERR -for dir in /i /k /kr /w; do - if ! mountpoint $dir &>/dev/null && \ - awk '{print $2}' /etc/fstab | grep -xF $dir &>/dev/null; then - if awk '{print $3}' /etc/fstab | grep -xF nfs &>/dev/null; then - mount $dir || echo "warning: failed to mount nfs on $dir" - else - mount $dir - fi - fi -done -EOF - sudo chmod +x /root/imount - sudo dd of=/etc/systemd/system/imount.service <&2' ERR +# for dir in /i /k /kr /w; do +# if ! mountpoint $dir &>/dev/null && \ +# awk '{print $2}' /etc/fstab | grep -xF $dir &>/dev/null; then +# if awk '{print $3}' /etc/fstab | grep -xF nfs &>/dev/null; then +# mount $dir || echo "warning: failed to mount nfs on $dir" +# else +# mount $dir +# fi +# fi +# done +# EOF +# sudo chmod +x /root/imount +# sudo dd of=/etc/systemd/system/imount.service < >(logger) # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. @@ -16,6 +14,9 @@ exec &> >(logger) [[ $EUID == 0 ]] || exec sudo -E "${BASH_SOURCE[0]}" "$@" +#set -x +#exec &> >(logger) + source /a/bin/errhandle/err usage() { @@ -29,8 +30,6 @@ tun_dev, and action is from $script_type env variable, openvpn sets this. Is idempotent. -todo: Need to give mail.iankelling.org an ipv6 dns address. - EOF exit $1 } diff --git a/mail-setup b/mail-setup index 1e073ba..8ddb6b9 100755 --- a/mail-setup +++ b/mail-setup @@ -44,8 +44,9 @@ EOF ####### instructions for icedove ##### -# Incoming mail server: mail.iankelling.org, port 143, username iank, connection security starttls, authentication method normal password -# we could also just use 127.0.0.1 with no ssl, but todo: disable that in dovecot, so mail is secure from local programs. +# Incoming mail server: mail.iankelling.org, port 143, username iank, connection security starttls, authentication method normal password, +# then click advanced so it accepts it. +# we could also just use 127.0.0.1 with no ssl # # hamburger -> preferences -> preferences -> advanced tab -> config editor button -> security.ssl.enable_ocsp_must_staple = false # background: dovecot does not yet have ocsp stapling support @@ -75,12 +76,14 @@ EOF # # 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 +# echo "iank:$(doveadm pw -s SHA512-CRYPT)::::::" >>/p/c/filesystem/etc/dovecot/users ####### end perstent password instructions ###### # * persistent dkim/dns instructions + +#### begin dkim generation section #### # # Remove 1 level of comments in this section, set the domain var # # for the domain you are setting up, then run this and copy dns settings # # into dns. @@ -90,29 +93,30 @@ EOF # # https://debian-administration.org/article/718/DKIM-signing_outgoing_mail_with_exim4 # openssl genrsa -out $domain-private.pem 2048 -# Then, to get the public key strings to put in bind: -# -# sed explanation: skip the first few lines, then put them into the hold space, then -# on the last line, back to the patern space, remove the newlines, then add a newline -# at the last char - 240, because bind txt records need strings <=255 chars, -# other dkim stuff at the begining is is 25 chars, and the pubkey is 393, so this -# leaves us a bit of extra room at the end and a bunch at the beginning. -# +# # Then, to get the public key strings to put in bind: + # # selector is needed for having multiple keys for one domain. # # I dun do that, so just use a static one: li -# echo "txt record name: li._domainkey.$domain" # # Debadmin page does not have v=, fastmail does, and this # # says it\'s recommended in 3.6.1, default is DKIM1 anyways. # # https://www.ietf.org/rfc/rfc6376.txt # # Join and print all but first and last line. # # last line: swap hold & pattern, remove newlines, print. # # lines 2+: append to hold space -# echo "bind txt record contents:" +# echo "bind txt record:" # cat </etc/iptables/rules.v6 <<'EOF' *nat @@ -214,7 +217,7 @@ EOF fi # our nostart pi fails to avoid enabling -sudo systemctl disable openvpn +systemctl disable openvpn # trisquel 8 = openvpn, debian stretch = openvpn-client vpn_ser=openvpn-client @@ -290,26 +293,27 @@ cat >/etc/spamassassin/mylocal.cf <<'EOF' # entirely of whitespace".) This is a safe, terse alternative: clear_report_template report (_SCORE_ / _REQD_ requ) _TESTSSCORES(,)_ autolearn=_AUTOLEARN -internal_networks 85.119.83.50 2001:ba8:1f1:f0c9::2 209.51.188.13 2001:470:142::13 +internal_networks 85.119.83.50 +trusted_networks 72.14.176.105 2600:3c00:e000:280::2 85.119.83.50 18.4.89.0/24 209.51.188.0/24 74.94.156.208/28 2603:3005:71a:2e00::/64 2001:470:142::/48 EOF - -if [[ $HOSTNAME == "$MAIL_HOST" ]]; then - m systemctl stop spamassassin - m systemctl disable spamassassin - - # per readme.debian - sed -i '/^\s*CRON\s*=/d' /etc/default/spamassassin - e CRON=1 >>/etc/default/spamassassin - # just noticed this in the config file, seems like a good idea. - sed -i '/^\s*NICE\s*=/d' /etc/default/spamassassin - e 'NICE="--nicelevel 15"' >>/etc/default/spamassassin - - m systemctl enable spamassassin - m systemctl start spamassassin - m systemctl reload spamassassin - - cat >/etc/systemd/system/spamddnsfix.service <<'EOF' +case $HOSTNAME in + bk|$MAIL_HOST) + m systemctl stop spamassassin + m systemctl disable spamassassin + + # per readme.debian + sed -i '/^\s*CRON\s*=/d' /etc/default/spamassassin + e CRON=1 >>/etc/default/spamassassin + # just noticed this in the config file, seems like a good idea. + sed -i '/^\s*NICE\s*=/d' /etc/default/spamassassin + e 'NICE="--nicelevel 15"' >>/etc/default/spamassassin + + m systemctl enable spamassassin + m systemctl start spamassassin + m systemctl reload spamassassin + + cat >/etc/systemd/system/spamddnsfix.service <<'EOF' [Unit] Description=spamd dns bug fix cronjob @@ -317,10 +321,10 @@ Description=spamd dns bug fix cronjob Type=oneshot ExecStart=/a/bin/distro-setup/spamd-dns-fix EOF - # 2017-09, debian closed the bug on this saying upstream had fixed it. - # remove this when i\'m using the newer package, ie, debian 10, or maybe - # ubuntu 18.04. - cat >/etc/systemd/system/spamddnsfix.timer <<'EOF' + # 2017-09, debian closed the bug on this saying upstream had fixed it. + # remove this when i\'m using the newer package, ie, debian 10, or maybe + # ubuntu 18.04. + cat >/etc/systemd/system/spamddnsfix.timer <<'EOF' [Unit] Description=run spamd bug fix script every 10 minutes @@ -334,10 +338,12 @@ OnUnitActiveSec=550 [Install] WantedBy=timers.target EOF - m systemctl daemon-reload - m systemctl restart spamddnsfix.timer - m systemctl enable spamddnsfix.timer -fi + m systemctl daemon-reload + m systemctl restart spamddnsfix.timer + m systemctl enable spamddnsfix.timer + ;; +esac + ##### end spamassassin config @@ -397,7 +403,7 @@ if [[ ! $MAIL_HOST ]]; then err "\$MAIL_HOST not set" fi -m sudo gpasswd -a iank adm #needed for reading logs +m gpasswd -a iank adm #needed for reading logs ### make local bounces go to normal maildir @@ -406,7 +412,7 @@ dirs=(/m/md/bounces/{cur,tmp,new}) m mkdir -p ${dirs[@]} m chown iank:iank /m /m/md m ln -sfT /m/md /m/iank -m chmod 700 /m /m/md +m chmod 771 /m /m/md m chown -R $u:Debian-exim /m/md/bounces m chmod 775 ${dirs[@]} m usermod -a -G Debian-exim $u @@ -423,7 +429,7 @@ f=/p/c/filesystem/etc/exim4/passwd.client if [[ ! -e $f ]]; then f=/p/c/machine_specific/$HOSTNAME/filesystem/etc/exim4/passwd.client fi -m sudo rsync -ahhi --chown=root:Debian-exim --chmod=0640 $f /etc/exim4/ +m rsync -ahhi --chown=root:Debian-exim --chmod=0640 $f /etc/exim4/ # by default, only 10 days of logs are kept. increase that. m sed -ri 's/^(\s*rotate\s).*/\11000/' /etc/logrotate.d/exim4-base @@ -526,12 +532,19 @@ cat >/etc/exim4/conf.d/data_local_acl <<'EOF' # pretty quickly looking through my spam folder. warn + # all internal ips. note this is duplicated in mylocal.cf, shouldnt have any effect there but leaving just in case + !hosts = <; 72.14.176.105 2600:3c00:e000:280::2 85.119.83.50 18.4.89.0/24 209.51.188.0/24 74.94.156.208/28 2603:3005:71a:2e00::/64 2001:470:142::/48 + remove_header = X-Spam_score: X-Spam_score_int : X-Spam_bar : X-Spam_report + +warn + !hosts = <; 72.14.176.105 2600:3c00:e000:280::2 85.119.83.50 18.4.89.0/24 209.51.188.0/24 74.94.156.208/28 2603:3005:71a:2e00::/64 2001:470:142::/48 condition = ${if < {$message_size}{5000K}} spam = Debian-exim:true - add_header = X-Spam_score: $spam_score\n\ - X-Spam_score_int: $spam_score_int\n\ - X-Spam_bar: $spam_bar\n\ - X-Spam_report: $spam_report + add_header = X-Spam_score_int: $spam_score_int + add_header = X-Spam_score: $spam_score + add_header = X-Spam_bar: $spam_bar + add_header = X-Spam_report: $spam_report + add_header = X-Spam_action: $spam_action #accept # spf = pass:fail:softfail:none:neutral:permerror:temperror @@ -539,7 +552,10 @@ warn # add_header = Reply-to: dmarctest@iankelling.org EOF -cat >/etc/exim4/conf.d/auth/29_exim4-config_auth <<'EOF' + +case $HOSTNAME in + $MAIL_HOST) + cat >/etc/exim4/conf.d/auth/29_exim4-config_auth <<'EOF' # from 30_exim4-config_examples plain_server: @@ -552,7 +568,31 @@ server_prompts = : server_advertise_condition = ${if eq{$tls_in_cipher}{}{}{*}} .endif EOF + ;; + bk) + + # avoid accepting mail for invalid users + # https://wiki.dovecot.org/LMTP/Exim + cat >>/etc/exim4/conf.d/rcpt_local_acl <<'EOF' +deny + message = invalid recipient + domains = +local_domains + !verify = recipient/callout=no_cache +EOF + + cat >/etc/exim4/conf.d/auth/29_exim4-config_auth <<'EOF' +dovecot_plain: + driver = dovecot + public_name = PLAIN + server_socket = /var/run/dovecot/auth-client + server_set_id = $auth1 +EOF + ;; +esac +# todo: for mail submission, test imap based authentication for bk. +# eg: can we send as other ppl? +# see sender validation in /a/opt/mailinabox/setup/mail-users.sh cat >/etc/exim4/conf.d/router/900_exim4-config_local_user <<'EOF' ### router/900_exim4-config_local_user ################################# @@ -573,10 +613,11 @@ local_user: EOF cat >/etc/exim4/conf.d/transport/30_exim4-config_dovecot_lmtp <<'EOF' dovecot_lmtp: - driver = lmtp - socket = /var/run/dovecot/lmtp - #maximum number of deliveries per batch, default 1 - batch_max = 200 + driver = lmtp + socket = /var/run/dovecot/lmtp + #maximum number of deliveries per batch, default 1 + batch_max = 200 + envelope_to_add EOF # this avoids some error. i cant remember what. todo: @@ -647,17 +688,16 @@ dovecot-setup() { # # dovecot-lmtpd is for exim to deliver to dovecot instead of maildir # directly. The reason to do this is to use dovecot\'s sieve, which - # has extensions that allow it to be almost equivalent to exim\'s - # filter capabilities, some ways probably better, some worse, and + # can generally do more than exims filters (a few things less) and # sieve has the benefit of being supported in postfix and # proprietary/weird environments, so there is more examples on the - # internet. I was torn about whether to do this or not, meh. - pi dovecot-core dovecot-imapd dovecot-sieve dovecot-lmtpd + # internet. + pi dovecot-core dovecot-imapd dovecot-sieve dovecot-lmtpd dovecot-sqlite for f in /p/c{/machine_specific/$HOSTNAME,}/filesystem/etc/dovecot/users; do e $f if [[ -e $f ]]; then - m sudo rsync -ahhi --chown=root:dovecot --chmod=0640 $f /etc/dovecot/ + m rsync -ahhi --chown=root:dovecot --chmod=0640 $f /etc/dovecot/ break fi done @@ -665,29 +705,128 @@ dovecot-setup() { m sudo -u $u /a/exe/lnf -T $f $uhome/sieve/${f##*/} done + # https://wiki.dovecot.org/SSL/DovecotConfiguration + cat >/etc/dovecot/dhparam <<'EOF' +-----BEGIN DH PARAMETERS----- +MIIBCAKCAQEAoleil6SBxGqQKk7j0y2vV3Oklv6XupZKn7PkPv485QuFeFagifeS +A+Jz6Wquqk5zhGyCu63Hp4wzGs4TyQqoLjkaWL6Ra/Bw3g3ofPEzMGEsV1Qdqde4 +jorwiwtr2i9E6TXQp0noT/7VFeHulIkayTeW8JulINdMHs+oLylv16McGCIrxbkM +8D1PuO0TP/CNDs2QbRvJ1RjY3CeGpxMhrSHVgBCUMwnA2cvz3bYjI7UMYMMDPNrE +PLrwsYzXGGCdJsO2vsmmqqgLsZiapYJlUNjfiyWLt7E2H6WzkNB3VIhIPfLqFDPK +xioE3sYKdjOt+p6mlg3l8+OLtODEFPHDqwIBAg== +-----END DH PARAMETERS----- +EOF + cat >/etc/dovecot/local.conf <>/etc/dovecot/local.conf </etc/dovecot/local.conf.ext <<'EOF' +passdb { + driver = sql + args = /etc/dovecot/dovecot-sql.conf.ext +} +userdb { + driver = sql + args = /etc/dovecot/dovecot-sql.conf.ext +} + EOF - cat >/etc/dovecot/conf.d/20-lmtp.conf </etc/dovecot/dovecot-sql.conf.ext <<'EOF' +# from mailinabox +driver = sqlite +connect = /m/rc/users.sqlite +default_pass_scheme = SHA512-CRYPT +password_query = SELECT email as user, password FROM users WHERE email='%u'; +user_query = SELECT email AS user, "mail" as uid, "mail" as gid, "/m/md/%d/%n" as home FROM users WHERE email='%u'; +iterate_query = SELECT email AS user FROM users; +EOF + chmod 0600 /etc/dovecot/dovecot-sql.conf.ext # per Dovecot instructions + + # db needs to be in a www-data writable directory + db=/m/rc/users.sqlite + if [[ ! -s $db ]]; then + sqlite3 $db <<'EOF' +CREATE TABLE users ( +id INTEGER PRIMARY KEY AUTOINCREMENT, +email TEXT NOT NULL UNIQUE, +password TEXT NOT NULL, +extra, +privileges TEXT NOT NULL DEFAULT ''); +EOF + fi + # example of adding a user: + # hash: doveadm pw -s SHA512-CRYPT -p passhere + # sqlite3 /m/rc/users.sqlite <<'EOF' + #insert into users (email, password) values ('testignore@bk.b8.nz', 'hash'); + #EOF + + + + + case $HOSTNAME in + $MAIL_HOST) + # If we changed 90-sieve.conf and removed the active part of the + # sieve option, we wouldn\'t need this, but I\'d rather not modify a + # default config if not needed. This won\'t work as a symlink in /a/c + # unfortunately. + m sudo -u $u /a/exe/lnf -T sieve/main.sieve $uhome/.dovecot.sieve + + if [[ ! -e $uhome/sieve/personal.sieve ]]; then + touch $uhome/sieve/personal{,end}{,test}.sieve + fi + rm -fv /etc/dovecot/conf.d/20-lmtp.conf # file from prev version + cat >>/etc/dovecot/local.conf <>/etc/dovecot/local.conf </etc/dovecot/local.conf </etc/dovecot/sieve-spam.sieve <<'EOF' +require ["regex", "fileinto", "imap4flags"]; -# for debugging info, uncomment these. -# logs go to syslog and to /var/log/mail.log -# auth_verbose=yes -#mail_debug=yes +if allof (header :regex "X-Spam-Status" "^Yes") { + fileinto "Spam"; + stop; +} EOF + sievec /etc/dovecot/sieve-spam.sieve + + ;; + esac ####### end dovecot-setup ######## } +# * nextcloud setup + +# https://docs.nextcloud.com/server/19/admin_manual/installation/source_installation.html +# curl from the web installer requirement, but i switched to cli +pi php-curl php-fileinfo php-bz2 +web-conf - apache2 expertpathologyreview.com <<'EOF' +Alias /nextcloud "/var/www/nextcloud/" + + Require all granted + AllowOverride All + Options FollowSymLinks MultiViews + + + Dav off + + + +EOF + +cd /var/www +wget https://download.nextcloud.com/server/releases/latest.zip +unzip -q latest.zip +rm latest.zip +chown -R www-data.www-data nextcloud +cd /var/www/nextcloud +sudo -u www-data php occ maintenance:install --database sqlite --admin-user iank --admin-pass swarm.numbered.alienist +cd /var/www/nextcloud/config +# https://docs.nextcloud.com/server/19/admin_manual/installation/source_installation.html +cat >/etc/php/$phpver/fpm/pool.d/localwww.conf <<'EOF' +[www] +clear_env = no +EOF +cat config.php - >tmp.php <<'EOF' +$CONFIG['overwrite.cli.url'] = 'https://expertpathologyreview.com/nextcloud'; +$CONFIG['htaccess.RewriteBase'] = '/nextcloud'; +$CONFIG['trusted_domains'] = array ( + 0 => 'expertpathologyreview.com', + ); +#$CONFIG[''] = ''; +fwrite(STDOUT, "config.php 2>/dev/null +rm tmp.php +sudo -u www-data php /var/www/nextcloud/occ maintenance:update:htaccess + + +# * roundcube setup + +roundcube-setup() { + # avoid prompt + debconf-set-selections <<'EOF' +roundcube-core roundcube/dbconfig-install boolean false +EOF + # zip according to /installer + # which requires adding a line to /usr/local/lib/roundcubemail/config/config.inc.php + # $config['enable_installer'] = true; + pi roundcube roundcube-sqlite3 php-zip + rcdir=/usr/local/lib/roundcubemail + # point debian cronjob to our local install, preventing daily cron error + + f=/usr/share/roundcube/bin/cleandb.sh + if [[ ! -L $f ]]; then + if [[ -e $f ]]; then + m rm -f $f + fi + m ln -sfT $rcdir/bin/cleandb.sh /usr/share/roundcube/bin/cleandb.sh + fi + + # todo, consider installing the extensions mailinabox uses + + #### begin dl roundcube + # note, im r2e subbed to https://github.com/roundcube/roundcubemail/releases.atom + v=1.4.8; f=roundcubemail-$v-complete.tar.gz + cd /a/opt + if [[ -e $f ]]; then + timestamp=$(stat -c %Y $f) + else + timestamp=0 + fi + m wget -nv -N https://github.com/roundcube/roundcubemail/releases/download/$v/$f + new_timestamp=$(stat -c %Y $f) + if [[ $timestamp != $new_timestamp ]]; then + m tar -C /usr/local/lib --no-same-owner -zxf $f + m rm -rf $rcdir + m mv $rcdir-$v $rcdir + fi + cd - + #### end dl roundcube + + /a/exe/web-conf -r $rcdir - apache2 mail.expertpathologyreview.com < + Options +FollowSymLinks + # This is needed to parse $rcdir/.htaccess. + AllowOverride All + Require all granted + +# Protecting basic directories: + + Options -FollowSymLinks + AllowOverride None + +EOF + + if [[ ! -e $rcdir/config/secret ]]; then + base64 $rcdir/config/secret || [[ $? == 141 ]] + fi + secret=$(cat $rcdir/config/secret) + # todo: expire mail for testignore@b8.nz + + # config from mailinabox + cat >$rcdir/config/config.inc.php < array( + 'verify_peer' => false, + 'verify_peer_name' => false, + ), + ); +\$config['imap_timeout'] = 15; +\$config['smtp_server'] = 'tls://127.0.0.1'; +\$config['smtp_conn_options'] = array( + 'ssl' => array( + 'verify_peer' => false, + 'verify_peer_name' => false, + ), + ); +\$config['product_name'] = 'webmail'; +\$config['des_key'] = '$secret'; +\$config['plugins'] = array('archive', 'zipdownload', 'password', 'managesieve', 'jqueryui'); +\$config['skin'] = 'elastic'; +\$config['login_autocomplete'] = 2; +\$config['password_charset'] = 'UTF-8'; +\$config['junk_mbox'] = 'Spam'; +?> +EOF + + m mkdir -p /var/tmp/roundcubemail /m/rc + m chown -R www-data.www-data /var/tmp/roundcubemail /m/rc + m chmod 750 /var/tmp/roundcubemail + # Ensure the log file monitored by fail2ban exists, or else fail2ban can't start. + # todo: setup fail2ban + # todo: setup dnssec. + # todo: check for other mailinabox things + m sudo -u www-data touch /var/log/roundcube/errors.log + + # Password changing plugin settings + cat $rcdir/plugins/password/config.inc.php.dist - >$rcdir/plugins/password/config.inc.php <<'EOF' +# following are from mailinabox +$config['password_minimum_length'] = 8; +$config['password_db_dsn'] = 'sqlite:////m/rc/users.sqlite'; +$config['password_query'] = 'UPDATE users SET password=%D WHERE email=%u'; +$config['password_dovecotpw'] = '/usr/bin/doveadm pw'; +$config['password_dovecotpw_method'] = 'SHA512-CRYPT'; +$config['password_dovecotpw_with_method'] = true; +EOF + # so PHP can use doveadm, for the password changing plugin + m usermod -a -G dovecot www-data + m usermod -a -G mail $u + + # so php can update passwords + m chown www-data:dovecot /m/rc/users.sqlite + m chmod 664 /m/rc/users.sqlite + + # Run Roundcube database migration script (database is created if it does not exist) + m $rcdir/bin/updatedb.sh --dir $rcdir/SQL --package roundcube + m chown www-data:www-data /m/rc/roundcube.sqlite + m chmod 664 /m/rc/roundcube.sqlite + + # Enable PHP modules. + m phpenmod -v php mcrypt imap + + # dpkg says this is required + m a2enmod proxy_fcgi setenvif + fpm=$(dpkg-query -s php-fpm | sed -nr 's/^Depends:.* (php[^ ]*-fpm)( .*|$)/\1/p') # eg: php7.3-fpm + phpver=$(dpkg-query -s php-fpm | sed -nr 's/^Depends:.* php([^ ]*)-fpm( .*|$)/\1/p') + m a2enconf $fpm + # 3 useless guides on php fpm fcgi debian 10 later, i figure out from reading + # /etc/apache2/conf-enabled/php7.3-fpm.conf + m a2dismod php$phpver + # according to /install, we should set date.timezone, + # but that is dumb, the system already has the right zone in + # /var/log/roundcubemail/errors.log + cat >/etc/php/$phpver/fpm/conf.d/30-local.ini <<'EOF' +date.timezone = "America/New_York" +# for nextcloud +upload_max_filesize = 2000M +post_max_size = 2000M +EOF + + m systemctl restart $fpm + # dunno if reload/restart is needed + m systemctl reload apache2 + m systemctl reload exim4 + + # todo: backups, carddav w nextcloud +} # * if MAIL_HOST @@ -791,7 +1178,6 @@ EOF # * exim - # todo, these pem files look old and useless. whats going on sudo rsync -ahhi --chown=root:Debian-exim --chmod=0640 \ /p/c/filesystem/etc/exim4/passwd /p/c/filesystem/etc/exim4/*.pem /etc/exim4/ @@ -828,8 +1214,7 @@ EOF # man page: is used to build the local_domains list, together with "localhost" # iank.bid is for testing # mail.iankelling.org is for machines i own -dc_other_hostnames='*.iankelling.org;iankelling.org;*zroe.org;zroe.org;!bk.b8.nz;*.b8.nz;b8.nz' - +dc_other_hostnames='!mail2.iankelling.org;!mibtest.iankelling.org;*.iankelling.org;iankelling.org;zroe.org;!bk.b8.nz;*.b8.nz;b8.nz' EOF @@ -877,8 +1262,16 @@ wget -q -N https://publicsuffix.org/list/public_suffix_list.dat EOF m chmod 755 $f + # make all system users be aliases + for u in $(awk 'BEGIN { FS = ":" } ; $6 !~ /^\/home/ { print $1 }' /etc/passwd); do + if ! grep -q "^$u:" aliases; then + echo "$u: root" |tee -a /etc/aliases + fi + done + + # alerts is basically the postmaster address sed -i --follow-symlinks -f - /etc/aliases < /etc/mailname + cat >>/etc/exim4/conf.d/main/000_local <>/etc/exim4/update-exim4.conf.conf <$dir/config-v1.1.xml <<'EOF' + + + + expertpathologyreview.com + + expertpathologyreview.com Mail + expertpathologyreview.com + + + mail2.iankelling.org + 993 + SSL + %EMAILADDRESS% + password-cleartext + + + + mail2.iankelling.org + 587 + STARTTLS + %EMAILADDRESS% + password-cleartext + true + false + + + + expertpathologyreview.com website. + + + + + + + %EMAILADDRESS% + + + + + + + +EOF + + roundcube-setup + ;; + # * not MAIL_HOST and not bk + *) # remove mail. uses 2 lines to properly remove whitespace sed -ri -f - /etc/hosts <<'EOF' s#^(127\.0\.1\.1 .*) +mail\.iankelling\.org$#\1# @@ -922,11 +1386,8 @@ EOF 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 + + rm -fv /etc/exim4/conf.d/main/000_localmacros # old filename cat >>/etc/exim4/update-exim4.conf.conf </etc/mailname - - ;;& - ## we use this host to monitor MAIL_HOST - bk) - - cat >>/etc/exim4/update-exim4.conf.conf <