X-Git-Url: https://iankelling.org/git/?a=blobdiff_plain;f=mail-setup;h=28e02ce089f63edc39362f7123610f77bc3ad578;hb=e958999a4ab6fddd723270b596b4899c0811fa41;hp=f8cb3ee83e05dec206fb5d9c7fe0103e0b1b1392;hpb=7d9ec600a5ed9f88b85e02a27ee017b85721a6ac;p=distro-setup diff --git a/mail-setup b/mail-setup index f8cb3ee..28e02ce 100755 --- a/mail-setup +++ b/mail-setup @@ -3,17 +3,6 @@ # Copyright (C) 2019 Ian Kelling # SPDX-License-Identifier: AGPL-3.0-or-later -# todo: sandbox / harden exim: -# 1. stop it from running as root. how? -# https://www.exim.org/exim-html-current/doc/html/spec_html/ch-security_considerations.html -# * avoid using .forward files, remove that router -# * set deliver_drop_privilege -# * set user to run as Debian-exim in systemd -# * set port to something like 2500, and forward 25 to 2500 with iptables. same for 587. -# https://superuser.com/questions/710253/allow-non-root-process-to-bind-to-port-80-and-443/1334552#1334552 -# * consider whether other routers like postmaster need modification / removal. -# 2. restrict its filesystem access from within systemd - # todo: harden dovecot. need to do some research. one way is for it to only listen on a wireguard vpn interface, so only clients that are on the vpn can access it. # todo: consider hardening cups listening on 0.0.0.0 # todo: stop/disable local apache, and rpc.mountd, and kdeconnect when not in use. @@ -26,8 +15,6 @@ # todo: emailing info@amnimal.ninja produces a bounce, user doesn't exist # instead of a simple rejection like it should. -# todo: auto restart of je on checkrestart - # todo: run mailping test after running, or otherwise # clear out terminal alert @@ -369,7 +356,7 @@ fi bhost_t=false case $HOSTNAME in $MAIL_HOST) : ;; - kd|frodo|x2|x3|kw|sy) + kd|frodo|x2|x3|kw|sy|bo) bhost_t=true ;; esac @@ -378,7 +365,7 @@ esac # * Install universal packages -# installs epanicclean +# installs epanicclean iptables-exim ip6tables-exim /a/bin/ds/install-my-scripts if [[ $(debian-codename-compat) == bionic ]]; then @@ -394,7 +381,7 @@ pi-nostart exim4 exim4-daemon-heavy spamassassin openvpn unbound clamav-daemon w # note: pyzor debian readme says you need to run some initialization command # but its outdated. -pi spf-tools-perl p0f postgrey pyzor razor jq moreutils certbot +pi spf-tools-perl p0f postgrey pyzor razor jq moreutils certbot fail2ban # bad packages that sometimes get automatically installed pu openresolv resolvconf @@ -418,21 +405,6 @@ fi # our nostart pi fails to avoid enabling -# * user forward file -case $HOSTNAME in - $MAIL_HOST) - # afaik, these will get ignored on MAIL_HOST because they are routing to my own - # machine, but rm them is safer - rm -fv $uhome/.forward /root/.forward - ;; - *) - # this can\'t be a symlink and has permission restrictions - # it might work in /etc/aliases, but this seems more proper. - e setting $uhome/.forward to $forward - install -m 644 {-o,-g}$u <(e $forward) $uhome/.forward - ;; -esac - # * Mail clean cronjob i /etc/systemd/system/mailclean.timer <<'EOF' @@ -498,18 +470,28 @@ case $HOSTNAME in ;; esac -i /etc/systemd/system/wg-quick@wgmail.service.d/override.conf <, Serg G. Brester +# made config file IPv6 capable (see new section Init?family=inet6) + +[INCLUDES] + +after = iptables-blocktype.local + iptables-common.local +# iptables-blocktype.local is obsolete + +[Definition] + +# Option: actionflush +# Notes.: command executed once to flush IPS, by shutdown (resp. by stop of the jail or this action) +# Values: CMD +# +actionflush = -F f2b- + + +[Init] + +# Option: chain +# Notes specifies the iptables chain to which the Fail2Ban rules should be +# added +# Values: STRING Default: INPUT +chain = INPUT + +# Default name of the chain +# +name = default + +# Option: port +# Notes.: specifies port to monitor +# Values: [ NUM | STRING ] Default: +# +port = ssh + +# Option: protocol +# Notes.: internally used by config reader for interpolations. +# Values: [ tcp | udp | icmp | all ] Default: tcp +# +protocol = tcp + +# Option: blocktype +# Note: This is what the action does with rules. This can be any jump target +# as per the iptables man page (section 8). Common values are DROP +# REJECT, REJECT --reject-with icmp-port-unreachable +# Values: STRING +blocktype = REJECT --reject-with icmp-port-unreachable + +# Option: returntype +# Note: This is the default rule on "actionstart". This should be RETURN +# in all (blocking) actions, except REJECT in allowing actions. +# Values: STRING +returntype = RETURN + +# Option: lockingopt +# Notes.: Option was introduced to iptables to prevent multiple instances from +# running concurrently and causing irratic behavior. -w was introduced +# in iptables 1.4.20, so might be absent on older systems +# See https://github.com/fail2ban/fail2ban/issues/1122 +# Values: STRING +lockingopt = -w + +# Option: iptables +# Notes.: Actual command to be executed, including common to all calls options +# Values: STRING +iptables = /usr/local/bin/iptables-exim + + +[Init?family=inet6] + +# Option: blocktype (ipv6) +# Note: This is what the action does with rules. This can be any jump target +# as per the iptables man page (section 8). Common values are DROP +# REJECT, REJECT --reject-with icmp6-port-unreachable +# Values: STRING +blocktype = REJECT --reject-with icmp6-port-unreachable + +# Option: iptables (ipv6) +# Notes.: Actual command to be executed, including common to all calls options +# Values: STRING +iptables = /usr/local/bin/ip6tables-exim +EOF + +i /etc/fail2ban/jail.d/exim.local <<'EOF' +[exim] +enabled = true +port = 25,587 +filter = exim +banaction = iptables-exim +EOF +if $ir; then + m systemctl restart fail2ban +fi + # * common exim4 config +## old, not using forward files anymore +rm -fv $uhome/.forward /root/.forward + + # 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 +# prevents things like cron mail for user without alias +awk 'BEGIN { FS = ":" } ; $6 !~ /^\/home/ || $7 ~ /\/nologin$/ { print $1 }' /etc/passwd| while read -r user; do if [[ ! $user ]]; then continue fi @@ -852,6 +953,20 @@ awk 'BEGIN { FS = ":" } ; $6 !~ /^\/home/ { print $1 }' /etc/passwd| while read fi done + +awk 'BEGIN { FS = ":" } ; $6 ~ /^\/home/ && $7 !~ /\/nologin$/ { print $1 }' /etc/passwd| while read -r user; do + case $HOSTNAME in + $MAIL_HOST) + sed -i "/^user:/d" /etc/aliases + ;; + *) + if ! grep -q "^$user:" /etc/aliases; then + echo "$user: root" |m tee -a /etc/aliases + fi + ;; + esac +done + if ! grep -q "^ncsoft:" /etc/aliases; then echo "ncsoft: graceq2323@gmail.com" |m tee -a /etc/aliases fi @@ -892,12 +1007,14 @@ fi m sed -ri 's/^(\s*rotate\s).*/\11000/' /etc/logrotate.d/exim4-base -## https://blog.dhampir.no/content/make-exim4-on-debian-respect-forward-and-etcaliases-when-using-a-smarthost -# i only need .forwards, so just doing that one. -cd /etc/exim4/conf.d/router -b=userforward_higher_priority -# replace the router name so it is unique -sed -r s/^\\S+:/$b:/ 600_exim4-config_userforward >175_$b +## disabled. not using .forward files, but this is still interesting +## for reference. +# ## https://blog.dhampir.no/content/make-exim4-on-debian-respect-forward-and-etcaliases-when-using-a-smarthost +# # i only need .forwards, so just doing that one. +# cd /etc/exim4/conf.d/router +# b=userforward_higher_priority +# # replace the router name so it is unique +# sed -r s/^\\S+:/$b:/ 600_exim4-config_userforward >175_$b # todo, consider 'separate' in etc/exim4.conf, could it help on busy systems? @@ -1268,7 +1385,7 @@ PrivateNetwork=true BindPaths=$bindpaths Restart=always # time to sleep before restarting a service -RestartSec=1000 +RestartSec=20 [Install] # for openvpn @@ -1381,8 +1498,8 @@ case $HOSTNAME in break fi done - for f in /p/c/subdir_files/sieve/*sieve /a/c/subdir_files/sieve/*sieve; do - m sudo -u $u /a/exe/lnf -T $f $uhome/sieve/${f##*/} + for f in /p/c/subdir_files/sieve/*sieve /a/bin/ds/subdir_files/sieve/*sieve; do + m sudo -u $u /a/exe/lnf -v -T $f $uhome/sieve/${f##*/} done # https://wiki.dovecot.org/SSL/DovecotConfiguration @@ -1415,7 +1532,6 @@ ssl = required ssl_cipher_list = ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384 ssl_protocols = TLSv1.2 ssl_prefer_server_ciphers = no -ssl_dh_parameters_length = 2048 protocol lmtp { #per https://wiki2.dovecot.org/Pigeonhole/Sieve/Configuration @@ -1727,7 +1843,7 @@ if [[ $HOSTNAME == bk ]]; then #### begin dl roundcube # note, im r2e subbed to https://github.com/roundcube/roundcubemail/releases.atom - v=1.4.11; f=roundcubemail-$v-complete.tar.gz + v=1.4.13; f=roundcubemail-$v-complete.tar.gz cd /a/opt if [[ -e $f ]]; then timestamp=$(stat -c %Y $f) @@ -1859,7 +1975,6 @@ EOF m chown -R www-data.www-data $rctmpdir /m/rc m chmod 750 $rctmpdir # Ensure the log file monitored by fail2ban exists, or else fail2ban can't start. - # todo: setup fail2ban # todo: check for other mailinabox things m sudo -u www-data touch $rclogdir/errors.log @@ -1966,7 +2081,7 @@ EOF 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 + fpm=$(dpkg-query -s php-fpm | sed -nr 's/^Depends:.* (php[^ ]*-fpm)( .*|$)/\1/p') # eg: php7.4-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 @@ -2160,7 +2275,7 @@ if (( ${#files[@]} )); then fi -# ** auth +# ** exim: auth case $HOSTNAME in bk|je) @@ -2196,7 +2311,7 @@ server_advertise_condition = ${if eq{$tls_in_cipher}{}{}{*}} EOF fi -# ** main daemon use non-default config file +# ** exim: main daemon use non-default config file case $HOSTNAME in bk|$MAIL_HOST) # to see the default comments in /etc/default/exim4: @@ -2207,8 +2322,11 @@ QUEUERUNNER='combined' QUEUEINTERVAL='30m' COMMONOPTIONS='-C /etc/exim4/my.conf' UPEX4OPTS='-o /etc/exim4/my.conf' -#E4BCD_PANICLOG_NOISE='malware acl condition: clamd /var/run/clamav/clamd\.ctl : unable to connect to UNIX socket' +#E4BCD_PANICLOG_NOISE='exim user lost privilege for using -C option' EOF + chown Debian-exim:Debian-exim /usr/sbin/exim4 + # needs guid set in order to become Debian-exim + chmod g+s,u+s /usr/sbin/exim4 i /etc/exim4/trusted_configs <<'EOF' /etc/exim4/my.conf EOF @@ -2222,7 +2340,45 @@ EOF ;; esac +# ** exim non-root + +case $HOSTNAME in + bk|je|li) + # no reason to expect it to ever be there. + rm -fv /etc/systemd/system/exim4.service.d/nonroot.conf + ;; + *) + i /etc/systemd/system/exim4.service.d/nonroot.conf <<'EOF' +[Service] +# see 56.2 Root privilege in exim spec +AmbientCapabilities=CAP_NET_BIND_SERVICE +# https://www.redhat.com/sysadmin/mastering-systemd +# things that seem good and reasonabl.e +PrivateTmp=yes +ProtectHome=yes +# note, in t10 systemd, if one of these is an sshfs mountpoint, +# this whole setting doesnt work. tried it with a newer systemd 250 though +# an nspawn, and it worked there. +InaccessiblePaths=d m media mnt nocow o p q +NoNewPrivileges=yes +ProtectSystem=yes + +# when we get newer systemd +#ProtectDevices=yes +EOF + i /etc/exim4/conf.d/main/000_local-noroot <<'EOF' +# see 56.2 Root privilege in exim spec +deliver_drop_privilege = true +EOF + # Note: there are other routers that would also fail due to not running as root, + # but afaik, the main router will catch all mail. If not, we will see + # something in the queue. + rm -fv /etc/exim4/conf.d/router/600_exim4-config_userforward + ;; +esac + case $HOSTNAME in + # ** $MAIL_HOST|bk|je) $MAIL_HOST|bk|je) @@ -2239,7 +2395,6 @@ EOF CHECK_RCPT_VERIFY_SENDER = true # default config comment says: If you enable this, you might reject legitimate mail, # but eggs has had this a long time, so that seems unlikely. -CHECK_DATA_VERIFY_HEADER_SYNTAX = true CHECK_RCPT_SPF = true CHECK_RCPT_REVERSE_DNS = true CHECK_MAIL_HELO_ISSUED = true @@ -2369,6 +2524,7 @@ ignore_target_hosts = ${HOSTNAME}wg.b8.nz # note changes here also require change in passwd.client route_list = * eximbackup.b8.nz same_domain_copy_routing = yes +errors_to = alerts@iankelling.org no_more EOF @@ -2382,9 +2538,8 @@ backup_remote: .endif hosts_require_auth = * hosts_try_auth = * - return_path = alerts@iankelling.org envelope_to_add - # manual return path because we dont want it to be the envelope sender + # manual return path because we want it to be the envelope sender # we got not the one we are using in this smtp transport headers_add = "Return-path: $sender_address" .ifdef REMOTE_SMTP_SMARTHOST_HOSTS_AVOID_TLS @@ -2422,10 +2577,10 @@ EOF # this avoids some error. i cant remember what. todo: # test it out and document why/if its needed. - i /etc/exim4/host_local_deny_exceptions <<'EOF' -mail.fsf.org -*.posteo.de -EOF + # i /etc/exim4/host_local_deny_exceptions <<'EOF' + # mail.fsf.org + # *.posteo.de + # EOF # cron email from smarthost hosts will automatically be to # USER@FQDN. I redirect that to alerts@, on the smarthosts, but in @@ -2508,10 +2663,12 @@ 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. + # + # # TODO: remove mx.iankelling.org once systems get updated mail-setup from jan 2022 cat >>/etc/exim4/update-exim4.conf.conf <>/etc/exim4/update-exim4.conf.conf <>/etc/exim4/update-exim4.conf.conf <>/etc/exim4/update-exim4.conf.conf <>/etc/exim4/conf.d/main/000_local-nn <<'EOF' + # spool_directory = /var/spool/myexim4 + # EOF cat >>/etc/myexim4/update-exim4.conf.conf <<'EOF' dc_eximconfig_configtype='smarthost' dc_smarthost='nn.b8.nz' @@ -2860,7 +3037,7 @@ sre exim4 case $HOSTNAME in $MAIL_HOST) m systemctl --now enable mailbindwatchdog - ;; + ;; *) soff mailbindwatchdog ;; @@ -2901,7 +3078,7 @@ EOF test_to="testignore@expertpathologyreview.com, testignore@je.b8.nz, testignore@amnimal.ninja, jtuttle@gnu.org" cat >>/etc/cron.d/mailtest <