failure to limit access to a secure area with self-signed client SSL cert fingerprint match

PGNet Dev pgnet.dev at gmail.com
Mon Mar 20 17:51:47 UTC 2023


i run

	nginx -v
		nginx version: nginx/1.23.3 (COPR Build)

the server's setup to use LE certs


	server {

	...
     ssl_trusted_certificate   "/www/sec/le/deploy/otherexample.com/intermediate_ca.ec.crt.pem";
     ssl_certificate           "/www/sec/le/deploy/otherexample.com/fullchain.ec.crt.pem";
     ssl_certificate_key       "/www/sec/le/deploy/otherexample.com/priv.ec.key";
	...

i've a secure area that i want to limit access to clients only with exact-matching ssl cert fingerprints

i've added

     map $ssl_client_fingerprint $test_ssl_fp_reject {
		default 1;
		# cert's SHA1 FP
		01234567890ABCDEFGHIJK1234567890ABCDEFGH 0;
     }
	...
	log_format ssl_client
	    '"Client fingerprint" $ssl_client_fingerprint '
	    '"Client DN" $ssl_client_s_dn ';
	...

	server {
		...
		# attempt the verify, to populate $ssl_client_fingerprint
		ssl_verify_client optional;
		ssl_verify_depth 2;
		ssl_client_certificate "/etc/ssl/cert.pem";
		...
		location /sec/test {
			if ($test_ssl_fp_reject) {return 403; }

			root /www/sec/test;
			try_files /test.php =444;
			fastcgi_pass   phpfpm;
			fastcgi_index  test.php;
			fastcgi_param  PATH_INFO $fastcgi_script_name;
			include fastcgi.conf;
		}
		...
		access_log  /var/log/nginx/ssl.log ssl_client;

the client cert's self-signed with my own CA, and usage's config'd for Client auth,

	openssl x509 -in desktop.example.com.client.ec.crt.pem -text -noout
		Certificate:
		    Data:
		        Version: 3 (0x2)
		        Serial Number: 4859 (0x12fb)
		        Signature Algorithm: ecdsa-with-SHA256
		        Issuer: C = US, ST = NY, O = example.com, OU = example.com_CA, CN = example.com_CA_INT, emailAddress = ssl at example.com
		        Validity
		            Not Before: Mar 20 11:17:47 2023 GMT
		            Not After : Mar 17 11:17:47 2024 GMT
		        Subject: C = US, ST = NY, L = New_York, O = example.com, OU = example.com_CA, CN = desktop.example.com, emailAddress = ssl at example.com
		        Subject Public Key Info:
		            Public Key Algorithm: id-ecPublicKey
		                Public-Key: (384 bit)
		                pub:
		                    04:...:e5
		                ASN1 OID: secp384r1
		                NIST CURVE: P-384
		        X509v3 extensions:
		            X509v3 Basic Constraints:
		                CA:FALSE
		            Netscape Cert Type:
		                SSL Client, S/MIME
		            Netscape Comment:
		                example.com CLIENT Certificate
		            X509v3 Subject Key Identifier:
		                CC:...:06
		            X509v3 Authority Key Identifier:
		                D0:...:CD
		            X509v3 Key Usage: critical
		                Digital Signature, Non Repudiation, Key Encipherment, Data Encipherment, Key Agreement
		            X509v3 Extended Key Usage:
		                TLS Web Client Authentication, E-mail Protection
		            X509v3 Subject Alternative Name:
		                DNS:desktop.example.com, DNS:www.desktop.example.com
		    Signature Algorithm: ecdsa-with-SHA256
		    Signature Value:
		        30:...:6f

i've imported the cert as .pfx into Firefox & Chrome.

i can access

	https://otherexample.com

as usual.

now, on access to EITHER of

	https://otherexample.com
	https://otherexample.com/sec/test

in browser i get

	400 Bad Request
	The SSL certificate error
	nginx

while in log, i _do_ see the captured FP & DN,

	tail -f /var/log/nginx/ssl.log

		"Client fingerprint" 01234567890ABCDEFGHIJK1234567890ABCDEFGH "Client DN" emailAddress=ssl at example.com,CN=desktop.example.com,OU=example.com_CA,O=example.com,L=New_York,ST=NY,C=US


if i toggle

	-	ssl_verify_client optional;
	+	ssl_verify_client off;

now, access to

	https://otherexample.com

works. but

	https://otherexample.com/sec/test

returns

	403 Forbidden
	nginx

since the $ssl_client_fingerprint doesn't populate

	tail -f /var/log/nginx/ssl.log

		"Client fingerprint" - "Client DN" -

and, if I turn off ALL client verification, then access to frontend and by secure area works as expected.

what config change's needed to

	(1) keep the site publicly accessible using the LE certs"
	(2) lock down to secure area for exact FP-match access only?


More information about the nginx mailing list