aiosmtpd icon indicating copy to clipboard operation
aiosmtpd copied to clipboard

Add option to reload cert files periodically (letsencrypt)

Open FrederikLauber opened this issue 4 years ago • 4 comments
trafficstars

Hi,

as far as I can tell, at the moment, certs are only read on context creation. This poses a problem for lets encrypt setups as the certs will regularly change on disk but an always running aiosmtpd controller will always use the context at startup. Would it be possible to either add an option to reload the certs after some time?

FrederikLauber avatar Feb 22 '21 14:02 FrederikLauber

I believe it should be possible. I'm not sure if the capability to hot-swap the controller(?) exists, but I certainly like the idea. Obviously the current workaround would be to drain the existing connections/and or terminate and then just restart. But that feels wrong, if nothing else :upside_down_face:

waynew avatar Feb 22 '21 16:02 waynew

For SMTPS, likely difficult. I'm not familiar with the innards of create_server; the Controller likely needs to be restarted.

For STARTTLS ... probably doable? Because the TLS Context is not pressed into service until SMTP receives the STARTTLS command.

However, the current implementation uses TLS Context as passed into __init__ during SMTP instantiation. Changing the mechanism will likely break things.

That said, the SMTP.tls_context attribute is accessible. Even if SMTP is started by Controller, one can access the attribute via Controller.smtpd.tls_context. If you use Controller via your own program, you can implement a "watcher" of sorts; upon detecting the cert & key change, create a new TLS Context and 'inject' it via Controller.smtpd.tls_context.

If we're talking about the CLI program, I think the best way is to not make it even more complex than it already is, but use certbot's --post-hook option to restart the CLI program.

Edit: Come to think of it, if you're not using the CLI program but use the Controller class directly, your program can also watch, say, for SIGHUP. When SIGHUP is received, your program would then create a new TLS Context and inject it into Controller.smtpd.tls_context

pepoluan avatar Feb 22 '21 18:02 pepoluan

@waynew I believe you created the current test certs in f414dcd ?

Can you create an additional pair of cert+key? I'm a bit rusty with OpenSSL incantation.. 😅

I want to test if we can replace the cert+key on the fly. If so, I'll add a test to ensure this behavior.

(Don't replace the current server.crt and server.key files; just add a pair of new ones into the tests/certs dir)

pepoluan avatar Feb 22 '21 18:02 pepoluan

I'm pretty sure, based on the days, that I used this incantation:

openssl req -new -newkey rsa:2048 -days 36500 -nodes -x509 -keyout server.key -out server.crt

And then just filled out the appropriate fields. Since I created it I used:

Issuer: C = US, ST = AR, L = Greenwood, O = Aiosmtpd, OU = DevTeam, CN = aes, emailAddress = [email protected]

Since that's where I was living at the time :joy:. I went ahead and created some here: https://github.com/aio-libs/aiosmtpd/compare/master...waynew:alt-certs?expand=1

waynew avatar Feb 23 '21 17:02 waynew