Hello Thomas,

Thank you for your answer and the time you took to write it down.

Actually I had created a root CA and an Intermediate CA that I use to sign my 
certificates.
I am confused by the name of the directive "ssl_client_certificate" and in your 
explanation you tell me that I need to specify the CA certificate that signed 
the client certificate.
So I will try that, that confused me.

Thank you



Le jeudi 13 mars 2025 à 01:54:04 UTC+1, Thomas Ward <tew...@ubuntu.com> a écrit 
: 









On 2025-03-12 19:45, Mik J wrote: 

>  When I read your explanation, I understand that in this file
>   ssl_client_certificate /path/to/client/cert/ca.pem;
> => I would need to concatenate all my individual client certificates ?

No.  This is where a deeper understanding of how PKI works is important.

In the proper scenario, you will have a Certificate Authority certificate that 
is used to issue and sign all SSL Client Certificates.  Using my direct example 
of a PKI chain from before, let's assume this is the chain of certs that exist 
in my PKI wherever I manage the X.509 certificates:
CN=Spigot-CA,OU=Technical,O=Spigot,C=US (Serial 69D2DC9DAAABD023)
|-> CN=teward,OU=Admin,O=Spigot (Serial 575EDDCAAA0D654F)
|-> CN=johndoe,OU=HR,O=Spigot
|-> CN=janedoe,OU=Random,O=Spigot
Only one is the Certificate Authority - CN=Spigot-CA - which is the certificate 
that cryptographically signs every client certificate - CN=teward, CN=johndoe, 
CN=janedoe are an example of multiple users.

You ONLY specify in `ssl_client_certificate` the certificate that is the CA 
certificate.  In this case, `/etc/ssl/Spigot-CA/ca.crt` if put in for  
ssl_client_certificate would have the PEM encoded form of the CA certificate 
with the CN=Spigot-CA.    


Every single client certificate in the PKI chain is **issued and signed** by 
that CA certificate. Case in point, I just created this example PKI in a local 
tree of certificates and want to show you the client certificate and its data 
after its parsed by OpenSSL:

$ openssl x509 -noout -text -in teward.crt
Certificate:
    Data:
        Version: 3 (0x2)
        Serial Number: 6295713191616669007 (0x575eddcaaa0d654f)
        Signature Algorithm: sha256WithRSAEncryption
        Issuer: C = US, O = Spigot, OU = Technical, CN = Spigot-CA, 
emailAddress = nore...@example.com
        Validity
            Not Before: Mar 11 23:26:00 2025 GMT
            Not After : Mar 11 23:26:00 2026 GMT
        Subject: O = Spigot, OU = Admin, CN = teward, emailAddress = 
nore...@example.com
        Subject Public Key Info:
            Public Key Algorithm: rsaEncryption
                Public-Key: (2048 bit)
                Modulus:
                    ...
                Exponent: 65537 (0x10001)
        X509v3 extensions:
            ...
    Signature Algorithm: sha256WithRSAEncryption
    Signature Value:
        ...

See the "Issuer" line where the issuing certificate authority is CN=Spigot-CA?  
That means the certificate *must* be issued by that CA certificate.  However, 
that alone is not enough.  By giving NGINX the **trusted CA certificate** in 
`ssl_client_certificate`, we are explicitly telling it what certificate to use 
for verification of the signature and issuing line to validate against.

Therefore, behind the scenes, NGINX will make sure the signature on the 
certificate from its issuing CA is in fact from the CA certificate expected 
(therefore preventing the Red Team or a bad guy from creating a different CA 
certificate with the same DN and then a client cert with your same DN on the 
client cert) to make sure it's legitimate.

With my brief explanation of how PKI for client authentication works out of the 
way...


>  I wanted to remove "ssl_client_certificate /etc/ssl/certs/myuser.crt" 
>because I wanted that client verification would work for myuser1, 
>myuser2....not juste for one user.
> Basicly for all my users in my company, and the website would be exposed on 
> the internet.

DO NOT remove the `ssl_client_certificate` line.  As explained above, that's 
CRITICAL to validate what client certificates are in fact allowed. As long as 
all your authorized client certificates for all your users (in my example, 
teward, johndoe, and janedoe) are *issued and signed* by the CA certificate, 
then the client certificates will be validated against the CA certificate to 
make sure that they're signed by the CA certificate NGINX is told to expect, 
and then from there the clients will either be accepted or rejected **based on 
the validity of the certificate and that it was issued by the expected CA 
certificate**.

You don't need to have a certificate with all the certificate public keys, etc. 
of your client certificates, you just need the PEM-encoded file of the CA 
certificate, that's how PKI validation will validate the signature on the 
client certificates.

>  Thank you for clarifying the attack scenario, I didn't think about it at all.
> 

You're welcome, there's OTHER attack scenarios (like the one i just explained 
also in my example describing PKI above) but this one was actually used in a 
pentester's exercise against an Internet-facing TLS Client Certificate-shielded 
endpoint we actually have at my dayjob and they failed to pass any way of 
generating a 'fake' cert to bypass the client protections, because the CA 
certificate was actually used to check/test the signatures for validity.

(Also note as a disclaimer, I'm a CISSP certified security professional, so 
there's an understanding of how cryptography and the PKI chains are meant to be 
used and in fact are used in this scenario ingrained from the CISSP training)

---
Thomas
_______________________________________________
nginx mailing list
nginx@nginx.org
https://mailman.nginx.org/mailman/listinfo/nginx

Reply via email to