plugins icon indicating copy to clipboard operation
plugins copied to clipboard

security/acme-client: add support for generic post-cert-issue hooks

Open kquinsland opened this issue 3 years ago • 3 comments

  • [X] I have read the contributing guide lines at https://github.com/opnsense/plugins/blob/master/CONTRIBUTING.md
  • [X] I have searched the existing issues, open and closed, and I'm convinced that mine is new.
  • [X] When the request is meant for an existing plugin, I've added its name to the title.

Is your feature request related to a problem? Please describe. This is a spinoff for #2757.

In short: I have a small collection of shell scripts that move certificates onto various devices throughout my network. Some of the devices in question require a non-trivial amount of work to install the certificate into the device.

As of right now, it is possible to configure opnSense to execute an arbitrary script after cert issuance through configd. Unfortunately, this script must have preexisting knowledge of where on disk the cert/key material resides or must know the full set of domain(s) that the cert is meant for so it can iterate over every certificate on disk looking for the one that matches all domains.

The path to the key material can be obtained from reading the logs but there appears to be no way to pass this into a user-defined action/script/command.

Describe the solution you'd like

I am looking for a way to invoke an arbitrary shell script after the acme client successfully (re)issues a TLS certificate. This invocation mechanism should pass some information about the recent certificate issuance into the script.

Depending on implementation, this data should be made available to the script:

  • Domain(s) for which the certificate is good for. CN + SAN(s). Either a space delineated string with the CN as first domain and SAN(s) following or a dedicated split between CN and additional SAN(s).
  • The location on disk for the key material

I am not super familiar with the internals of opnSense but I can see a few reasonable implementations:

  • A symlink is created. The location/name of the symlink would be well known/deterministic. E.G.: The certificate common name is appended to a well known path. For a certificate issued to foo.example.net, a symlink from /var/etc/acme-client/certs/links/example.foo.net/ to /var/etc/acme-cllient/certs/someUUIDHere/ would be made. This might be a bad idea if the UUID changes at any point immediately after the acme client runs before the automation is done.
  • A fixed and well known set of arguments is provided. The first argument will always be the common name $argv[1] => foo.example.net, the second argument will always be the path on disk: $argv[2] => /var/etc/acme-client/certs/someUUIDHere/ ... etc. This might require a small "send arguments to automation" checkbox; sending arguments to automation that don't expect them could end poorly... or could be fine. /shrug
  • A similar approach but instead of command line arguments, env vars. E.G.: .$_ENV["ACME_CERT_CN"] => 'foo.example.net'.
  • The user is given a simple text box into which they can define the string which will be passed to the script. The input supports tokens for each of the bits of data. E.G.:
command: someUserCreatedConfigDCommandHere
arguments: --log-level=WARN --otherScriptArgumentHere .... --cert-cn=${ACME_CERT_CN} --cert-location=${ACME_CERT_DIR}

where ${ACME_CERT_CN} and ${ACME_CERT_DIR} would be replaced with foo.example.net and /var/etc/acme-client/certs/someUUIDHere/ and the entire string is appended to whatever the command: value for /usr/local/opnsense/service/conf/actions.d/actions_myCertHooks.conf is. The system would basically exec:

/root/acme_hooks/deployCertToThing.sh --log-level=WARN --otherSccriptArgumentHere --cert-cn=foo.example.net --cert-location=/var/etc/acme-client/certs/someUUIDHere/

Describe alternatives you've considered

  • Manually running the first certificate issuance and then pulling the key material path from the logs and then hard-coding that into the actions.d/actions_MyCustomStuff.conf file
  • Doing a for d in ls /var/etc/acme-client/certs/ do; openssl x509 -noout -subject -in d.pem and then branching into relevant code when the correct certificate is found.
  • Spinning up separate infrastructure to own the certificate request/deploy stuff and keeping the ACME client in opnsense dealing only with the web ui cert

Additional context

https://forum.opnsense.org/index.php?topic=27682.0

kquinsland avatar Mar 28 '22 00:03 kquinsland

Somehow same with me, would like to move from pfSense to OPNSense but since I have some 30-40 shell scripts pushing acme certs from pfSense to various systems doing various individual things I am also badly missing to be able to trigger an arbitrary shell script after the certificate was renewed in ACME-Client on OPNSense. If there was a way to address the Cert/Key/Fullchain Bundle by a well known or fixed name all my problems would be solved and I could gladly move from pfSense to OPNSense...

Zappo-II avatar Apr 05 '22 10:04 Zappo-II

I have some 30-40 shell scripts pushing acme certs from pfSense to various systems doing various individual things I am also badly missing to be able to trigger an arbitrary shell script after the certificate was renewed in ACME-Client on OPNSense.

I came to my senses and created a basic deployment of the Certbot docker container. The shell scripts that would normally be executed by pfSense now accompany the docker container and are executed as post deploy hooks. Certbot is run daily and for each certificate that is renewed, the shell script is executed which does the necessary conversion/transfer.

Currently this runs in my k8s cluster but this could live anywhere on the network.

kquinsland avatar May 05 '22 15:05 kquinsland

Yeah, did something similar using acme.sh docker and docker...

Zappo-II avatar May 05 '22 15:05 Zappo-II

This issue has been automatically timed-out (after 180 days of inactivity).

For more information about the policies for this repository, please read https://github.com/opnsense/plugins/blob/master/CONTRIBUTING.md for further details.

If someone wants to step up and work on this issue, just let us know, so we can reopen the issue and assign an owner to it.

OPNsense-bot avatar Sep 23 '22 23:09 OPNsense-bot