Dynamic/Wildcard SSL certificates with SNI?

Hi,

I’m working on a “Web simulator” designed to serve a large number of
web sites on a private, self-contained network, where I’m also in
control of issuing SSL certificates.

The relevant bits of my nginx.conf look like this:

server {
  listen 80 default_server;
  server_name $http_host;
  root /var/www/vservers/$http_host;
  index index.html index.htm;
}

ssl_certificate_key /var/www/vserver_certs/vserver.key;

server {
  listen 443 default_server;
  ssl on;
  ssl_certificate /var/www/vserver_certs/vserver.cer;
  server_name $http_host;
  root /var/www/vservers/$http_host;
  index index_html index.htm;
}

There is no consistency across the set of vserver host names (and
therefore not much to be gained by using wildcards in the certificate
common or alt name fields).

Right now, I’m trying to cram all of my vserver host names into the
alt_names field of the “vserver.cer” certificate, but I’m bumping up
against the 16k limit of the cert file size, after which browsers
start rejecting it with an error.

I’d like to generate per-vserver certs, and dynamically select the
correct certificate file based on the SSI-negotiated server name,
like so:

server {
  listen 443 default_server;
  ssl on;
  ssl_certificate /var/www/vserver_certs/$ssl_server_name.cer;
  server_name $http_host;
  root /var/www/vservers/$http_host;
  index index_html index.htm;
}

but nginx doesn’t seem to currently support this (it wants to open the
certificate file at startup time, and doesn’t appear to allow variable
expansion in the cert file name :frowning:

The alternative would be to add an https server block for each vserver:

server {
  listen 443;
  ssl_certificate /var/www/vserver_certs/vserver1.foo.com.cer;
  server_name vserver1.foo.com;
  root /var/www/vservers/vserver1.foo.com;
  index index_html index.htm;
}

server {
  listen 443;
  ssl_certificate /var/www/vserver_certs/vserver2.bar.org.cer;
  server_name vserver2.bar.org;
  root /var/www/vservers/vserver2.bar.org;
  index index_html index.htm;
}

...

and so on, relying on SNI to match the correct block. But this could
get out of hand really fast, as I expect to be dealing with several
thousand vservers.

Am I missing something when attempting to dynamically use
$ssl_server_name to locate the appropriate certificate file ?

If that’s not currently possible, is this something of interest to the
rest of the community, and would it be worth bringing up on the
development mailing list ?

Thanks much for any help, pointers, ideas, etc!

–Gabriel

server {
ssl on;
ssl_certificate /var/www/vserver_certs/vserver.cer;
server_name $http_host;
root /var/www/vservers/$http_host;
index index_html index.htm;
}

There is no consistency across the set of vserver host names (and
therefore not much to be gained by using wildcards in the certificate
common or alt name fields).

Just issue a certificate for ..* and always serve that.

At least, until the CAB-forum decides this is a not a good idea and
stops browsers from accepting it.
I think the above certificate should still be legal, but I’m not 100%
sure.

On Thu, 15 Jan 2015 21:13:21, Rainer D. wrote:

I think the above certificate should still be legal, but I?m not 100% sure.
I’m afraid it’s already too late for that :frowning:

Since some of my vserver names look like “foo.com” and others like
foo.bar.org”, I already tried (using alt_names):

*.*, *.*.*

and

*.com, *.*.com, *.org, *.*.org, *.net, *.*.net

both forms causing warning popups on any recent (windows7-era) browser.

Apparently, the current policy in effect is not to accept tld-wide
wildcards, much less wildcards across ALL tlds ([.].*).

Since I’m already mass-scripting the csr generation and cert signing
for each vserver, it should be really simple to script generating the
corresponding nginx config file, but allowing demand-driven,
request-time
loading of certificate files would work around that enormous ugliness :slight_smile:

Thanks,
–Gabriel

allowing demand-driven, request-timeloading of certificatefiles

I don’t think thats possible with openssl, especially in a event-driven
application
like nginx.

That having said, haproxy has a nice functionality: you can just point
to one
or more directories and haproxy will load every single certificate in
that
directory for you (at startup), and it will handle those certificates
based on
SNI.

Lukas