Currently it's not trivial to get certificates for meek-server using Let's Encrypt. The --webroot option, for example, wants to write a token to the filesystem so the web server can serve it, but meek-server doesn't serve files from the filesystem.
Ideally this works in a way that certificates can be renewed (e.g. in a cron job) without restarting tor or meek-server.
To upload designs, you'll need to enable LFS and have an admin enable hashed storage. More information
Child items 0
Show closed items
No child items are currently assigned. Use child items to break down this issue into smaller parts.
Linked items 0
Link issues together to show that they're related.
Learn more.
I'm looking for ideas of good ways to handle TLS certificates and their renewal for meek bridges. I want to use Let's Encrypt for this process, and I hope that someone who knows Let's Encrypt well can contribute some ideas.
All three of the meek bridges use HTTPS to receive connections from the CDN, so they need TLS certificates. For example, when you use meek-azure, your traffic is forwarded to the bridge at https://meek.bamsoftware.com/. How it works now is I do the usual domain validation procedure with a CA, receive an email to show that I control the domain, install the cert and key, and then run the server like this:
{{{
meek-server --cert /etc/meek/cert.pem --key /etc/meek/key.pem
}}}
When I used Let's Encrypt in the past, using the --webroot option, it wanted to write a file to the URL path /.well-known/acme-challenge/{token}. That won't work for meek-server as it exists today, because meek-server never serves files from the filesystem. But it could. Perhaps we could add an option like --acme-webroot that would allow serving files from a single whitelisted directory.
Currently you have to restart meek-server in order to make it notice a changed certificate and key file. It would be better if that were not necessary--maybe we could periodically stat the files, and re-load them if they have changed?
This is going to be an issue for Snowflake as well, because we will want to use WebSocket over TLS for the server component.
Use on non-web servers? This question is more about using Let's Encrypt for e.g. IMAP or SMTP, but it's related in the sense that it's about a server type for which there is no ACME plugin.
allow ports other than 443. Somewhat related, says that the HTTPS authenticators can only run on port 443. (If we were not running meek-server on 443, then it would be pretty easy to run Let's Encrypt in standalone mode, which binds to 443. But we are running meek-server on 443.)
I stand corrected, as long as you use Go 1.6 or later, reloading the cert is trivial (See tls.Config.GetCertificate). dcf, is "you must build with Go 1.6 or later" a reasonable requirement for meek-server?
Not having to tear down the Listener on certificate reload is rather convenient. I can probably do the code for this in an evening if so...
I stand corrected, as long as you use Go 1.6 or later, reloading the cert is trivial (See tls.Config.GetCertificate). dcf, is "you must build with Go 1.6 or later" a reasonable requirement for meek-server?
I stand corrected, as long as you use Go 1.6 or later, reloading the cert is trivial (See tls.Config.GetCertificate). dcf, is "you must build with Go 1.6 or later" a reasonable requirement for meek-server?
Untested, should work, if there's something wrong it should be trivial. Behavior is:
If the cert/key fail to stat() or load when creating the listener, fail hard.
On each incoming connection, if the mtime of either the cert or key has changed, reload the certificate, otherwise use the cached cert.
Once the listener is created, failures to stat() or reload the certificate result in an error message logged at most once every 60s, and the existing cached certificate to be used.
Note that stat()-ing 2 files every incoming connection may be a tad expensive (though that's outside the mutex). Performance can be improved by only reloading once in a while (gettimeofday() is vDSO-ed on sensible systems), and by using a RWLock instead of a Mutex. Both to me are pre-mature optimizations since TLS handshake crypto blows both 2 syscalls and slight lock contention out of the water overhead wise.
I think the other half of this is easiest to implement via an --acme-webroot that lets meek-server serve files over port 80 like you mentioned in your tor-dev@ e-mail.
Untested, should work, if there's something wrong it should be trivial. Behavior is:
If the cert/key fail to stat() or load when creating the listener, fail hard.
On each incoming connection, if the mtime of either the cert or key has changed, reload the certificate, otherwise use the cached cert.
Once the listener is created, failures to stat() or reload the certificate result in an error message logged at most once every 60s, and the existing cached certificate to be used.
Note that stat()-ing 2 files every incoming connection may be a tad expensive (though that's outside the mutex). Performance can be improved by only reloading once in a while (gettimeofday() is vDSO-ed on sensible systems), and by using a RWLock instead of a Mutex. Both to me are pre-mature optimizations since TLS handshake crypto blows both 2 syscalls and slight lock contention out of the water overhead wise.
I think the other half of this is easiest to implement via an --acme-webroot that lets meek-server serve files over port 80 like you mentioned in your tor-dev@ e-mail.
Thanks. That's beautiful. I'll write tests for certContext.
It occurs to me that an --acme-webroot option will only work if meek-server is listening with TLS on port 443 or with non-TLS on port 80. So I think I'll check that one of those is true, and if not, throw an error at startup if the user tried to use --acme-webroot. If they have something else running on 80 or 443, then they'll have to work out their own thing, for example running letsencrypt in standalone mode.
Here's my branch using Russ Cox's LE client library. The mechanism is the same as Yawning's (replacing GetCertificate). It's a new dependency, but only about 50 lines of code in meek-server itself: http://github.com/gtank/meek/tree/letsencrypt
The example torrc works fine on a Debian machine and starts bridging without noticeable delay on first fetch. The biggest caveats I can think of are
Here's my branch using Russ Cox's LE client library. The mechanism is the same as Yawning's (replacing GetCertificate). It's a new dependency, but only about 50 lines of code in meek-server itself: http://github.com/gtank/meek/tree/letsencrypt
Let's Encrypt support is activated by the --acme-hostnames option, which specifies the set of hostnames for which the server will ask for certificates. For example,