
On the fly SSL registration and renewal inside Nginx with Let's Encrypt - snaky
https://github.com/GUI/lua-resty-auto-ssl
======
kodablah
Nice. Good to see this has a shared storage option (Redis) for load balanced
servers. The LE HTTP challenge gives no guarantee which A record it will use.
Similarly, if your LB chooses another server even behind the same IP, it'd
have to share the challenge state. I haven't read deeply, but I assume it
handles the race conditions that can occur with auto renewal (i.e. different
servers triggering auto renewal at the same time, overusing LE and hitting the
quota faster). It was something I struggled with during the implementation of
pluggable storage adapters for Caddy[0].

0 -
[https://github.com/mholt/caddy/pull/913](https://github.com/mholt/caddy/pull/913)

~~~
okket
If you are going this scale, there is another way: Use your own DNS server and
try the DNS-01 challenge. My setup works with [0]letsencrypt.sh,
[1]pdns_api.sh, [2]PowerDNS4 (MySQL backend w/ replication) and a little
script that distributes the certs and restarts services. The nice thing is,
this works for anything you can put in DNS, you do not need not to respond to
a HTTP request for a name (think mail server).

[0]
[https://github.com/lukas2511/letsencrypt.sh](https://github.com/lukas2511/letsencrypt.sh)
[1]
[https://github.com/silkeh/pdns_api.sh](https://github.com/silkeh/pdns_api.sh)
[2] [https://github.com/PowerDNS/pdns](https://github.com/PowerDNS/pdns)

------
artursapek
Wow, this is awesome. LetsEncrypt is great but I still find it somewhat clumsy
to use it in production. This is the first no-downtime solution I've seen.

The certificate cartel is slowly dying :)

~~~
snaky
You can even update Nginx binary with no downtime -
[https://nginx.org/en/docs/control.html#upgrade](https://nginx.org/en/docs/control.html#upgrade)

------
koolba
Hey this is pretty cool. Would be even cooler if it held off on the SSL
handshake with the initial client until after the certificate was issued by
LetsEncrypt. If it's only a couple of seconds it might be possible.

~~~
nickblah
Author here.. If I'm understanding you correctly, I believe that's how things
are already working. The very first time a client hits a new domain, the SSL
handshake initiates the certificate registration with Let's Encrypt (assuming
the domain is part of the whitelist of allowed domains). The certificate is
registered in the background, while this first request is paused. The SSL
handshake is then completed with the first client once the certificate is
successfully issued. This does lead to the very first client's request being
delayed a few seconds, but this is a one-time delay (per allowed domain).

~~~
gonzo
Nice work!

We'll look into including this in pfsense 2.4.

------
wyattjoh
Not having this featured built into NGINX is the reason why I transitioned my
production servers over from it to Caddy. Having SSL just "dealt with" is the
biggest time saver ever.

------
msumpter
Awesome!

I had been playing around with [https://github.com/jwilder/nginx-
proxy](https://github.com/jwilder/nginx-proxy) and docker-gen to handle
automatic Let's Encrypt generation for my docker containers.

It's amazing how quick to get some of these thing setup with very work:
[https://github.com/msumpter/docker-lua-resty-auto-
ssl](https://github.com/msumpter/docker-lua-resty-auto-ssl)

------
SixSigma
You can use StartSSL free certs for TLS too

[https://startssl.com/](https://startssl.com/)

I set up Courier today to use it for TLS imap

[http://maht0x0r.blogspot.co.uk/2016/07/another-server-
more-c...](http://maht0x0r.blogspot.co.uk/2016/07/another-server-more-courier-
fun.html)

------
njharman
Let's Encrypt is awesome. I've used it to setup real https on several of my
domains. It was easy, automatically renews, just works.

------
tinganho
Just did something similar. Though with HAProxy inside a Docker container.
[https://github.com/tinganho/haproxy-with-letsencrypt-auto-
re...](https://github.com/tinganho/haproxy-with-letsencrypt-auto-renewal)

------
noeleon
The shared storage redis backed option is great. I hacked together something
that served .well-known from an NFS mount to overcome my issues when behind a
proxy / LB.

My $work has a very terribe DNS infrastructure that needs lots of work to
implement dns-01.

------
bsamuels
I wonder if there would be a way to integrate Let's Encrypt with router admin
interfaces. It would be really cool if consumer routers used a valid https
certificate on their web ui

------
sandGorgon
This is awesome.. hopefully we can bake nginx inside docker. Without something
like this, we could not spin up nginx because there was a circular dependency
on the certificate files.

~~~
hobs
I used a combo of [https://github.com/dmp1ce/nginx-proxy-
letsencrypt](https://github.com/dmp1ce/nginx-proxy-letsencrypt) and
[https://github.com/jwilder/nginx-proxy](https://github.com/jwilder/nginx-
proxy) with no problems besides normal nginx configuration.

Does assume you will have a shared volume so you can save/check certs, but it
works great for my use case.

~~~
sandGorgon
Well the shared volume to "seed" a certificate is a no go for us. I would
rather spend 6 bucks for a cert.

~~~
hobs
Totally get it, just thought I would share.

------
d33
Is there anything that would prevent an attack involving bogus SNI requests in
order to trigger a DOS?

~~~
nickblah
Yes, by default the module requires that you explicitly whitelist the domains
you want to allow certificate registration for. So while you could allow any
domain to be registered, that's not recommended for this precise reason. But
the whitelist is defined as a Lua function, so you have quite a bit of
flexibility in integrating the whitelist logic with other sources of
information.

See [https://github.com/GUI/lua-resty-auto-
ssl#precautions](https://github.com/GUI/lua-resty-auto-ssl#precautions) and
the "allowed_domain" configuration for a bit more detail.

------
finnn
This is really cool. Have you considered implimenting the DVSNI challenge?

~~~
nickblah
Author here. I hadn't really considered it, but it should be possible. Since
we're handling this with nginx and Lua, it made it pretty trivial to handle
the simple HTTP challenge (since we can easily intercept the /.well-
known/acme-challenge request), so that's why we went with that approach, but
other approaches should be possible.

~~~
finnn
I guess I figured DVSNI should be even easier since you're already evaluating
the domains of incoming TLS connections and picking which cert to respond with
from there.

~~~
nickblah
I haven't actually looked into DVSNI in too much detail before, so that could
definitely be the case. I'll have to investigate a bit more (or any pull
requests are always welcome). Thank you for the tip!

~~~
finnn
No problem, thanks for building this!

------
LoSboccacc
ah this would nicely handle the let's encrypt wildcard issue. too bad I just
forked $$$ for a wildcard cert. but hey will turn off renew and have a go with
this :)

~~~
schoen
Bear in mind that you could potentially hit a rate limit depending on the
number of subdomains you have (or a different rate limit depending on how the
plugin requests particular certs). I'm sure a small number of users will
become very aware of this issue very soon.

This is a reason that being at least somewhat aware of the overall list of
names to be covered ahead of time could be helpful.

------
bmurphy1976
Apparently this requires OpenResty. OpenResty is an app server type platform
built on Nginx. This does not appear to work on your standard run-of-the-mill
Nginx system package.

OpenResty is a cool project, but it brings a lot of additional infrastructure
along with it that you may not want.

It would be nice of this was clearly indicated in the title of this post.

Updated: see comment below, the README has been clarified, you can run this
with the nginx_lua extension. You don't necessarily need all of OpenResty.

~~~
gtirloni
Compiling nginx from scratch to include ngx_lua is a bummer because of all the
added questions that need to be answered (packaging, repositories, automation,
etc).

It becomes 98% of the time spent enabling this awesome feature (at least on
CentOS and Fedora, from what I can tell there aren't RPM packages for
ngx_lua).

~~~
msumpter
That has been one of my major driving forces behind creating
Dockerfiles/docker-compose my personal/work projects to stand up quick
environments. Docker support on CentOS 5 doesn't exist but I only have a few
servers left from that era luckily.

If you want to give this a try within Docker I setup a repo here to try it
out: [https://github.com/msumpter/docker-lua-resty-auto-
ssl](https://github.com/msumpter/docker-lua-resty-auto-ssl)

------
eloy
Please, please stop using the name "SSL" and use "TLS".

As others replied, x509 would be even more correct, but SSL is completely
incorrect, because that protocol is insecure and shouldn't be used. Using SSL
suggest that the software supports that protocol, although it doesn't (as it
should)

~~~
everfree
If we're getting nitpicky, let's use the term TLS to describe the protocol and
X.509 to describe the certificates and renewals.

------
ssahoo
So taking extra lua dependency burden, and risk just to save 50 bucks to buy a
real SSL certificate?

I'm going to call it certificateless SSL.

