Dear all,

recent NaviServer updates add proper support for mutual TLS (mTLS) along with 
improved certificate introspection.

What is mTLS?
In standard TLS, only the server presents a certificate. With mTLS, the client 
also presents a certificate, allowing the server to authenticate the client 
based on X.509 credentials. This is commonly used for service-to-service 
communication, APIs, and zero-trust setups.

Configuration and runtime usage
mTLS can now be enabled via the nsssl configuration:

    ns_param clientcertmode   request   ;# none|request|require
    ns_param clientcafile     client-ca.crt
    #ns_param clientcapath    client-ca
At runtime, client certificate information is available via:

    ns_conn clientcert   ;# full certificate details
Example result:

    present      1
    verified     1
    verifyresult ok
    subject      {CN = test-client, O = NaviServer Test}
    issuer       {CN = NaviServer Test Client CA}
    serial       538810D38E442686F1431D499F011619C174EA92
    notbefore    {Apr 30 08:12:20 2026 GMT}
    notafter     {Apr 30 08:12:20 2027 GMT}
    fingerprint  
cba8c79368235286bddeec9959d5b09230520b6a65d1b1cc6fb33a7aaf3c18f1
    san {
      dns   {client1.example.org client2.example.org}
      email [email protected]
      uri   spiffe://example.org/user/test-client
    }
A summary is also included in:

    ns_conn details      ;# includes a minimal clientcert summary
The returned information includes subject, issuer, validity, fingerprint, and 
SAN entries (DNS, email, URI such as SPIFFE IDs, IP). This can be mapped e.g. 
via authorization handler to a local userid.

Creating client certificates

Client certificates must include the clientAuth extended key usage and 
typically SAN entries. Then the certificate has to be added to your browser, 
such it sends it on request (steps are browser dependent). 

Creation example:

    cat > client.ext <<EOF
    [client_ext]
    basicConstraints = CA:FALSE
    keyUsage = digitalSignature
    extendedKeyUsage = clientAuth
    subjectAltName = @alt_names

    [alt_names]
    DNS.1 = client1.example.org
    URI.1 = spiffe://example.org/user/alice
    email.1 = [email protected]
    EOF

    openssl x509 -req -in client.csr \
      -CA ca.crt -CAkey ca.key -CAcreateserial \
      -out client.crt -days 365 -sha256 \
      -extfile client.ext
Certificate inspection

A new command is available to inspect certificates without a live connection:

    ns_certctl info /path/to/cert.pem
This returns a Tcl dictionary with subject, issuer, validity, fingerprint, and 
SAN entries, and can be used for checks such as expiration handling.

Note on previous behavior
The earlier client certificate support in NaviServer was incomplete, since 
validation paths (CA file/path) were not properly configurable. As a result, 
verification was effectively not usable (and in very old OpenSSL setups might 
have appeared to accept certificates without proper validation). This has now 
been corrected.

I have also substantially reworked the documentation and added a mTLS (Mutual 
TLS) section

    https://naviserver.sourceforge.io/5.1/manual/files/admin-config.html?v=5.1.0

Feedback and testing reports are welcome.

Best regards
-gustaf





_______________________________________________
naviserver-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/naviserver-devel

Reply via email to