mTLS client verification fails in >=1.21.4
|Reported by:||Owned by:|
|Keywords:||certificate mtls verification||Cc:|
|uname -a:||Linux mtls 5.10.68+ #1 SMP Fri Dec 3 10:04:10 UTC 2021 x86_64 GNU/Linux|
|nginx -V:||nginx version: nginx/1.21.6|
I am using Nginx for performing mTLS authentication, terminating it and forwarding incoming connections to the backend.
I have been using Nginx docker images tagged with 'stable' until around Dec 21,2021 when the 1.21.4 image was tagged as 'stable', at which point all mTLS connections started failing in production. We had to revert to 1.21.3 to make them work again.
Nginx config looks like this:
error_log /dev/stdout info;
listen 443 ssl;
ssl_protocols TLSv1.2 TLSv1.3;
This is the error I'm seeing in nginx logs in versions >=1.21.4:
2022/03/16 16:02:11 [info] 22#22: *18 client 10.126.0.10:20695 connected to 0.0.0.0:443
2022/03/16 16:02:11 [info] 22#22: *18 client SSL certificate verify error: (18:self signed certificate) while SSL handshaking, client: 10.126.0.10, server: 0.0.0.0:443
2022/03/16 16:02:11 [crit] 22#22: *18 SSL_shutdown() failed (SSL: error:14094123:SSL routines:ssl3_read_bytes:application data after close notify) while SSL handshaking, client: 10.126.0.10, server: 0.0.0.0:443
ca_cert.pem is a self-signed root CA (x509 RSA).
The client authenticates using a key and a cert signed by the key & CA.
The problem is that the signed cert's Issuer is identical to Subject implying it's self-signed, which works well in 1.21.3, but is rejected in 1.21.4 and more recent versions as a self-signed cert.
It is signed as can be validated via the root CA, it is issuer=subject in the client cert that apparently causes the problem.
This is a breaking change that seems to have been inadvertently introduced in version 1.21.4.
Setting ssl_verify_client to optional_no_ca works around the error but then it is not mTLS anymore as the client may send no certs.
I couldn't find anything in the changelog to explain this. It does not seem to be related to a drop in support for NPN. I was able to recreate this with a simple python socket as a client. It also fails on python 3.10, where NPN was replaced with ALPN.