Kategorien
Allgemein Mailserver

Unmöglicher Pöstler mit Ecken und Kanten

Ein alter Esel aus der Schatztruhe

Als ich im Jahr 2008 einen Asus EeePC 1000H für knapp 700 Franken gekauft habe, hätte ich nicht gedacht, dass der Entscheid, den guten alten Esel alias Asinus (lat. der Esel) mit 2 GB Ram zu bestücken, ein guter Schachzug gewesen ist. Dies hat jetzt nämlich zur Folge, dass das Ding heute noch mit dem 32-Bit Debian 11.5 auf einem i386 Prozessor (Atom) noch wie geschmiert läuft. Debian oder FreeBSD sei’s gedankt, da z.B. Ubuntu bei 32 Bit schon lange aufgegeben hat. Auf alle Fälle läuft der Asinus noch super und das paßte perfekt, als ich nach langer Suche eine neuere (2022) fünfteilige Anleitung für einen Mailserver fand, der auf der Basis von Debian 11 von Null an (engl. from scratch) aufgebaut werden konnte. Der Asinus hat seitlich auch noch einen Slot für eine SD Card, die interne HD und die Batterie habe ich rausgenommen, so dass das Eselchen geräuschlos arbeitet. Es hat bei ihm einfach alles für dieses Projekt gepaßt, da mein Mini Lab fast nur mit einer Flotte von Raspberry Pi ausgestattet ist (siehe Impressum). Klar hatte das Projekt von Anfang an Ecken und Kanten, aber mir ging es wie bei allen Projekten (Webserver, Nextcloud, Mailserver, NAS, Blockchain) ums Prinzip.

Debian 11.5 rauf auf den Asinus

Wenn eine Software von einer öffentlichen Stelle wie Debian.org heruntergeladen wird, muss hinterher immer eine Verifikation stattfinden. Das mache ich in der Regel mit dem Windows-Tool «HashMyFiles». Und die SHA256Sum des Image «debian-11.5.0-i386-netinst.iso» findet man hier. Häufig gestellte Fragen über Debian-Installations-Images siehe Debian CD FAQ. Dies ist das Resultat der Verifikation:

700a775805262e16858f64eebe1a3317edef568fc44a5d55fa6f8ce48301acb2  debian-11.5.0-i386-netinst.iso
700a775805262e16858f64eebe1a3317edef568fc44a5d55fa6f8ce48301acb2  HashMyFiles OK

Das Flashen des Images «debian-11.5.0-i386-netinst.iso» auf einen 4 GB USB-Stick erfolgte mit dem Tool «Rufus» (Ver. 3.20.1929):

Start „debian-11.5.0-i386-netinst.iso“

Beim Asinus muss man zum Starten des USB-Sticks im BIOS die Gerätereihenfolge so ändern, dass der Stick beim nächsten Booten das Debian 11.5 i386 als Erstes startet. Dann habe ich die Optionen eingegeben:

  • Graphical Install
  • German
  • Schweiz
  • Schweizerdeutsch
  • Netzwerk-Hardware erkennen

Dann kommt «leider» die folgende Meldung

Teile Ihrer Hardware benötigen nicht-freie Firmware-Dateien, um zu funktionieren. Die Firmware kann von einem Wechseldatenträger, wie einem USB-Stick oder einer Diskette, geladen werden. Die fehlenden Firmware-Dateien sind: rt2860.bin. Falls Sie ein solches Medium nun vorliegen haben, legen/stecken Sie es ein und fahren Sie fort.
Nein
Ja
Bemerkung zum Ralink-Treiber

Die Datei „firmware-ralink_0.43_all.deb“ wurde unter dem Link gefunden und auf einen anderen USB-Stick geladen und in einem anderen USB-Steckplatz eingesteckt. Beim Einlegen des USB-Sticks und die Selektion von «Ja» (siehe oben) wurde die Datei gelesen. Das hat geklappt. Danach ging es weiter mit der Installation des Betriebssystems Debian 11.5.

https://packages.debian.org/search?searchon=contents&keywords=rt2860.bin
  • Primäre Netzwerk-Schnittstelle
eth0: Qualcomm Atheros AR8121/AR8113 Gigabit or Fast-Ethernet
wlan0: Ralink Corp. RT2790 Wireless 802.11n IT/2R PCIe

Es ist natürlich empfehlenswert, die Schnittstelle «eth0» zu wählen, die hier maximal 100 Mbps aufweist. Das genügt für unser Projekt «Ein unmöglicher Pöstler». Außerdem stehen die Partitionierungsdaten für die 32 GB microSDHC nicht zur Verfügung, statt dessen sind im folgenden Beispiel die Daten für die 160 GB Originalfestplatte für Debian 8 aufgeführt.

  • Rechnername: mail
  • Domain-Name: ifit.at
  • Root-Passwort: *** (stark)
  • Vollständiger Name des Benutzers: Louis A. Venetz
  • Benutzername für Ihr Konto: louis
  • Passwort für louis: *** (stark)
  • Partitionierungsmethode: Geführt – vollständige Festplatte verwenden
  • Zu partitionierende Festplatte: SCSI1 (0,0,0) (sda) – 160.0 GB (ST9160827AS)
  • Partitionierungsschema: Alle Dateien auf eine Partition, für Anfänger empfohlen
Geführte Partitionierung
Software-RAID konfigurieren
Logical Volume Manager konfigurieren
Verschlüsselte Datenträger konfigurieren
iSCSI-Volumes konfigurieren
SCSI1 (0,0,0) (sda) – 160.0 GB ATA ST9160827AS
	Nr. 1 primär	155.8 GB	f	ext4		/
	Nr. 5	logisch	  4.3 GB	f	Swap		Swap
  • Änderungen auf die Festplatten schreiben? Ja
  • Einen Netzwerkspiegel verwenden? Ja
  • Schweiz
  • debian.ethz.ch
  • Keinen http-Proxy
  • An der Paketverwendungserfassung teilnehmen? Ja

[ ] Debian desktop environment
[ ] … Gnome
[ ] … Xfce
[ ] … KDE
[ ] … Cinnamon
[ ] … MATE
[ ] … LXDE
[ ] Webserver
[ ] Druckerserver (gelöscht, da unnötig vom Installer ausgewählt!)
[*] SSH Server     
[*] Standard-Systemwerkzeuge

Hinweis zur Paketverwendungserfassung

Nur die letzten beiden Optionen sind aktiviert. Den Rest braucht es für dieses Projekt nicht.

Es scheint, als ob diese Installation von Debian das einzige Betriebssystem auf diesem Computer ist. Wenn dies der Fall ist, sollte es kein Problem sein, den Bootloader in den Master Boot Record Ihrer ersten Festplatte zu installieren.
Warnung: Wenn der Installer eines anderen Betriebssystems auf Ihrem Computer nicht richtig erkennt, Sie aber den Master Boot Record verändern, werden Sie dieses andere Betriebssystem vorläufig nicht mehr starten können. Allerdings kann GRUB im Nachhinein manuell konfiguriert werden, so dass das andere Betriebssystem wieder startet.
Den GRUB-Bootloader in den Master Boot Record installieren? Ja

Das neu installierte System muss boot-Fähig gemacht werden, indem der GRUB-Bootloader auf einem boot-fähigen Medium installiert wird. Gewöhnlich wird dazu GRUB im Master Boot Record Ihrer ersten Festplatte installiert. Wenn Sie möchten, können Sie GRUB auch auf einer anderen Partition, einem anderen Laufwerk oder auf einer Diskette installieren.

Gerät für die Bootloader-Installation:
		Gerät on Hand eingeben
		/dev/sda (ata-ST9160828AS_SRF188D0)

Installation abgeschlossen
Die Installation ist abgeschlossen und es ist an der Zeit, Ihr neues System zu starten. Achten Sie darauf, das Installationsmedium zu entfernen (CD, Disketten), so dass Sie das neue System starten statt einer erneuten Installation. <Weiter>

Build Email Server From Scratch on Debian – Basic Postfix Setup

Der erste Teil der zugrunde liegenden Anleitung für diesen Mailserver stammt vom folgenden Link. Der Asinus ist jedoch an einem Modem von UPC Cablecom (neu: Sunrise) angeschlossen, welches im Bridge Mode geschaltet ist. Der Bridge Mode vergibt dem Asinus via DHCP die IP-Adresse 84.74.0.14/22 (1022 Hosts), welche leider in der SORBS-Datenbank gelistet ist, obwohl noch gar keine Mails gesendet worden sind. Das ist natürlich ein Problem und es wird auch nicht das einzige sein. Ich komme aber später noch darauf zurück. Zunächst wollen wir Postfix so gut wie möglich konfigurieren.

Internet Service Providers (ISP)

Sobald die IP-Adresse des ISP bekannt ist, kann man via SSH (dieses Protokoll habe ich ja bei der Konfiguration aktiviert) auf den Server zugreifen. Aber die Domain «ifit.at» muss auch noch in der DNS-Zone von Swiss-DNS als A Record (und später noch als MX sowie verschiedenen TXT Records) eingetragen sein.

Dann kann man im PuTTY oder via Terminal auf einen anderen Linux-Client oder -Server auf den Asinus schon zugreifen. Hinweis: Das Packet „sudo“ habe ich auf der Console installiert und den Benutzer «louis» nachher in «visudo» eingetragen, damit dieser Benutzer auch über SSH sudo-Rechte bekommen kann.

Firewall UFW für SSH aktivieren

louis@mail:~$ sudo apt install ufw
louis@mail:~$ sudo ufw default deny incoming
louis@mail:~$ sudo ufw default allow outgoing
louis@mail:~$ sudo ufw allow ssh
louis@mail:~$ sudo ufw enable
louis@mail:~$ ...
louis@mail:~$ sudo ufw status numbered
Status: active
     To                         Action      From
     --                         ------      ----
[ 1] 22/tcp                     ALLOW IN    Anywhere

Hostname des Mailserver überprüfen

Hinweis: „sudo“ und „louis“ sind bereits installiert! Der MX Record muss in der DNS Zone «ifit.at» auch definiert sein.

louis@mail:~$ hostname -f
mail.ifit.at

MX Record für den Mailserver

Für einen Mailserver braucht es zwingend einen MX Record. Aber wie bei der Ausgabe von «dig» und «host» zu sehen ist, werden diese Antworten früher oder später zu Problemen führen. Der Reverse DNS Pointer sollte auf mail.ifit.at zeigen. Aber diese Änderung kann ich nicht selbst machen, warum auch immer, nur der ISP UPC Cablecom (neu: Sunrise) kann das machen. Aber die Mitarbeiter von UPC haben offiziell seit Jahren keine Ahnung, wissen es nicht oder wollen es nicht wissen. Ich hoffe, dass es bei Sunrise besser wird!
louis@mail:~$ dig -x 84.74.0.14 +short
84-74-0-14.dclient.hispeed.ch.

louis@mail:~$ host 84.74.0.14
14.0.74.84.in-addr.arpa domain name pointer 84-74-0-14.dclient.hispeed.ch.

Postfix SMTP Server installieren

louis@mail:~$ sudo apt-get install postfix -y
louis@mail:~$ sudo postconf mail_version
mail_version = 3.5.13

louis@mail:~$ sudo ss -lnpt | grep master
LISTEN 0      100          0.0.0.0:25        0.0.0.0:*    users:(("master",pid=1857,fd=13))
LISTEN 0      100             [::]:25           [::]:*    users:(("master",pid=1857,fd=14))

louis@mail:~$ dpkg -L postfix | grep /usr/sbin/
/usr/sbin/postalias
/usr/sbin/postcat
/usr/sbin/postconf
/usr/sbin/postdrop
/usr/sbin/postfix
/usr/sbin/postfix-add-filter
/usr/sbin/postfix-add-policy
/usr/sbin/postkick
/usr/sbin/postlock
/usr/sbin/postlog
/usr/sbin/postmap
/usr/sbin/postmulti
/usr/sbin/postqueue
/usr/sbin/postsuper
/usr/sbin/posttls-finger
/usr/sbin/qmqp-sink
/usr/sbin/qmqp-source
/usr/sbin/qshape
/usr/sbin/rmail
/usr/sbin/sendmail
/usr/sbin/smtp-sink
/usr/sbin/smtp-source

Firewall mit TCP Port 25 ergänzen

louis@mail:~$ sudo ufw allow 25/tcp
louis@mail:~$ sudo ufw status
Status: active
To                         Action      From
--                         ------      ----
22/tcp                     ALLOW       Anywhere
25/tcp                     ALLOW       Anywhere

https://www.ipvoid.com/port-scan/
Port Scanning Results
Port	Type	Status	Service
21	TCP	 Filtered	ftp
22	TCP	 Open		ssh
23	TCP	 Filtered	telnet
25	TCP	 Open		smtp
53	TCP	 Filtered	domain
80	TCP	 Filtered	http
110	TCP	 Filtered	pop3
111	TCP	 Filtered	rpcbind
135	TCP	 Filtered	msrpc
139	TCP	 Filtered	netbios-ssn
...

Auf TCP Port 25 von Google zugreifen

louis@mail:~$ sudo apt install telnet
louis@mail:~$ telnet gmail-smtp-in.l.google.com 25
Trying 108.177.119.26...
Connected to gmail-smtp-in.l.google.com.
Escape character is '^]'.
220 mx.google.com ESMTP oq19-20020a170906cc9300b007c0d428795dsi6062953ejb.191 - gsmtp
quit
221 2.0.0 closing connection oq19-20020a170906cc9300b007c0d428795dsi6062953ejb.191 - gsmtp
Connection closed by foreign host.

Postfix Hostname richtig setzen

louis@mail:~$ sudo nano /etc/postfix/main.cf
...
myhostname = mail.ifit.at
alias_maps = hash:/etc/aliases
alias_database = hash:/etc/aliases
myorigin = /etc/mailname
mydestination = $myhostname, ifit.at, mail.ifit.at, localhost.ifit.at, localhost
relayhost =
mynetworks = 127.0.0.0/8 [::ffff:127.0.0.0]/104 [::1]/128
mailbox_size_limit = 0
recipient_delimiter = +
inet_interfaces = all
inet_protocols = all
...
louis@mail:~$ sudo systemctl restart postfix
Hinweis zu «myhostname»
Sobald «myhostname» (siehe oben 3. Zeile) in Postfix gesetzt ist, spielt der Hostname des Betriebssystems keine Rolle mehr. Der Hostname des Betriebssystems kann in einen beliebigen Hostnamen geändert werden.

Email Alias generieren

louis@mail:~$ sudo nano /etc/aliases
# See man 5 aliases for format
postmaster:    root
root:   louis
louis@mail:~$ sudo newaliases
Hinweis zur 1. Datensicherung
Es werden in diesem Blog nicht alle Einzelheiten, die ich zwar von der Originalanleitung übernommen habe, aufgezeichnet, da sie nicht unbedingt zwingend sind. Der Leser kann dies aber jederzeit selbst tun. Man kann zwar mit «telnet», «sendmail» und «mailutils» (siehe Step 8: Email in der Originalanleitung) schon Mails senden und lesen, aber das verwirrt eher als es zu einer vertieften Einsicht verhilft. Es gibt jedoch schon auch gewisse praktische Punkte, die auch in der Originalanleitung fehlen. Was z.B. zu empfehlen ist, ist nach jedem Part eine Datensicherung durchzuführen, d.h. ein Image zu schreiben. Ich verwende hierzu das Tool Win32DiskImager.exe in Windows 10. Die erste Sicherungsdatei (Image) lautet bei mir: «2022-11-25-Asinus-i386-on-Debian-11.5-Server-Linux-Kernel-5.10.0-19-686-pae+Postfix.img«. Selbstverständlich wurde auch eine Verifikation durchgeführt.

Install Dovecot IMAP Server on Debian & Enable TLS Encryption

Dies ist der zweite Teil der Originalanleitung und den findet man hier. Als erste Maßnahme richte ich das automatisch Login ein. Es wird jedoch vorausgesetzt, dass ein Schlüsselpaar von Private und Public Key vorhanden ist. Wenn nicht, dann gäbe es unter dem Link Security von RaspiBolt eine ausführliche Anleitung. Unter Linux wäre der erste Befehl «ssh-copy-id louis@mail.ifit.at» hilfreich, danach ginge es mit dem Befehl «ssh louis@mail.ifit.at» weiter. Aber machen Sie das nicht auf dem Asinus, da Sie beim ersten Befehl das starke Passwort nicht wissen.

Automatisches Login (Keys)

louis@mail:~$ pwd
/home/louis
louis@mail:~$ mkdir .ssh
louis@mail:~$ nano .ssh/authorized_keys
       ### Public Key einfügen ###
louis@mail:~$ chmod -R 700 .ssh/
louis@mail:~$ chown -R louis:louis ~/.ssh
louis@mail:~$ chmod 600 ~/.ssh/authorized_keys
louis@mail:~$ sudo nano /etc/ssh/sshd_config
       ### PasswordAuthentication yes => no ###
louis@mail:~$ sudo service ssh restart

Ports in Firewall öffnen (nur IMAP)

louis@mail:~$ sudo ufw allow 80,443,587,465,143,993/tcp
Rule added
Rule added (v6)
louis@mail:~$ sudo ufw status numbered
Status: active
     To                         Action      From
     --                         ------      ----
[ 1] 22/tcp                     ALLOW IN    Anywhere
[ 2] 80,143,443,465,587,993/tcp ALLOW IN    Anywhere
[ 3] 80,143,443,465,587,993/tcp (v6) ALLOW IN    Anywhere (v6)
louis@mail:~$ sudo ufw delete 3
Deleting:
 allow 80,143,443,465,587,993/tcp
Proceed with operation (y|n)? y
Rule deleted (v6)
louis@mail:~$ sudo ufw status numbered
Status: active
     To                         Action      From
     --                         ------      ----
[ 1] 22/tcp                     ALLOW IN    Anywhere
[ 2] 80,143,443,465,587,993/tcp ALLOW IN    Anywhere

Email Server sichern mit TLS Zertifikat

louis@mail:~$ sudo apt update && sudo apt upgrade
louis@mail:~$ sudo apt install certbot
Hinweis zum Port 80

Der folgende Befehl installiert den Apache-Webserver, falls er noch nicht auf dem System installiert ist. Ausserdem ist nötig, den Port 80 (siehe oben) zumindest temporär offen zu halten. Sie können dann später (nach der Zertifizierung) den «Tag der Offenen Tür» wieder beenden!

Let’s Encrypt rät jedoch den Port 80 auch nach der Zertifizierung offen zu behalten. Warum, ist mir nach vielen Jahren Verwendung immer noch nicht ganz klar!
louis@mail:~$ sudo apt install python3-certbot-apache
louis@mail:~$ sudo nano /etc/apache2/sites-available/mail.ifit.at.conf
<VirtualHost *:80>
        ServerName mail.ifit.at

        DocumentRoot /var/www/html/
</VirtualHost>
louis@mail:~$ sudo a2ensite mail.ifit.at.conf
Enabling site mail.ifit.at.
To activate the new configuration, you need to run:
  systemctl reload apache2
louis@mail:~$ sudo a2dissite 000-default
Site 000-default disabled.
To activate the new configuration, you need to run:
  systemctl reload apache2
louis@mail:~$ sudo systemctl reload apache2
louis@mail:~$ sudo certbot certonly -a apache --agree-tos --no-eff-email --staple-ocsp --email web@ifit.ch -d mail.ifit.at
Saving debug log to /var/log/letsencrypt/letsencrypt.log
Plugins selected: Authenticator apache, Installer None
Account registered.
Requesting a certificate for mail.ifit.at
Performing the following challenges:
http-01 challenge for mail.ifit.at
Enabled Apache rewrite module
Waiting for verification...
Cleaning up challenges
	
IMPORTANT NOTES:
 - Congratulations! Your certificate and chain have been saved at:
   /etc/letsencrypt/live/mail.ifit.at/fullchain.pem
   Your key file has been saved at:
   /etc/letsencrypt/live/mail.ifit.at/privkey.pem
   Your certificate will expire on 2023-02-23. To obtain a new or
   tweaked version of this certificate in the future, simply run
   certbot again. To non-interactively renew *all* of your
   certificates, run "certbot renew"
 - If you like Certbot, please consider supporting our work by:
   Donating to ISRG / Let's Encrypt:   https://letsencrypt.org/donate
   Donating to EFF:                    https://eff.org/donate-le
Hinweis zum grünen A+

Nach der Zertifizierung schließe ich normalerweise Port 80 wieder und führe den Befehl «https://www.ssllabs.com/ssltest/analyze.html?d=mail.ifit.at» im Browser aus. Wenn man kein grünes A+ bekommt, dann stimmt ‹was nicht. Das geht aber hier jetzt nicht mehr, weil es einen Konflikt mit der Subdomain «postfixadmin.ifit.at» gibt, die im dritten Teil der Originalanleitung behandelt wird.

https://www.ssllabs.com/ssltest/analyze.html?d=postfixadmin.ifit.at

Submission Service in Postfix aktivieren

louis@mail:~$ sudo nano /etc/postfix/master.cf
...
submission     inet     n    -    y    -    -    smtpd
  -o syslog_name=postfix/submission
  -o smtpd_tls_security_level=encrypt
  -o smtpd_tls_wrappermode=no
  -o smtpd_sasl_auth_enable=yes
  -o smtpd_relay_restrictions=permit_sasl_authenticated,reject
  -o smtpd_recipient_restrictions=permit_mynetworks,permit_sasl_authenticated,reject
  -o smtpd_sasl_type=dovecot
  -o smtpd_sasl_path=private/auth
...
smtps     inet  n       -       y       -       -       smtpd
  -o syslog_name=postfix/smtps
  -o smtpd_tls_wrappermode=yes
  -o smtpd_sasl_auth_enable=yes
  -o smtpd_relay_restrictions=permit_sasl_authenticated,reject
  -o smtpd_recipient_restrictions=permit_mynetworks,permit_sasl_authenticated,reject
  -o smtpd_sasl_type=dovecot
  -o smtpd_sasl_path=private/auth
...
louis@mail:~$ sudo nano /etc/postfix/main.cf
...
# TLS parameters
#smtpd_tls_cert_file=/etc/ssl/certs/ssl-cert-snakeoil.pem
#smtpd_tls_key_file=/etc/ssl/private/ssl-cert-snakeoil.key
smtpd_tls_security_level=may
smtp_tls_CApath=/etc/ssl/certs
smtp_tls_security_level=may
smtp_tls_session_cache_database = btree:${data_directory}/smtp_scache

#Enable TLS Encryption when Postfix receives incoming emails
smtpd_tls_cert_file=/etc/letsencrypt/live/mail.ifit.at/fullchain.pem
smtpd_tls_key_file=/etc/letsencrypt/live/mail.ifit.at/privkey.pem
smtpd_tls_security_level=may
smtpd_tls_loglevel = 1
smtpd_tls_session_cache_database = btree:${data_directory}/smtpd_scache

#Enable TLS Encryption when Postfix sends outgoing emails
smtp_tls_security_level = may
smtp_tls_loglevel = 1
smtp_tls_session_cache_database = btree:${data_directory}/smtp_scache

#Enforce TLSv1.3 or TLSv1.2
smtpd_tls_mandatory_protocols = !SSLv2, !SSLv3, !TLSv1, !TLSv1.1
smtpd_tls_protocols = !SSLv2, !SSLv3, !TLSv1, !TLSv1.1
smtp_tls_mandatory_protocols = !SSLv2, !SSLv3, !TLSv1, !TLSv1.1
smtp_tls_protocols = !SSLv2, !SSLv3, !TLSv1, !TLSv1.1
...
louis@mail:~$ sudo systemctl restart postfix
louis@mail:~$ sudo ss -lnpt | grep master
LISTEN 0      100          0.0.0.0:25        0.0.0.0:*    users:(("master",pid=3620,fd=13))                                                
LISTEN 0      100          0.0.0.0:587       0.0.0.0:*    users:(("master",pid=3620,fd=17))                                                
LISTEN 0      100          0.0.0.0:465       0.0.0.0:*    users:(("master",pid=3620,fd=20))

Dovecot IMAP Server installieren

louis@mail:~$ sudo apt install dovecot-core dovecot-imapd

IMAP Protokoll einschalten

louis@mail:~$ sudo nano /etc/dovecot/dovecot.conf
...
# Enable installed protocols
protocols = imap
!include_try /usr/share/dovecot/protocols.d/*.protocol

Speicherort der Mailbox festlegen

louis@mail:~$ sudo postconf mail_spool_directory
mail_spool_directory = /var/mail
...
louis@mail:~$ sudo nano /etc/dovecot/conf.d/10-mail.conf
...
#
# See doc/wiki/Variables.txt for full list. Some examples:
#
#   mail_location = maildir:~/Maildir
#   mail_location = mbox:~/mail:INBOX=/var/mail/%u
#   mail_location = mbox:/var/mail/%d/%1n/%n:INDEX=/var/indexes/%d/%1n/%n
#
# <doc/wiki/MailLocation.txt>
#
#mail_location = mbox:~/mail:INBOX=/var/mail/%u
mail_location = maildir:~/Maildir
...
louis@mail:~$ sudo adduser dovecot mail
Füge Benutzer »dovecot« der Gruppe »mail« hinzu ...
Benutzer dovecot wird zur Gruppe mail hinzugefügt.

Dovecot sendet Emails an Message Store

louis@mail:~$ sudo apt install dovecot-lmtpd
louis@mail:~$ sudo nano /etc/dovecot/dovecot.conf
# Enable installed protocols
# protocols = imap
protocols = imap lmtp
!include_try /usr/share/dovecot/protocols.d/*.protocol
...
Vorher

service lmtp {
  unix_listener lmtp {
    #mode = 0666
  }

  # Create inet listener only if you can't use the above UNIX socket
  #inet_listener lmtp {
    # Avoid making LMTP visible for the entire internet
    #address =
    #port =
  #}
}
Nachher

service lmtp {
 unix_listener /var/spool/postfix/private/dovecot-lmtp {
   mode = 0600
   user = postfix
   group = postfix
  }

  # Create inet listener only if you can't use the above UNIX socket
  #inet_listener lmtp {
    # Avoid making LMTP visible for the entire internet
    #address =
    #port =
  #}
}
...
louis@mail:~$ sudo nano /etc/postfix/main.cf
...	
smtpd_relay_restrictions = permit_mynetworks permit_sasl_authenticated defer_unauth_destination
myhostname = mail.ifit.at
alias_maps = hash:/etc/aliases
alias_database = hash:/etc/aliases
myorigin = /etc/mailname
mydestination = $myhostname, ifit.at, mail.ifit.at, localhost.ifit.at, localhost
relayhost =
mynetworks = 127.0.0.0/8 [::ffff:127.0.0.0]/104 [::1]/128
mailbox_size_limit = 0
recipient_delimiter = +
inet_interfaces = all
inet_protocols = ipv4
mailbox_transport = lmtp:unix:private/dovecot-lmtp
smtputf8_enable = no

User Authentication Mechanism

louis@mail:~$ sudo nano /etc/dovecot/conf.d/10-auth.conf
...
#disable_plaintext_auth = yes
disable_plaintext_auth = yes
..
#auth_username_format = %Lu
auth_username_format = %n
...
#auth_mechanisms = plain
auth_mechanisms = plain login

SSL/TLS Encryption

louis@mail:~$ sudo nano /etc/dovecot/conf.d/10-ssl.conf
...
# ssl = yes
ssl = required
...
# ssl_cert = </etc/dovecot/private/dovecot.pem
ssl_cert = </etc/letsencrypt/live/mail.ifit.at/fullchain.pem
# ssl_key = </etc/dovecot/private/dovecot.key
ssl_key = </etc/letsencrypt/live/mail.ifit.at/privkey.pem
…
# Prefer the server's order of ciphers over client's.
#ssl_prefer_server_ciphers = no
ssl_prefer_server_ciphers = yes
…
# Minimum SSL protocol version to use. Potentially recognized values are SSLv3,
# TLSv1, TLSv1.1, and TLSv1.2, depending on the OpenSSL version used.
#ssl_min_protocol = TLSv1
ssl_min_protocol = TLSv1.2

SASL Authentication

louis@mail:~$ sudo nano /etc/dovecot/conf.d/10-master.confVorher
service auth {
  # auth_socket_path points to this userdb socket by default. It's typically
  # used by dovecot-lda, doveadm, possibly imap process, etc. Users that have
  # full permissions to this socket are able to get a list of all usernames and
  # get the results of everyone's userdb lookups.
  #
  # The default 0666 mode allows anyone to connect to the socket, but the
  # userdb lookups will succeed only if the userdb returns an "uid" field that
  # matches the caller process's UID. Also if caller's uid or gid matches the
  # socket's uid or gid the lookup succeeds. Anything else causes a failure.
  #
  # To give the caller full permissions to lookup all users, set the mode to
  # something else than 0666 and Dovecot lets the kernel enforce the
  # permissions (e.g. 0777 allows everyone full permissions).
  unix_listener auth-userdb {
    #mode = 0666
    #user =
    #group =
  }

  # Postfix smtp-auth
  #unix_listener /var/spool/postfix/private/auth {
  #  mode = 0666
  #}

  # Auth process is run as this user.
  #user = $default_internal_user
}
Nachher
service auth {
  # auth_socket_path points to this userdb socket by default. It's typically
  # used by dovecot-lda, doveadm, possibly imap process, etc. Users that have
  # full permissions to this socket are able to get a list of all usernames and
  # get the results of everyone's userdb lookups.
  #
  # The default 0666 mode allows anyone to connect to the socket, but the
  # userdb lookups will succeed only if the userdb returns an "uid" field that
  # matches the caller process's UID. Also if caller's uid or gid matches the
  # socket's uid or gid the lookup succeeds. Anything else causes a failure.
  #
  # To give the caller full permissions to lookup all users, set the mode to
  # something else than 0666 and Dovecot lets the kernel enforce the
  # permissions (e.g. 0777 allows everyone full permissions).
  #unix_listener auth-userdb {
    #mode = 0666
    #user =
    #group =
  #}

  # Postfix smtp-auth
  unix_listener /var/spool/postfix/private/auth {
    mode = 0660
    user = postfix
    group = postfix
  }
  # Auth process is run as this user.
  #user = $default_internal_user
}
louis@mail:~$ sudo systemctl restart postfix dovecot
louis@mail:~$ sudo ss -lnpt | grep dovecot	
LISTEN 0      100          0.0.0.0:993       0.0.0.0:*    users:(("dovecot",pid=7580,fd=37))                                     
LISTEN 0      100          0.0.0.0:143       0.0.0.0:*    users:(("dovecot",pid=7580,fd=35))                                     
LISTEN 0      100             [::]:993          [::]:*    users:(("dovecot",pid=7580,fd=38))                                     
LISTEN 0      100             [::]:143          [::]:*    users:(("dovecot",pid=7580,fd=36))
louis@mail:~$ sudo systemctl status dovecot
● dovecot.service - Dovecot IMAP/POP3 email server
     Loaded: loaded (/lib/systemd/system/dovecot.service; enabled; vendor preset: enabled)
     Active: active (running) since Fri 2022-11-25 21:48:45 CET; 1min 31s ago
       Docs: man:dovecot(1)
             http://wiki2.dovecot.org/
   Main PID: 7580 (dovecot)
      Tasks: 4 (limit: 4754)
     Memory: 2.2M
        CPU: 214ms
     CGroup: /system.slice/dovecot.service
             ├─7580 /usr/sbin/dovecot -F
             ├─7584 dovecot/anvil
             ├─7585 dovecot/log
             └─7586 dovecot/config

Nov 25 21:48:45 mail systemd[1]: Starting Dovecot IMAP/POP3 email server...
Nov 25 21:48:45 mail dovecot[7580]: master: Dovecot v2.3.13 (89f716dc2) starting up for imap, lmtp, imap, lmtp (core dumps disab>
Nov 25 21:48:45 mail systemd[1]: Started Dovecot IMAP/POP3 email server.

TLS Zertifikate automatisch erneuern

Hinweis zur Zertifikatserneuerung

Das Zertifikat wird nicht täglich (das finde ich echt etwas zu viel), sondern wöchentlich erneuert. Ausserdem empfiehlt Let’s Encrypt, den Port 80 offen zu lassen. Falls «crontab» Fehlermeldungen produziert oder das Zertifikat nicht automatisch erneuert werden sollte, dann wäre das ein Hinweis, dass Let’s Encrypt den Port 80 für diesen Zweck offen haben will. Dann könnte man sich überlegen, die Erneuerung manuell alle drei Monate zu vollziehen und dabei den Port 80 kurzfristig zu öffnen und nach dem positiven SSLLab-Test wieder zu schließen.

louis@mail:~$ sudo crontab -e
no crontab for root - using an empty one
Select an editor.  To change later, run 'select-editor'.
  1. /bin/nano        <---- easiest
  2. /usr/bin/vim.basic
  3. /usr/bin/vim.tiny
Choose 1-3 [1]: ENTER
# Edit this file to introduce tasks to be run by cron.
#
# Each task to run has to be defined through a single line
# indicating with different fields when the task will be run
# and what command to run for the task
#
# To define the time you can provide concrete values for
# minute (m), hour (h), day of month (dom), month (mon),
# and day of week (dow) or use '*' in these fields (for 'any').
#
# Notice that tasks will be started based on the cron's system
# daemon's notion of time and timezones.
#
# Output of the crontab jobs (including errors) is sent through
# email to the user the crontab file belongs to (unless redirected).
#
# For example, you can run a backup of all your user accounts
# at 5 a.m every week with:
# 0 5 * * 1 tar -zcf /var/backups/home.tgz /home/
#
# For more information see the manual pages of crontab(5) and cron(8)
#
# m h  dom mon dow   command
@weekly certbot renew --quiet && systemctl reload postfix dovecot apache2
crontab: installing new crontab

Dovecot automatisch neu starten

louis@mail:~$ sudo systemctl restart dovecot
louis@mail:~$ sudo mkdir -p /etc/systemd/system/dovecot.service.d/
louis@mail:~$ sudo nano /etc/systemd/system/dovecot.service.d/restart.conf
[Service]
Restart=always
RestartSec=5s
louis@mail:~$ sudo systemctl daemon-reload
louis@mail:~$ sudo pkill dovecot
louis@mail:~$ systemctl status dovecot
● dovecot.service - Dovecot IMAP/POP3 email server
     Loaded: loaded (/lib/systemd/system/dovecot.service; enabled; vendor preset: enabled)
    Drop-In: /etc/systemd/system/dovecot.service.d
             └─restart.conf
     Active: active (running) since Sat 2022-11-26 18:29:45 CET; 49s ago
       Docs: man:dovecot(1)
             http://wiki2.dovecot.org/
   Main PID: 1385 (dovecot)
      Tasks: 4 (limit: 4753)
     Memory: 2.2M
        CPU: 161ms
     CGroup: /system.slice/dovecot.service
             ├─1385 /usr/sbin/dovecot -F
             ├─1386 dovecot/anvil
             ├─1387 dovecot/log
             └─1388 dovecot/config

Laptop beim Zuklappen laufen lassen

louis@mail:~$ sudo nano /etc/systemd/logind.conf
#  This file is part of systemd.
#
#  systemd is free software; you can redistribute it and/or modify it
#  under the terms of the GNU Lesser General Public License as published by
#  the Free Software Foundation; either version 2.1 of the License, or
#  (at your option) any later version.
#
# Entries in this file show the compile time defaults.
# You can change settings by editing this file.
# Defaults can be restored by simply deleting this file.
#
# See logind.conf(5) for details.
...
[Login]
#NAutoVTs=6
#ReserveVT=6
#KillUserProcesses=no
#KillOnlyUsers=
#KillExcludeUsers=root
#InhibitDelayMaxSec=5
#UserStopDelaySec=10
#HandlePowerKey=poweroff
#HandleSuspendKey=suspend
#HandleHibernateKey=hibernate
#HandleLidSwitch=suspend
HandleLidSwitch=ignore
#HandleLidSwitchExternalPower=suspend
#HandleLidSwitchDocked=ignore
#HandleRebootKey=reboot
louis@mail:~$ sudo service systemd-logind restart
Abschliessende Bemerkung zur 2. Datensicherung

Nachdem ich die Konfiguration von Part 2 nochmals durchgegangen bin, habe ich die Benutzer «louis» und «lavenetz» in Thunderbird sowie «colin» auf einem Huawei und «alisha» auf einem iPhone7+ gestestet. Obwohl die Kommunikation zwischen den lokalen Benutzern des Asinus hervorragend funktionieren, haben sie keine längerfristige Bedeutung, da im nächsten Teil 3 PostfixAdmin virtuelle Accounts eingeführt werden und die lokalen nicht mehr funktionieren. Nun kann ich die zweite Datensicherung durchführen. Die Datei lautet: 2022-11-26-Asinus-i386-on-Debian-11.5-Server-Linux-Kernel-5.10.0-19-686-pae+Postfix+Dovecot.img

PostfixAdmin – Create Virtual Mailboxes on Debian Mail Server

Im dritten Teil der Originalanleitung wird das relativ heikle Thema PostfixAdmin behandelt. In den vorigen Teilen habe ich gezeigt, wie Postfix-SMTP-Server und Dovecot-IMAP-Server eingerichtet werden, aber bisher waren nur E-Mail-Adressen für Benutzer mit lokalem Unix-Konten möglich. Dieser Teil ermöglicht, virtuelle Postfächer auf dem Debian-Mailserver mit PostfixAdmin zu erstellen, einer webbasierten Open-Source-Schnittstelle zum Konfigurieren und Verwalten eines Postfix-basierten E-Mail-Servers für mehrere Domains und Benutzer. Als Erstes installiere ich den Datenbankserver MariaDB.

Datenbank Server MariaDB installieren

Using username "louis".
Authenticating with public key
Linux mail 5.10.0-19-686-pae #1 SMP Debian 5.10.149-2 (2022-10-21) i686
The programs included with the Debian GNU/Linux system are free software;
 the exact distribution terms for each program are described in the
 individual files in /usr/share/doc/*/copyright.
Debian GNU/Linux comes with ABSOLUTELY NO WARRANTY, to the extent
 permitted by applicable law.
You have mail.
Last login: Sun Nov 27 12:30:57 2022
louis@mail:~$ date
So 27 Nov 2022 16:32:37 CET
louis@mail:~$ df -Th
Dateisystem    Typ      Größe Benutzt Verf. Verw% Eingehängt auf
udev           devtmpfs  991M       0  991M    0% /dev
tmpfs          tmpfs     201M    792K  200M    1% /run
/dev/sda1      ext4       29G    1.5G   26G    6% /
tmpfs          tmpfs    1003M       0 1003M    0% /dev/shm
tmpfs          tmpfs     5.0M       0  5.0M    0% /run/lock
tmpfs          tmpfs     201M       0  201M    0% /run/user/1000
tmpfs          tmpfs     201M       0  201M    0% /run/user/0
louis@mail:~$ sudo apt update
OK:1 http://debian.ethz.ch/debian bullseye InRelease
Holen:2 http://debian.ethz.ch/debian bullseye-updates InRelease [44.1 kB]
Holen:3 http://security.debian.org/debian-security bullseye-security InRelease [48.4 kB]
Es wurden 92.4 kB in 2 s geholt (45.2 kB/s).
Paketlisten werden gelesen… Fertig
Abhängigkeitsbaum wird aufgebaut… Fertig
Statusinformationen werden eingelesen… Fertig
Alle Pakete sind aktuell.
louis@mail:~$ sudo apt install mariadb-server mariadb-client
...
louis@mail:~$ systemctl status mariadb
● mariadb.service - MariaDB 10.5.15 database server
     Loaded: loaded (/lib/systemd/system/mariadb.service; enabled; vendor preset: enabled)
     Active: active (running) since Sun 2022-11-27 16:37:38 CET; 2min 8s ago
       Docs: man:mariadbd(8)
             https://mariadb.com/kb/en/library/systemd/
    Process: 7040 ExecStartPre=/usr/bin/install -m 755 -o mysql -g root -d /var/run/mysqld (code=exited, status=0/SUCCESS)
    Process: 7041 ExecStartPre=/bin/sh -c systemctl unset-environment _WSREP_START_POSITION (code=exited, status=0/SUCCESS)
    Process: 7043 ExecStartPre=/bin/sh -c [ ! -e /usr/bin/galera_recovery ] && VAR= ||   VAR=`cd /usr/bin/..; /usr/bin/galera_recovery`; [ $? -e>
    Process: 7105 ExecStartPost=/bin/sh -c systemctl unset-environment _WSREP_START_POSITION (code=exited, status=0/SUCCESS)
    Process: 7107 ExecStartPost=/etc/mysql/debian-start (code=exited, status=0/SUCCESS)
   Main PID: 7090 (mariadbd)
     Status: "Taking your SQL requests now..."
      Tasks: 9 (limit: 4753)
     Memory: 49.7M
        CPU: 2.026s
     CGroup: /system.slice/mariadb.service
             └─7090 /usr/sbin/mariadbd

MariaDB Post-Installation Security

louis@mail:~$ sudo mysql_secure_installation
NOTE: RUNNING ALL PARTS OF THIS SCRIPT IS RECOMMENDED FOR ALL MariaDB
      SERVERS IN PRODUCTION USE!  PLEASE READ EACH STEP CAREFULLY!
In order to log into MariaDB to secure it, we'll need the current
password for the root user. If you've just installed MariaDB, and
haven't set the root password yet, you should just press enter here.
Enter current password for root (enter for none): ENTER
OK, successfully used password, moving on...
Setting the root password or using the unix_socket ensures that nobody
can log into the MariaDB root user without the proper authorisation.
You already have your root account protected, so you can safely answer 'n'.
Switch to unix_socket authentication [Y/n] n
 ... skipping.
You already have your root account protected, so you can safely answer 'n'.
Change the root password? [Y/n] n
 ... skipping.
By default, a MariaDB installation has an anonymous user, allowing anyone
to log into MariaDB without having to have a user account created for
them.  This is intended only for testing, and to make the installation
go a bit smoother.  You should remove them before moving into a
production environment.
Remove anonymous users? [Y/n] ENTER
 ... Success!
Normally, root should only be allowed to connect from 'localhost'.  This
ensures that someone cannot guess at the root password from the network.
Disallow root login remotely? [Y/n] ENTER
 ... Success!
By default, MariaDB comes with a database named 'test' that anyone can
access.  This is also intended only for testing, and should be removed
before moving into a production environment.
Remove test database and access to it? [Y/n] ENTER
 - Dropping test database...
 ... Success!
 - Removing privileges on test database...
 ... Success!
Reloading the privilege tables will ensure that all changes made so far
will take effect immediately.
Reload privilege tables now? [Y/n] ENTER
 ... Success!
Cleaning up...
All done!  If you've completed all of the above steps, your MariaDB
installation should now be secure.
Thanks for using MariaDB

Download PostfixAdmin auf den Asinus

louis@mail:~$ sudo apt install wget	
Paketlisten werden gelesen… Fertig
Abhängigkeitsbaum wird aufgebaut… Fertig
Statusinformationen werden eingelesen… Fertig
wget ist schon die neueste Version (1.21-1+deb11u1).
0 aktualisiert, 0 neu installiert, 0 zu entfernen und 0 nicht aktualisiert.
louis@mail:~$ wget https://github.com/postfixadmin/postfixadmin/archive/postfixadmin-3.3.11.tar.gz
--2022-11-27 16:50:50--  https://github.com/postfixadmin/postfixadmin/archive/postfixadmin-3.3.11.tar.gz
Auflösen des Hostnamens github.com (github.com)… 140.82.121.3
Verbindungsaufbau zu github.com (github.com)|140.82.121.3|:443 … verbunden.
HTTP-Anforderung gesendet, auf Antwort wird gewartet … 302 Found
Platz: https://codeload.github.com/postfixadmin/postfixadmin/tar.gz/refs/tags/postfixadmin-3.3.11 [folgend]
--2022-11-27 16:50:50--  https://codeload.github.com/postfixadmin/postfixadmin/tar.gz/refs/tags/postfixadmin-3.3.11
Auflösen des Hostnamens codeload.github.com (codeload.github.com)… 140.82.121.10
Verbindungsaufbau zu codeload.github.com (codeload.github.com)|140.82.121.10|:443 … verbunden.
HTTP-Anforderung gesendet, auf Antwort wird gewartet … 200 OK
Länge: 1869783 (1.8M) [application/x-gzip]
Wird in »postfixadmin-3.3.11.tar.gz« gespeichert.
postfixadmin-3.3.11.tar.gz           100%[===================================================================>]   1.78M  6.02MB/s    in 0.3s
2022-11-27 16:50:51 (6.02 MB/s) - »postfixadmin-3.3.11.tar.gz« gespeichert [1869783/1869783]
louis@mail:~$ sudo mkdir -p /var/www/
louis@mail:~$ sudo tar xvf postfixadmin-3.3.11.tar.gz -C /var/www/
postfixadmin-postfixadmin-3.3.11/
...
postfixadmin-postfixadmin-3.3.11/tests/bootstrap.php
louis@mail:~$ sudo mv /var/www/postfixadmin-postfixadmin-3.3.11 /var/www/postfixadmin
louis@mail:~$ cd /var/www/postfixadmin
louis@mail:/var/www/postfixadmin$ ls -la
insgesamt 308
drwxrwxr-x 15 root root  4096  2. Mär 2022  .
drwxr-xr-x  4 root root  4096 27. Nov 16:55 ..
drwxrwxr-x  4 root root  4096  2. Mär 2022  ADDITIONS
-rw-rw-r--  1 root root 60234  2. Mär 2022  CHANGELOG.TXT
-rw-rw-r--  1 root root   719  2. Mär 2022  check_mailpass_expiration.sh
-rw-rw-r--  1 root root  2832  2. Mär 2022  common.php
-rw-rw-r--  1 root root  1648  2. Mär 2022  composer.json
-rw-rw-r--  1 root root 29371  2. Mär 2022  config.inc.php
drwxrwxr-x  2 root root  4096  2. Mär 2022  configs
drwxrwxr-x  6 root root  4096  2. Mär 2022  debian
drwxrwxr-x  3 root root  4096  2. Mär 2022  DOCUMENTS
-rw-rw-r--  1 root root 74896  2. Mär 2022  functions.inc.php
drwxrwxr-x  3 root root  4096  2. Mär 2022  .github
-rw-rw-r--  1 root root   115  2. Mär 2022  .gitignore
-rw-rw-r--  1 root root 15148  2. Mär 2022  GPL-LICENSE.TXT
-rw-rw-r--  1 root root   248  2. Mär 2022  index.php
-rw-rw-r--  1 root root  7102  2. Mär 2022  INSTALL.TXT
drwxrwxr-x  2 root root  4096  2. Mär 2022  languages
drwxrwxr-x  3 root root  4096  2. Mär 2022  lib
-rw-rw-r--  1 root root  2189  2. Mär 2022  LICENSE.TXT
drwxrwxr-x  2 root root  4096  2. Mär 2022  model
-rw-rw-r--  1 root root   204  2. Mär 2022  password_expiration.sql
-rw-rw-r--  1 root root   739  2. Mär 2022  .php_cs.dist
-rw-rw-r--  1 root root   797  2. Mär 2022  phpunit.xml
-rw-rw-r--  1 root root    66  2. Mär 2022  postfixadmin.my.cnf
-rw-rw-r--  1 root root  1187  2. Mär 2022  psalm.xml
drwxrwxr-x  5 root root  4096  2. Mär 2022  public
-rw-rw-r--  1 root root  2010  2. Mär 2022  README.md
drwxrwxr-x  3 root root  4096  2. Mär 2022  scripts
-rw-rw-r--  1 root root   661  2. Mär 2022  SECURITY.md
drwxrwxr-x  2 root root  4096  2. Mär 2022  templates
drwxrwxr-x  2 root root  4096  2. Mär 2022  tests
-rw-rw-r--  1 root root   662  2. Mär 2022  .travis.yml
drwxrwxr-x  3 root root  4096  2. Mär 2022  VIRTUAL_VACATION
louis@mail:/var/www/postfixadmin$ cd



Setting Up Permissions

louis@mail:~$ sudo mkdir /var/www/postfixadmin/templates_c
louis@mail:~$ sudo apt install acl
Paketlisten werden gelesen… Fertig
Abhängigkeitsbaum wird aufgebaut… Fertig
Statusinformationen werden eingelesen… Fertig
Die folgenden NEUEN Pakete werden installiert:
  acl
0 aktualisiert, 1 neu installiert, 0 zu entfernen und 0 nicht aktualisiert.
Es müssen 62.0 kB an Archiven heruntergeladen werden.
Nach dieser Operation werden 206 kB Plattenplatz zusätzlich benutzt.
Holen:1 http://debian.ethz.ch/debian bullseye/main i386 acl i386 2.2.53-10 [62.0 kB]
Es wurden 62.0 kB in 0 s geholt (308 kB/s).
Vormals nicht ausgewähltes Paket acl wird gewählt.
(Lese Datenbank ... 42820 Dateien und Verzeichnisse sind derzeit installiert.)
Vorbereitung zum Entpacken von .../acl_2.2.53-10_i386.deb ...
Entpacken von acl (2.2.53-10) ...
acl (2.2.53-10) wird eingerichtet ...
Trigger für man-db (2.9.4-2) werden verarbeitet ...
louis@mail:~$ sudo setfacl -R -m u:www-data:rwx /var/www/postfixadmin/templates_c/
louis@mail:~$ sudo setfacl -R -m u:www-data:rx /etc/letsencrypt/live/ /etc/letsencrypt/archive/

Database und User für PostfixAdmin

Die im Folgenden unter «post…» angedeuteten Angaben (Datenbank und User) sind sehr wichtig und sind vom Leser bzw. Anwender entsprechend zu ergänzen.

louis@mail:~$ sudo mysql -u root
Welcome to the MariaDB monitor.  Commands end with ; or \g.
Your MariaDB connection id is 36
Server version: 10.5.15-MariaDB-0+deb11u1 Debian 11
Copyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others.
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
MariaDB [(none)]> create database post...;
Query OK, 1 row affected (0.002 sec)
MariaDB [(none)]> grant all privileges on post....* to 'post...'@'localhost' identified by 'post...';
Query OK, 0 rows affected (0.006 sec)
MariaDB [(none)]> flush privileges;
Query OK, 0 rows affected (0.003 sec)
MariaDB [(none)]> exit;
Bye

PostfixAdmin konfigurieren

Hinweis Beendigungszeichen „?>“

Die im Folgenden unter «post…» angedeuteten Angaben (Datenbank und User) sind wieder entsprechend zu ergänzen. Gemäss Kommentar von einem Leser namens „Flemming“ in der Originalanleitung setze ich am Schluss der php-Datei das Beendigungszeichen „?>“. Ohne dieses Beendigungszeichen gibt es auch eine Script-Fehlermeldung.

louis@mail:~$ sudo nano /var/www/postfixadmin/config.local.php
<?php
$CONF['configured'] = true;
$CONF['database_type'] = 'mysqli';
$CONF['database_host'] = 'localhost';
$CONF['database_port'] = '3306';
$CONF['database_user'] = 'post...';
$CONF['database_password'] = 'post...';
$CONF['database_name'] = 'post...';
$CONF['encrypt'] = 'dovecot:ARGON2I';
$CONF['dovecotpw'] = "/usr/bin/doveadm pw -r 5";
if(@file_exists('/usr/bin/doveadm')) { // @ to silence openbase_dir stuff; see https://github.com/postfixadmin/postfixadmin/issues/171
    $CONF['dovecotpw'] = "/usr/bin/doveadm pw -r 5"; # debian
}
?>

Webzugriff für den PostfixAdmin

Für die Domain «ifit.at» muss auch noch in der DNS-Zone von Swiss-DNS für die Subdomain «postfixadmin.ifit.at» ein A Record ergänzt werden. Danach erzeuge ich für den Apache Webserver ein Virtual Host Config File für den PostfixAdmin. Falls jemand auf einer Windows 10 Umgebung ohne eigenen DNS Server arbeitet, muss man als Admin (run cmd as administrator) auch die «hosts»-Datei mit C:\Windows\System32\drivers\etc>notepad hosts anpassen. Wenn man alles richtig macht, auch die notwendigen und empfohlenen PHP Module erfolgreich installiert, dann bekommt man die setup.php-Seite unter https://postfixadmin,ifit.at/setup.php !!!

louis@mail:~$ sudo nano /etc/apache2/sites-available/postfixadmin.conf
<VirtualHost *:80>
  ServerName postfixadmin.ifit.at
  DocumentRoot /var/www/postfixadmin/public
  ErrorLog ${APACHE_LOG_DIR}/postfixadmin_error.log
  CustomLog ${APACHE_LOG_DIR}/postfixadmin_access.log combined
  <Directory />
    Options FollowSymLinks
    AllowOverride All
  </Directory>
  <Directory /var/www/postfixadmin/>
    Options FollowSymLinks MultiViews
    AllowOverride All
    Order allow,deny
    allow from all
  </Directory>
</VirtualHost>
louis@mail:~$ sudo a2ensite postfixadmin.conf
Enabling site postfixadmin.
To activate the new configuration, you need to run:
  systemctl reload apache2
louis@mail:~$ sudo systemctl reload apache2
louis@mail:~$ sudo apt install php7.4-fpm php7.4-imap php7.4-mbstring php7.4-mysql php7.4-json php7.4-curl php7.4-zip php7.4-xml php7.4-bz2 php7.4-intl php7.4-gmp
...
louis@mail:~$ sudo systemctl restart apache2
louis@mail:~$ sudo apt install certbot
Paketlisten werden gelesen… Fertig
Abhängigkeitsbaum wird aufgebaut… Fertig
Statusinformationen werden eingelesen… Fertig
certbot ist schon die neueste Version (1.12.0-2).
0 aktualisiert, 0 neu installiert, 0 zu entfernen und 0 nicht aktualisiert.
louis@mail:~$ sudo apt install python3-certbot-apache
Paketlisten werden gelesen… Fertig
Abhängigkeitsbaum wird aufgebaut… Fertig
Statusinformationen werden eingelesen… Fertig
python3-certbot-apache ist schon die neueste Version (1.10.1-1).
0 aktualisiert, 0 neu installiert, 0 zu entfernen und 0 nicht aktualisiert.
louis@mail:~$ sudo certbot --apache --agree-tos --redirect --hsts --staple-ocsp --email web@ifit.ch -d postfixadmin.ifit.at
Saving debug log to /var/log/letsencrypt/letsencrypt.log
Plugins selected: Authenticator apache, Installer apache
Requesting a certificate for postfixadmin.ifit.at
Performing the following challenges:
http-01 challenge for postfixadmin.ifit.at
Enabled Apache rewrite module
Waiting for verification...
Cleaning up challenges
Created an SSL vhost at /etc/apache2/sites-available/postfixadmin-le-ssl.conf
Enabled Apache socache_shmcb module
Enabled Apache ssl module
Deploying Certificate to VirtualHost /etc/apache2/sites-available/postfixadmin-le-ssl.conf
Enabling available site: /etc/apache2/sites-available/postfixadmin-le-ssl.conf
Enabled Apache headers module
Adding Strict-Transport-Security header to ssl vhost in /etc/apache2/sites-available/postfixadmin-le-ssl.conf
Enabled Apache rewrite module
Redirecting vhost in /etc/apache2/sites-enabled/postfixadmin.conf to ssl vhost in /etc/apache2/sites-available/postfixadmin-le-ssl.conf
OCSP Stapling was enabled on SSL Vhost: /etc/apache2/sites-available/postfixadmin-le-ssl.conf.
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Congratulations! You have successfully enabled https://postfixadmin.ifit.at
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
IMPORTANT NOTES:
 - Congratulations! Your certificate and chain have been saved at:
   /etc/letsencrypt/live/postfixadmin.ifit.at/fullchain.pem
   Your key file has been saved at:
   /etc/letsencrypt/live/postfixadmin.ifit.at/privkey.pem
   Your certificate will expire on 2023-02-25. To obtain a new or
   tweaked version of this certificate in the future, simply run
   certbot again with the "certonly" option. To non-interactively
   renew *all* of your certificates, run "certbot renew"
 - If you like Certbot, please consider supporting our work by:

   Donating to ISRG / Let's Encrypt:   https://letsencrypt.org/donate
   Donating to EFF:                    https://eff.org/donate-le

Statistik in Dovecot aktivieren


louis@mail:~$ sudo nano /etc/dovecot/conf.d/10-master.conf
...
service dict {
  # If dict proxy is used, mail processes should have access to its socket.
  # For example: mode=0660, group=vmail and global mail_access_groups=vmail
  unix_listener dict {
    #mode = 0600
    #user =
    #group =
  }
}

service stats {
    unix_listener stats-reader {
    user = www-data
    group = www-data
    mode = 0660
}

unix_listener stats-writer {
    user = www-data
    group = www-data
    mode = 0660
  }
}
louis@mail:~$ sudo gpasswd -a www-data dovecot
Benutzer www-data wird zur Gruppe dovecot hinzugefügt.
louis@mail:~$ sudo systemctl restart dovecot
louis@mail:~$ sudo setfacl -R -m u:www-data:rwx /var/run/dovecot/stats-reader /var/run/dovecot/stats-writer

Endlich: Die erste Setup-Page ist da !!!

Korrektur von Fehlern (Flemming)

louis@mail:~$ sudo nano /etc/apache2/sites-available/postfixadmin.conf

<VirtualHost *:80>
  ServerName postfixadmin.ifit.at
  DocumentRoot /var/www/postfixadmin/public

  ErrorLog ${APACHE_LOG_DIR}/postfixadmin_error.log
  CustomLog ${APACHE_LOG_DIR}/postfixadmin_access.log combined

  <Directory />
    Options FollowSymLinks
    AllowOverride All
  </Directory>

  <Directory /var/www/postfixadmin/>
#    Options FollowSymLinks MultiViews
    Options Indexes Includes FollowSymLinks ExecCGI MultiViews
    AllowOverride All
    Order allow,deny
    allow from all
  </Directory>

RewriteEngine on
RewriteCond %{SERVER_NAME} =postfixadmin.ifit.at
RewriteRule ^ https://%{SERVER_NAME}%{REQUEST_URI} [END,NE,R=permanent]
</VirtualHost>
louis@mail:~$ sudo systemctl restart apache2
louis@mail:~$ sudo apt install libapache2-mod-php7.4 php7.4-cli
Paketlisten werden gelesen… Fertig
Abhängigkeitsbaum wird aufgebaut… Fertig
Statusinformationen werden eingelesen… Fertig
php7.4-cli ist schon die neueste Version (7.4.33-1+deb11u1).
php7.4-cli wurde als manuell installiert festgelegt.
Vorgeschlagene Pakete:
  php-pear
Die folgenden NEUEN Pakete werden installiert:
  libapache2-mod-php7.4
0 aktualisiert, 1 neu installiert, 0 zu entfernen und 0 nicht aktualisiert.
Es müssen 1’405 kB an Archiven heruntergeladen werden.
Nach dieser Operation werden 4’270 kB Plattenplatz zusätzlich benutzt.
Möchten Sie fortfahren? [J/n]
Holen:1 http://security.debian.org/debian-security bullseye-security/main i386 libapache2-mod-php7.4 i386 7.4.33-1+deb11u1 [1’405 kB]
Es wurden 1’405 kB in 0 s geholt (3’166 kB/s).
Vormals nicht ausgewähltes Paket libapache2-mod-php7.4 wird gewählt.
(Lese Datenbank ... 43136 Dateien und Verzeichnisse sind derzeit installiert.)
Vorbereitung zum Entpacken von .../libapache2-mod-php7.4_7.4.33-1+deb11u1_i386.deb ...
Entpacken von libapache2-mod-php7.4 (7.4.33-1+deb11u1) ...
libapache2-mod-php7.4 (7.4.33-1+deb11u1) wird eingerichtet ...

Creating config file /etc/php/7.4/apache2/php.ini with new version
Module mpm_event disabled.
Enabling module mpm_prefork.
apache2_switch_mpm Switch to prefork
apache2_invoke: Enable module php7.4
Trigger für libapache2-mod-php7.4 (7.4.33-1+deb11u1) werden verarbeitet ...
louis@mail:~$ sudo systemctl restart apache2

Super, hat geklappt!

PostfixAdmin-Installation im Browser

Wenn die Setup-Seite fehlerlos auftaucht, muss man sich mit einem selbst erfundenem oder generierten Setup Passwort anmelden. Diese Anmeldung erzeugt einen String der Art: $CONF[’setup_password›] = ‹$2y$10$58fIawuOb5y538RMBol/DOoqv2bJ7zhPRzRO.4Xq7MLeQJHmaFwF2›; welches man in der Datei config.local.php einträgt.

Hinweis zum String (nicht echt)

Der hier gezeigte String ist von der Originalanleitung übernommen worden und stimmt hier natürlich nicht.

louis@mail:~$ sudo nano /var/www/postfixadmin/config.local.php
<?php
$CONF['configured'] = true;
$CONF['database_type'] = 'mysqli';
$CONF['database_host'] = 'localhost';
$CONF['database_port'] = '3306';
$CONF['database_user'] = 'post...';
$CONF['database_password'] = 'post...';
$CONF['database_name'] = 'post...';
$CONF['encrypt'] = 'dovecot:ARGON2I';
$CONF['dovecotpw'] = "/usr/bin/doveadm pw -r 5";
if(@file_exists('/usr/bin/doveadm')) { // @ to silence openbase_dir stuff; see https://github.com/postfixadmin/postfixadmin/issues/171
    $CONF['dovecotpw'] = "/usr/bin/doveadm pw -r 5"; # debian
}
$CONF['setup_password'] = '$2y$10$58fIawuOb5y538RMBol/DOoqv2bJ7zhPRzRO.4Xq7MLeQJHmaFwF2';
?>

Postfix braucht jetzt MariaDB

louis@mail:~$ sudo apt install postfix-mysql
...
louis@mail:~$ sudo nano /etc/postfix/main.cf
...
mailbox_transport = lmtp:unix:private/dovecot-lmtp
smtputf8_enable = no
virtual_mailbox_domains = proxy:mysql:/etc/postfix/sql/mysql_virtual_domains_maps.cf
virtual_mailbox_maps =
   proxy:mysql:/etc/postfix/sql/mysql_virtual_mailbox_maps.cf,
   proxy:mysql:/etc/postfix/sql/mysql_virtual_alias_domain_mailbox_maps.cf
virtual_alias_maps =
   proxy:mysql:/etc/postfix/sql/mysql_virtual_alias_maps.cf,
   proxy:mysql:/etc/postfix/sql/mysql_virtual_alias_domain_maps.cf,
   proxy:mysql:/etc/postfix/sql/mysql_virtual_alias_domain_catchall_maps.cf
virtual_transport = lmtp:unix:private/dovecot-lmtp
louis@mail:~$ sudo mkdir /etc/postfix/sql/
louis@mail:~$ sudo nano /etc/postfix/sql/mysql_virtual_domains_maps.cf
user = post...
password = post...
hosts = localhost
dbname = post...
query = SELECT domain FROM domain WHERE domain='%s' AND active = '1'
#query = SELECT domain FROM domain WHERE domain='%s'
#optional query to use when relaying for backup MX
#query = SELECT domain FROM domain WHERE domain='%s' AND backupmx = '0' AND active = '1'
#expansion_limit = 100
louis@mail:~$ sudo nano /etc/postfix/sql/mysql_virtual_mailbox_maps.cf
user = post...
password = post...
hosts = localhost
dbname = post...
query = SELECT maildir FROM mailbox WHERE username='%s' AND active = '1'
#expansion_limit = 100
louis@mail:~$ sudo nano /etc/postfix/sql/mysql_virtual_alias_domain_mailbox_maps.cf
user = post...
password = post...
hosts = localhost
dbname = post...
query = SELECT maildir FROM mailbox,alias_domain WHERE alias_domain.alias_domain = '%d' and mailbox.username = CONCAT('%u', '@', alias_domai>
louis@mail:~$ sudo nano /etc/postfix/sql/mysql_virtual_alias_maps.cf
user = post...
password = post...
hosts = localhost
dbname = post...
query = SELECT goto FROM alias WHERE address='%s' AND active = '1'
#expansion_limit = 100
louis@mail:~$ sudo nano /etc/postfix/sql/mysql_virtual_alias_domain_maps.cf
user = post...
password = post...
hosts = localhost
dbname = post...
query = SELECT goto FROM alias,alias_domain WHERE alias_domain.alias_domain = '%d' and alias.address = CONCAT('%u', '@', alias_domain.target_domain) AND alias.active = 1 AND alias_domain.active='1'
louis@mail:~$ sudo nano /etc/postfix/sql/mysql_virtual_alias_domain_catchall_maps.cf
# handles catch-all settings of target-domain
user = post...
password = post...
hosts = localhost
dbname = post...
query = SELECT goto FROM alias,alias_domain WHERE alias_domain.alias_domain = '%d' and alias.address = CONCAT('@', alias_domain.target_domain                   ) AND alias.active = 1 AND alias_domain.active='1'
louis@mail:~$ sudo chmod 0640 /etc/postfix/sql/*
louis@mail:~$ sudo setfacl -R -m u:postfix:rx /etc/postfix/sql/
louis@mail:~$ sudo postconf mydestination
mydestination = $myhostname, ifit.at, mail.ifit.at, localhost.ifit.at, localhost
louis@mail:~$ sudo postconf -e "mydestination = \$myhostname, localhost.\$mydomain, localhost"
louis@mail:~$ sudo postconf mydestination
mydestination = $myhostname, localhost.$mydomain, localhost
louis@mail:~$ sudo nano /etc/postfix/main.cf
…
mailbox_transport = lmtp:unix:private/dovecot-lmtp
smtputf8_enable = no

virtual_mailbox_domains = proxy:mysql:/etc/postfix/sql/mysql_virtual_domains_maps.cf
virtual_mailbox_maps =
   proxy:mysql:/etc/postfix/sql/mysql_virtual_mailbox_maps.cf,
   proxy:mysql:/etc/postfix/sql/mysql_virtual_alias_domain_mailbox_maps.cf
virtual_alias_maps =
   proxy:mysql:/etc/postfix/sql/mysql_virtual_alias_maps.cf,
   proxy:mysql:/etc/postfix/sql/mysql_virtual_alias_domain_maps.cf,
   proxy:mysql:/etc/postfix/sql/mysql_virtual_alias_domain_catchall_maps.cf

virtual_transport = lmtp:unix:private/dovecot-lmtp

virtual_mailbox_base = /var/vmail
virtual_minimum_uid = 2000
virtual_uid_maps = static:2000
virtual_gid_maps = static:2000
louis@mail:~$ sudo systemctl restart postfix
louis@mail:~$ sudo adduser vmail --system --group --uid 2000 --disabled-login --no-create-home
Lege Systembenutzer »vmail« (UID 2000) an ...
Lege neue Gruppe »vmail« (GID 2000) an ...
Lege neuen Benutzer »vmail« (UID 2000) mit Gruppe »vmail« an ...
Erstelle Home-Verzeichnis »/home/vmail« nicht.
louis@mail:~$ sudo mkdir /var/vmail/
louis@mail:~$ sudo chown vmail:vmail /var/vmail/ -R

Dovecot braucht jetzt auch MariaDB

louis@mail:~$ sudo apt install dovecot-mysql
...
louis@mail:~$ sudo nano /etc/dovecot/conf.d/10-mail.conf
...
#
# <doc/wiki/MailLocation.txt>
#
#mail_location = mbox:~/mail:INBOX=/var/mail/%u
mail_location = maildir:~/Maildir
mail_home = /var/vmail/%d/%n/
louis@mail:~$ sudo nano /etc/dovecot/conf.d/10-auth.conf
# Username formatting before it's looked up from databases. You can use
# the standard variables here, eg. %Lu would lowercase the username, %n would
# drop away the domain if it was given, or "%n-AT-%d" would change the '@' into
# "-AT-". This translation is done after auth_username_translation changes.
#auth_username_format = %Lu
#auth_username_format = %n
auth_username_format = %u
...
# Default realm/domain to use if none was specified. This is used for both
# SASL realms and appending @domain to username in plaintext logins.
#auth_default_realm =
auth_default_realm = ifit.at
…
#!include auth-system.conf.ext
!include auth-sql.conf.ext
#!include auth-ldap.conf.ext
#!include auth-passwdfile.conf.ext
#!include auth-checkpassword.conf.ext
#!include auth-static.conf.ext
auth_debug = yes
auth_debug_passwords = yes
louis@mail:~$ sudo nano /etc/dovecot/dovecot-sql.conf.ext
...
# Query to get a list of all usernames.
#iterate_query = SELECT username AS user FROM users
driver = mysql
connect = host=localhost dbname=post... user=post... password=post...
default_pass_scheme = ARGON2I
password_query = SELECT username AS user,password FROM mailbox WHERE username = '%u' AND active='1'
user_query = SELECT maildir, 2000 AS uid, 2000 AS gid FROM mailbox WHERE username = '%u' AND active='1'
iterate_query = SELECT username AS user FROM mailbox

Domain und Mailboxes in PostfixAdmin

Abschliessende Bemerkung zur 3. Datensicherung

Nachdem ich die Konfiguration von Part 3 durchgegangen bin, habe ich die Benutzer «louis» und «lavenetz» in Thunderbird sowie «colin» auf einem Huawei und «alisha» auf einem iPhone7+ nochmals in PostfixAdmin eingegeben und gestestet. Für eine perfekte Kommunikation fehlen noch SPF, DKIM und DMARC, die im nächsten Teil 4 eingeführt werden. Nun kann ich die zweite Datensicherung durchführen. Die Datei lautet: 2022-11-27-Asinus-i386-on-Debian-11.5-Server-Linux-Kernel-5.10.0-19-686-pae+Postfix+Dovecot+PostfixAdmin.img

Setup SPF & DKIM with Postfix

SPF Record in der DNS Zone eintragen

Obwohl ich bereits jetzt schon Mails mit einem Mail-Client senden und empfangen kann, muss die Mail-Zustellung an den Posteingang eines Empfängers verbessert werden, indem ich SPF und DKIM auf dem Debian-Server einrichte. Der SPF-Eintrag (Sender Policy Framework) gibt an, welche Hosts oder IP-Adressen eMails im Namen einer Domain senden dürfen. Ich muss also dem Asinus erlauben, eMails für ifit.at zu senden. Für SPF muss in der DNS Zone «ifit.at» ein TXT Record eingetragen werden.

Nachdem der Eintrag erfolgt ist, sollte normalerweise Minuten später der Eintrag im DNSChecker ersichtlich sein.

louis@mail:~$ sudo su -
[sudo] Passwort für louis:
root@mail:~# dig ifit.at txt
; <<>> DiG 9.16.33-Debian <<>> ifit.at txt
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 57272
;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 512
;; QUESTION SECTION:
;ifit.at.                       IN      TXT
;; ANSWER SECTION:
ifit.at.                10800   IN      TXT     "v=spf1 mx ~all"
;; Query time: 40 msec
;; SERVER: 62.2.24.162#53(62.2.24.162)
;; WHEN: Mon Nov 28 12:32:02 CET 2022
;; MSG SIZE  rcvd: 63

Unter dem Link https://dmarcian.com/spf-survey/ kann man den TXT Eintrag auch testen:

SPF Policy Agent auf Debian aktivieren

root@mail:~# sudo apt install postfix-policyd-spf-python
...
root@mail:~# sudo nano /etc/postfix/master.cf
#
# Other external delivery methods.
#
ifmail    unix  -       n       n       -       -       pipe
  flags=F user=ftn argv=/usr/lib/ifmail/ifmail -r $nexthop ($recipient)
bsmtp     unix  -       n       n       -       -       pipe
  flags=Fq. user=bsmtp argv=/usr/lib/bsmtp/bsmtp -t$nexthop -f$sender $recipient
scalemail-backend unix -       n       n       -       2       pipe
  flags=R user=scalemail argv=/usr/lib/scalemail/bin/scalemail-store ${nexthop} ${user} ${extension}
mailman   unix  -       n       n       -       -       pipe
  flags=FRX user=list argv=/usr/lib/mailman/bin/postfix-to-mailman.py ${nexthop} ${user}
policyd-spf  unix  -       n       n       -       0       spawn
    user=policyd-spf argv=/usr/bin/policyd-spf
root@mail:~# sudo nano /etc/postfix/main.cf
…
mailbox_transport = lmtp:unix:private/dovecot-lmtp
smtputf8_enable = no

virtual_mailbox_domains = proxy:mysql:/etc/postfix/sql/mysql_virtual_domains_maps.cf
virtual_mailbox_maps =
   proxy:mysql:/etc/postfix/sql/mysql_virtual_mailbox_maps.cf,
   proxy:mysql:/etc/postfix/sql/mysql_virtual_alias_domain_mailbox_maps.cf
virtual_alias_maps =
   proxy:mysql:/etc/postfix/sql/mysql_virtual_alias_maps.cf,
   proxy:mysql:/etc/postfix/sql/mysql_virtual_alias_domain_maps.cf,
   proxy:mysql:/etc/postfix/sql/mysql_virtual_alias_domain_catchall_maps.cf

virtual_transport = lmtp:unix:private/dovecot-lmtp

virtual_mailbox_base = /var/vmail
virtual_minimum_uid = 2000
virtual_uid_maps = static:2000
virtual_gid_maps = static:2000

authorized_submit_users = root,www-data,vmail

policyd-spf_time_limit = 3600
smtpd_recipient_restrictions =
   permit_mynetworks,
   permit_sasl_authenticated,
   reject_unauth_destination,
   check_policy_service unix:private/policyd-spf

root@mail:~# exit

Abgemeldet
root@mail:~# sudo systemctl restart postfix

DKIM auf Debian aktivieren

louis@mail:~$ sudo apt install opendkim opendkim-tools
...
louis@mail:~$ sudo gpasswd -a postfix opendkim
Benutzer postfix wird zur Gruppe opendkim hinzugefügt.
louis@mail:~$ sudo nano /etc/opendkim.conf
...
Vorher

# Common signing and verification parameters. In Debian, the "From" header is
# oversigned, because it is often the identity key used by reputation systems
# and thus somewhat security sensitive.
Canonicalization        relaxed/simple
#Mode                   sv
#SubDomains             no
OversignHeaders         From
Nachher

Canonicalization        relaxed/simple
Mode                    sv
SubDomains              no
OversignHeaders         From
...
# The trust anchor enables DNSSEC. In Debian, the trust anchor file is provided
# by the package dns-root-data.
TrustAnchorFile         /usr/share/dns/root.key
#Nameservers            127.0.0.1
Nameservers             8.8.8.8,1.1.1.1
# Map domains in From addresses to keys used to sign messages
KeyTable           refile:/etc/opendkim/key.table
SigningTable       refile:/etc/opendkim/signing.table
# Hosts to ignore when verifying signatures
ExternalIgnoreList  /etc/opendkim/trusted.hosts
# A set of internal hosts whose mail should be signed
InternalHosts       /etc/opendkim/trusted.hosts

Signing Table, Key Table und Trusted Hosts File

louis@mail:~$ sudo mkdir -p /etc/opendkim/keys
louis@mail:~$ sudo chown -R opendkim:opendkim /etc/opendkim
louis@mail:~$ sudo chmod go-rw /etc/opendkim/keys
louis@mail:~$ sudo nano /etc/opendkim/signing.table
*@ifit.at      default._domainkey.ifit.at
*@*.ifit.at    default._domainkey.ifit.at
louis@mail:~$ sudo nano /etc/opendkim/key.table
default._domainkey.ifit.at     ifit.at:default:/etc/opendkim/keys/ifit.at/default.private
louis@mail:~$ sudo nano /etc/opendkim/trusted.hosts
127.0.0.1
localhost

.ifit.at

Private/Public Keypair generieren

louis@mail:~$ sudo mkdir /etc/opendkim/keys/ifit.at
louis@mail:~$ sudo opendkim-genkey -b 2048 -d ifit.at -D /etc/opendkim/keys/ifit.at -s default -v
opendkim-genkey: generating private key
opendkim-genkey: private key written to default.private
opendkim-genkey: extracting public key
opendkim-genkey: DNS TXT record written to default.txt
louis@mail:~$ sudo chown opendkim:opendkim /etc/opendkim/keys/ifit.at/default.private
louis@mail:~$ sudo chmod 600 /etc/opendkim/keys/ifit.at/default.private

Public Key im DNS veröffentlichen

louis@mail:~$ sudo cat /etc/opendkim/keys/ifit.at/default.txt
default._domainkey      IN      TXT     ( "v=DKIM1; h=sha256; k=rsa; "
          "p=MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAzjnnPuxHL8UN6f8hj5RRRdITThnUfmIimYDCMyi2XjS9SB51Lcb2jL2UcWW7e8DvhqCHX5Fkv4pXeLPU9mWZ8sMjp/qcy9AxVFfc+n/qzMYw6LlSJsGdzY8EO9NbNLOcvHNCGEWo+MHcTl3IOMxdHUJtlTaRazdx9k3bjy76PX7E9iAZs57z/pn4QJ3I04FN9OXSGtkD3aKcPn"
          "DjDczaLZU5HPDzOvR/qouXaxXtWUGEwFNGXBzNFZb0KqtwdhWWf394YTrqOxL7QAkFH4Zn/ScxjU6Iq2H8uTXtDVSTqVvjeb8oBx0s/npDaJuYbVR83EJPoA8JL42sMOGSZoqjgwIDAQAB" )  ; ----- DKIM key default for ifit.at
louis@mail:~$ sudo opendkim-testkey -d ifit.at -s default -vvv

opendkim-testkey: using default configfile /etc/opendkim.conf
opendkim-testkey: checking key 'default._domainkey.ifit.at'
opendkim-testkey: key not secure
opendkim-testkey: key OK

Hinweis zu DKIM

Beim DomainKeys Identified Mail (DKIM) handelt es sich um einen öffentlichen Schlüssel (Public Key). Der Empfänger eines meiner eMails, welches ich mit meinem Private Key verschlüsselt habe, kann es mit dem Public Key, den ich im TXT Record DKIM zur Verfügung stelle, entschlüsseln. Die obige Meldung «key not secure» kommt daher, dass DNSSEC beim Registrar (swizzonic.ch) für diese Domain (noch) nicht gesetzt ist, wie dies bei meinen anderen Mailservern «ifit.ch» (swizzonic.ch) und «ifit.news» (whois.com) der Fall ist. Es hat relativ lange gedauert, bis ich u.a. diese Sache auch in den Griff bekommen habe. Ich hoffe nur, dass der Leser dieses Blogs langsam versteht, warum ich dieses Projekt «Unmöglicher Pöstler mit Ecken und Kanten» genannt habe! Es gibt auch Hilfsmittel (Tools), mit deren Hilfe man DKIM testen kann:

https://www.dmarcanalyzer.com/dkim/dkim-check/

Kein Hinweis von «query timed out!» ist ein gutes Zeichen.

Postfix mit OpenDKIM verknüpfen

louis@mail:~$ sudo mkdir /var/spool/postfix/opendkim

louis@mail:~$ sudo chown opendkim:postfix /var/spool/postfix/opendkim
louis@mail:~$ sudo nano /etc/opendkim.conf

Socket               local:/var/spool/postfix/opendkim/opendkim.sock

louis@mail:~$ sudo nano /etc/default/opendkim


SOCKET="local:/var/spool/postfix/opendkim/opendkim.sock"

louis@mail:~$ sudo nano /etc/default/opendkim
RUNDIR=/run/opendkim
USER=opendkim
GROUP=opendkim
PIDFILE=$RUNDIR/$NAME.pid
EXTRAAFTER=

louis@mail:~$ sudo nano /etc/postfix/main.cf
...
virtual_transport = lmtp:unix:private/dovecot-lmtp

virtual_mailbox_base = /var/vmail
virtual_minimum_uid = 2000
virtual_uid_maps = static:2000
virtual_gid_maps = static:2000

authorized_submit_users = root,www-data,vmail

policyd-spf_time_limit = 3600
smtpd_recipient_restrictions =
   permit_mynetworks,
   permit_sasl_authenticated,
   reject_unauth_destination,
   check_policy_service unix:private/policyd-spf

# Milter configuration
milter_default_action = accept
milter_protocol = 6
smtpd_milters = local:opendkim/opendkim.sock
non_smtpd_milters = $smtpd_milters

louis@mail:~$ sudo systemctl restart opendkim postfix

SPF and DKIM Check in Google Mail

Testing Email Score and Placement

Der Score unter www.mail-tester.com ist 9.3 und ist blacklisted.

DMARC Record to Protect Your Domain Name From Email Spoofing

Zur Erinnerung: Im vorigen Kapitel (Teil 4 der Originalanleitung) habe ich die heiklen Themen Sender Policy Framework (SPF) und DomainKeys Identified Mail (DKIM) behandelt. In Teil 5 der Originalanleitung kommt nun noch ein wichtiges Thema hinzu: Domain-based Message Authentication, Reporting and Conformance (DMARC). Im folgenden sieht man ein Screenshot der SPF-, DKIM- und DMARC-Einträge in der TXT Record Tabelle meiner DNS-Zone «ifit.at». Auf den Eintrag «_token._dnswl.ifit.at» (DNS Whitelist) komme ich später noch zurück.

SPF-, DKIM- und DMARC Einträge

Diese drei Einträge werden mit Hilfe des Tools «www.mail-tester.com» dargestellt (siehe 3fach grüne Checksymbole im folgenden Screenshot).

Abschliessende Bemerkung zur 4. Datensicherung

Bei der 4. Datensicherung wurden Teile 4 und 5 zusammengefasst. Die Datei heisst: 2022-11-28-Asinus-i386-on-Debian-11.5-Server-Linux-Kernel-5.10.0-19-686-pae+Postfix+Dovecot+PostfixAdmin+SPF+DKIM+DMARC.img. Auch hier wurde wieder eine Verifikation durchgeführt.

Installation von OpenDMARC

louis@mail:~$ sudo apt install opendmarc
...
louis@mail:~$ sudo opendmarc-check ifit.at
DMARC record for ifit.at:
        Sample percentage: 100
        DKIM alignment: relaxed
        SPF alignment: relaxed
        Domain policy: none
        Subdomain policy: unspecified
        Aggregate report URIs:
                mailto:lavenetz@ifit.at
        Failure report URIs:
                (none)

Oh Schreck! IP 84.74.0.14 ist im SORBS !

Hinweis zur SORBS Datenbank

Ich habe stundenlang mit dem Support von UPC Cablecom (neu: Sunrise) telefoniert mit der Bitte, sie mögen mich doch bitte aus der SORBS Datenbank entfernen und Reverse DNS setzen, so dass der PTR Record auf mail.ifit.at zeigt. Aber die hatten kein Gehör und haben mich auf die Sunrise Community verwiesen. Toll, nicht? In der Zwischenzeit habe ich erfahren, dass ich ein Business Abo mit einer fixen IP brauche, damit ich den Reverse DNS PTR (Pointer) selbst setzen oder vom ISP setzen lassen kann. Es zeigt sich, dass im Zusammenhang mit Reverse DNS ziemlich Schindluderei getrieben wird. Warum gibt es so viele Blacklisten? Was ist da in der Informatik – vor allem in den letzten Jahren – aus dem Ruder gelaufen? (Hinweis: Ich kann doch diese Bemerkung machen, da ich schon seit 1977 dabei bin und 1980 den Bachelor in Computer Science abgeschlossen habe, oder nicht?) Aber schauen wir doch mal, ob es nicht noch andere Möglichkeiten gibt? Das wäre z.B. FCrDNS.

https://ipadmin.junkemailfilter.com/rdns.php

Forward Confirmed Reverse DNS Lookup

Warum Forward Confirmed rDNS wichtig ist – FCrDNS verhindert, dass andere mein Host fälschen. Wenn ich der Bösewicht bin und den Reverse-Lookup für meine IP-Adressen kontrolliere, kann ich dort alles eingeben. Ich könnte mich als eine Bank ausgeben und versuchen, einen dazu zu bringen, seine Kontodaten preiszugeben. Was ich jedoch nicht fälschen kann, ist, wenn einer nach dem falschen Namen suchen würde, den ich zurückgebe, und er entweder nicht aufgelöst wird oder in eine andere IP-Adresse aufgelöst wird, dann wüsste man, dass er nicht echt ist. Wenn es auf dieselbe IP-Adresse aufgelöst wird, weiss man, dass es gut ist. Dies liegt daran, dass nur der Domaininhaber dafür sorgen kann, dass FCrDNS ordnungsgemäß funktioniert. Dies ist ein sehr wichtiges Tool zur Erkennung von E-Mail-Phishing-Betrug.

Here's how it's suppsed to work. Suppose your IP is 1.2.3.4:

1.2.3.4 --- PTR Record ---> hostname.example.com
hostname.example.com --- A Record ---> 1.2.3.4

The name that is returned by the rDNS lookup needs to point back to the same IP address.

Angewendet auf meine IP würde lauten:

Looking up Reverse DNS for IP Address: [84.74.0.14]

RDNS for 84.74.0.14 is: [84-74-0-14.dclient.hispeed.ch] - (PTR record - 14.0.74.84.in-addr.arpa)
IP Address for 84-74-0-14.dclient.hispeed.ch is: [84.74.0.14]
SUCCESS! - Forward Confirmed Reverse DNS is CORRECT!
The IP address for the reverse lookup name matches the original IP

Hostkarma blacklist Removal Form

Hinweis: Dies ist ein Entfernungsformular aus Höflichkeit für diejenigen, die entweder fälschlicherweise aufgelistet wurden oder das Problem behoben haben und nun bereit sind, entfernt zu werden. Diese Entfernung ist kurzfristig und wenn mehr Spam erkannt wird, wird man erneut gelistet. Wenn sie meinen Server irrtümlich aufgelistet haben, möchte ich auf die Whitelist gesetzt werden, oder wenn ich Kommentare habe, könnte ich denen eine E-Mail an remove@junkemailfilter.com senden. Der Junk-E-Mail-Filter ist eines der fortschrittlichsten Spam-Filtersysteme der Welt. Es fungiert als Frontend-Spamfilter für Domains. MX-Einträge werden auf ihre Server verwiesen. Sie erhalten die E-Mail, verarbeiten sie und senden sie an meinen bestehenden E-Mail-Server.

https://ipadmin.junkemailfilter.com/remove.php
Share this:

Von Louis A. Venetz

Dipl. Ing. FH in Systemtechnik
Freier Fachjournalist BR