danielealbano / cachegrand

cachegrand - a modern data ingestion, processing and serving platform built for today's hardware
BSD 3-Clause "New" or "Revised" License
975 stars 34 forks source link

Verify the client certificate #374

Closed danielealbano closed 1 year ago

danielealbano commented 1 year ago

This PR introduces a new functionality to enable, or disable, the client certificate validation.

For it to work it's necessary to provide a ca certificate (or a ca certificate chain) in the config file.

When set to true, the client connecting over TLS will have to:

When a certificate is not passed or the certificate can't be validated with the CAs known to cachegrand the connection will be terminated and log messages will be printed with level verbose, e.g.

without any certificate

[2023-03-29T10:04:57Z][VERBOSE    ][worker][id: 00][cpu: 01][network_channel] Failed to perform the TLS handshake because <SSL - No client certification received from the client, but required by the authentication mode>
[2023-03-29T10:04:57Z][VERBOSE    ][worker][id: 00][cpu: 01][worker_network_op] TLS handshake failed for the connection <127.0.0.1:34374>, coming from listener <0.0.0.0:6380>
[2023-03-29T10:04:57Z][VERBOSE    ][worker][id: 00][cpu: 01][worker_network_op] [FD:    5][ACCEPT] Listener <0.0.0.0:6380> failed to accept a new connection

with an unknown ca certificate

[2023-03-29T10:06:44Z][VERBOSE    ][worker][id: 00][cpu: 01][network_channel] Failed to perform the TLS handshake because <X509 - Certificate verification failed, e.g. CRL, CA or signature check failed>
[2023-03-29T10:06:44Z][VERBOSE    ][worker][id: 00][cpu: 01][worker_network_op] TLS handshake failed for the connection <127.0.0.1:45572>, coming from listener <0.0.0.0:6380>
[2023-03-29T10:06:44Z][VERBOSE    ][worker][id: 00][cpu: 01][worker_network_op] [FD:    5][ACCEPT] Listener <0.0.0.0:6380> failed to accept a new connection

with a self signed certificate

[2023-03-29T10:07:41Z][VERBOSE    ][worker][id: 00][cpu: 01][network_channel] Failed to perform the TLS handshake because <AES - Invalid key length>
[2023-03-29T10:07:41Z][VERBOSE    ][worker][id: 00][cpu: 01][worker_network_op] TLS handshake failed for the connection <127.0.0.1:50142>, coming from listener <0.0.0.0:6380>
[2023-03-29T10:07:41Z][VERBOSE    ][worker][id: 00][cpu: 01][worker_network_op] [FD:    5][ACCEPT] Listener <0.0.0.0:6380> failed to accept a new connection

the client might, or might not, report that the connection because of a tls check issue, e.g.

$ redis-cli -p 6380 --tls --cert ./self-signed-cert.pem --key ./self-signed-cert.key PING
Could not connect to Redis at 127.0.0.1:6380: SSL_connect failed: certificate verify failed

The PR also introduces a support function to read the peer certificate common name for later usage, the verification must always set at least to optional for this to work.