Changelog
mTLS requires clients to present a client certificate to authenticate usage. The mTLS flow goes roughly like:
Authentication is facilitated by PKI. The subset of cases where this may be undesirable includes:
Where this is desirable includes:
Assuming the basic web configuration has already been setup, together with certificates. Then the main changes are:
server {
ssl_client_certificate <PATH_TO_CA_CERT>;
ssl_verify_client optional;
if ($ssl_client_verify != SUCCESS) {
... # reject clients
}
...
}
If no special behaviour based on the validity of the client certificate is required (processed based on the return code of $ssl_client_verify), then ssl_verify_client can be set to "on", and the response will be a simple 400 Bad Request.
Note the ssl_trusted_certificate directive is mainly for OSCP stapling, not for hiding the list of accepted client certificates from the client. Using this in tandem with ssl_verify_client without ssl_client_certificate raises a configuration error.
Consider the following additional considerations:
stream to route TCP packets to the backend, and poke a hole in the firewall (see nginx configuration).bind option to the "listen" directives.# Create CA user:~$ easyrsa init-pki # configure vars, e.g. for ECC user:~$ easyrsa build-ca # Create client certificate user:~$ easyrsa gen-req <MY_CLIENT> user:~$ easyrsa --san=DNS:<MY_DOMAIN> sign-req client <MY_CLIENT> # Verify client certificate, e.g. extended key usage of Client Authentication and SAN user:~$ cat pki/issued/<MY_CLIENT>.crt # Package into p12 bundle (set export password if desired) # Note there is no real need to generate the full chain user:~$ openssl pkcs12 -export \ -in pki/issued/<MY_CLIENT>.crt \ -inkey pki/private/<MY_CLIENT>.key \ -out pki/private/<MY_CLIENT>.p12
Generally per usual for Linux/Windows.
For iOS devices, the .p12 file needs to be created using the -legacy flag in OpenSSL 3, and then either:
So many hurdles to leap through... *internal screaming* Even then, the client certificate is added only to Apple's keychain, so these certificates cannot be used in other browsers (with the sole exception of Safari) unless those apps support client cert importing mechanisms, see answer. *more internal screaming*