Linux: E-Mails mit Stunnel, Getmail, OpenSMTPd, Dovecot und Tor

Verschlüsselt, anonymisiert, schützt alles!

Die Anleitung richtet ein Mailsystem für einen Rechner mit einem Benutzer ein, für den mit getmail 6 verschlüsselt über Stunnel und optional „anonymisiert“ über Tor E-Mails von verschiedenen POP3 Konten mehrerer Anbieter abgeholt werden, die der Benutzer anschließend neben den internen E-Mails, die OpenSMTPd zustellt, gesammelt über Dovecot als lokalem POP3 Server mit seiner E-Mail Anwendung abruft. E-Mails zum Versand versendet der Benutzer mit seiner E-Mail Anwendung oder dem Mixmaster Remailer Client verschlüsselt über Stunnel und optional „anonymisert“ über Tor. Zu Getmail wird auch die Einbindung von SpamAssassin und ClamAV zur Spam- und Malware-Erkennung angesprochen.

Man kann die Komponenten zusätzlich mit AppArmor und Chroot-Umgebungen oder Chroot-Funktionen regulieren und absichern, worauf die Anleitung nicht eingeht. Falls man die Anleitung umsetzen will, sollte man vorher ein vollständiges Backup aller Konfigurationen, Verzeichnisse, Dateien etc. des bisher eingesetzten Mailsystems anfertigen. Nach dem Backup und vor der praktischen Umsetzung sollten alle beteiligten Dienste, ev. Cron-Jobs usw. des bisherigen Mailsystems gestoppt oder deinstallieren werden.

Stunnel

Stunnel tunnelt die Verbindungen von Anwendungen über TLS-Tunnel, basierend auf OpenSSL, die selbst keine TLS-Verschlüsselung beherschen oder Server-Zertifikate nicht verifizieren können. Stunnel kann aber auch für Anwendungen verwendet werden, die TLS beherrschen, wenn man sich nicht auf die Verschlüsselungsfunktionen der Anwendungen verlassen oder weil man genaue Vorgaben und spezielle Optionen bezüglich der TLS-Verschlüsselung setzen will. Allerdings muss man sich mit Stunnel auf die Sicherheit von OpenSSL und Stunnel verlassen.

Installation

Nach dem Download der Stunnel Quellcode-Archivdatei, der GnuPG-Signaturdatei und/oder SHA256 Prüfummendatei, wird die Archivdatei nach Import des auf der Seite verlinkten GnuPG-Schlüssels überprüft:

cd /pfad/downloadverzeichnis
gpg --verify stunnel-version.tar.gz.asc
sha256sum -c stunnel-version.tar.gz.sha256

Nach erfolgreicher Überprüfung wird Stunnel kompiliert und installiert:

tar -xzf stunnel-version.tar.gz
cd stunnel-version
./configure --sysconfdir=/etc --localstatedir=/var [--disable-ipv6] --disable-libwrap --disable-fips --disable-systemd
make
sudo make install

Benutzerkonto

Neues Konto und nötige Verzeichnisse für den stunnel Systembenutzer anlegen:

sudo adduser --system --disabled-password --disabled-login --home /run/stunnel --shell /bin/false --group stunnel
id -u stunnel
sudo mkdir /var/log/stunnel
sudo mkdir /run/stunnel
sudo chown stunnel:adm /var/log/stunnel
sudo chown stunnel:stunnel /run/stunnel
sudo chmod 750 /var/log/stunnel
sudo chmod 2750 /run/stunnel

Logrotation

Die folgende Konfiguration zum Rotieren der Stunnel Logdateien anlegen:

/etc/logrotate.d/stunnel
/var/log/stunnel/*.log {
        daily
         missingok
         rotate 4
         compress
         delaycompress
         notifempty
         create 640 stunnel adm
         sharedscripts
         copytruncate
}
sudo mv /pfad/stunnel /etc/logrotate.d/
sudo chown root:root /etc/logrotate.d/stunnel
sudo chmod 644 /etc/logrotate.d/stunnel

Konfiguration

Die folgende Stunnel Konfigurationsdatei installieren:

/etc/stunnel/stunnel.conf
; generelle Stunnel Optionen
debug = 7
foreground = no
log = append
output = /var/log/stunnel/stunnel.log
pid = /run/stunnel/stunnel.pid
socket = l:TCP_NODELAY=1
socket = r:TCP_NODELAY=1
syslog = no
 
; generelle OpenSSL Optionen
RNDbytes = 32
RNDfile = /dev/urandom
CApath = /etc/ssl/certs
CRLpath = /etc/ssl/crls
ciphers = Liste (für TLSv1.2)
ciphersuites = Liste (für TLSv1.3)
; curves oder curves = Kurvenname oder Liste d. Kurvennamen
sslVersionMin = TLSv1.2
sslVersionMax = TLSv1.3
options = NO_COMPRESSION
options = NO_TICKET
options = SINGLE_DH_USE
options = -TLS_ROLLBACK_BUG
options = -CIPHER_SERVER_PREFERENCE
options = -ALLOW_UNSAFE_LEGACY_RENEGOTIATION
options = -LEGACY_SERVER_CONNECT
renegotiation = no
sessionCacheSize = 1
sessionCacheTimeout = 1
 
; E-Mail Konten
[konto-pop]
accept = 127.0.0.1:nnn1
; protocol = pop3
connect = pop.domain.tld:995
; mit Tor Onion Service:
connect = string.onion:995
sni = pop.domain.tld
checkHost = [pop.]domain.tld
verify = 3
requireCert = no
verifyPeer = yes
securityLevel = >=2
 
[konto-smtp]
accept = 127.0.0.1:nnn2
; protocol = smtp
connect = smtp.domain.tld:[465|587]
; mit Tor Onion Service:
connect = string.onion:[465|587]
sni = smtp.domain.tld
checkHost = [smtp.]domain.tld
verify = 3
requireCert = no
verifyPeer = yes
securityLevel = >=2
 
; [remailer-smtp]
; accept = 127.0.0.1:2525
; protocol = smtp
; connect = sub.remailer.tld:[465|587]
; sni = sub.remailer.tld
; verify = 4
; securityLevel = >=2
sudo mv /pfad/stunnel.conf /etc/stunnel/stunnel.conf
sudo chown root:stunnel /etc/stunnel/stunnel.conf
sudo chmod 640 /etc/stunnel/stunnel.conf

Erläuterung

Generelle Stunnel Optionen

Siehe man stunnel.

E-Mail Konten

Für jedes E-Mail Konto wird dessen Konfiguration in einem eigenen [Konto-Abschnitt] festgelegt. Mit accept = 127.0.01:Port teilt man Stunnel mit, für das Konto lokal am angegebenen Port Verbindungen entgegenzunehmen. Muss man STARTTLS verwenden, ist die protocol = pop3|smtp Zeile anzugeben. Mit connect = Hostname:Port teilt man Stunnel den Hostnamen des Mailservers und dessen Port mit, zu dem Stunnel die Verbindung weiterleiten soll und mit sni = Hostname wird zwecks Server Name Indication laut RFC 3546 - Transport Layer Security (TLS) Extensions der Hostname des Mailservers nochmals eingetragen. Von den generellen Optionen abweichende Optionen kann man – wie z. B. verifiy im Remailer Abschnitt – ebenfalls angeben.

Mit der verify Option bestimmt man, wie das Server-Zertifikat des Mailservers überprüft wird. Mit verify = 3 wird das vom Mailserver präsentierte Zertifikat gegen das lokal gespeicherte Server-Zertifikat des Mailservers und alle beteiligten CA-Zertifikate geprüft. Will man die CA-Zertifikate bzw. die Zertifikatskette ausschließen und nur das Server-Zertifikat prüfen, setzt man verify = 4. Im obigen Beispiel ist das im [remailer-smtp] Abschnitt der Fall, wenn z. B. ein Remailer ein selbstsigniertes Zertifikat verwendet. Zusätzlich kann man mit der checkHost Option einen Host- bzw. Domainnamen angeben, der im Server-Zertifikat enthalten sein muss.

Mit der securityLevel Option wird vorgegeben, welchen Sicherheitsgrad eine TLS-Verbindung ingesammt aufweisen muss, ausgedrückt in 80 - 256bit oder Level 0 – 5 (siehe man SSL_CTX_set_security_level). Das umfasst Cipher-Suites, TLS-Versionen, Algorithmen und Längen der verwendeten Schlüssel und MACs, Kompression, Session-Tickets. Zum Beispiel bestimmt Level 2 (112bit): RSA, DSA und DH Schlüssel >= 2048bit, ECC Schlüssel >=224bit, keine Export Cipher-Suites oder Cipher-Suites mit RC4, kein SSLv3, deaktivierte Kompression und Level 3 (128bit): zusätzlich RSA, DSA und DH Schlüssel >= 3072bit, ECC Schlüssel >=256bit, keine Cipher-Suites ohne Forward Secrecy, kein TLS < 1.1, deaktivierte Session-Tickets. Der maximale Sicherheitsgrad, den man setzen kann ist natürlich abhängig davon, was der Mailserver bzw. Mailanbieter maximal unterstützt.

Wer Mixmaster oder Mixmaster4096 verwendet und selbst kompiliert, kann vorher in der mix.c Datei die SMTPPORT Variable auf die Portnummer ändern, an der Stunnel auf Verbindungen zu dem Mixmaster Remailer lauscht, der Mixmaster Nachrichten per TLS oder STARTTLS entgegennimmt, da zumeist bereits ein lokaler MTA auf Port 25 lauscht.

mixmaster/src/mix.c
/* addresses */
SMTPPORT = 25;

Anschließend trägt man in seine mix.cfg Konfigurationsdatei für Mixmaster ein:

mix.cfg
REMAIL          n
SMTPRELAY       127.0.0.1
SMTPPORT        2525
CHAIN           sub.remailer.tld,*,*,*
Generelle OpenSSL Optionen

Welche TLS-Versionen und Cipher-Suites Stunnel für eine verschlüsselte Verbindung mit einem Mailserver verwendet, richtet sich nach den sslVersion Optionen, mit dem man vorgibt, welche TLS-Versionen akzeptiert bzw. unterstützt werden und den Parametern der ciphersuites bzw. ciphers Option, mit der man den Katalog der Cipher-Suites angibt, die Stunnel dem Mailserver als unterstützte Cipher-Suites signalisiert. Da man nur >= TLS 1.2 als TLS-Version einsetzen sollte, wird sslVersionMin = TLSv1.2, sslVersionMax = TLSv1.3 gesetzt. Wenn ein E-Mail Anbieter z. B. nur TLS < 1.2 anbietet, sollte man den Anbieter aufgeben.

Mit options = -OPTION könnnen zusätzliche OpenSSL Optionen „deaktiviert“ bzw. von Stunnel nicht verwendet werden. Die Optionen dienen dazu, die Aufnahme und TLS-Verschlüsselung der Verbindung möglichst sicher einzurichten. So werden u. a. Maßnahmen gegen TLS-Angriffe explizit aktiviert, jede TLS-Verbindung bzw. -Sitzung soll sich genauso wie die Schlüssel des DH-Schlüsselaustauschs einmalig und neu gestalten, wenn das Neuaushandeln von TLS-Sitzungen aktiviert (renegotiation = yes) ist, dann soll nur das sichere Neuaushandeln möglich sein und die Auswahl des TLS-Protokolls und der verwendeten Cipher Suites soll nicht dem Zufall bzw. der Präferenz des Mailservers überlassen, sondern durch Stunnel dem Mailserver (im Rahmen der von ihm unterstützen Protokollversionen und Cipher Suites) vorgegeben werden.

Für nähere Informationen zur Bestimmung der options OpenSSL Optionen:

sudo aptitude install libssl-doc libssl-dev
man SSL_CTX_set_options
less /usr/include/openssl/ssl.h
stunnel -options

Für nähere Informationen zu Algorithmen und Cipher-Suites, die von der installierten OpenSSL-Version unterstützt werden:

openssl ciphers -v
man ciphers

Für nähere Informationen zu den von der installierten OpenSSL-Version implementierten Kurven für die curve Stunnel Option und die ECDHE Cipher Suites:

openssl ecparam -list_curves

Solange die verwendete OpenSSL-Version keine Alternativen implementiert hat, bleibt nur, eine Kurve wie prime256v1 für die curves Option einzusetzen.

curves = prime256v1

Mit aktuelleren OpenSSL-Versionen (>= 1.1.1) können mehrere Kurvennamen in eine Liste eingesetzt werden:

curves = X448:X25519:P-521:P384:P-256

Für die ciphers Option kann man z. B. setzen:

ciphers = ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES128-GCM-SHA256

Für die ciphersuites Option kann man z. B. einsetzen:

ciphersuites = TLS_CHACHA20_POLY1305_SHA256:TLS_AES_256_GCM_SHA384:TLS_AES_128_GCM_SHA256

Prüfung der Mailserver

Zur Bestimmung der generellen OpenSSL Optionen und der kontenspezifischen Optionen in jedem E-Mail [Konto-Abschnitt] muss man zu jedem E-Mail Konto neben dem Hostnamen des POP3 und SMTP Servers außerdem in Erfahrung bringen:

  • soll oder kann die Verbindung zum Mailserver per TLS und/oder STARTTLS erfolgen?
  • auf welchen Ports lauscht der Mailserver?
  • wie lautet die maximale TLS-Version, die der Mailserver unterstützt?
  • welche Cipher Suites unterstützt der Mailserver?

Für die benötigten Informationen kann man z. B. das sslyze Python-Skript verwenden, um die Server vorab zu überprüfen. Eine sslyze Alternative ist das testssl TLS-Prüfskript.

mit testssl
testssl --cipher-per-proto --preference --server-defaults --quiet hostname:port
mit sslyze

Nach Prüfung mit --tlsv1_2 zur Verwendung der TLS-Protokollversion 1.2 wird mit --reneg getestet, ob der Mailserver das client-initiierte Neuaushandeln und das sichere Neuaushandeln von TLS-Sitzungen (s. o.) unterstützt. Das Resultat kann ein Indikator dafür sein, ob der Anbieter Wert auf die Absicherung von TLS-Verbindungen legt. Mit --hide_rejected_ciphers werden die Cipher-Suites nicht ausgegeben, die vom Mailserver eh nicht unterstützt werden.

cd /pfad/sslyze
./sslyze.py --help

TLS zum POP3 Server

./sslyze.py --sni pop.domain.tld --reneg --certinfo=full --tlsv1_2 --hide_rejected_ciphers pop.domain.tld:995

TLS zum SMTP Server

./sslyze.py --sni smtp.domain.tld --reneg --certinfo=full --tlsv1_2 --hide_rejected_ciphers smtp.domain.tld:[465|587]

STARTTLS zum POP3 Server

./sslyze.py --starttls=pop3 --sni pop.domain.tld --reneg --certinfo=full --tlsv1_2 --hide_rejected_ciphers pop.domain.tld:[110|995]

STARTTLS zum SMTP Server

./sslyze.py --starttls=smtp --sni smtp.domain.tld --reneg --certinfo=full --tlsv1_2 --hide_rejected_ciphers smtp.domain.tld:[587|465]

Beispielausgabe (gekürzt) für die Überprüfung des POP3 Servers des E-Mal Anbieters Posteo:

./sslyze.py --sni posteo.de --reneg --certinfo=full --tlsv1_2 --hide_rejected_ciphers posteo.de:995
CHECKING HOST(S) AVAILABILITY
-----------------------------
posteo.de:995  => 89.146.220.134:995

SCAN RESULTS FOR POSTEO.DE:995 - 89.146.220.134:995
---------------------------------------------------
* TLSV1_2 Cipher Suites:
    Preferred:                       
              ECDHE-RSA-AES256-GCM-SHA384   ECDH-384 bits  256 bits
    Accepted:                        
              ECDHE-RSA-AES256-SHA384       ECDH-384 bits  256 bits
              ECDHE-RSA-AES128-SHA256       ECDH-384 bits  128 bits
              ECDHE-RSA-AES128-GCM-SHA256   ECDH-384 bits  128 bits
              ...
              DHE-RSA-AES128-GCM-SHA256     DH-1024 bits   128 bits

TLS mit TLS 1.2 zu posteo:995 ist möglich.

./sslyze.py --starttls=pop3 --sni posteo.de --reneg --certinfo=full --tlsv1_2 --hide_rejected_ciphers posteo.de:995
CHECKING HOST(S) AVAILABILITY
-----------------------------
posteo.de:995  => WARNING: Could not connect (timeout); discarding corresponding tasks.

STARTTLS mit TLS 1.2 zu posteo.de:995 ist nicht möglich.

./sslyze.py --starttls=pop3 --sni posteo.de --reneg --certinfo=full --tlsv1_2 --hide_rejected_ciphers posteo.de:110
SCAN RESULTS FOR POSTEO.DE:110 - 89.146.220.134:110
---------------------------------------------------
siehe 1. Kommando

STARTTLS mit TLS 1.2 zu posteo.de:110 ist möglich.

Bezüglich der zu efragenden Merkmale:

  • Hostname: posteo.de
  • Verbindung möglich per TLS auf Port 995 oder STARTTLS auf Port 110
  • TLS 1.2 Protokoll wird unterstützt
mit openssl s_client

Außerdem benötigt man das aktuelle und geprüfte Server-Zertifikat der Server und begleitende Metadaten.

TLS zum POP3 Server

openssl s_client -connect pop.domain.tld:[995|110] -no_ssl3 -no_tls1 -no_tls1_1 -verify 3 -CApath /etc/ssl/certs/

TLS zum SMTP Server

openssl s_client -connect smtp.domain.tld:[465|587] -no_ssl3 -no_tls1 -no_tls1_1 -verify 3 -CApath /etc/ssl/certs/

STARTTLS zum POP3 Server

openssl s_client -connect pop.domain.tld:[110|995] -starttls pop3 -no_ssl3 -no_tls1 -no_tls1_1 -verify 3 -CApath /etc/ssl/certs/

STARTTLS zum SMTP Server

openssl s_client -connect smtp.domain.tld:[587|465] -starttls smtp -no_ssl3 -no_tls1 -no_tls1_1 -verify 3 -CApath /etc/ssl/certs/

Beispielausgabe (gekürzt) für die Überprüfung und den Download des POP3 Servers des E-Mal Anbieters Posteo:

openssl s_client -connect posteo.de:995 -no_ssl3 -no_tls1 -no_tls1_1 -verify 3 -CApath /etc/ssl/certs/
verify depth is 3
depth=2 ... CN = StartCom Certification Authority
verify return:1
depth=1 ... CN = StartCom EV Server CA
verify return:1
depth=0 ... CN = www.posteo.de
verify return:1

Die Überprüfung des Server-Zertifikats gegen die CA-Zertifikate im Zertifikatsspeicher (Zertifikatskette) ergab keine Probleme – sofern man der herkömmlichen PKI/CA Infrastruktur noch Vertrauen schenkt.

echo | openssl s_client -connect domain.tld:port -no_ssl3 -no_tls1 -no_tls1_1 -verify 3 -CApath /etc/ssl/certs/ | awk '/-----BEGIN CERTIFICATE-----/, /-----END CERTIFICATE-----/' > /pfad/domain_tld.pem

Der Zertifikats-Block des Servers wird in domain_tld.pem Dateien abgespeichert, als root in den Zertifikatsspeicher unter /etc/ssl/certs verschoben und die symbolischen Hash-Links im Zertifikatsspeicher aktualisiert:

sudo mv /pfad/domain_tld.pem /etc/ssl/certs
sudo chmod 644 /etc/ssl/certs/domain_tld.pem
sudo c_rehash /etc/ssl/certs

Der gleiche Vorgang wiederholt sich bei Ablauf der Gültigkeit und Aktualisierung eines Zertifikats. Deshalb lässt man sich noch den Fingerprint ausgeben und notiert sich aus der Ausgabe z. B. in einer Kalenderanwendung die wichtigsten Daten zu den Server-Zertifikaten:

openssl x509 -fingerprint -in /etc/ssl/certs/domain_tld.pem -text
openssl x509 -fingerprint -in /etc/ssl/certs/posteo_de.pem -text 
Beispiel: Posteo Zertifikat-Daten
posteo.de:995 (POP3)
SHA1 Fingerprint=3A:89:D8:AD:DC:A7:23:5C:8F:44:E9:DD:2E:85:6A:31:D2:D3:C9:70
Signature Algorithm: sha256WithRSAEncryption
Issuer: C=IL, O=StartCom Ltd., OU=StartCom Certification Authority, CN=StartCom Extended Validation Server CA
Validity
Not Before: Apr 16 13:03:06 2014 GMT
Not After : Apr 16 16:23:04 2016 GMT

Bei E-Mail Anbietern, die Angaben zu Fingerprints und aktuell gültigen Server-Zertifikaten auf ihren Webseiten veröffentlichen, wie z. B. im Posteo-Impressum, kann man den Fingerprint zusätzlich abgleichen. Außerdem kann man ergänzend regelmäßig die Stunnel Logdatei auf Unregelmäßigkeiten prüfen und sich Treffer per E-Mail zusenden lassen:

/etc/cron.d/stunnelzertcheck
# /etc/cron.d/stunnelcertcheck: Check auf Zertifikatefehler
MAILTO=""
PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin:/opt/bin
 
15 */3 * * * root    /pfad/bin/stunnelcheck
 
# EOF
/pfad/stunnelcheck
#!/bin/sh
 
stunnellog="/var/log/stunnel/stunnel.log"
match="$(egrep -c -i "(certificate (unknown|not found in local repository|(check|verify) failed)|public keys do not match)" $stunnellog)"
 
if [ "$match" -gt 0 ]; then
  printf "Zertifikat-Fehlermeldungen liegen vor\n" && \
  printf "Im stunnel.log wurden Zertifikat-Fehlermeldungen entdeckt:\n\n=====\n$(egrep -i -m 1 -n -B 22 -e "(certificate (unknown|not found in local repository|(check|verify) failed)|public keys do not match)" $stunnellog)\n=====\n\nBitte Zertifikate überprüfen und aktualisieren." | mail -s "[stunnel] Zertifikatfehler" root && \
  logrotate -f /etc/logrotate.d/stunnel
else
  exit 0
fi
 
exit 0

Inbetriebnahme

Die folgende systemd Unit-Datei installieren. Wer Stunnel ohne Tor betreibt, entfernt tor.service und ändert den ExecStart Aufruf in /usr/local/bin/stunnel.

/etc/systemd/system/stunnel.service
[Unit]
Description=Stunnel Daemon
After=network.target network-online.target tor.service
Wants=network-online.target tor.service
 
[Service]
Type=forking
RuntimeDirectory=stunnel
RuntimeDirectoryMode=02750
PIDFile=/run/stunnel/stunnel-mix.pid
User=stunnel
ExecStart=/etc/systemd/scripts/stunnel-tor
ExecReload=/bin/kill -HUP $MAINPID
Restart=always
RestartSec=180s
UMask=0027
PrivateTmp=true
PrivateDevices=true
InaccessiblePaths=/boot /root /home
ReadOnlyPaths=/etc /usr
ReadWritePaths=/var/log/stunnel
NoNewPrivileges=true
CapabilityBoundingSet=
RestrictNamespaces=~cgroup ipc net mnt pid user uts
LockPersonality=true
MemoryDenyWriteExecute=true
ProtectClock=true
ProtectControlGroups=true
ProtectHome=true
ProtectHostname=true
ProtectKernelLogs=true
ProtectKernelModules=true
ProtectKernelTunables=true
ProtectProc=invisible
ProtectSystem=full
ProcSubset=pid
RestrictAddressFamilies=AF_INET AF_UNIX
RestrictRealtime=true
RestrictSUIDSGID=true
RemoveIPC=true
SystemCallArchitectures=native
SystemCallFilter=@system-service
SystemCallErrorNumber=EPERM
 
[Install]
WantedBy=multi-user.target
sudo mv /pfad/stunnel.service /etc/systemd/system/stunnel.service
sudo chown root:root /etc/systemd/system/stunnel.service
sudo systemctl enable stunnel.service
sudo systemctl start stunnel.service

Wer die Stunnel-Verbindungen über Tor anonymisieren will und dafür torsocks installiert hat, installiert zusätzlich das stunnel-tor Skript:

/etc/systemd/scripts/stunnel-tor
#!/bin/sh
# mit torsocks Log:
LD_PRELOAD=/usr/local/lib/torsocks/libtorsocks.so TORSOCKS_LOG_LEVEL=5 TORSOCKS_LOG_FILE_PATH=/var/log/stunnel/torsocks.log /usr/local/bin/stunnel /etc/stunnel/stunnel.conf
# ohne torsocks Log:
LD_PRELOAD=/usr/local/lib/torsocks/libtorsocks.so /usr/local/bin/stunnel /etc/stunnel/stunnel.conf
 
exit 0
sudo mv /pfad/stunnel-tor /etc/systemd/scripts/
sudo chown root:root /etc/systemd/scripts/stunnel-tor
sudo chmod 755 /etc/systemd/scripts/stunnel-tor

Getmail

Getmail ist dafür zuständig, E-Mails mehrerer E-Mail Konten auf POP3 Servern abzuholen. Die Abholung wird per Cron-Job angestoßen und die TLS-Verschlüsselung über Stunnel durchgeführt. Die Stunnel Verbindungen können wiederum mit torsocks über Tor getunnelt und „anonymisiert“ werden. Da bei der herkömmlichen Verwendung von Getmail durch den Benutzer die Getmail Konfigurationsdateien im Heimatverzeichnis des Benutzers mit den enthalten E-Mail Anmeldenamen und Passphrasen im Klartext vorliegen (und damit hypothetisch ausgelesen werden könnten), wird die Getmail Konfiguration ausgelagert und der Prozess der Mail-Abolung nicht mehr durch den Benutzer durchgeführt, sondern durch einen eigenen getmail Systembenutzer. Der Benutzer hat danach auch keine eigene mbox Datei mehr unter /var/mail und auf die mbox Datei des getmail Systembenutzers keinen direkten Zugriff.

Installation

sudo aptitude install getmail6 lockfile-progs

Benutzerkonto

Für Getmail wird der getmail Systembenutzer angelegt, der mit Getmail die E-Mails abholt.

sudo adduser --system --disabled-password --disabled-login --home /var/lib/getmail --shell /bin/false --group getmail

Danach wird das getmail Heimatverzeichnis vorbereitet:

sudo mkdir /var/lib/getmail/{.getmail,.mail,.logs}

Übergabe an getmail bei bereits bestehender mbox Datei oder Anlegen der getmail mbox Datei:

sudo mv /var/mail/mboxdatei /var/mail/getmail
sudo chown -R getmail:mail /var/mail/
sudo chmod 770 /var/mail/
sudo chmod 660 /var/mail/getmail
sudo touch /var/mail/getmail
sudo chown -R getmail:mail /var/mail/
sudo chmod 770 /var/mail/
sudo chmod 660 /var/mail/getmail

Logrotation

Die folgende Konfiguration zum Rotieren der Getmail Logdateien anlegen:

/etc/logrotate.d/getmail
/var/lib/getmail/.logs/getmail.log
{
        rotate 2
        weekly
        missingok
        notifempty
        compress
        create 0640 getmail getmail
        prerotate
          if [ -f "/var/lock/getthemail.lock" ];
            then
               # Abholung aller E-Mails <= 10 Min.
                sleep 600
          fi
        endscript
}
sudo mv /pfad/getmail /etc/logrotate.d/
sudo chown root:root /etc/logrotate.d/getmail
sudo chmod 644 /etc/logrotate.d/getmail

Konfiguration

Für jedes E-Mail Konto, für das Getmail E-Mails von einem POP3 Server abholen soll, wird ein Unterverzeichnis in /var/lib/getmail/.getmail/ angelegt:

sudo mkdir /var/lib/getmail/.getmail/{konto1,konto2,kontoN}

In jedem Unterverzeichnis wird eine getmailrc Konfigurationsdatei nach folgendem Schema angelegt.

/var/lib/getmail/.getmail/konto/getmailrc
[retriever]
type = SimplePOP3Retriever
server = 127.0.0.1
port = nnnn
username = benutzername[@domain.tld]
password = passphrase
 
[filter-1]
type = Filter_classifier
path = /usr/bin/clamdscan
arguments = ("--stdout", "--no-summary", "-")
exitcodes_keep = (0,1)
 
[filter-2]
type = Filter_external
path = /usr/bin/reformail
arguments = ("-R", "X-getmail-filter-classifier:", "X-Virus-Clamscan:")
 
[filter-3]
type = Filter_external
path = /usr/bin/spamc
arguments = ("-p","spamd-port","-u","debian-spamd","-4","-s","1000000")
 
[destination]
type = Mboxrd # oder Maildir
path = /var/mail/getmail
 
[options]
verbose = 1
read_all = false
delete = true
message_log = ~/.logs/getmail.log
message_log_verbose = true
delivered_to = false

Erläuterung

[retriever]

Getmail bringt zwar auch den SimplePOP3SSLRetriever mit, der aber nicht so viele Optionen zur Konfiguration der TLS-Transportverschlüsselung bietet wie Stunnel, mit dem für den SimplePOP3Retriever die TLS-Transportverschlüsselung zum POP3 Server aufgebaut wird. Als Parameter der server und port Variablen wiederholen sich die accept = Angaben im [konto-pop] Abschnitt in der stunnel.conf Datei (s. o.). Anschließend folgen Benutzername und Passwort, mit denen man sich beim Mailserver anmeldet.

[filter[-n]]

Hier können optional alle möglichen Anwendungen als Filter eingebunden werden, an die Getmail E-Mails nach ihrem Erhalt zur Verarbeitung weiterleitet. Im obigen Beispiel wird mit dem ersten Filter die E-Mail mit clamdscan und dem clamd Daemon von ClamAV auf Malware untersucht. Mit exitcodes_keep = (0,1) werden E-Mails mit Funden nur markiert, mit exitcodes_drop = (1,) nicht ausgeliefert. Der zweite Filter schreibt mit Hilfe von reformail aus dem Maildrop Paket den Namen der Getmail Kopfzeile, in der das Resultat des ClamAV-Scans steht, in „X-Virus-Clamscan:“ um. Danach folgt als dritter Filter der Aufruf der spamc Anwendung für den spamd Daemon von SpamAssassin zur Spam-Erkennung und -Markierung.

[options]

Mit read_all = false holt Getmail nur E-Mails, die er noch nicht gesehen hat, also nur neue E-Mails und mit delete = true wird sichergestellt, dass E-Mails nach ihrer Abholung nicht auf dem POP3 Server verbleiben, sondern gelöscht werden. Vor dem ersten Start sollte man einmal read_all = true setzen, um die Mailbox auf dem POP3 Server vollständig zu leeren. Mit den optionalen message_log Optionen kann man die Mail-Abholung und aufgetretene Fehler über die getmail.log Logdatei protokollieren lassen.

Für alle E-Mail Konten werden die enstprechenden Getmail Konfigurationen in die passenden Kontenverzeichnisse verschoben und abschließend alles dem getmail Systembenutzer übergeben:

sudo mv /pfad/getmailrc /var/lib/getmail/.getmail/kontoN/
sudo chmod 750 /var/lib/getmail
sudo chown -R getmail:getmail /var/lib/getmail

Inbetriebnahme

Im Pfad wird das getmail_master Skript angelegt und für den getmail Systembenutzer ausführbar gemacht.

/usr/local/bin/getmail_master
#!/bin/sh
 
lock_file="/var/lock/getthemail"
 
if [ ! -f "${lock_file}".lock ]; then
  lockfile-create "${lock_file}"
  lockfile-touch "${lock_file}" &
  # Save the PID of the lockfile-touch process
  badger="$!"
  for getdir in $( find /var/lib/getmail/.getmail -name getmailrc -print | sed "s/\/getmailrc//g" )
  do
    /usr/bin/getmail -v --getmaildir=${getdir}
  done
  kill "${badger}"
  lockfile-remove "${lock_file}"
fi
 
exit 0
sudo mv /pfad/getmail_master /usr/local/bin/getmail_master
sudo chmod 750 /usr/local/bin/getmail_master
sudo chown root:getmail /usr/local/bin/getmail_master

Das Skript wird per Cron-Job Getmail für alle E-Mail Konten, für die eine getmailrc Konfigurationsdatei existiert (s. o.), die E-Mails abholen lassen. Nachdem die Konfiguration für Getmail und den getmail Systembenutzer abgeschlossen ist, wird der Getmail Cron-Job in /etc/cron.d/ angelegt:

/etc/cron.d/getmail
MAILTO=""
PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin
 
*/31 * * * * root    sudo -H -u getmail /usr/local/bin/getmail_master

Alle 31 Minuten werden als getmail Systembenutzer mit Getmail die E-Mails aller POP3 Konten über Stunnel abgerufen und nach der optionalen Filterung in der /var/mail/getmail mbox Datei gespeichert, die Dovecot als lokaler POP3 Server verwaltet. Der Benutzer holt alle externen und internen E-Mails mit seiner E-Mail Anwendung von Dovecot ab.

OpenSMTPd

Der OpenSMTPd Mailserver übernimmt als MTA die Aufgabe, E-Mail Benachrichtigungen von lokalen Diensten und Skripten entgegenzunehmen und in der mbox Mailbox des lokalen getmail Benutzers zu speichern.

Installation

sudo aptitude install opensmtpd

Konfiguration

sudo vi /etc/smtpd.conf
/etc/smtpd.conf
table aliases file:/etc/aliases
listen on lo inet4
action "local" mbox alias <aliases>
match for local action "local"

Da die E-Mails später als getmail Benutzer über Dovecot aus der mbox Datei von getmail abgerufen werden und dehalb auch alle internen E-Mails an getmail weiterzuleiten sind, müssen die Aliase geändert und danach aktualisieren werden:

sudo vi /etc/aliases
/etc/aliases
name:getmail
sudo smtpctl update table aliases
sudo systemctl stop opensmtpd.service
sudo systemctl disable opensmtpd.service
sudo cp /usr/lib/systemd/opensmtpd.service /etc/systemd/system/
sudo vi /etc/systemd/system/opensmtp.service
/etc/systemd/system/opensmtpd.service
[Unit]
Description=OpenSMTPD
After=syslog.target network.target
Wants=network.target
 
[Service]
Type=forking
ExecStart=/usr/sbin/smtpd
Restart=on-failure
RestartSec=10s
UMask=0027
PermissionsStartOnly=true
NoNewPrivileges=true
CapabilityBoundingSet=CAP_NET_BIND_SERVICE CAP_SETUID CAP_SETGID CAP_SYS_CHROOT CAP_KILL CAP_DAC_READ_SEARCH CAP_CHOWN
LockPersonality=true
MemoryDenyWriteExecute=true
PrivateDevices=true
PrivateTmp=true
InaccessiblePaths=/boot /root /home
ReadOnlyPaths=/etc /usr
ReadWritePaths=/var/mail/getmail /var/spool/smtpd
ProtectClock=true
ProtectControlGroups=true
ProtectHome=true
ProtectHostname=true
ProtectKernelLogs=true
ProtectKernelModules=true
ProtectKernelTunables=true
ProtectProc=invisible
ProtectSystem=full
ProcSubset=pid
RemoveIPC=true
RestrictAddressFamilies=AF_INET AF_UNIX AF_NETLINK
RestrictNamespaces=~cgroup ipc net mnt pid user uts
RestrictRealtime=true
RestrictSUIDSGID=true
SystemCallArchitectures=native
SystemCallErrorNumber=EPERM
 
[Install]
WantedBy=multi-user.target
sudo systemctl daemon-reload
sudo systemctl enable opensmtpd.service
sudo systemctl start opensmtpd.service

Dovecot

Installation

sudo aptitude install dovecot-pop3d
sudo systemctl stop dovecot

Bei der Installation wird Frage nach Erstellung eines selbstsignierten SSL-Zertifikats mit Ja und localhost als Rechnername mit OK bestätigt. Falls ntpdate zur Zeitsynchronisierung mitinstalliert, aber nicht benötigt wird, weil bereits ein anderer Dienst (z. B. openntpd, tlsdate, systemd-timesyncd usw.) die Aufgabe übernimmt, kann man ntpdate nach der Dovecot Installation deinstallieren:

sudo aptitude purge ntpdate

Konfiguration

In der /etc/dovecot/dovecot.conf Konfigurationsdatei werden zwei Einträge auskommentiert:

/etc/dovecot/dovecot.conf
# !include conf.d/*.conf
# dict {
# }
...
!include_try local.conf

Das Auskommentieren bewirkt, dass Dovecot nur die dovecot.conf und die einzubindende local.conf Datei heranzieht und die Teil-Konfigurationsdateien unter /etc/dovecot/conf.d/ unberührt bleiben, aus denen nötige Einstellungen in die local.conf Datei übertragen werden.

Da für die Konfiguration die UID und GID von getmail nötig sind, lässt man sie sich ausgeben:

id getmail

Anschließend erstellt man die local.conf Konfigurationsdatei mit dem nachfolgenden Inhalt, die über die obige include_try Anweisung in der dovecot.conf Datei beim Start von Dovecot ausgewertet wird. Für n1 wird die UID und für n2 die GID von getmail (s. o. ) eingesetzt.

sudo touch /etc/dovecot/local.conf
sudo chmod 640 /etc/dovecot/local.conf
sudo vi /etc/dovecot/local.conf
/etc/dovecot/local.conf
base_dir = /var/run/dovecot/
default_login_user = dovenull
default_internal_user = dovecot
protocols = pop3
  service auth {
  user = $default_internal_user
  }
service pop3-login {
  chroot = login
  inet_listener pop3 {
    port = 0
  }
  inet_listener pop3s {
    address = 127.0.0.1
    port = 995
  }
  process_limit = 2
  process_min_avail = 1
  service_count = 1
  user = $default_login_user
}
protocol pop3 {
  pop3_uidl_format = %08Xu%08Xv
}
mail_location = mbox:~/.mail:INBOX=/var/mail/getmail
mail_privileged_group = mail
first_valid_uid = n1
last_valid_uid = n1
first_valid_gid = n2
last_valid_gid = n2
mbox_write_locks = fcntl
passdb {
  args = /etc/dovecot/passwd.dovecot
  driver = passwd-file
}
userdb {
  args = /etc/dovecot/passwd.dovecot
  driver = passwd-file
}
ssl = required
disable_plaintext_auth = yes
ssl_cert = </etc/dovecot/dovecot.pem
ssl_key = </etc/dovecot/private/dovecot.pem

Benutzerkonto

Für den getmail Benutzer wird ein Passwort erzeugt

doveadm pw -r 10000 -s SHA512-CRYPT -u getmail
Enter new password:
Retype new password:
{schema}string

Für den getmail Benutzer wird mit seinem Benutzernamen, dem ausgeworfenen Passwortstring, seiner UID, GID und seinem Heimatverzeichnis ein Eintrag in der Benutzer- und Passwort-Datenbankdatei erstellt:

sudo touch /etc/dovecot/passwd.dovecot
sudo chmod 640 /etc/dovecot/passwd.dovecot
sudo chown root:dovecot /etc/dovecot/passwd.dovecot
sudo echo 'getmail:{schema}string:n1:n2::/var/lib/getmail::allow_nets=127.0.0.1/8' > /etc/dovecot/passwd.dovecot

Erläuterung

Nähere Informationen erhält man im Dovecot Wiki. Nur so viel: Dovecot läuft nur als interner POP3S Server, der nur auf die mbox Datei von getmail unter /var/mail/getmail zugreift, wenn sich der getmail Benutzer nach Aufnahme einer TLS-verschlüsselten Verbindung mit seinem Benutzernamen und Passwort authentifiziert hat, die kombiniert in der Datei /etc/dovecot/passwd.dovecot gespeichert sind.

Inbetriebnahme

Die folgende systemd Unit-Datei installieren.

/etc/systemd/system/dovecot.service
[Unit]
Description=Dovecot IMAP/POP3 email server
After=local-fs.target network.target
Wants=network.target
 
[Service]
Type=simple
ExecStart=/usr/sbin/dovecot -F
NonBlocking=yes
Restart=on-failure
RestartSec=10s
UMask=0027
CapabilityBoundingSet=CAP_CHOWN CAP_DAC_OVERRIDE CAP_FSETID CAP_KILL CAP_NET_BIND_SERVICE CAP_SETUID CAP_SETGID CAP_SYS_CHROOT CAP_MKNOD
RestrictAddressFamilies=AF_INET AF_UNIX
LockPersonality=true
MemoryDenyWriteExecute=true
PrivateDevices=yes
PrivateTmp=true
ProtectClock=true
ProtectControlGroups=true
ProtectHome=true                                                                                           
ProtectHostname=true
ProtectKernelLogs=true
ProtectKernelModules=true
ProtectKernelTunables=true
ProtectProc=invisible
ProcSubset=pid
ProtectSystem=full
InaccessiblePaths=/boot /root
RemoveIPC=true
RestrictNamespaces=~cgroup ipc net mnt pid user uts
RestrictRealtime=true
RestrictSUIDSGID=true
SystemCallArchitectures=native
SystemCallFilter=~@clock @keyring @module @raw-io ptrace @debug @reboot @swap @obsolete @cpu-emulation @resources
 
 
[Install]
WantedBy=multi-user.target

Danach kann Dovecot gestartet werden:

sudo systemctl daemon-reload
sudo systemctl start dovecot

Die E-Mail Anwendung

Anhand der Thunderbird E-Mail Anwendung, wobei man jede x-beliebige E-Mail Anwendung nehmen könnte:

Für den Abruf der E-Mails aller Konten wird ein „Dovecot“ Konto mit folgenden Angaben angelegt:

POP3 Server localhost
Port 995
Benutzername getmail
Passwort Klartext-Passwort, das mit doveadm für den getmail Benutzer vergeben wurde
Verbindungssicherheit SSL/TLS
Authentifizierungsmethode Passwort, normal

In allen anderen Thunderbird E-Mail Konten wird unter Server-Einstellungen der Mailabruf deaktiviert.

Für jedes Thunderbird E-Mail Konto wird unter Postausgang-Server (SMTP) ein Stunnel Serverkonto mit folgenden Angaben angelegt:

Server localhost
Port laut Portnummer, an der Stunnel lt. Angaben in der stunnel.conf Datei für den SMTP-Server des Anbeiters lauscht
Verbindungssicherheit
Authentifizierungsmethode
keine
Passwort, ungesichert übertragen

Da Stunnel die Übertragung des Benutzernamens und des Passworts zur Authentifizierung beim Anbieter und dafür den Aufbau der TLS-verschlüsselten Verbindung zum SMT-Server des Anbieters übernimmt.

Verweise auf aktuelle Seite