I have a site that needs to answer on any number of arbitrary subdomains, e.g. client1.example.com, client2.example.com, etc. Everything is behind SSL.

I'd really like to use Let's Encrypt which, of course, means no wildcard cert. Is there any way to create a single server { ... } block that loads the appropriate directory or do I need separate config for every client subdomain?

Essentially, I want one server block answering to *.example.com, but loading the appropriate certificate based on the subdomain. Certificates are all stored in /etc/letsencrypt/live/[subdomain].example.com/.

  • The directory where newly created certificates are created uses the domain name as part of the naming format. Maybe you can automate that with a variable. The path is /etc/letsencrypt/live/client1.example.com/cert.pem. – jarvis May 25 '16 at 23:12
  • @jarvis That part is already in place. The question is really more about the Nginx config itself. Specifically the server block. Do I need 1 for each subdomain or is there some way I haven't found to handle *.example.com over SSL? I've updated the post in an attempt to clarify. Thanks. – Rob Wilkerson May 25 '16 at 23:44
  • Good question, @RobWilkerson. Unfortunately, based on my tests for a similar use-case, I think nginx is not there, yet, to process configurations dynamically, on-the-fly, using variables. I may be wrong, because of my limited knowledge / tests. If a solution already exists, I am all ears. – Pothi Kalimuthu May 26 '16 at 4:01

Two notes from my side:

  • AFAIK (but please, don't take this for granted) you can't use variables everywhere, including ssl_certificate, because nginx treats this as a literal string.

  • But (thinking out of the box): Create the Certificate Signing Request yourself (using openssl), and put all your domains into the Subject Alternative Name (SAN) field. In case you're using the official Let's Encrypt client, leverage the --csr option to send your created Certificate Signing Request to them. They will parse the field, validate the domains, and, in case this is successful, you'll get one signed certificate back which is valid for all your provided domains.

    Caveat 1: Currently, Let's Encrypt limits the number of domains in the Subject Alternative Name field to 100, according to this post. (Not sure if this is still true, I wasn't able to find something "official".)

    Caveat 2: The certificate is public, so anyone inspecting your cert is able to see all the domains this cert is valid for. If this is acceptable depends on your use case, environment, etc.

  • I know you're correct about the use of variables in the ssl directives. I'll take a look at the SAN field. I wasn't aware of that possibility. We may reach 100, but I don't expect that to happen for a while, so it might be a viable option. Thanks! – Rob Wilkerson May 31 '16 at 11:50
  • @RobWilkerson Happy to help! In case you need assistance / help, feel free to contact me. – gf_ May 31 '16 at 13:28
  • @RobWilkerson Regarding the limit: If you reach 100, you still could use a second cert with a second server { ... } block. – gf_ May 31 '16 at 13:34

You can use tools external to Nginx like sed and make to create templates to achieve what you want:


Via: nginx use $server_name on ssl_certificate path

  • He asked for a single server {...} block. – gf_ May 27 '16 at 14:29
  • Yes, which is possible if one uses multiple http { ... } blocks as per the Via link, or includes. But the include will then need to be dynamically generated with the aforementioned external tools. – JayMcTee May 27 '16 at 14:31

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.