feat(ssl): Allow using .pem for public key file

Try using $cert.pem as the certificate before falling back to
  $cert.crt, as .pem is the standard file extension for
  certificates. (RFC1421, RFC1424). This is different from the
  current behaviour, where only the .crt is used.

  NOTE: This could cause a regression if users have both a .pem and
  a .crt file in the /etc/nginx/certs directory. In that
  situation, the .pem will be used instead of the .crt, which
  can be problematic if the files contain different information
  (i.e. one contains the entire certificate chain, while the other
  does not). If this is an issue, the order can be changed so that
  the current behaviour is default.

Signed-off-by: David Li <jiawei.davidli@gmail.com>
This commit is contained in:
David Li 2015-09-29 18:05:56 -04:00
parent 8c193ba7e1
commit 5e927d4ac3
2 changed files with 34 additions and 15 deletions

View file

@ -81,9 +81,10 @@ To enable SSL:
$ docker run -d -p 80:80 -p 443:443 -v /path/to/certs:/etc/nginx/certs -v /var/run/docker.sock:/tmp/docker.sock:ro jwilder/nginx-proxy
The contents of `/path/to/certs` should contain the certificates and private keys for any virtual
hosts in use. The certificate and keys should be named after the virtual host with a `.crt` and
`.key` extension. For example, a container with `VIRTUAL_HOST=foo.bar.com` should have a
`foo.bar.com.crt` and `foo.bar.com.key` file in the certs directory.
hosts in use. The certificate and keys should be named after the virtual host with either a `.pem` or
`.crt` extension for certificates, and a `.key` extension for keys. If both `.pem` and `.crt` files
exist, then the `.pem` file is used. For example, a container with `VIRTUAL_HOST=foo.bar.com` should have either a
`foo.bar.com.pem` or `foo.bar.com.crt` file, and a `foo.bar.com.key` file in the certs directory.
#### Diffie-Hellman Groups
@ -93,14 +94,16 @@ should have a `foo.bar.com.dhparam.pem` file in the certs directory.
#### Wildcard Certificates
Wildcard certificates and keys should be name after the domain name with a `.crt` and `.key` extension.
For example `VIRTUAL_HOST=foo.bar.com` would use cert name `bar.com.crt` and `bar.com.key`.
Wildcard certificates and keys should be name after the domain name with either a `.pem` or
`.crt` extension for certificates, and a `.key` extension for keys. If both `.pem` and `.crt` files
exist, then the `.pem` file is used. For example `VIRTUAL_HOST=foo.bar.com` would use cert name `bar.com.pem`
and `bar.com.key`.
#### SNI
If your certificate(s) supports multiple domain names, you can start a container with `CERT_NAME=<name>`
to identify the certificate to be used. For example, a certificate for `*.foo.com` and `*.bar.com`
could be named `shared.crt` and `shared.key`. A container running with `VIRTUAL_HOST=foo.bar.com`
could be named `shared.pem` (or `shared.crt`) and `shared.key`. A container running with `VIRTUAL_HOST=foo.bar.com`
and `CERT_NAME=shared` will then use this shared cert.
#### How SSL Support Works
@ -117,9 +120,9 @@ is always preferred when available.
* If the container does not have a usable cert, a 503 will be returned.
Note that in the latter case, a browser may get an connection error as no certificate is available
to establish a connection. A self-signed or generic cert named `default.crt` and `default.key`
to establish a connection. A self-signed or generic cert named `default.pem` and `default.key`
will allow a client browser to make a SSL connection (likely w/ a warning) and subsequently receive
a 503.
a 503. A `default.crt` file will be used if `default.pem` is not found.
### Basic Authentication Support

View file

@ -58,13 +58,18 @@ server {
return 503;
}
{{ if (and (exists "/etc/nginx/certs/default.crt") (exists "/etc/nginx/certs/default.key")) }}
{{ if (and (or (exists "/etc/nginx/certs/default.pem") (exists "/etc/nginx/certs/default.crt")) (exists "/etc/nginx/certs/default.key")) }}
server {
server_name _; # This is just an invalid value which will never trigger on a real hostname.
listen 443 ssl spdy;
return 503;
ssl_certificate /etc/nginx/certs/default.crt;
{{ if (exists "/etc/nginx/certs/default.pem") }}
ssl_certificate /etc/nginx/certs/default.pem;
{{ else }}
ssl_certificate /etc/nginx/certs/default.crt;
{{ end }}
ssl_certificate_key /etc/nginx/certs/default.key;
}
{{ end }}
@ -97,16 +102,17 @@ upstream {{ $host }} {
{{ $certName := (first (groupByKeys $containers "Env.CERT_NAME")) }}
{{/* Get the best matching cert by name for the vhost. */}}
{{ $vhostCert := (closest (dir "/etc/nginx/certs") (printf "%s.crt" $host))}}
{{ $vhostCert := (closest (dir "/etc/nginx/certs") (printf "%s.key" $host))}}
{{/* vhostCert is actually a filename so remove any suffixes since they are added later */}}
{{/* vhostCert is actually a filename so remove any suffixes since they are added later. */}}
{{ $vhostCert := replace $vhostCert ".crt" "" -1 }}
{{ $vhostCert := replace $vhostCert ".pem" "" -1 }}
{{ $vhostCert := replace $vhostCert ".key" "" -1 }}
{{/* Use the cert specifid on the container or fallback to the best vhost match */}}
{{ $cert := (coalesce $certName $vhostCert) }}
{{ if (and (ne $cert "") (exists (printf "/etc/nginx/certs/%s.crt" $cert)) (exists (printf "/etc/nginx/certs/%s.key" $cert))) }}
{{ if (and (ne $cert "") (or (exists (printf "/etc/nginx/certs/%s.pem" $cert)) (exists (printf "/etc/nginx/certs/%s.crt" $cert))) (exists (printf "/etc/nginx/certs/%s.key" $cert))) }}
server {
server_name {{ $host }};
@ -127,7 +133,12 @@ server {
ssl_session_timeout 5m;
ssl_session_cache shared:SSL:50m;
{{ if (exists (printf "/etc/nginx/certs/%s.pem" $cert)) }}
ssl_certificate /etc/nginx/certs/{{ (printf "%s.pem" $cert) }};
{{ else }}
ssl_certificate /etc/nginx/certs/{{ (printf "%s.crt" $cert) }};
{{ end }}
ssl_certificate_key /etc/nginx/certs/{{ (printf "%s.key" $cert) }};
{{ if (exists (printf "/etc/nginx/certs/%s.dhparam.pem" $cert)) }}
@ -182,14 +193,19 @@ server {
}
}
{{ if (and (exists "/etc/nginx/certs/default.crt") (exists "/etc/nginx/certs/default.key")) }}
{{ if (and (or (exists "/etc/nginx/certs/default.pem") (exists "/etc/nginx/certs/default.crt")) (exists "/etc/nginx/certs/default.key")) }}
server {
server_name {{ $host }};
listen 443 ssl spdy {{ $default_server }};
access_log /var/log/nginx/access.log vhost;
return 503;
ssl_certificate /etc/nginx/certs/default.crt;
{{ if (exists "/etc/nginx/certs/default.pem") }}
ssl_certificate /etc/nginx/certs/default.pem;
{{ else }}
ssl_certificate /etc/nginx/certs/default.crt;
{{ end }}
ssl_certificate_key /etc/nginx/certs/default.key;
}
{{ end }}