From 58d303a236d810b1a1354b7dd55ded129c82e88f Mon Sep 17 00:00:00 2001 From: Ian Kelling Date: Wed, 21 Oct 2020 22:48:20 -0400 Subject: [PATCH] 2 exim daemons on bk --- brc | 2 +- conflink | 12 +- distro-end | 5 + mail-cert-cron | 17 +- mail-route | 18 +- mail-setup | 807 +++++++++++++++++++++++++++---------------------- mailtest-check | 3 + 7 files changed, 483 insertions(+), 381 deletions(-) diff --git a/brc b/brc index 7bf75e7..4c3ee1a 100644 --- a/brc +++ b/brc @@ -1783,7 +1783,7 @@ if [[ $- == *i* ]]; then if [[ $1 == prompt-command ]]; then return 0 fi - if (( ${#BASH_ARGC[@]} == 1 )); then + if (( ${#BASH_ARGC[@]} == 1 && BASH_SUBSHELL == 0 )); then echo -ne "$_title_escape ${PWD/#$HOME/~} " printf "%s" "$*" echo -ne "\007" diff --git a/conflink b/conflink index 710e626..450edf7 100755 --- a/conflink +++ b/conflink @@ -81,6 +81,12 @@ common-file-setup() { for dir in "$@"; do fs=$dir/filesystem if [[ -e $fs && $user =~ ^iank?$ ]]; then + cmd=( s rsync -aiSAX --chown=root:root --chmod=g-s + --exclude=/etc/dovecot/users + --exclude='/etc/exim4/passwd*' + --exclude='/etc/exim4/*.pem' + $fs/ / ) + echo "${cmd[*]}" while read -r line; do file="${line:12}" case $file in @@ -101,11 +107,7 @@ common-file-setup() { # A = preserve acls # X = preserve extended attributes # i = itemize - done < <(s rsync -aiSAX --chown=root:root --chmod=g-s \ - --exclude=/etc/dovecot/users \ - --exclude='/etc/exim4/passwd*' \ - --exclude='/etc/exim4/*.pem' \ - $fs/ /) + done < <(${cmd[@]}) fi if [[ -e $dir/subdir_files ]]; then diff --git a/distro-end b/distro-end index 1fa28a5..efbc3b3 100755 --- a/distro-end +++ b/distro-end @@ -557,6 +557,11 @@ EOF sudo tee /etc/openvpn/client-config-mail/mailclient <<'EOF' ifconfig-push 10.8.0.4 255.255.255.0 ifconfig-ipv6-push 2600:3c00:e000:280::2/64 +EOF + + sudo tee /etc/openvpn/client-config-mail/expertpath <<'EOF' +ifconfig-push 10.8.0.5 255.255.255.0 +ifconfig-ipv6-push 2600:3c00:e000:280::3/64 EOF sudo dd of=/etc/systemd/system/vpnmail.service <<'EOF' diff --git a/mail-cert-cron b/mail-cert-cron index 731621b..f89716a 100755 --- a/mail-cert-cron +++ b/mail-cert-cron @@ -4,25 +4,21 @@ trap 'echo "$0:$LINENO:error: \"$BASH_COMMAND\" returned $?" >&2' ERR [[ $EUID == 0 ]] || exec sudo -E "${BASH_SOURCE[0]}" "$@" - f=/a/bin/bash_unpublished/source-state if [[ -e $f ]]; then source $f fi + case $HOSTNAME in - $MAIL_HOST) + $MAIL_HOST|bk) local_mx=mail.iankelling.org - mkdir -p /etc/letsencrypt/live/$local_mx - chmod 700 /etc/letsencrypt/live - rsync_common="rsync -ogtL --chown=root:Debian-exim --chmod=640 root@li.iankelling.org:/etc/letsencrypt/live/$local_mx/" - # allow for temporary connection issues - ${rsync_common}fullchain.pem /etc/exim4/exim.crt ||: - ${rsync_common}privkey.pem /etc/exim4/exim.key ||: - if ! openssl x509 -checkend $(( 60 * 60 * 24 * 3 )) -noout -in /etc/exim4/exim.crt; then + # ||: is to allow for temporary connection issues. + rsync -ogtL --chown=root:Debian-exim --chmod=640 root@li.iankelling.org:/etc/letsencrypt/live/mail.iankelling.org/{fullchain.pem,privkey.pem} /etc/exim4 ||: + if ! openssl x509 -checkend $(( 60 * 60 * 24 * 3 )) -noout -in /etc/exim4/fullchain.pem; then echo "$0: error!: cert rsync failed and it will expire in less than 3 days" exit 1 fi - ;; + ;;& bk) # the folder name depended on what the fqdn was when we got the initial # cert. @@ -30,7 +26,6 @@ case $HOSTNAME in if [[ ! -d $ledir ]]; then ledir=/etc/letsencrypt/live/$(hostname -f) fi - fullchain=$ledir/fullchain.pem if ! diff -q $fullchain /etc/exim4/exim.crt &>/dev/null; then install -m 644 $fullchain /etc/exim4/exim.crt diff --git a/mail-route b/mail-route index c2b7959..9520060 100755 --- a/mail-route +++ b/mail-route @@ -125,7 +125,16 @@ modify() { # match source or dest port. note, when we send to a port, it picks a random high port as # the source. - iptcommon="OUTPUT -m tcp -p tcp -m multiport --ports 25,143,587 -j MARK --set-mark" + if [[ $HOSTNAME == bk ]]; then + ports=25 + ip4suf=5 + ip6suf=3 + else + ports=25,143,587 + ip4suf=4 + ip6suf=2 + fi + iptcommon="OUTPUT -m tcp -p tcp -m multiport --ports $ports -j MARK --set-mark" iptmod iptables -t mangle $iptables_op $iptcommon 0x1 iptmod iptables -t mangle $iptables_op $iptcommon 0x0 -d 10.0.0.0/8,172.16.0.0/12,192.168.0.0/16,127.0.0.0/8 # note, we could have used a custom chain and returned instead of setting the mark again. @@ -134,9 +143,8 @@ modify() { if [[ $tun_dev ]]; then # when $tun_dev goes away, so does this rule. - iptmod iptables -t nat $iptables_op POSTROUTING -o $tun_dev -m mark --mark 0x1 -j SNAT --to-source 10.8.0.4 - iptmod ip6tables -t nat $iptables_op POSTROUTING -o $tun_dev -m mark --mark 0x1 -j SNAT --to-source 2600:3c00:e000:280::2 - + iptmod iptables -t nat $iptables_op POSTROUTING -o $tun_dev -m mark --mark 0x1 -j SNAT --to-source 10.8.0.$ip4suf + iptmod ip6tables -t nat $iptables_op POSTROUTING -o $tun_dev -m mark --mark 0x1 -j SNAT --to-source 2600:3c00:e000:280::$ip6suf fi @@ -147,7 +155,7 @@ modify() { done iproutecmd="default via 10.8.0.1 table 1" - exists=true; ip route show $iproutecmd | grep . &>/dev/null || exists=false + exists=true; ip route show $iproutecmd 2>/dev/null | grep . &>/dev/null || exists=false if runtest; then e ip route $ip_op $iproutecmd; fi if [[ $tun_dev ]]; then # when $tun_dev goes away, so does this route. diff --git a/mail-setup b/mail-setup index 9662934..bdfe29a 100755 --- a/mail-setup +++ b/mail-setup @@ -3,7 +3,6 @@ # Copyright (C) 2019 Ian Kelling # SPDX-License-Identifier: AGPL-3.0-or-later - # background: I want to run exim in a network namespace so it can send # and receive through a vpn. This is needed so it can do ipv6, because # outside the namespace if we dont have ipv6, to send ipv6 through the @@ -74,6 +73,8 @@ else exit 1 fi source /a/bin/distro-functions/src/identify-distros + +# has nextcloud_admin_pass in it f=/p/c/machine_specific/bk/mail if [[ -e $f ]]; then source $f @@ -98,9 +99,8 @@ EOF exit $1 } -debug=false +# debug output if we pass any arg if (( $# )); then - debug=true set -x fi @@ -121,6 +121,8 @@ fi # * perstent password instructions +# Note: for cert cron, we need to manually run first to accept known_hosts + # # exim passwords: # # for hosts which have all private files I just use the same user # # for other hosts, each one get\'s their own password. @@ -165,7 +167,7 @@ fi # # 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:" +# echo "bind txt record: remember to truncate $domain so its relative to the bind zone" # cat </etc/apt/preferences.d/spamassassin <<'EOF' @@ -264,7 +274,6 @@ EOF fi -## * Install packages # light version of exim does not have sasl auth support. pi exim4 exim4-daemon-heavy spamassassin spf-tools-perl openvpn p0f postgrey pyzor razor jq moreutils # note: pyzor debian readme says you need to run some initialization command @@ -288,9 +297,7 @@ fi # our nostart pi fails to avoid enabling systemctl disable openvpn -uhome=$(eval echo ~$u) ### * user forward file - case $HOSTNAME in $MAIL_HOST|bk) # afaik, these will get ignored on MAIL_HOST because they are routing to my own @@ -357,11 +364,14 @@ 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 -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 +internal_networks 85.119.83.50 10.173.8.1 +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 10.173.8.1 EOF +# todo: figure out a reverse dns lookup for 10.173.8.1 in the nn. +# perhaps adding files in nsswitch should fix it? + # https://selivan.github.io/2017/12/30/systemd-serice-always-restart.html tmpdir=$(mktemp -d) cat >$tmpdir/openvpn-client-mail@.service <<'EOF' @@ -372,7 +382,6 @@ Wants=network-online.target Documentation=man:openvpn(8) Documentation=https://community.openvpn.net/openvpn/wiki/Openvpn24ManPage Documentation=https://community.openvpn.net/openvpn/wiki/HOWTO -Requires=iptables.service # needed to continually restatr StartLimitIntervalSec=0 @@ -411,29 +420,32 @@ RestartSec=1 [Install] WantedBy=multi-user.target EOF -tmp=$(install -vC $tmpdir/* /etc/systemd/system) +tmp=$(rsync -ic $tmpdir/* /etc/systemd/system) rm -rf $tmpdir if [[ $tmp ]]; then m systemctl daemon-reload fi +tmpdir=$(mktemp -d) +echo "nameserver 8.8.8.8" >$tmpdir/stub-resolv.conf +mkdir -p /etc/nn-resolv +rsync -ic $tmpdir/* /etc/nn-resolv +rm -rf $tmpdir +m chattr +i /etc/nn-resolv/stub-resolv.conf + +### begin setup network namespace ### -f=/etc/nn-resolv/stub-resolv.conf -l="nameserver 8.8.8.8" -if ! grep -Fxq "$l" /etc/nn-resolv/stub-resolv.conf &>/dev/null; then - mkdir -p ${f%/*} - echo "$l" >$f - chattr +i $f +nn_progs=(exim4) +if [[ $HOSTNAME == "$MAIL_HOST" ]]; then + # Note dovecots lmtp doesnt need to be in the same nn to accept delivery. + nn_progs+=(spamassassin dovecot) fi -### begin setup network namespace ### case $HOSTNAME in $MAIL_HOST|bk) reload=false tmpdir=$(mktemp -d) - for unit in exim4 spamassassin; do - dir=/etc/systemd/system/$unit.service.d - mkdir -p $dir + for unit in ${nn_progs[@]}; do cat >$tmpdir/nn.conf <<'EOF' [Unit] After=network.target @@ -452,8 +464,10 @@ Restart=always # time to sleep before restarting a service RestartSec=1 EOF - tmp=$(install -vC $tmpdir/* $dir) + mkdir -p /etc/systemd/system/$unit.service.d + tmp=$(rsync -ic $tmpdir/* /etc/systemd/system/$unit.service.d) if [[ $tmp ]]; then + printf "rsync to /etc/systemd/system/$unit.service.d\n%s\n" "$tmp" reload=true fi done @@ -493,11 +507,6 @@ case $HOSTNAME in sed -i '/^\s*NICE\s*=/d' /etc/default/spamassassin e 'NICE="--nicelevel 15"' >>/etc/default/spamassassin - # We wait until later to stop if we arent mailhost, so that if we - # are transitioning from mail host to non-mail host, we wont screw - # up exim. - m systemctl enable spamassassin - m systemctl start spamassassin ;; esac ##### end spamassassin config @@ -510,6 +519,7 @@ if [[ -e /p/c/filesystem ]]; then # after my internet was down for a bit: # NOTE: Pulled options changed on restart, will need to close and reopen TUN/TAP device. m /a/exe/vpn-mk-client-cert -b mailclient -n mail -s /b/ds/mail-route li.iankelling.org + m /a/exe/vpn-mk-client-cert -c bk.b8.nz -b expertpath -n mail -s /b/ds/mail-route li.iankelling.org fi m rsync -aiSAX --chown=root:root --chmod=g-s /a/bin/ds/mail-cert-cron /usr/local/bin @@ -535,7 +545,7 @@ OnCalendar=daily [Install] WantedBy=timers.target EOF -tmp=$(install -vC $tmpdir/* /etc/systemd/system) +tmp=$(rsync -ic $tmpdir/* /etc/systemd/system) if [[ $tmp ]]; then m systemctl daemon-reload fi @@ -547,17 +557,23 @@ m systemctl start mailcert m systemctl restart mailcert.timer m systemctl enable mailcert.timer +# * common exim4 config -# * common exim4 config -source /a/bin/bash_unpublished/source-state -if [[ ! $MAIL_HOST ]]; then - err "\$MAIL_HOST not set" -fi +# Make all system users be aliases. preventative +# measure for things like cron mail for user without alias +awk 'BEGIN { FS = ":" } ; $6 !~ /^\/home/ { print $1 }' /etc/passwd| while read -r user; do + if [[ ! $user ]]; then + continue + fi + if ! grep -q "^$user:" /etc/aliases; then + echo "$user: root" |tee -a /etc/aliases + fi +done -m gpasswd -a iank adm #needed for reading logs +m gpasswd -a iank adm #needed for reading logs ### make local bounces go to normal maildir # local mail that bounces goes to /Maildir or /root/Maildir @@ -595,7 +611,13 @@ b=userforward_higher_priority # replace the router name so it is unique sed -r s/^\\S+:/$b:/ 600_exim4-config_userforward >175_$b -#### begin setup alternate config for daemon +# todo, consider 'separate' in etc/exim4.conf, could it help on busy systems? + +#### begin setup alternate config for main daemon + +#in debian, config file used is first found of: +#CONFIGURE_FILE=/etc/exim4/exim4.conf:/var/lib/exim4/config.autogenerated +# but we can use this alternate for the daemon update-exim4defaults -f --commonoptions '-C /etc/exim4/my.conf' l="UPEX4OPTS='-o /etc/exim4/my.conf'" if ! grep -Fxq "$l" /etc/default/exim4; then @@ -605,11 +627,11 @@ fi cat >/etc/exim4/trusted_configs <<'EOF' /etc/exim4/my.conf EOF -#### end setup alternate config for daemon +#### end setup alternate config for main daemon # alerts is basically the postmaster address sed -i --follow-symlinks -f - /etc/aliases </etc/exim4/conf.d/main/000_local-nn </etc/exim4/conf.d/rcpt_local_acl <<'EOF' -# Only hosts we control send to @mail.iankelling.org, so make sure -# they are all authed. -# Note, if we wanted authed senders for all domains, -# we could make this condition in acl_check_mail -deny - message = ian trusted domain recepient but no auth - !authenticated = * - domains = mail.iankelling.org +# i had a thing here so alerts would only come from +# authed hosts. I ditched it, but leaving this here since +# I might add somethign later. EOF # This acl already exists in rcpt, this just makes it more widespread. @@ -703,11 +727,11 @@ cat >/etc/exim4/conf.d/data_local_acl <<'EOF' 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 + !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 ; 10.173.8.1 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 + !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 ; 10.173.8.1 condition = ${if < {$message_size}{5000K}} spam = Debian-exim:true add_header = X-Spam_score_int: $spam_score_int @@ -723,43 +747,6 @@ warn EOF -case $HOSTNAME in - $MAIL_HOST) - cat >/etc/exim4/conf.d/auth/29_exim4-config_auth <<'EOF' -# from 30_exim4-config_examples - -plain_server: -driver = plaintext -public_name = PLAIN -server_condition = "${if crypteq{$auth3}{${extract{1}{:}{${lookup{$auth2}lsearch{CONFDIR/passwd}{$value}{*:*}}}}}{1}{0}}" -server_set_id = $auth2 -server_prompts = : -.ifndef AUTH_SERVER_ALLOW_NOTLS_PASSWORDS -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 - # 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 @@ -788,56 +775,6 @@ dovecot_lmtp: envelope_to_add EOF -# this avoids some error. i cant remember what. todo: -# test it out and document why/if its needed. -cat >/etc/exim4/host_local_deny_exceptions <<'EOF' -mail.fsf.org -*.posteo.de -EOF - -# for iank@fsf.org, i have mail.fsf.org forward it to fsf@iankelling.org. -# and also have mail.iankelling.org whitelisted as a relay domain. -# I could avoid that if I changed this to submit to 587 with a -# password like a standard mua. -cat >/etc/exim4/conf.d/router/190_exim4-config_fsfsmarthost <<'EOF' -# smarthost for fsf mail -# ian: copied from /etc/exim4/conf.d/router/200_exim4-config_primary, and added senders = and -# replaced DCsmarthost with mail.fsf.org -fsfsmarthost: - debug_print = "R: smarthost for $local_part@$domain" - driver = manualroute - domains = ! +local_domains - senders = *@fsf.org - transport = remote_smtp_smarthost - route_list = * mail.fsf.org::587 byname - host_find_failed = ignore - same_domain_copy_routing = yes - no_more - -posteosmarthost: - debug_print = "R: smarthost for $local_part@$domain" - driver = manualroute - domains = ! +local_domains - senders = *@posteo.net - transport = remote_smtp_smarthost - route_list = * posteo.de::587 byname - host_find_failed = ignore - same_domain_copy_routing = yes - no_more - -gnusmarthost: - debug_print = "R: smarthost for $local_part@$domain" - driver = manualroute - domains = ! +local_domains - senders = *@gnu.org - transport = remote_smtp_smarthost - route_list = * fencepost.gnu.org::587 byname - host_find_failed = ignore - same_domain_copy_routing = yes - no_more -EOF - - cat >/etc/exim4/update-exim4.conf.conf <<'EOF' # default stuff, i havent checked if its needed dc_minimaldns='false' @@ -1102,78 +1039,62 @@ EOF ####### end dovecot-setup ######## } -# * nextcloud setup +# * thunderbird autoconfig 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 - # install checker, nextcloud/settings/admin/overview - pi php-gmp php-bcmath php-imagick php-apcu +if [[ $HOSTNAME == bk ]]; then + /a/exe/web-conf apache2 autoconfig.expertpathologyreview.com + dir=/var/www/autoconfig.expertpathologyreview.com/html/mail + mkdir -p $dir + # taken from mailinabox + cat >$dir/config-v1.1.xml <<'EOF' + + + + expertpathologyreview.com - cd /var/www - if [[ ! -e nextcloud/index.php ]]; then - wget https://download.nextcloud.com/server/releases/latest.zip - unzip -q latest.zip - rm -f 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 $nextcloud_admin_pass - fi - 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' -# https://docs.nextcloud.com/server/19/admin_manual/configuration_server/email_configuration.html -$CONFIG["mail_smtpmode"] = "sendmail"; -$CONFIG["mail_smtphost"] = "127.0.0.1"; -$CONFIG["mail_smtpport"] = 25; -$CONFIG["mail_smtptimeout"] = 10; -$CONFIG["mail_smtpsecure"] = ""; -$CONFIG["mail_smtpauth"] = false; -$CONFIG["mail_smtpauthtype"] = "LOGIN"; -$CONFIG["mail_smtpname"] = ""; -$CONFIG["mail_smtppassword"] = ""; -$CONFIG["mail_domain"] = "expertpathologyreview.com"; + expertpathologyreview.com Mail + expertpathologyreview.com -# https://github.com/nextcloud/user_external#readme -# plus mailinabox example -$CONFIG['user_backends'] = array(array('class' => 'OC_User_IMAP','arguments' => array('127.0.0.1', 143, null),),); + + mail2.iankelling.org + 993 + SSL + %EMAILADDRESS% + password-cleartext + + + mail2.iankelling.org + 587 + STARTTLS + %EMAILADDRESS% + password-cleartext + true + false + -# based on installer check -# https://docs.nextcloud.com/server/19/admin_manual/configuration_server/caching_configuration.html -$CONFIG['memcache.local'] = '\OC\Memcache\APCu'; + + expertpathologyreview.com website. + + -$CONFIG['overwrite.cli.url'] = 'https://expertpathologyreview.com/nextcloud'; -$CONFIG['htaccess.RewriteBase'] = '/nextcloud'; -$CONFIG['trusted_domains'] = array ( - 0 => 'expertpathologyreview.com', - ); -#$CONFIG[''] = ''; -fwrite(STDOUT, " + + + %EMAILADDRESS% + + + + + + + EOF - php tmp.php >config.php 2>/dev/null - rm tmp.php - sudo -u www-data php /var/www/nextcloud/occ maintenance:update:htaccess - list=$(sudo -u www-data php /var/www/nextcloud/occ --output=json_pretty app:list) - for app in contacts calendar user_external; do - if [[ $(printf "%s\n" "$list"| jq ".enabled.$app") == null ]]; then - m sudo -u www-data php /var/www/nextcloud/occ app:install $app - fi - done - - # todo: install apps with occ. contacts, calendar, mail -} +fi # * roundcube setup -roundcube-setup() { +if [[ $HOSTNAME == bk ]]; then ### begin composer install # https://getcomposer.org/doc/faqs/how-to-install-composer-programmatically.md @@ -1221,7 +1142,7 @@ roundcube-setup() { fi m wget -nv -N https://github.com/roundcube/roundcubemail/releases/download/$v/$f new_timestamp=$(stat -c %Y $f) - if [[ $timestamp != $new_timestamp || ! -e $rcdir/config/secret ]]; then + if [[ $timestamp != "$new_timestamp" || ! -e "$rcdir/config/secret" ]]; then m tar -C /usr/local/lib --no-same-owner -zxf $f m rm -rf $rcdir m mv $rcdir-$v $rcdir @@ -1262,11 +1183,16 @@ Alias /nextcloud "/var/www/nextcloud/" # based on install checker, links to # https://docs.nextcloud.com/server/19/admin_manual/issues/general_troubleshooting.html#service-discovery -RewriteRule ^\.well-known/host-meta /nextcloud/public.php?service=host-meta [QSA,L] -RewriteRule ^\.well-known/host-meta\.json /nextcloud/public.php?service=host-meta-json [QSA,L] -RewriteRule ^\.well-known/webfinger /nextcloud/public.php?service=webfinger [QSA,L] -RewriteRule ^\.well-known/carddav /nextcloud/remote.php/dav/ [R=301,L] -RewriteRule ^\.well-known/caldav /nextcloud/remote.php/dav/ [R=301,L] +# their example was a bit wrong, I figured it out by adding +# LogLevel warn rewrite:trace5 +# then watching the apache logs + +RewriteEngine on +RewriteRule ^/\.well-known/host-meta /nextcloud/public.php?service=host-meta [QSA,L] +RewriteRule ^/\.well-known/host-meta\.json /nextcloud/public.php?service=host-meta-json [QSA,L] +RewriteRule ^/\.well-known/webfinger /nextcloud/public.php?service=webfinger [QSA,L] +RewriteRule ^/\.well-known/carddav /nextcloud/remote.php/dav/ [R=301,L] +RewriteRule ^/\.well-known/caldav /nextcloud/remote.php/dav/ [R=301,L] ### end nextcloud settings EOF @@ -1274,7 +1200,6 @@ EOF 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 <>/etc/exim4/update-exim4.conf.conf </etc/php/$phpver/fpm/pool.d/localwww.conf <<'EOF' +[www] +clear_env = no EOF - cat >>/etc/exim4/conf.d/main/000_local <tmp.php <<'EOF' +# https://docs.nextcloud.com/server/19/admin_manual/configuration_server/email_configuration.html +$CONFIG["mail_smtpmode"] = "sendmail"; +$CONFIG["mail_smtphost"] = "127.0.0.1"; +$CONFIG["mail_smtpport"] = 25; +$CONFIG["mail_smtptimeout"] = 10; +$CONFIG["mail_smtpsecure"] = ""; +$CONFIG["mail_smtpauth"] = false; +$CONFIG["mail_smtpauthtype"] = "LOGIN"; +$CONFIG["mail_smtpname"] = ""; +$CONFIG["mail_smtppassword"] = ""; +$CONFIG["mail_domain"] = "expertpathologyreview.com"; + +# https://github.com/nextcloud/user_external#readme +# plus mailinabox example +$CONFIG['user_backends'] = array(array('class' => 'OC_User_IMAP','arguments' => array('127.0.0.1', 143, null),),); + + +# based on installer check +# https://docs.nextcloud.com/server/19/admin_manual/configuration_server/caching_configuration.html +$CONFIG['memcache.local'] = '\OC\Memcache\APCu'; + +$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 + list=$(sudo -u www-data php /var/www/nextcloud/occ --output=json_pretty app:list) + for app in contacts calendar user_external; do + if [[ $(printf "%s\n" "$list"| jq ".enabled.$app") == null ]]; then + m sudo -u www-data php /var/www/nextcloud/occ app:install $app + fi + done +fi + +# * exim host conditional config + +# ** auth +case $HOSTNAME in + $MAIL_HOST) + cat >/etc/exim4/conf.d/auth/29_exim4-config_auth <<'EOF' +# from 30_exim4-config_examples +plain_server: +driver = plaintext +public_name = PLAIN +server_condition = "${if crypteq{$auth3}{${extract{1}{:}{${lookup{$auth2}lsearch{CONFDIR/passwd}{$value}{*:*}}}}}{1}{0}}" +server_set_id = $auth2 +server_prompts = : +.ifndef AUTH_SERVER_ALLOW_NOTLS_PASSWORDS +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 + + +case $HOSTNAME in + # ** $MAIL_HOST|bk) + $MAIL_HOST|bk) + dovecot-setup + m systemctl enable dovecot + m systemctl restart dovecot + cat >>/etc/exim4/update-exim4.conf.conf <>/etc/exim4/conf.d/main/000_local <>/etc/exim4/conf.d/main/000_local-nn </etc/exim4/host_local_deny_exceptions <<'EOF' +mail.fsf.org +*.posteo.de +EOF + + # for iank@fsf.org, i have mail.fsf.org forward it to fsf@iankelling.org. + # and also have mail.iankelling.org whitelisted as a relay domain. + # I could avoid that if I changed this to submit to 587 with a + # password like a standard mua. + cat >/etc/exim4/conf.d/router/190_exim4-config_fsfsmarthost <<'EOF' +# smarthost for fsf mail +# ian: copied from /etc/exim4/conf.d/router/200_exim4-config_primary, and added senders = and +# replaced DCsmarthost with mail.fsf.org +fsfsmarthost: + debug_print = "R: smarthost for $local_part@$domain" + driver = manualroute + domains = ! +local_domains + senders = *@fsf.org + transport = remote_smtp_smarthost + route_list = * mail.fsf.org::587 byname + host_find_failed = ignore + same_domain_copy_routing = yes + no_more + +posteosmarthost: + debug_print = "R: smarthost for $local_part@$domain" + driver = manualroute + domains = ! +local_domains + senders = *@posteo.net + transport = remote_smtp_smarthost + route_list = * posteo.de::587 byname + host_find_failed = ignore + same_domain_copy_routing = yes + no_more + +gnusmarthost: + debug_print = "R: smarthost for $local_part@$domain" + driver = manualroute + domains = ! +local_domains + senders = *@gnu.org + transport = remote_smtp_smarthost + route_list = * fencepost.gnu.org::587 byname + host_find_failed = ignore + same_domain_copy_routing = yes + no_more +EOF + + # Greping /etc/exim4, unqualified mails this would end up as + # a return path, so it should go somewhere we will see. + # The debconf output about mailname is as follows: + # The 'mail name' is the domain name used to 'qualify' mail addresses without a domain + # name. + # This name will also be used by other programs. It should be the single, fully + # qualified domain name (FQDN). + # Thus, if a mail address on the local host is foo@example.org, the correct value for + # this option would be example.org. + # This name won\'t appear on From: lines of outgoing messages if rewriting is enabled. + echo iankelling.org > /etc/mailname + sudo rsync -ahhi --chown=root:Debian-exim --chmod=0640 \ /p/c/filesystem/etc/exim4/passwd /p/c/filesystem/etc/exim4/*.pem /etc/exim4/ @@ -1517,51 +1637,16 @@ EOF # 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/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 <$f <<'EOF' #!/bin/bash @@ -1570,109 +1655,73 @@ wget -q -N https://publicsuffix.org/list/public_suffix_list.dat EOF m chmod 755 $f - # make all system users be aliases - for user in $(awk 'BEGIN { FS = ":" } ; $6 !~ /^\/home/ { print $1 }' /etc/passwd); do - if ! grep -q "^$user:" /etc/aliases; then - echo "$u: root" |tee -a /etc/aliases - fi - done + ;; + # ** bk + ## we use this host to monitor MAIL_HOST and host a mail server for someone + bk) + echo bk.b8.nz > /etc/mailname + + cat >/etc/myexim4/conf.d/router/180_vpnmanual <<'EOF' +# copied from dnslookup, altered domains, added route_list, +# changed driver, removed ignore_target_hosts since it +# relies on a later defined macro +vpnmanual: + debug_print = "R: dnslookup for $local_part@$domain" + driver = manualroute + domains = iankelling.org:zroe.org + transport = remote_smtp + same_domain_copy_routing = yes + route_list = * 10.8.0.4 + no_more +EOF + tmpdir=$(mktemp -d) + cp -a /etc/init.d/exim4 $tmpdir/exim4in + sed -i -f - $tmpdir/exim4in <<'EOF' +s,/etc/default/exim4,/etc/default/exim4in,g +s,/run/exim4/exim.pid,/run/exim4/eximin.pid,g +EOF + tmp=$(rsync -ic $tmpdir/* /etc/init.d) + rm -rf $tmpdir - m systemctl start openvpn-client-mail@mail - m systemctl enable openvpn-client-mail@mail + tmpdir=$(mktemp -d) + cat >$tmpdir/alwaysrestart.conf <<'EOF' +[Unit] +# needed to continually restart +StartLimitIntervalSec=0 - /a/exe/cedit nn.b8.nz /etc/hosts <<'EOF' || [[ $? == 1 ]] -# note: i put this into bind for good measure -10.173.8.2 nn.b8.nz -# this is just here to avoid mainlog errors, however, it doesnt seem to work -# todo: look into it more. nsswitch.conf? cached result? i dunno -# list matching forced to fail: failed to find host name for 10.173.8.1 -10.173.8.1 defaultnn.b8.nz +[Service] +Restart=always +# time to sleep before restarting a service +RestartSec=1 EOF + mkdir -p /etc/systemd/system/exim4in.service.d + tmp+=$(rsync -ic $tmpdir/* /etc/systemd/system/exim4in.service.d) + if [[ $tmp ]]; then + printf "rsync to /etc/systemd/system/exim4in.service.d\n%s\n" "$tmp" + m systemctl daemon-reload + fi - rsync -ra --delete /etc/exim4/ /etc/myexim4 - cat >>/etc/myexim4/update-exim4.conf.conf <<'EOF' -dc_eximconfig_configtype='smarthost' -dc_smarthost='nn.b8.nz' + cat >/etc/default/exim4in <<'EOF' +# defaults but no queue runner and alternate config dir +QUEUERUNNER='no' +COMMONOPTIONS='-oP /run/exim4/eximin.pid' +UPEX4OPTS='-d /etc/myexim4' EOF - update-exim4.conf -d /etc/myexim4 - - ;; - # ** bk - ## we use this host to monitor MAIL_HOST and host a mail server for someone - bk) # dkim, client passwd file rsync -ahhi --chown=root:Debian-exim --chmod=0640 \ /p/c/machine_specific/bk/filesystem/etc/exim4/* /etc/exim4 - echo mail2.iankelling.org > /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 - nextcloud-setup ;; # ** not MAIL_HOST and not bk *) - for unit in exim4 spamassassin; do + for unit in ${nn_progs[@]}; do f=/etc/systemd/system/$unit.service.d/nn.conf rm -fv $f done @@ -1691,14 +1740,12 @@ EOF m systemctl disable openvpn-client-mail@mail m systemctl stop openvpn-client-mail@mail - rm -fv /etc/exim4/conf.d/main/000_localmacros # old filename - - cat >>/etc/exim4/update-exim4.conf.conf <<'EOF' + cat >>/etc/exim4/update-exim4.conf.conf </etc/mailname + hostname -A|awk '{print $1}' >/etc/mailname cat >>/etc/exim4/update-exim4.conf.conf <>/etc/myexim4/update-exim4.conf.conf <<'EOF' +dc_eximconfig_configtype='smarthost' +dc_smarthost='nn.b8.nz' +EOF + ;;& + bk) + rm -f /etc/myexim4/conf.d/router/180_vpnmanual + # config for the non-nn exim + cat >/etc/myexim4/conf.d/main/000_local-nn <<'EOF' +MAIN_HARDCODE_PRIMARY_HOSTNAME = mail2.iankelling.org +EOF + ;; + $MAIL_HOST) + # for bk, we have a exim4in.service that will do this for us. + update-exim4.conf -d /etc/myexim4 + ;; +esac + # * spool dir setup # ** bind mount setup @@ -1741,11 +1812,11 @@ if [[ -e /nocow ]]; then After=local-fs.target After=network.target EOF - dir=/etc/systemd/system/exim4.service.d - mkdir -p $dir - tmp=$(install -vC $tmpdir/* $dir) + mkdir -p /etc/systemd/system/exim4.service.d + tmp=$(rsync -ic $tmpdir/* /etc/systemd/system/exim4.service.d) rm -rf $tmpdir if [[ $tmp ]]; then + printf "rsync to /etc/systemd/system/exim4.service.d\n%s\n" "$tmp" m systemctl daemon-reload fi if ! mountpoint -q $sdir; then @@ -1789,7 +1860,17 @@ fi -# * reload exim +# * start exim / spamassassin + +# start spamassassin before exim, stop it after so if we are +# transitioning from being mail_host to not, we dont have exim +# complaining about no spamassassin. +case $HOSTNAME in + $MAIL_HOST|bk) + m systemctl enable spamassassin + m systemctl start spamassassin + ;; +esac if systemctl is-active exim4 >/dev/null; then m systemctl reload exim4 @@ -1798,7 +1879,15 @@ else fi case $HOSTNAME in - bk|$MAIL_HOST) : ;; + $MAIL_HOST) : ;; + bk) + if systemctl is-active exim4in >/dev/null; then + m systemctl reload exim4in + else + m systemctl start exim4in + fi + m systemctl enable exim4in + ;; *) m systemctl stop spamassassin m systemctl disable spamassassin @@ -1822,14 +1911,14 @@ EOF ;;& $MAIL_HOST) test_from=ian@iankelling.org - test_to=testignore@bk.b8.nz + test_to=testignore@expertpathologyreview.com cat >>/etc/cron.d/mailtest <