Skip to content

klibs: Add Automatic Certificate Management Environment (ACME) client - #2196

Open
francescolavra wants to merge 6 commits into
masterfrom
feature/acme
Open

francescolavra wants to merge 6 commits into
masterfrom
feature/acme

Conversation

@francescolavra

Copy link
Copy Markdown
Member

ACME is a protocol to automate TLS certificate renewal.

Add a klib that optionally checks the expiration date of existing on-disk certificates, and implements an ACME client that requests new certificates from a server when either there is no on-disk certificate, or the existing certificates are near the expiration date (i.e. less than one third of their lifetime remains).
This klib is meant to be enabled on images running a web server that uses these certificates to serve web content from one or more domains over TLS. It uses the following configuration settings:

  • "server": the ACME server from which certificate renewals will be requested
  • "web_dir": the filesystem directory from which the running web server serves all static files over HTTP; note: it is required for the server to support HTTP connections on TCP port 80
  • "email": an email contact of the domain administrator; this is an optional setting, and if present may be used by the ACME server to send notification emails about certificate renewals
  • "reload": optional action taken by the klib code to notify the running web server that a certificate has been renewed and therefore the server should re-load its cached certificates and corresponding private keys. Allowed values: "SIGHUP" (send a SIGHUP signal to the server process), "SIGUSR1" (send a SIGUSR1 signal to the server process)
  • "certificates": array of one or more certificate-key pairs that should be managed by the ACME client; each array member is an object with the following attributes:
    • "cert_chain": filesystem path of the public certificate file
    • "private_key": filesystem path of the private key file; the client creates a new private key (and thus overwrites this file) every time a certificate is renewed
    • "domains": array of fully qualified domain names for which the certificate is valid; the web server must be able to serve static files from "web_dir" over HTTP for each of these domains; if this setting is not present but the certificate file at the "cert_chain" path is present, the list of domains is read from that file

OPS configuration snippet example for Apache web server:

  "Klibs": ["acme", "tls"],
  "ManifestPassthrough": {
    "acme": {
      "server": "https://acme-v02.api.letsencrypt.org/directory",
      "web_dir": "/usr/local/apache2/htdocs",
      "email": "ddd@ex.com",
      "reload": "SIGUSR1",
      "certificates": [
        {
          "cert_chain": "/usr/local/apache2/conf/server.crt",
          "private_key": "/usr/local/apache2/conf/server.key",
          "domains": ["exampl.com"]
        }
      ]
    },
    "log_level": "info"
  }

OPS configuration snippet example for Nginx web server:

  "Klibs": ["acme", "tls"],
  "ManifestPassthrough": {
    "acme": {
      "server": "https://acme-v02.api.letsencrypt.org/directory",
      "web_dir": "/",
      "email": "ddd@ex.com",
      "reload": "SIGHUP",
      "certificates": [
        {
          "cert_chain": "/etc/ssl/certs/server.crt",
          "private_key": "/etc/ssl/private/server.key",
          "domains": ["exampl.com"]
        }
      ]
    },
    "log_level": "info"
  }

Francesco Lavra added 6 commits October 10, 2026 21:11
Having every net_http_req() caller set the `url` attribute of the request
tuple to a pointer to a buffer (that cannot be allocated on the stack)
creates too much boilerplate code.
Make net_http_req() callers use a new `query` field (with sstring type) in
struct net_http_req_params instead of setting the `url` attribute, and set
this attribute in the connection handler instantiated by net_http_req().
…ntry

If the length of the file to be written is less than the filesystem block
size, filesystem_write_linear() instantiates a zero-length scatter-gather
buffer, which when submitted to a virtIO storage device under QEMU makes
the write fail with "virtio: zero sized buffers are not allowed".
Up to now, the strncmp() function was only needed by lwIP; in a future
commit, the tls klib will be extended to include support for creating
certificates and CSRs, and this new code uses strncmp().
Remove the lwIP-specific strncmp() implementation, and add the function
prototype to a header file that can be included by any kernel code. The
actual implementation of this prototype already lives in the acpica
library.
And amend the parser unit tests accordingly.
It's a good programming practice for a function with output parameters to
not modify output arguments on failure.
ACME is a protocol to automate TLS certificate renewal.
Add a klib that optionally checks the expiration date of existing on-disk
certificates, and implements an ACME client that requests new certificates
from a server when either there is no on-disk certificate, or the existing
certificates are near the expiration date (i.e. less than one third of
their lifetime remains).
This klib is meant to be enabled on images running a web server that uses
these certificates to serve web content from one or more domains over TLS.
Example OPS configuration snippet:
```
  "ManifestPassthrough": {
    "acme": {
      "server": "https://acme-staging-v02.api.letsencrypt.org/directory",
      "web_dir": "/usr/local/apache2/htdocs",
      "email": "ddd@exampl.com",
      "reload": "SIGUSR1",
      "certificates": [
        {
          "cert_chain": "/usr/local/apache2/conf/server.crt",
          "private_key": "/usr/local/apache2/conf/server.key",
          "domains": ["exampl.com"]
        }
      ]
    }
  }
```
- "server" is the ACME server from which certificate renewals will be
requested
- "web_dir" is the filesystem directory from which the running web server
serves all static files over HTTP; note: it is required for the server to
support HTTP connections on TCP port 80
- "email" is an email contact of the domain administrator; this is an
optional setting, and if present may be used by the ACME server to send
notification emails about certificate renewals
- "reload": optional action taken by the klib code to notify the running
web server that a certificate has been renewed and therefore the server
should re-load its cached certificates and corresponding private keys.
Allowed values: "SIGHUP" (send a SIGHUP signal to the server process),
"SIGUSR1" (send a SIGUSR1 signal to the server process)
- "certificates": array of one or more certificate-key pairs that should be
managed by the ACME client; each array member is an object with the
following attributes:
  - "cert_chain": filesystem path of the public certificate file
  - "private_key": filesystem path of the private key file; the client
creates a new private key (and thus overwrites this file) every time a
certificate is renewed
  - "domains": array of fully qualified domain names for which the
certificate is valid; the web server must be able to serve static files
from "web_dir" over HTTP for each of these domains; if this setting is not
present but the certificate file at the "cert_chain" path is present, the
list of domains is read from that file
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant