pingcap / pingcap/tidb

require_secure_transport unexpectedly requires a client certificate after TLS reload

Open
#69,870 2 comments 0 reactions 1 assignee Claimed by @YangKeao View on GitHub
affects-4.0 affects-5.0 affects-5.1 affects-5.2 affects-5.3 affects-5.4 affects-6.0 affects-6.1 affects-6.2 affects-6.3 affects-6.4 affects-6.5 affects-6.6 affects-7.0 affects-7.1 affects-7.2 affects-7.3 severity/major sig/sql-infra type/bug
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

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.