Apache HTTP Server
The Apache adapter lets a Linux Mesh Node rotate the certificate of an Apache HTTP Server virtual host without dropping connections and with automatic rollback. The node stages each certificate as an immutable generation, switches an atomic current link, proves that Apache's configuration is valid and actually includes the managed snippet, performs a graceful restart (open connections finish while the configuration is re-read) and commits only when the virtual host serves the exact new leaf certificate.
The node only runs the SHA-256-pinned httpd/apache2 executable with fixed arguments — never a shell, command template or remote executable:
| Step | Command run by the node |
|---|---|
| Syntax test | apache2 -t -f <config> |
| Include check | apache2 -t -D DUMP_INCLUDES -f <config> (the managed snippet path must appear) |
| Activate | apache2 -k graceful -f <config> |
Requirements
- A Linux (or Linux-container) Mesh Node in the same reviewed privilege boundary as Apache: Apache must be able to read the managed certificate, and the node must be able to signal the pinned Apache process.
- The certificate and private key Apache serves today (imported as the first generation).
- A local durable filesystem for the managed directory that supports atomic symlink replacement and directory
fsync. - An HTTPS health endpoint on the virtual host, covered by the certificate.
Prepare the host
sha256sum /usr/sbin/apache2
7b2e9d4c1a0f8e6d5c3b2a1f0e9d8c7b6a5f4e3d2c1b0a9f8e7d6c5b4a3f2e1d /usr/sbin/apache2
sudo install -d -o edgepki -g edgepki -m 0700 /var/lib/sectigo-edge/apache
sudo systemctl edit edgepki-node
### add these lines in the editor, then save:
[Service]
ReadWritePaths=/var/lib/sectigo-edge/apache
The digest is an example; compute your own from the exact binary the node will invoke (/usr/sbin/httpd on some distributions) and re-pin after updates. The drop-in is needed because the installed unit only allows writes to /var/lib/edgepki.
Include the managed snippet inside the exact TLS virtual host managed by Sectigo Edge, and remove that host's own SSLCertificateFile and SSLCertificateKeyFile directives:
<VirtualHost *:443>
ServerName payments.prod.internal.example
SSLEngine on
Include "/var/lib/sectigo-edge/apache/sectigo-edge-tls.conf"
</VirtualHost>
The node owns sectigo-edge-tls.conf (it sets SSLCertificateFile and SSLCertificateKeyFile to files under the atomic current link) and rewrites local changes. Private keys are mode 0600; the managed root and generation directories are 0700.
Copy the currently served certificate chain and key to bootstrap files readable by the node's user, for example under /etc/sectigo-edge/bootstrap/.
Node configuration
{
"apache_enabled": true,
"apache_adapter_reference": "local/apache-production",
"apache_profile_id": "prod-service",
"apache_binary_path": "/usr/sbin/apache2",
"apache_binary_sha256": "<64 lowercase hex characters>",
"apache_configuration_file": "/etc/apache2/apache2.conf",
"apache_managed_directory": "/var/lib/sectigo-edge/apache",
"apache_bootstrap_certificate_file": "/etc/sectigo-edge/bootstrap/apache-certificate.pem",
"apache_bootstrap_private_key_file": "/etc/sectigo-edge/bootstrap/apache-private-key.pem",
"apache_reload_timeout_seconds": 10,
"apache_rollback_window_seconds": 3600
}
All paths must be absolute; the binary, root configuration and bootstrap pair must be regular, non-symlink files. apache_reload_timeout_seconds is 2–60 and apache_rollback_window_seconds 60–86400. Validate, restart, and check that sectigo-edge status lists "kind": "apache" with "health": "healthy" before enabling desired state.
Configure in the console
- Open ConsoleIntegrations and select Configure on Apache HTTP Server.
- Select Enable this integration and choose only Linux nodes under Target Mesh Nodes.
- Enter the Certificate / identity profile — exactly
apache_profile_id. - Enter the Local adapter reference — exactly
apache_adapter_reference(for examplelocal/apache-production). - Select Save desired state and wait for Healthy.
Each save creates a new desired-state revision. The node must acknowledge that exact revision as healthy before any Apache-bound issuance proceeds.
Policy requirements
- Add
apacheto the profile's allowed deployment modes, only for profiles permitted to activate Apache certificates (unknown or duplicate modes are rejected). - Define an explicit rotation block with bounded controls. Automatic activation is denied when the block is missing or its promotion mode is
manual. - Every signed issuance binds the profile, adapter reference and positive integration revision. Disabling, reassigning, degrading or revising the integration invalidates an in-flight deployment before activation.
How rotation and rollback work
- The node creates the key and CSR locally and persists a private, fsync-backed intent (transaction, CSR, key, SANs, profile, adapter, revision).
- The signed policy decision and issuance request are persisted before submission, so an interruption replays exactly.
- The issued certificate is matched to the intent and written into a new immutable generation while the old one stays active.
- The adapter moves
current, runs the syntax test and the include check. - It performs the graceful restart and requires the configured HTTPS health URL to return 2xx while serving the exact staged leaf.
- Success commits active/previous and starts the rollback window. Any failure restores the previous link, re-tests and gracefully reloads it.
- After a crash with a pending promotion, the previous generation is restored before the adapter reports healthy again.
Rotation requests use the same local POST /v1/managed/rotate call as NGINX with "integrationKind": "apache" and "adapterReference": "local/apache-production" (see NGINX → How rotation works). For manual promotion, an operator uses Verify & promote in ConsoleRotation with the exact HTTPS health URL; the console does not change its slot state until the assigned node has executed the graceful restart, verified the served leaf and reported the matching command.
Verify
sudo -u edgepki /usr/sbin/apache2 -t -D DUMP_INCLUDES -f /etc/apache2/apache2.conf | grep sectigo-edge
(3) /var/lib/sectigo-edge/apache/sectigo-edge-tls.conf
openssl s_client -connect payments.prod.internal.example:443 -servername payments.prod.internal.example </dev/null 2>/dev/null \
| openssl x509 -noout -serial -enddate
serial=1F7A3C9D0B6E2481
notAfter=Oct 2 15:02:44 2026 GMT
Example output. Also confirm the Apache HTTP Server card is Healthy and that promotions appear as certificate.promoted trust events.
Troubleshooting
| Code or message | Meaning | What to do |
|---|---|---|
apache_not_configured | The node has no Apache settings | Add the keys and restart |
adapter_reference_invalid / profile_not_mapped | Console and node disagree | Make them identical |
apache_configuration_invalid | Syntax test failed or the managed snippet is not in the include dump | Fix the configuration and the Include placement |
apache_active_pointer_invalid | current does not match the recorded active generation | Restore it or investigate tampering |
apache_recovery_pending | An interrupted promotion/rollback is unresolved | Fix the underlying cause so recovery can complete |
apache_state_invalid | The manifest cannot be read or verified | Investigate local changes |
apache_integration_unavailable / apache_integration_binding_mismatch | Rotation refused: integration not healthy, or reference/profile mismatch | Fix desired state, then retry |
| Node will not start | Non-Linux node, unsafe path, wrong digest or mismatched bootstrap pair | Run edgepki-node -validate-config |
See also Zero-downtime rotation.