Score:0

SSL stapling and variable SSL certificates in NGINX

id flag

I have several domains, all of which are served by the same NGINX instance. I am trying to setup a generic server configuration for HTTPS, such that every domain uses its own certificate and has SSL stapling enabled. These settings as defined in default.conf are as follows:

server {
    listen 443 default_server ssl;

    ssl_protocols TLSv1.2 TLSv1.3;
    ssl_ciphers ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-RSA-AES128-GCM-SHA256;

    ssl_stapling        on;
    ssl_stapling_verify on;

    ssl_trusted_certificate /ssl/chain.pem;

    ssl_certificate     /ssl/$ssl_server_name/fullchain.pem;
    ssl_certificate_key /ssl/$ssl_server_name/privkey.pem;
}

Every domain has a server block assigned to it in separate configuration files, inheriting the SSL settings as defined above. For example, example.conf would say:

server {
    listen 443 ssl;

    server_name example.com;

    location / {
        return 200 "Hello, world!";
    }
}

Unfortunately, this does not work. With this configuration, running openssl s_client -connect example.com:443 -status results in a message saying OCSP response: no response sent.

Interestingly, when I change the configuration to not use $ssl_server_name but one of the domain names (lets say example.com, see snippet below), I do receive a proper OCSP response for that specific domain. As expected, this fails for the other domains since the wrong certificate is provided.

server {
    ...
    ssl_certificate     /ssl/example.com/fullchain.pem;
    ssl_certificate_key /ssl/example.com/privkey.pem;
    ...
}

This is no solution to me of course, because it still requires me to specify each certificate per domain.

Questions

  1. Is it possible to combine the usage of $ssl_server_name and SSL stapling and if so, how?
  2. Is the behaviour of NGINX as I have described it expected/documented?
  3. Are there any issues with the configuration presented here that might cause trouble?
dave_thompson_085 avatar
jp flag
What version of OpenSSL? Below 1.1.1, `openssl s_client` does not send SNI by default; you must specify e.g. `-servername example.com`
Score:1
fr flag
anx

The behaviour of ssl_stapling on being silently disregarded when using variables in the file name is tracked as defect #1813.

The only documentation that even suggests that this is a special case is in the documentation of the ssl_certificate directive (emphasis mine):

Since version 1.15.9, variables can be used in the file name when using OpenSSL 1.0.2 or higher:

ssl_certificate     $ssl_server_name.crt;
ssl_certificate_key $ssl_server_name.key;

Note that using variables implies that a certificate will be loaded for each SSL handshake, and this may have a negative impact on performance.

There currently appear to be no plans to complete the "variables in ssl_* directives" implementation in this and related regards.

If you have no way of speeding this up by paying someone to do so, you might be interested in also watching progress on enhancement #813 - a mechanism able to fetch and store OCSP responses before they already would have been needed likely solves most of your problem as well. Assuming that solutions comes in the form of a dynamic certificate cache, that could then be initialized by simply sending a request to all known domains to have them loaded.


Until then, just have your nginx configuration be statically listing all the domains and the repeated mentions of them in filenames.. use configuration management software (such as Ansible) to ease the job of generating updates and issuing reloads.

In any case, do define a static, separate default_server block for those poor non-SNI clients. Nginx has a few surprising interactions between per-server configuration and the treatment of clients that do not say which one they meant to talk to.

Michaël van de Weerd avatar
id flag
Great explanation, exactly what I was looking for. It's unfortunate that NGINX does not support a more dynamic way of configuring webservers, but it's good that I now know for sure. I will look into software that can help me with this as you've suggested. Thank you!
I sit in a Tesla and translated this thread with Ai:

mangohost

Post an answer

Most people don’t grasp that asking a lot of questions unlocks learning and improves interpersonal bonding. In Alison’s studies, for example, though people could accurately recall how many questions had been asked in their conversations, they didn’t intuit the link between questions and liking. Across four studies, in which participants were engaged in conversations themselves or read transcripts of others’ conversations, people tended not to realize that question asking would influence—or had influenced—the level of amity between the conversationalists.