Das Problem

Das Problem

Das Problem

Ich kann nicht herausfinden, wie ich Postfix zwingen kann, eine TLS-Verbindung zu MySQL zu verwenden. IchdürfenStellen Sie als Postfix-Benutzer manuell eine Verbindung vom Postfix-Server zum MySQL-Server mit TLS her, damit bei der MySQL-Authentifizierung nichts schief geht. Das Problem ist klar: Postfix fordert kein TLS für die MySQL-Verbindung an.

Versionen:

  • Betriebssystem: CentOS 7
  • Postfix: 2:2.10.1-6.el7 und 2:3.2.4-1.gf.el7
  • MySQL (MariaDB): 5.5.56

Wie ich hierher gekommen bin

Ich habe im gesamten Web, einschließlich der verschiedenen StackExchange-Sites, nach einer Antwort auf diese Frage gesucht. Ich habe die Postfix- und MySQL-Dokumentation wiederholt ausführlich gelesen. Die beste Antwort, die ich gefunden habe, lehne ich als unnötig kompliziert ab: „Richten Sie einen SSH-Tunnel zwischen Ihren Postfix- und MySQL-Servern ein und stellen Sie dann eine Verbindung darüber her.„Es muss eine Möglichkeit geben, Postfix anzuweisen, die TLS-Verschlüsselung (SSL) mit dem MySQL-Client zu verwenden.

Bevor wir uns mit dem Setup befassen, möchte ich Folgendes klarstellen: Mein Mailserver-Setup funktioniert einwandfrei ohne MySQL TLS. Ich verwende TLS erfolgreich für SMTPS und IMAPS und das hathat nichts mit meiner Frage zu tun. E-Mails werden sowohl in mein Netzwerk hinein als auch aus meinem Netzwerk heraus sicher transportiert, mit der Ausnahme, dass MySQL-Verbindungen zwischen Postfix und dem MySQL-Server unverschlüsselt sind. Abgesehen von der offengelegten Postfix-MySQL-Verbindung gibt es mit meiner E-Mail-Infrastruktur keinerlei Probleme.

Aufgrund geänderter Sicherheitsanforderungen muss ich jedoch meine vorhandene Infrastruktur aktualisieren, um alle MySQL-Verbindungen zu verschlüsseln. Das Einrichten von TLS für MySQL-Verbindungen war einfach. Manuelle Tests zeigen, dass MySQL-Clients von allen zulässigen Hosts aus erfolgreich über einen TLS-verschlüsselten Link eine Verbindung herstellen können.. Das MySQL TLS-Setup ist also auch solide und funktioniert für allesaußer Postfix.

Was ich versucht habe

Relevante Konfiguration auf dem Postfix-Server:

/etc/postfix/main.cf

Reduziert auf nur eine von mehreren Verbindungen, um das Material so spezifisch wie möglich zu halten.

virtual_alias_maps = proxy:mysql:/etc/postfix/lookup_aliases.cf
proxy_read_maps = $virtual_alias_maps
/etc/postfix/lookup_aliases.cf

Anmeldeinformationen und Hostnamen verschleiert.

hosts = mysql-server.domain.tld
user = postfix
password = *****
dbname = mail
option_file = /etc/my.cnf.d/client.cnf
option_group = client
tls_verify_cert = yes
query = SELECT goto FROM alias WHERE address = '%s' AND active = '1'
/etc/meine.cnf

Diese Datei ist unverändert. Ich füge sie nur ein, um zu zeigen, dass die nächste Konfigurationsdatei ordnungsgemäß in die MySQL-Client-Konfiguration aufgenommen wird.

!includedir /etc/my.cnf.d
/etc/my.cnf.d/client.cnf
[client]
ssl = true

Erfolgreich -- MANUELL -- MySQL TLS-Verbindungsausgabe vom Postfix-Server als Postfix-Benutzer

Beachten Sie insbesondere, dass TLS erfolgreich eingesetzt wird:

# hostname -f
mail.domain.tld

# sudo -u postfix mysql -h mysql-server.domain.tld -u postfix -p mail
Enter password:
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A

Welcome to the MariaDB monitor.  Commands end with ; or \g.
Your MariaDB connection id is 72
Server version: 5.5.56-MariaDB MariaDB Server

Copyright (c) 2000, 2017, Oracle, MariaDB Corporation Ab and others.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

MariaDB [mail]> \s
--------------
mysql  Ver 15.1 Distrib 5.5.56-MariaDB, for Linux (x86_64) using readline 5.1

Connection id:     72
Current database:  mail
Current user:      [email protected]
SSL:           Cipher in use is DHE-RSA-AES256-GCM-SHA384
Current pager:     stdout
Using outfile:     ''
Using delimiter:   ;
Server:            MariaDB
Server version:        5.5.56-MariaDB MariaDB Server
Protocol version:  10
Connection:        mysql-server.domain.tld via TCP/IP
Server characterset:   latin1
Db     characterset:   utf8
Client characterset:   utf8
Conn.  characterset:   utf8
TCP port:      3306
Uptime:            1 hour 27 min 23 sec

Threads: 1  Questions: 271  Slow queries: 0  Opens: 13  Flush tables: 2  Open tables: 39  Queries per second avg: 0.051
--------------

MariaDB [mail]> \q
Bye

Relevante Konfiguration auf dem MySQL-Server:

MySQL-Zuschüsse

Beachten Sie, dass TLS (SSL) ERFORDERLICH ist, ansonsten sind die Berechtigungen jedoch relativ lax, bis ich dieses TLS-Verbindungsproblem gelöst habe:

MariaDB [(none)]> SHOW GRANTS FOR 'postfix'@'10.0.101.%';
+-----------------------------------------------------------------------------------------------------+
| Grants for [email protected].%                                                                       |
+-----------------------------------------------------------------------------------------------------+
| GRANT USAGE ON *.* TO 'postfix'@'10.0.101.%' IDENTIFIED BY PASSWORD '*SOMEPASSWORDHASH' REQUIRE SSL |
| GRANT SELECT ON `mail`.* TO 'postfix'@'10.0.101.%'                                                  |
+-----------------------------------------------------------------------------------------------------+
2 rows in set (0.00 sec)

Protokolle

Postfix-Verbindung schlägt fehl, wenn SSL erforderlich ist

Obwohl der manuelle Befehlszeilentest der MySQL TLS-Verbindung hier ERFOLGREICH ist, verwendet Postfix MySQL TLS immer noch nicht.

Das allgemeine MySQL-Protokoll:

180217 14:45:15       16 Connect   [email protected] as anonymous on mail
      16 Connect   Access denied for user 'postfix'@'mail.domain.tld' (using password: YES)

Das Postfix-Protokoll:

Feb 19 19:22:55 mail postfix/cleanup[11951]: warning: proxy:mysql:/etc/postfix/lookup_aliases.cf lookup error for "[email protected]"
Feb 19 19:22:55 mail postfix/cleanup[11951]: warning: E2CCA2069823: virtual_alias_maps map lookup problem for [email protected] -- message not accepted, try again later
Postfix-Verbindung erfolgreich, wenn REQUIRE SSL entfernt wird

Dies ist Postfix, das erfolgreich eine Verbindung herstellt, nachdem die Berechtigung von SSL ERFORDERLICH in KEINE ERFORDERLICH geändert wurde. Die Verbindung ist jedochnicht verschlüsselt.

180217 15:17:21       26 Connect   [email protected] as anonymous on mail
          26 Query show databases
          26 Query show tables
          26 Field List    admin
          26 Field List    alias
          26 Field List    alias_domain
          26 Field List    config
          26 Field List    domain
          26 Field List    domain_admins
          26 Field List    fetchmail
          26 Field List    log
          26 Field List    mailbox
          26 Field List    quota
          26 Field List    quota2
          26 Field List    vacation
          26 Field List    vacation_notification
          26 Query select @@version_comment limit 1

Abschluss

Ich muss nur dafür sorgen, dass Postfix ssl = trueseine MySQL-Clientverbindungen berücksichtigt. Bitte lassen Sie mich wissen, wenn Sie weitere Informationen benötigen.

Aktualisieren:

Nachdem ich diese Frage gestellt hatte, entdeckte ich bei genauerem Lesen, dass Postfix-Versionen älter als 2.11 das Lesen von MySQL-Konfigurationsdateien überhaupt nicht unterstützen. Daher ist es unmöglich, die vom Hersteller bereitgestellte Version von Postfix (Version 2.10) für die Verwendung von MySQL TLS zu konfigurieren. Ich finde eine schlechte Formulierung in der Postfix-Dokumentation gut, wo der obere Teil vondie Postfix-Dokumentation zur MySQL-Konfigurationlautet:

Postfix 3.1 and earlier don't read [client] option group settings unless a non-empty option_file or option_group value are specified. To enable this, specify, for example "option_group = client".

Der Autor hat es versäumt, klarzustellen:

These options are ignored for Postfix 2.10 and earlier.  Postfix 2.11 through 3.1 don't read [client] option group settings unless a non-empty option_file or option_group value are specified. To enable this, specify, for example "option_group = client".

Ich habe Postfix auf CentOS 7 von der vom Hersteller bereitgestellten Version 2.10 auf dieGhettoForge Plus im Lieferumfang enthaltenVersion 3.2. Ich habe das zusätzliche Paket installiert postfix3-mysql. Ich hatte große Hoffnungen, aber diese wurden enttäuscht. Jetzt, sogar mit Postfix 3.2,stellt immer noch keine Verbindung zu MySQL über einen TLS-Link her.

Ich habe beides versucht option_file = /etc/my.cnf(sollte die Standardeinstellung sein und ist unnötig), aber option_file = /etc/my.cnf.d/client.cnfohne Erfolg.

Ich habe sogar versucht, Postfix durch Hinzufügen zu zwingen, TLS zu berücksichtigen tls_verify_cert = yes. Auch das hatte keine Wirkung. Beachten Sie, dass der Zertifikatsname übereinstimmt, sodass diese Überprüfung erfolgreich ist, wenn sie jemals tatsächlich versucht wird.

Antwort1

Zusammenfassung

Um eine MySQL TLS-Verbindung von Postfix aus herzustellen, benötigen Sie:

  1. Postfix Version 2.11 oder neuerCentOS 7 bietet nurPostfix Version 2.10. Sie müssen ein Upgrade für Postfix von einem anderen Medium als CentOS erwerben. Ich habe mich für die Verwendung der postfix3Pakete postfix3-mysqlvon entschiedenGhettoForge Plusweil es scheintsehr empfehlenswert von der CentOS-Community.
  2. Satzin Ihren mysql_tableKonfigurationsdateienentweder:
    1. Mindestens eine zulässige tls_ciphersEinstellung;
    2. Ein clientseitiges TLS-Zertifikat und der dazugehörige private Schlüssel,von einer Zertifizierungsstelle signiert, die sowohl für den MySQL-Server als auch für Ihren Postfix-Client gilt; oder
    3. beide.
  3. Verlassen Sie sich nicht darauf, diese in Ihren Dateien /etc/my.cnf oder /etc/my.cnf.d/* festzulegen! Der Postfix MySQL-Code liest diese Dateien nicht, um zu bestimmen, ob eine MySQL TLS-Verbindung hergestellt werden soll; sie werden viel zu spät analysiert. Dernurmysql_tableDer beste Weg, Postfix zum Öffnen einer MySQL TLS-Verbindung zu veranlassen, besteht darin, die TLS-Einstellungen in Ihren Konfigurationsdateien anzugeben . Punkt.

Wie ich hierher gekommen bin

Schließlich habe ich mir den Quellcode von Postfix 3.2 durchgelesen. Die Zeilen 653-658 von src/global/dict_mysql.c waren besonders aufschlussreich.

Endgültige Lösung

Wenn Sie das Verhalten von emulieren möchten , müssen Sie Ihren Konfigurationsdateien ssl = truelediglich eine Zeile ähnlich der folgenden hinzufügen :mysql_table

tls_ciphers = TLSv1.2

Unsere Konfiguration erfordert die ausschließliche Verwendung von TLS 1.2. Dies wurde in der Konfiguration unserer MySQL-Server bereits seit langem erzwungen, sodass ich nicht automatisch auf die Idee kam, dies auch auf den Clients durchzusetzen. Sie können jedoch gerne andere Chiffren hinzufügen, wenn Ihre Organisation ältere Chiffren toleriert.

Beachten Sie, dass wir vollkommen zufrieden damit sind, keine clientseitigen Zertifikate zu verwenden. Wir verwenden andere Mittel, um unsere Datenbankverbindungen zu schützen und aktiv zu überwachen. Wir möchten einfach keine zusätzliche Komplexität.

Alternative Lösung

Wenn Sie lieber erzwingen möchten, dass sich nur bekannte und vertrauenswürdige Clients mit Ihren MySQL-Servern verbinden – und dies nicht durch andere Mechanismen zur Durchsetzung von Richtlinien wie strenge Firewalls, strikte Kennwortkomplexität, Kennwortrotationsperioden, Verbindungsüberwachung usw. erreicht werden kann –, können Sie mithilfe dieser zusätzlichen Einstellungen in Ihren mysql_tableKonfigurationsdateien auch clientseitige Zertifikate verwenden:

tls_key_file = /path/to/private.key
tls_cert_file = /path/to/public.certificate
tls_CAfile = /path/to/common.CA.certificate # OR tls_CApath = /path/to/CA-and-intermediate-chain-certificates/

Auch hier gilt, dass diese in /etc/my.cnf oder /etc/my.cnf.d/* festgelegt werden müssen.wird nicht helfen. Diese Dateien werden erst analysiert,nachder Verbindungstyp (TLS oder nicht-TLS) hatbereits entschieden.

Wenn Sie sich für die Verwendung clientseitiger Zertifikate entscheiden,erzwingen Sie sie auf dem Server! DunichtSie benötigen clientseitige Zertifikate, wenn Sie nur MySQL-Datenverkehr verschlüsseln möchten. Verwenden Sie stattdessen einfach die tls_ciphersoben genannte Alternative. Durch das Hinzufügen clientseitiger Zertifikate kann MySQL überprüfen, ob ein verbindender Client bereits bekannt und vertrauenswürdig ist, abernur wenn Sie MySQL sagen, wie das geht! Es wird nicht raten und sich nur auf die Anwesenheit einer gemeinsamen CA zwischen Client und Server zu verlassen, ist nur eine Teilimplementierung dieses leistungsstarken Tools. Wenn Sie an diesem MySQL-Sicherheitsmodell interessiert sind, habe ich mindestens eins gefundenAnleitung mit guten Beispielen zur Verwendung der Client-Zertifikatsvalidierung.

verwandte Informationen