4

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/.

Rob Wilkerson
  • 1,365
  • 4
  • 16
  • 24
  • 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 04:01

2 Answers2

0

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.

gxx
  • 5,483
  • 2
  • 21
  • 42
  • 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. – gxx 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. – gxx May 31 '16 at 13:34
0

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

http://nginx.org/en/docs/faq/variables_in_config.html

Via: nginx use $server_name on ssl_certificate path

JayMcTee
  • 3,763
  • 12
  • 20
  • He asked for a single `server {...}` block. – gxx 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