Hallo Heiko,
Heiko Schlittermann (Fri, Feb 12, 2021 at 10:21:49PM +0100):
Hallo Bert,
bert schulze bs@bescit.de (Fr 12 Feb 2021 18:55:28 CET):
Hm. Der Exim verwendet ganz normal die Mysql Client libraries. Soweit ich auf https://dev.mysql.com/doc/c-api/8.0/en/mysql-real-connect.html verstanden habe, müsste mit ein, zwei weiteren Funktionsaufrufen auch eine Verbindung per TLS möglich sein.
Das ist shonmal ein hilfreicher Startpunkt.
https://dev.mysql.com/doc/c-api/8.0/en/c-api-encrypted-connections.html
Wenn ein Aufruf von mysql_options() nach _init() und vor _connect() reicht, klingt das zunächst akzeptabel…
Ab 5.6.36 kann man MYSQL_OPT_SSL_MODE mit SSL_MODE_REQUIRED versehen und eine verschlüsselte Verbindung erzwingen, für Versionen davor ist es notwendig nach _connect() via mysql_get_ssl_cipher() zu prüfen ob eine verschlüsselte Verbindung ausgehandelt wurde.
Debian nutzt den MariaDB Fork, hier keine Spur von MYSQL_OPT_SSL_MODE zu finden, also wohl auch die Strategie mysql_get_ssl_cipher() prüfen.
https://mariadb.com/kb/en/mysql_optionsv/
(Weiter geht es unten).
Ein Workaround wäre sicher ein SOCAT Tunnel oder etwas ähnliches.
An ssh -NL localhost:3306:localhost:3306 mittels pubkey auth hatte ich auch schon gedacht, aber ja das ist wieder manueller Aufwand und ein weiteres vermeidbares Scheunentor.
Ob als extra Direktive, oder in die mysql_servers option mit eingebaut, liesse sich noch diskutieren.
Vielleicht
mysql_servers = <; [tls://]localhost[:port]/DB/User/Passwort
Das würde dann das Verhalten implizieren TLS zu erzwingen wenn tls:// als Protokoll angegeben wurde und darauf bestehen verschlüsselt zu kommuizieren?
Ich spinne mal weiter: Wir haben den UseCase das sowohl SQL als auch MTA in einem vertrauenswürdigem Netz betrieben werden, dann ist diese Option vollkommen OK.
Was aber wenn die Verbindung durch ein nicht vertrauenswürdiges Netz geroutet werden muss und es einen potentiellen MITM geben könnte?
Hier geht es dann weiter und man müsste mindestens prüfen ob das Server Zertifikat durch eine vertrauenswürdige CA ausgestellt wurde (und ggf. noch nicht revoked). Dafür brauchen wir:
MYSQL_OPT_SSL_CA || MYSQL_OPT_SSL_CAPATH MYSQL_OPT_SSL_CRL || MYSQL_OPT_SSL_CRLPATH
Worauf ich hinaus will: mit mysql_servers ist es bestimmt nicht getan.
tls_mysql_servers // für den connection string tls_mysql_servers_verify // default true, anderenfalls fallback unencrypted
tls_mysql_servers_ca // füttert CA PEM oder Pfad zu CA PEM(s)
Wie funktioniert das prüfen der Revocation Informationen? Kann hier bestehende Funktionalität von Exim4 verwendet werden?
Jetzt kommen noch die *paranoiden* Nutzer, die darauf bestehen ein Client Zertifikat zu nutzen:
MYSQL_OPT_SSL_CERT && MYSQL_OPT_SSL_KEY
tls_mysql_certificate // Pfad zum PEM Zertifikat tls_mysql_privatekay // Pfad zum PEM Zertifikat
Und das Sahnehäubchen, die Auswahl der zu nutzenden Cipher Suites
MYSQL_OPT_SSL_CIPHER
tls_mysql_require_ciphers
Was wiederum je nach Verwendung von GnuTLS oder openssl als Priority oder in der openssl Syntax erfolgen muss.
Aber hm. Aufwand? 3600€. Oder wie meinst Du die Frage?
Denke die Ausführungen erklären was ich meinte, es ging mir darum wie dreckig man sich die Finger machen müsste:)
Wenn Du das selbst machen möchtest, gib Bescheid, ich unterstütze Dich gerne dabei.
Zunächst habe ich mir mal darüber Gedanken gemacht, je nachdem wie komplex die Geschichte werden soll, würde ich mich daran beteiligen.
-- Heiko
Gruß Bert