require_secure_transport unexpectedly requires a client certificate after TLS reload
- Dominant language
- Go
- Stars
- 40.5k
- Forks
- 6.2k
- PR merge metrics
- PR metrics pending
Description
## Bug Report
### 1. Minimal reproduce step (Required)
1. Generate a CA and server certificate:
```sh
mkdir -p /tmp/tidb-tls
cd /tmp/tidb-tls
openssl req -x509 -newkey rsa:2048 -sha256 -days 3650 -nodes \
-keyout ca-key.pem -out ca.pem -subj '/CN=TiDB Test CA'
openssl req -newkey rsa:2048 -sha256 -nodes \
-keyout server-key.pem -out server.csr -subj '/CN=127.0.0.1'
printf '%s\n' \
'subjectAltName=IP:127.0.0.1' \
'extendedKeyUsage=serverAuth' > server-ext.cnf
openssl x509 -req -sha256 -days 365 \
-in server.csr -CA ca.pem -CAkey ca-key.pem -CAcreateserial \
-extfile server-ext.cnf -out server-cert.pem
chmod 600 ca-key.pem server-key.pem
```
2. Start TiDB with the generated server certificate and CA:
```toml
[security]
ssl-ca = "/tmp/tidb-tls/ca.pem"
ssl-cert = "/tmp/tidb-tls/server-cert.pem"
ssl-key = "/tmp/tidb-tls/server-key.pem"
```
3. Connect over TLS without a client certificate. Enable secure transport and reload TLS:
```sql
SET GLOBAL require_secure_transport = ON;
ALTER INSTANCE RELOAD TLS;
```
4. Reconnect over TLS without a client certificate:
```sh
mysql -h 127.0.0.1 -P 4000 -u root --ssl-mode=REQUIRED
```
### 2. What did you expect to see? (Required)
The TLS connection should succeed. `require_secure_transport=ON` should reject plaintext TCP connections, but it should not require a client certificate. Client certificates should only be mandatory for accounts configured with `REQUIRE X509` or equivalent certificate constraints.
### 3. What did you see instead (Required)
The connection fails during the TLS handshake:
```
ERROR 2013 (HY000): Lost connection to MySQL server at 'reading authorization packet', system error: 0
```
The TiDB log reports:
```
tls: client didn't provide a certificate
```
When `ssl-ca` is configured, `LoadTLSCertificates` maps `require_secure_transport=ON` to `tls.RequireAndVerifyClientCert`. Reloading TLS therefore changes TLS into mutual TLS and locks out clients that use encryption without a client certificate.
This behavior was introduced by #15341 and first released in v4.0.0.
Related to #69508, but this issue covers the unexpected client-certificate requirement after TLS reload.
### 4. What is your TiDB version? (Required)
```
origin/master
Git Commit Hash: f994e8da27712f3f48a290177f1d851ad9de9f28
```
Contributor guide
Assessment
This issue has not been assessed yet.