How to Setup a Private CA with Signed Intermediate Certificate for Web Server TLS


1 views

In standard PKI implementations, root CAs rarely sign end-entity certificates directly. Instead, they delegate signing authority to intermediate CAs, which then issue certificates to end users. This creates a chain of trust:

Root CA
  │
  └── Intermediate CA (signed by root)
      │
      └── Server Certificate

While most public CAs won't issue intermediate certificates to individuals, some enterprise-focused providers offer this service:

  • DigiCert offers Private SSL intermediates starting at ~$2,000/year
  • Sectigo provides Managed PKI services with custom intermediates
  • GlobalSign has Enterprise SSL programs

Here's how to create your own CA hierarchy once you obtain an intermediate:

# Generate root CA (for internal use only)
openssl genrsa -out rootCA.key 4096
openssl req -x509 -new -nodes -key rootCA.key -sha256 -days 3650 -out rootCA.crt

# Generate intermediate CSR
openssl genrsa -out intermediate.key 4096
openssl req -new -key intermediate.key -out intermediate.csr

# Have public CA sign your intermediate
# (This step requires commercial arrangement)

# Sign server certificates with your intermediate
openssl x509 -req -in server.csr -CA intermediate.crt -CAkey intermediate.key \
  -CAcreateserial -out server.crt -days 365 -sha256

For your certificates to be trusted:

  1. Clients must have your intermediate cert in their trust store
  2. The intermediate must chain back to a publicly trusted root
  3. OCSP/CRL endpoints must be properly configured

Nginx configuration using intermediate chain:

server {
    listen 443 ssl;
    ssl_certificate /path/to/server.crt;
    ssl_certificate_key /path/to/server.key;
    
    # Chain file contains intermediate + root
    ssl_trusted_certificate /path/to/chain.pem;
    
    ssl_protocols TLSv1.2 TLSv1.3;
}

For smaller deployments, consider:

  • Let's Encrypt's automated certificates (free, limited to 90 days)
  • Private PKI with tools like Smallstep or Cloudflare's Origin CA
  • Hybrid approaches using public certs for external traffic and private CA for internal
  • Store root CA keys offline in hardware security modules (HSMs)
  • Implement certificate revocation (OCSP stapling, CRLs)
  • Monitor certificate expiration with tools like certbot or Nagios
  • Enforce strong cryptographic standards (SHA-256, 2048-bit+ keys)

In standard PKI implementations, browsers trust certificates signed by root Certificate Authorities (CAs) whose public keys are embedded in operating systems and browsers. The typical chain looks like:

Root CA Certificate
    ↓
Intermediate CA Certificate
    ↓
End-entity (Server) Certificate

Major CAs do offer intermediate certificate services, though with strict requirements:

  • DigiCert offers Enterprise PKI solutions starting at ~$2,000/year
  • Sectigo provides Private CA services with audit requirements
  • GlobalSign has Enterprise SSL programs for large organizations

Here's how you'd generate and use your own intermediate CA:

# Generate private key for intermediate CA
openssl genrsa -aes256 -out intermediate.key 4096

# Create CSR for intermediate certificate
openssl req -new -key intermediate.key -out intermediate.csr

# Submit CSR to commercial CA for signing
# After receiving signed intermediate.crt, create certificate chain:

cat intermediate.crt root.crt > chain.crt

Once you have the intermediate certificate, you can sign your own server certificates:

# Create server private key
openssl genrsa -out server.key 2048

# Generate CSR
openssl req -new -key server.key -out server.csr

# Sign with intermediate CA
openssl x509 -req -in server.csr -CA intermediate.crt -CAkey intermediate.key \
-CAcreateserial -out server.crt -days 365 -sha256

When deploying certificates signed by your intermediate CA:

  • Configure web servers to send the full chain (server + intermediate)
  • Set proper OCSP/must-staple extensions for revocation
  • Monitor certificate expiration dates for all issued certs
# Keep intermediate CA keys offline
mv intermediate.key /secure/offline/storage/

# Implement certificate revocation
openssl ca -config openssl.cnf -revoke compromised.crt

# Regular CRL generation
openssl ca -config openssl.cnf -gencrl -out crl.pem