36

How I can use a variable name in file path ?

ssl_certificate /home/ec2-user/.certificados/$server_name.crt;
ssl_certificate_key /home/ec2-user/.certificados/$server_name.key;
Claytinho
  • 473
  • 1
  • 4
  • 6

3 Answers3

41

You cannot use variables in every directive. ssl_certificate is treated as a literal string and is one of the many directives where variables are unsupported.

To specify different certificates for hosts, you have to explicitly write it in a server block:

server {
    server_name example.com;
    ssl_certificate /home/ec2-user/.certificados/example.com.crt;
    ssl_certificate_key /home/ec2-user/.certificados/example.com.key;
    # ...
}
server {
    server_name example.net;
    ssl_certificate /home/ec2-user/.certificados/example.net.crt;
    ssl_certificate_key /home/ec2-user/.certificados/example.net.key;
    # ...
}
# ...

If you feel uncomfortable duplicating the configuration, create templates and generate the nginx configuration using those templates. See also http://nginx.org/en/docs/faq/variables_in_config.html.

Michael Hampton
  • 237,123
  • 42
  • 477
  • 940
Lekensteyn
  • 6,111
  • 6
  • 37
  • 55
  • 10
    support for variables in `ssl_certificate` and `ssl_certificate_key` was added today! http://nginx.org/en/docs/http/ngx_http_ssl_module.html#ssl_certificate – Andrew Brown Feb 26 '19 at 18:00
  • Note that using variables implies that a certificate will be loaded for each SSL handshake, and this may have a negative impact on performance. – Time Killer Apr 16 '22 at 09:05
13

You can use variables since nginx 1.15.9 (26 Feb 2019)

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

But be aware of Changes with nginx 1.15.12 (16 Apr 2019):

Bugfix: a segmentation fault might occur in a worker process if variables were used in the "ssl_certificate" or "ssl_certificate_key" directives and OCSP stapling was enabled.

Daniel F
  • 343
  • 3
  • 16
  • 3
    Something to keep in mind here is when the certificate has a static path, it is loaded at init time which runs as root. When using a variable, it is loaded at runtime which generally runs as www or nginx so it is likely not going to have the permissions. – Pierre-Luc Bertrand Jul 04 '20 at 23:24
0

Simple Starting Point

Here is a complete, basic, dynamic SSL cert configuration. The regex used pulls the TLDN, for instance, seacoast.com even if the request is www.seacoast.com. If you want the full domain name, just use $ssl_server_name variable anywhere in your block.

map $ssl_server_name $domain {
 default $ssl_server_name;
 ~(([^\.]+)\.([^\.]+))$ $1;
}

server {
 listen 443 ssl http2 default_server;
 listen [::]:443 ssl http2 default_server;
 server_name _;

 add_header Content-Type text/html;
 return 200 "domain: $domain, document_root: $document_root, request_uri: $request_uri";

 ssl_certificate /etc/letsencrypt/live/$domain/fullchain.pem; 
 ssl_certificate_key /etc/letsencrypt/live/$domain/privkey.pem; 
}

I found that SSL enabled blocks are unable to pull variables out of server_name and would leave me with a blank variable, whereas http blocks worked as expected. I am running Nginx 1-Alpine Docker, and automatically generating letsencrypt certs for dozens of domains.

Neal Bozeman
  • 101
  • 1