jetforce icon indicating copy to clipboard operation
jetforce copied to clipboard

Automatically reload TLS certificate

Open michael-lazar opened this issue 4 years ago • 9 comments

I noticed that my TLS certificate was expired on my jetforce server, even though certbot had already refreshed the certificate in my filesystem.

I want to see if there's any way for python to automatically detect the file change and reload without needing to manually restart the server every couple of months.

michael-lazar avatar Jan 10 '20 05:01 michael-lazar

There are libraries like watchdog for finding out when a file changes on the operating system. But because this is a simple situation, just two files that change infrequently, I think some simple polling could be done, just checking if the file is different every 10 minutes or something, maybe by comparing fingerprints/hashes. It could also be programmed to check based on when the current cert expires. Doing both is probably the best of both worlds. Thoughts? Thanks a lot for writing this by the way, it's really great and easy to use.

makew0rld avatar May 18 '20 03:05 makew0rld

Thanks for the discussion :) I like the polling approach more than checking the expiration date because certs can be rotated long before they expire.

This should be made easier with the new TLS connection factory that's being added in the v0.3.0 branch. With the new behavior, the SSL context is cached when the first connection is made, and then retrieved from the cache on subsequent connection. I think it would be straightforward to do something like invalidate the cache every X hours and let the SSL context reload itself on a new connection.

Personally, I was able to solve this for my own server after I discovered that certbot had renewal hooks. I added a script at /etc/letsencrypt/renewal-hooks/deploy/jetforce.sh that restarts the systemd service whenever my certificates change.

michael-lazar avatar May 18 '20 04:05 michael-lazar

I'm going to close this ticket for now, since the recommended approach for gemini seems to be moving strongly towards using self-signed certificates that don't necessarily need to be rotated. I will probably update the documentation regarding this once I get around to moving my own server to using a self-signed certificate.

michael-lazar avatar Jun 26 '20 04:06 michael-lazar

I haven't seen anything suggesting using certs that don't need to be rotated, the majority of certs in my TOFU db expire in the next few months.

makew0rld avatar Jun 26 '20 18:06 makew0rld

@makeworld-the-better-one

I read your recent gemlog post on TOFU certs, thanks for posting that!

gemini://makeworld.gq/gemlog/2020-07-03-tofu-rec.gmi

I have a question, which is that I still don't understand the security benefit for why you would want to add an expiration to a TOFU certificate. I don't mean for this to come off as standoffish. I hope you don't mind me asking it here.

I understand the usefulness of certificate expirations in the context of Certificate Authorities. Say Let's Encrypt signs your server's certificate, which says "Let's Encrypt vouches for the identity of this certificate key pair for the next 90 days". Next, say your server's private key is compromised. The attacker only has until the end of that 90 day window before the certificate becomes effectively useless because a root CA doesn't vouch for it anymore. Ideally, if you discover that your certificate has been compromised you can revoke it immediately by adding it to a CRL. But the expiration date at least caps the damage that can be done if the attacker no longer has access to the server. (assuming that the server cycles their private key whenever refreshing the certificate, which is the default behavior of certbot)

Now with self-signed certificates, what happens if your private key is compromised? There is no third-party root CA signing the certificate, so absolutely all trust is placed in that private key. Assuming that gemini clients are using your recommended approach and checking the SPKI, the first thing that I would do as an attacker is generate a new certificate that keeps the SPKI the same but updates the expiration 1000 years in the future. Then, clients will accept it without even notifying the user and I can MITM until eternity.

With straight MITM attacks (no compromised private key), all that the expiration date does is provide a window of time where an attacker can hijack the connection without raising suspicion. If I were a dastardly ISP, I would look at all server certificates and then selectively MITM a connection only once a certificate has expired and I can swap in my own certificate. This vulnerability that can be prevented if certificates never expire. [1]

These are the only two categories of attacks that I can come up with. With the first category the expiration doesn't seem to make a significant difference. With the second category the expiration date actually makes things less secure. What am I missing here?

[1] Granted, I would also selectively MITM all connections the first time they were made to a new domain, but that's an unavoidable security tradeoff with the TOFU model.

michael-lazar avatar Jul 05 '20 03:07 michael-lazar

Thanks for bringing this up. I'll take a stab at this now, but I will be looking at this again in the morning (EST) and responding again probably.

I think you are very right about the idea of removing expiry dates entirely. My post was written with the intent of addressing Gemini as it stands right now, where the majority of certs on sites expire within the year, and there is no guarantee sites will use the same key when they regenerate the cert.

I will write another post tomorrow, that outlines the TOFU idea you propose, and the changes that would need to be made to my original post. The main ones that I see would be to not store the expiry date anymore, and to definitely use the SPKI and not the whole cert, so that the expiry date is not stored there either. And always notify the user when the cert changes.

Solderpunk has mentioned how he wants to write a tool that will generate certs for Gemini servers, like openssl but with defaults that make sense for Gemini. I will suggest to him that this tool generates certs with an expiry date 100 years in the future or something like that.

Setting up TOFU like this will require changes from client authors and server maintainers, hopefully we can all work together on this.

makew0rld avatar Jul 05 '20 04:07 makew0rld

I'd like to point out that in my original post, I put checking the cert ID first, before checking expiry. So if you're using SPKI for a cert ID, the expiry of the cert isn't even considered. It only comes into play if the cert ID doesn't match, at which point the expiry is looked at to determine if the new cert should be accepted.

But I still agree with you. I'll write up my post and also open a thread on the mailing list.

makew0rld avatar Jul 05 '20 15:07 makew0rld

Alright I've posted it, and also sent it to the mailing list. Please chime in there if I made some mistake, or if I've misunderstood you somehow. :crossed_fingers:

gemini://makeworld.gq/gemlog/2020-07-05-tofu-2.gmi

makew0rld avatar Jul 05 '20 16:07 makew0rld

Please see that mailing post thread for further discussion, titled "Removing expiry dates for TOFU". Solderpunk has rejected the idea, with good reason.

makew0rld avatar Jul 06 '20 14:07 makew0rld