OpenVPN Management Suite
A certificate-lifecycle and VPN administration system designed around a narrow security boundary: an offline root CA establishes a constrained operational intermediate, while a dedicated local daemon mediates routine issuance, revocation, CRL generation, and client provisioning without exposing CA key material to the web application.
vpn-certd is production-ready and in active use. vpn-certctl is operational.
ovpn-admin remains under active development.
Context
Operating an OpenVPN deployment requires more than generating certificates.
A usable system must support:
- Client and server certificate issuance
- Certificate-profile enforcement
- Revocation
- CRL generation and distribution
- Client-bundle creation
- Operator access
- Auditability
- Recovery after credential or CA compromise
The straightforward implementation would place all of those capabilities inside one administrative web application.
That design is attractive because it reduces the number of services and interfaces. The web application already knows which user is authenticated, which certificate they want, and which workflow they are performing. Giving that same process access to the CA key appears efficient.
It also produces the wrong trust boundary.
A web application handles HTTP requests, cookies, sessions, templates, browser-originated input, database state, and a large dependency tree. It is therefore one of the most exposed processes in the system.
The architecture of this suite begins with one requirement:
Compromise of the operator-facing application must not directly disclose the operational CA private key.
The system does not assume that the web layer is impossible to compromise. It assumes that a web-layer compromise is plausible and attempts to limit what authority that compromise inherits.
Architecture
The hierarchy separates three different kinds of authority:
- Root authority, used only to establish the operational trust layer
- Operational signing authority, required for routine certificate lifecycle operations
- Operator workflow authority, used to request and administer those operations
Keeping these authorities in separate components does not eliminate compromise. It prevents one exposed application process from automatically possessing every capability in the PKI.
Decision 1: Keep the root outside routine systems
The root CA is not present on any running service.
It exists to establish or replace the operational intermediate CA. Routine client and server certificate operations do not require the root key.
This reduces the root key’s exposure frequency. The root does not need to be present when:
- A new VPN user is provisioned
- A client certificate is renewed
- A certificate is revoked
- A CRL is regenerated
- A client bundle is assembled
- A server certificate is issued under the established hierarchy
The trade-off is operational complexity.
Replacing or renewing the intermediate requires a deliberate manual procedure and access to the offline root material. That process must therefore be documented and recoverable. An offline root that no operator can restore is confidential but operationally useless.
The value of the offline root is not that it makes the PKI invulnerable. It limits the consequences of an operational intermediate compromise. If the intermediate is lost or compromised, a replacement hierarchy can still be established without replacing the root trust anchor across every client.
Decision 2: Constrain the operational intermediate
The operational intermediate CA has a path-length constraint of zero and signs the client and server certificates used by the VPN environment. It cannot create another subordinate CA below itself.
This is a deliberate limitation.
The operational CA needs enough authority to issue the certificates required by OpenVPN, but it does not need the ability to extend the hierarchy indefinitely.
Its authority should be constrained through:
- Certificate profiles
- Common-name rules
- Validity limits
- Key-size requirements
- Key-usage constraints
- Extended-key-usage constraints
- Duplicate-subject policy
- Path-length restrictions
A common mistake in small PKI deployments is to treat certificate policy as a web-form concern. The UI prevents an operator from choosing invalid values, but the signing component accepts whatever it receives.
That leaves policy enforcement in the least-trusted component.
In this design, the control plane may request an operation, but the certificate daemon determines whether that operation is valid.
Decision 3: Isolate signing in a dedicated daemon
vpn-certd is a single-purpose Go service responsible for:
- Client certificate generation
- Existing-CSR signing
- Server certificate issuance
- Certificate revocation
- CRL regeneration and retrieval
- Client-bundle generation
- Central policy enforcement
The daemon owns the operational CA responsibility. The web application does not.
This separation has several consequences.
The daemon has a smaller responsibility set
It does not need to implement:
- Browser sessions
- HTML rendering
- User-interface state
- General application workflows
- Arbitrary database access
- Client-side JavaScript
- Public HTTP routing
A smaller responsibility set does not automatically mean secure code, but it makes the component easier to reason about and restrict.
The signing key does not cross the process boundary
The web application requests a certificate operation. It does not receive the intermediate private key or load it into its own process memory.
Policy is enforced at the privileged boundary
A compromised caller cannot simply bypass a frontend validation check and invoke OpenSSL with arbitrary parameters. The daemon exposes named operations and applies its own policy before executing them.
Failure is localized
If the control plane is unavailable, the certificate daemon and CLI may remain operational. If the daemon is unavailable, administrative workflows fail, but the web application does not silently fall back to manipulating CA state directly.
Decision 4: Use AF_UNIX instead of a network API
The daemon exposes a local Unix socket rather than a TCP listener.
This removes an entire category of network exposure. The CA service is not reachable simply because an attacker can route to the host.
Access can be controlled through:
- Socket ownership
- Unix group membership
- File mode
- Service identities
- Local privilege boundaries
- Systemd unit permissions
The documented deployment uses a dedicated service account, a socket with restricted permissions, no TCP or UDP access, and systemd hardening that limits capabilities and writable paths.
The choice of AF_UNIX is not security by itself.
A Unix socket becomes weak when:
- It is world-writable
- Multiple unrelated applications share the service account
- The protocol accepts arbitrary commands
- The daemon trusts caller-supplied policy
- The host is already fully compromised
- Socket authorization is not aligned with operator roles
The socket is therefore one layer in the design, not the complete control.
It narrows the reachable interface and allows the host operating system to participate in access control.
Decision 5: Support both server-side generation and CSR signing
The daemon supports both server-side key generation and signing of an existing CSR.
These modes serve different operational needs.
Server-side key generation
The daemon generates the key and certificate and can assemble a complete client bundle.
Advantages:
- Simpler provisioning
- Consistent key parameters
- Easier automation
- Fewer client-side steps
Trade-off:
- Private-key material exists temporarily within the provisioning system
- Bundle delivery becomes security-sensitive
- Operators must protect generated artifacts
- Password handling and output storage require care
CSR signing
The caller generates the private key and sends only the CSR for signing.
Advantages:
- The CA service never handles the requester’s private key
- Better separation for systems capable of secure local generation
- Reduced key-distribution exposure
Trade-off:
- More complex client workflow
- Caller-generated keys may violate policy
- CSR parsing and validation become critical
- Provisioning is less convenient for non-technical users
Supporting both modes is useful, but they should not be treated as equivalent.
The appropriate mode depends on who controls the endpoint, how bundles are delivered, and whether local key generation can be trusted.
Policy enforcement
The daemon centralizes rules such as:
- Subject pattern
- Certificate lifetime
- Duplicate common-name handling
- Key type and size
- Key usage
- Extended key usage
- Client versus server profile
- Permitted operation
The purpose is not simply consistency.
It means that a control-plane bug must cross an additional enforcement boundary before it becomes an invalid certificate.
For example, even if the web UI allows an operator to submit an invalid common name, the daemon can reject it.
Likewise, the control plane should not be able to request:
- An unconstrained CA certificate
- An excessive validity period
- An unsupported key profile
- A server certificate under a client profile
- A duplicate subject where policy forbids it
This design is stronger than treating the daemon as a wrapper around an arbitrary OpenSSL command.
Operating-system hardening
The daemon runs under a dedicated account and uses host restrictions including:
NoNewPrivileges- Private temporary storage
- A read-only view of most of the filesystem
- Home-directory protection
- Executable-memory restrictions
- Restricted namespaces
- An empty capability bounding set
- Limited writable paths
- AF_UNIX-only communication
These controls are valuable because the daemon is privileged in a PKI sense even when it does not require Linux root privileges.
The signing key gives the process significant authority within the VPN trust model.
The hardening objective is therefore:
Give the daemon access to the smallest set of host resources required to perform certificate lifecycle operations.
This does not protect against every daemon vulnerability. It reduces what a daemon compromise can do outside the PKI state it already controls.
Administration control plane
ovpn-admin is the operator-facing Rust and Svelte control plane.
Its role is to manage:
- Operator authentication
- Sessions
- Roles
- Certificate workflows
- User-facing validation
- Connected-client visibility
- Controlled disconnect actions
- Presentation and operator feedback
It does not perform CA operations directly.
Instead, it delegates named operations to vpn-certd.
This distinction is important.
The control plane decides who may request an operation.
The daemon decides whether the requested certificate operation is valid and how it is executed.
Both layers are required.
The daemon cannot determine whether a business operator is authorized to revoke a particular user unless that context is provided. The web application should not determine certificate policy merely because it knows the operator’s role.
The architecture separates application authorization from CA policy rather than trying to solve both in one layer.
Compromise analysis
Assume the operator-facing control plane is compromised.
The attacker may gain:
- Access to application sessions
- Access to the control-plane database
- Ability to submit daemon operations available to the application
- Visibility into certificate metadata
- Ability to attempt issuance or revocation requests
The attacker does not automatically gain:
- Direct access to the intermediate private key
- Arbitrary filesystem access to CA state
- A generic OpenSSL execution interface
- Network access to a CA API
- Root-CA material
- Authority outside the daemon’s accepted operation model
This is still a serious incident.
A compromised control plane may be able to request valid certificates for unauthorized identities unless the daemon receives enough authenticated context to enforce stronger policy.
The system therefore bounds the compromise; it does not make the compromise harmless.
The remaining risk depends on:
- Socket authorization
- Daemon protocol design
- Policy expressiveness
- Audit quality
- Control-plane role enforcement
- Host integrity
- Detection of unusual issuance
Revocation is part of issuance
Certificate systems are often designed around successful issuance and treat revocation as an administrative afterthought.
That is dangerous for VPN access.
A practical lifecycle must answer:
- How does an operator identify the correct certificate?
- Which serial number is revoked?
- Which revocation reason is recorded?
- When is the CRL regenerated?
- How does OpenVPN receive the updated CRL?
- What happens if publication fails?
- Is CRL expiry monitored?
- How is the replacement certificate associated with the old one?
The suite treats revocation and CRL generation as first-class operations.
A protected signing key without a reliable revocation process produces credentials that are difficult to invalidate when users leave, devices are lost, or keys are suspected of compromise.
Auditability
Certificate operations record metadata such as:
- Subject
- Serial number
- Timestamp
- Operation type
- CSR fingerprint
- Revocation reason
This supports later review of:
- Who or what certificate was issued
- Which request produced it
- When it was revoked
- Whether a CSR changed between attempts
- Whether unusual issuance patterns occurred
The current audit model should still be understood as an operational record, not necessarily a tamper-proof security ledger.
If the daemon host is compromised, locally stored audit data may also be altered.
A stronger future design would send security events off-host or append them to a separately controlled logging system.
Failure modes
The architecture is designed to fail visibly rather than silently bypass the CA boundary.
Certificate daemon unavailable
New issuance and revocation stop.
Existing OpenVPN certificates continue to function until expiry or revocation. This is an availability failure, not an immediate trust failure.
Socket permissions incorrect
Authorized tooling cannot reach the daemon, or unauthorized local processes gain access.
This makes socket ownership and service identity part of the deployment’s security configuration.
CRL publication fails
A certificate may be marked revoked in CA state while OpenVPN continues to use an older CRL.
Monitoring CRL age and publication success is therefore as important as regenerating it.
Operational intermediate compromised
An attacker may issue trusted VPN certificates within the intermediate’s permitted scope.
Recovery requires:
- Isolating the signing service
- Preserving evidence
- Replacing the intermediate
- Reissuing affected certificates
- Updating trust and CRLs
- Investigating how the key was reached
Root material unavailable
The operational intermediate cannot be replaced when needed.
This is why offline storage must include tested recovery, not simply encrypted media placed in a drawer.
Security boundaries
| Boundary | Purpose | Remaining limitation |
|---|---|---|
| Offline root to operational intermediate | Keeps the root outside routine systems | Root recovery remains a manual operational dependency |
| Control plane to certificate daemon | Prevents direct CA-key handling by the web application | A compromised caller may still request permitted operations |
| AF_UNIX socket | Removes network exposure and enables filesystem authorization | Host compromise can cross the local boundary |
| Daemon policy to CA state | Centralizes certificate constraints | Policy defects affect all callers |
| Intermediate to OpenVPN | Limits routine issuance to the operational hierarchy | Intermediate compromise still affects all certificates it may issue |
Current status
Operational:
- Offline-root and intermediate hierarchy
vpn-certdvpn-certctl- Local Unix-socket interface
- Client certificate issuance
- Server certificate issuance
- CSR signing
- Certificate revocation
- CRL regeneration
- OpenVPN CRL integration
- Client-bundle generation
- Central policy enforcement
Under active development:
ovpn-admin- Broader administrative workflows
- Improved operator visibility
- More complete audit export
- Expanded lifecycle automation
The certificate daemon is a production-used security component. The administration layer is an evolving control plane, not a finished commercial product.