Nachdem Anfang Mai 2021 mehrere Sicherheitslücken in Exim bekannt wurden, habe ich mich daran gemacht und mit den Möglichkeit von Systemd und AppArmor den Exim-Prozess weiter eingeschränkt. Dabei ist anzumerken, dass Exim auf dem Server nur eine Durchgangsstation ist: Er nimmt E‑Mails per Netzwerk für lokale Systeme entgegen und schreibt diese als Batched-SMTP in eine Datei in /srv/mail-relay oder liefert E‑Mails an externe Systeme aus, die lokal per /usr/sbin/sendmail abgegeben werden. Daher brauche ich keine komplexe Filterung für lokale Benutzer oder andere Hilfsprozesse wie Spamfilter.
Systemd-Beschränkungen für Exim
Ausgehend von meiner Grundeinstellungen zur Härtung mit Systemd musste ich folgende Beschränkungen lockern, damit Exim funktioniert:
[Service]
# Grundeinstellungen von https://jo-so.de/2021-05/H%C3%A4rtung-Systemd.html
…
CapabilityBoundingSet=CAP_CHOWN CAP_DAC_OVERRIDE CAP_DAC_READ_SEARCH \
CAP_FOWNER CAP_NET_BIND_SERVICE CAP_SETGID CAP_SETUID
NoNewPrivileges=false
# /var muss schreibbar sein
ProtectSystem=full
RestrictAddressFamilies=AF_INET AF_INET6
SystemCallFilter=@chown @setuid
AppArmor-Profil für Exim
Für AppArmor habe ich wieder mit einem Minimalprofil im complain-Modus
begonnen und mich Stück für Stück durch die audit-Meldungen vom Kernel
gearbeitet und die Regeln erstellt. Wer das Profil übernimmt, sollte auch für
einige Tage das Profil mit profile … flags=(complain) {
nutzen, um nur zu
beobachten, wo es Abweichungen gibt und es danach scharf (also in den
enforce-Modus) schalten.
include <tunables/global>
profile exim4 /{usr/,}sbin/exim4 {
include <abstractions/base>
include <abstractions/nameservice>
capability chown dac_override dac_read_search fowner setgid setuid,
/run/exim4/ r,
owner /run/exim4/exim.pid rw,
# Config
/etc/{aliases,email-addresses} r,
/etc/exim4/** r,
/var/lib/exim4/config.autogenerated{,.tmp} r,
/etc/letsencrypt/archive/jo-so.de/privkey*.pem r,
# Log
/var/log/exim4/{mainlog,paniclog,rejectlog} rw,
# Mail delivery
/var/mail/* rwkl,
/var/spool/exim4/ r,
/var/spool/exim4/** rw,
/var/spool/exim4/db/retry.lockfile k,
/var/spool/exim4/input/* k,
owner /srv/mail-relay/* rwkl,
# sub-processes
/usr/sbin/exim4 ix,
/{,usr/}bin/{dash,uname} ix,
/usr/bin/spfquery.mail-spf-perl ix,
# This is used by spfquery.mail-spf-perl
/usr/bin/spfquery.mail-spf-perl r,
/usr/share/perl{,5}/**.pm r,
}
Da ich für Systemd die Einstellung NoNewPrivileges=true
nutze, lassen sich
leider keine Subprofile für die Unterprozesse verwenden; sonst kommt man die
Meldung apparmor="DENIED" operation="exec" info="no new privs"
. Daher müssen
alle entsprechenden Rechte im Hauptprofil definiert werden und die Unterprozesse
dieses Profil erben; Option ix
. Leider konnte ich nicht die Stelle ausfindig
machen, die den Aufruf von /bin/sh -c uname
verursacht, weshalb ich diesen
Zugriff nur zulassen konnte.