I'm trying to make multiple database connexion though traefik. I got that hostSNI for non TLS routing won't work if the host is specific. So I configured two databases for TLS support by generating a openssl certificate.
The problem is that, even with a mysql ssl connection, I got a timeout.
The routing configuration is set on passthrough, why should I config my certs in the dynamic config file in traefik ?
I got another configuration file to set the certificates for my other routes.
To use HostSNI() you need to have a certificate for Traefik, either a custom purchased one or let LetsEncrypt create one for you.
Forwarding the connection to your DB, you need to share the same cert with the DB, or use a different cert for the DB (which is known to Traefik or use insecureSkipVerify) or potentially use no encryption at all.
Same issue here. I have the certificates placed in the dynamic config file and it has worked for other services I have running on HTTP routes. But on TCP routes things are not working:
MariaDB container file is correctly mapping 3306 to 8086 and I have all ports open on firewall and whatnot, it works just fine with non-SSL connection. At the same time, I have the certs into my MariaDB's container and a configuration file pointing to them: when using the wrong permissions to the certs there was an error during container initialization, then fixing it there were no errors on the output, meaning mariadb was able to read the certs.
You want Traefik and your DB to use the same TLS cert? Then pass the encrypted TLS traffic from Traefik with TLS passthrough to the target service. (Doc)
Well pointed. But still, the connection seems to hang. Are there any option I can activate to check where it's hanging? When I stop traefik container at server side, the client returns with the following error:
ERROR 2013 (HY000): Lost connection to MySQL server at 'handshake: reading initial communication packet', system error: 11
At the same time, I don't really need SNI if I just change to a different entrypoint (different port), and make the rule check for HostSNI(*), letting the database itself handle the SSL certificates verification, right?
Yes. You can pass the encrypted TCP connection through Traefik with HostSNI(`*`) and use a different port/entrypoint per target service, not enabling any TLS in Traefik.
Exactly what we are trying to avoid. Our goal is to target multiple database host with the same port.
Personnaly I surrended, too much wasting time for a poor ROI. I now have configured ssh over docker to use the web url using traefik, then using ssh tunneling for reaching the database.
I ran into a similar issue, but in my case with Postgres. I was able to get it to work, but with those things in place:
I am using Traefik v3 (in my case v3.0.0-beta3); The STARTTLS feature for Postgres is only in that version onward (I know you are using MariaDB, but just FYI);
I had to set the database port in my container to be the same as exposed on the host (i.e. 5432 on host and 5432 in container); This was the cause of my connection timeout;
I don't use TLS for the database in the container, only at the Traefik entrypoint with the labels;
I need to set at least one TCP entrypoint port for all the DB connections on Traefik (i.e. 5432). If your Traefik runs on the same host as your DB, you will need to change this so you don't have a port conflict.
Make sure your have a default cert on Traefik for ${domain} or you will have to specify it. I don't use passthrough as I don't have TLS enabled on the DB.
I think in your case you will have to specify a service backend port and address (in the Traefik labels) if you don't have service discovery capabilities in your system.
With all of that in place, I am able to have one port and use HostSNI to send the traffic to my different databases. i.e.:
my-db-1.example.com:5432 (goes to db1 backend container)
my-db-2.example.com:5432 (goes to db2 backend container)
my-db-3.example.com:5432 (goes to db3 backend container)
@Dreimus did you manage to get it to work ? I'm stuck at the same issue. The best I could do is get the response from mysql container via openssl s_client -connect demo.domain.com:3306 that gave me in the end:
---
read R BLOCK
I
8.2.0 m@=FrNXk�����eLQHYNvjA"caching_sha2_password2��#08S01Got timeout reading communication packetsclosed
Which mean it got to the container... but no client I could find can actually connect to the mysql at all
Hey, did you have anymore luck with this ? I can get routing working properly with SNI, and I can see I'm getting routed to the right container using ncat --ssl:
But no matter how hard I try I cannot get the mysql client to connect, and I just end up with the same error message as you:
:/tmp$ docker run mysql:8.3.0 mysql -u root -h redacted --port 3306 --verbose 4 --tls-sni-servername redacted
ERROR 2013 (HY000): Lost connection to MySQL server at 'reading initial communication packet', system error: 0
I'm honestly starting to think that something is wrong with the way the mysql client opens a session and that it may be incompatible with traefik, since it works fine with postgresql.