Dear all,

as a follow-up to the recent mTLS support announcement, I’ve added a
complete demo certificate setup to fresh checkouts of NaviServer.

The build now generates a small certificate hierarchy under
$home/certificates/, including:

a local Certificate Authority (ca.crt)
a server certificate (server.pem)
a client certificate (client.crt / client.key)
The CA acts as a trust anchor for both server and client certificates.
This allows a fully self-contained setup for development and testing,
without relying on external infrastructure.

With this in place, a default nsd-config setup can be used to test
mTLS out-of-the-box. The HTTPS configuration now requests client
certificates by default, so one can directly experiment with client
authentication (e.g., via curl).

In addition, the new setup is used in the regression test suite, which
now includes end-to-end tests for mTLS using these generated
certificates.

Next steps

Feature-wise, the 5.1 branch is largely complete (unless something
urgent comes up).

There is still some cleanup work ahead, including:

removal of outdated version dependency macros
revisiting atom usage
consolidating setup patterns
cleaning up legacy header case definitions
In parallel, we will prepare the upcoming releases:

finalize changelog summaries for 5.0.* and 5.1.0
perform additional platform testing
extend static analysis and test coverage
Feedback and testing reports are very welcome.

all the best
-g


> On 01.05.2026, at 19:12, Gustaf Neumann (sslmail) <[email protected]> wrote:
> 
> 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