dvtirol / serles-acme

Pluggable ACME: a tiny ACME-CA implementation to enhance existing CA infrastructure
https://serles-acme.readthedocs.io/
GNU General Public License v3.0
46 stars 10 forks source link

add a backend to directly use CertBot for CSR signing #1

Closed nneul closed 1 year ago

uedvt359 commented 1 year ago

Hi! This looks interesting, thanks! Do you have an example how hooking this up to certbot would look like?

nneul commented 1 year ago

I will in next day or so - still working on it, and can add it as an included example once I have it fully working and then can strip out the 'stuff specific to my deployment' to make it suitable for a general example.

nneul commented 1 year ago

Example wrapper added to the examples-external directory that could be used as a starting point.

I was able to request a cert from an arbitrary server in my intranet, pointing to the serles installation, and it was handed back a fully valid LetsEncrypt signed cert chain.

uedvt359 commented 1 year ago

Sorry, stressful week. I haven't forgotten about this, I'll take a look soon!

uedvt359 commented 1 year ago

Hi, sorry it took me so long to review your code. I have a few questions regarding the architecture of the backend. Right now, you pass information about the csr/order as json on stdin. This is obviously not standardized (since there is no such standard). This means that all external/wrapper script need to be written specifically for serles-acme.

Given that your certbot script is already in python - why go to the trouble of exec'ing another process and serializing the data transmitted between them? Would you be open to submit your certbot-backend directly?

Or is the certbot wrapper just an example, and what you need is something else which you can't share? I'm not completely opposed to adding an 'external' backend (with all the nonstandard interfacing it needs), but I would prefer more tailored backends if possible and practical.

nneul commented 1 year ago

The certbot backend was just an example based primarily on how existing code does it with openssl - it could potentially be ANY ACME client (or any other certificate obtaining mechanism). I could certainly make a specific tie-in directly to certbot pretty easily, though that wouldn't be as generalized in "allow a particular deployment to plug in whatever tool suits their needs without necessarily customizing serles' code".

Mainly the model was "add a plugin interface".

For my utilization of certbot - I would likely have to add several additional configuration settings for the 'certbot specific plugin' since it will need to pass a number of additional parameters to certbot. The example external I provided was for native dns-route53 validation, but in my actual use case deployment, I can't directly use that, I actually need to have a custom hook to be able to allow certbot to deal with multiple different AWS account credential sets depending on the particular domain being serviced, and that isn't supported natively. Figure I'll probably have a configuration setting to just add additional arguments to the certbot invocation.

If the 'pass via stdin' is primary concern with the particular external implementation, it would be pretty trivial to have that pass via a temporary directory+file. The subject DN and alt names should already be in the CSR itself and could be pulled from the CSR itself. The email isn't, but it's not clear that is really required -- I just passed that through cause it was available in the calling context.

I'll see what I can do about putting together a certbot specific backend since that would be more 'drop-in', but would definitely still like to see some variation of the generalized 'plugin/external' support that didn't require directly customizing the code.

nneul commented 1 year ago

One thing that could be helpful for above - do you happen to have an example using that config file library that you are using to load in an array of values as opposed to a multiline string?

uedvt359 commented 1 year ago

Mainly the model was "add a plugin interface". but would definitely still like to see some variation of the generalized 'plugin/external' support that didn't require directly customizing the code.

Well, serles-acme already has a plugin interface; using python modules. they don't have to be loaded from within serles - as long as they can be found on the python path they can be imported.

For example, you can put serles/backends/external.py in ~/.local/lib/python3.*/site-packages/externalSerlesPlugin.py and load it in the config with backend = externalSerlesPlugin:Backend. Or you could install it to e.g /tmp/externalSerlesPlugin.py and set PYTHONPATH=/tmp with the same config again.

Of course, I'd suggest modifying certbot-wrapper.py to provide a class Backend directly.

do you happen to have an example using that config file library that you are using to load in an array of values as opposed to a multiline string?

I don't think python's ConfigParser can do that. splitting multiline strings is (afaict) the recommended practise.

nneul commented 1 year ago

You were absolutely right on the "just do certbot directly" -- this is much cleaner. Please review updates and let me know if this works for you.

uedvt359 commented 1 year ago

I'll try to take a look at this this week. thanks for being patient with me :)

uedvt359 commented 1 year ago

Thank you a lot for contributing this!

nneul commented 1 year ago

@uedvt359 Any plans to do a new pypi release?

uedvt359 commented 1 year ago

yeah, a release is overdue. I'll try to find time for it soon

uedvt359 commented 10 months ago

@nneul - took me long enough, but there is finally a 1.1.0 release on pypi.