You save a connection to 10.20.4.15, the VPN drops, and the client still connects. That is not good news. A private address is a location inside whatever routing context you happen to be in, and plenty of networks use the same ranges. The client reached a MySQL server, it just may not have reached yours.

The fix has two halves, and only one of them is about the network. Keep the connection on its intended path, and make the client authenticate the server it is talking to. The first half is where a VPN helps; the second half has to be configured.

Encrypted to what, exactly?

TLS protects the conversation from anyone in the middle, and it says nothing about who the endpoint claims to be unless the client checks. A certificate that validates against a trusted authority proves the certificate came from that authority. It does not prove the certificate was issued for the hostname you meant to reach, and those are different questions.

This is not a theoretical gap. Captive portals, wrong-VRF mistakes and overlapping address plans all produce a server that is perfectly willing to negotiate TLS with you. If the client only requires encryption, the session is private and pointed at the wrong database.

So the relevant question is not whether the connection is encrypted but whether it is encrypted to the identity you intended. In MySQL's client, that distinction lives entirely in the ssl-mode setting.

The five ssl-mode values in practice

Five values exist, and only one of them answers the question this runbook is about. The table lists what each actually guarantees rather than what its name suggests.

ModeWhat it guarantees
DISABLEDNo TLS at all; everything on the wire is readable
PREFERREDTries TLS and falls back to plaintext when the account and server allow it, so it is not a fail-closed requirement
REQUIREDRefuses to connect without TLS, and does not validate the certificate
VERIFY_CAValidates the server certificate against the configured CA and does not check the hostname
VERIFY_IDENTITYValidates the CA and checks that the certificate names the host the client used

Only the last row answers the question in this article. PREFERRED is worth flagging on its own, because a client that silently drops to plaintext is worse than one that refuses: you believe you have encryption and the packet capture disagrees.

A connection you can run today

The command below is the shape to use, with two placeholders: the approved database name and a CA file obtained through an approved channel. Neither should be taken from whatever the server offers you on first contact.

mysql --host=db.corp.example --user=app_reader \
  --ssl-mode=VERIFY_IDENTITY \
  --ssl-ca=/approved/path/ca.pem --password

--password with no value prompts, which keeps the secret out of the process list and out of your shell history. That is a small habit with a large payoff on shared jump hosts, where a command line is visible to other users.

When this fails, the error text distinguishes the cases better than intuition does. A CA failure means the chain does not validate and you should be looking at which CA signed the server certificate. A hostname failure means the chain is fine and the name does not match, which usually means you connected to the right server by the wrong name rather than to the wrong server.

A prompt appearing is not evidence that a password was already transmitted, and a failed connection does not prove that nothing left the client. If you are reconstructing a past event, identify the client, its configuration, the authentication plugin and the stage that failed. Estimating exposure from the final error message is guesswork.

When the name comes from a tunnel

Local port forwarding breaks the identity check in a way that surprises people. If you forward a local port to the database and connect to localhost, the client validates the certificate against localhost, and no certificate was issued for that name. The connection may be perfectly safe and the verification will still fail, which is the check working as intended.

There are two honest answers. Give the forwarded endpoint a name that resolves to the loopback address and appears in the server certificate, or use the hostname end to end so the client verifies the real identity. The first is convenient for developers and requires certificate work; the second is simpler to reason about and often the right default for automation. Disabling verification to make the forward work throws away the property you were trying to add.

Acceptance is three conditions

Write the acceptance test as three separate statements: the connection used the intended route, encryption was required rather than preferred, and the server identity was verified against trusted material. A green VPN icon establishes none of them.

For GUI clients and for MariaDB, check the vendor's own documentation rather than assuming the flag spelling carries over. The MySQL encrypted-connection documentation covers the mode differences and the CA distribution requirement, and it is the reference to check before you change a production connection string.

ဆက်စပ်ဆောင်းပါးများ