Lab services, internal dashboards, and development endpoints sometimes need certificates that chain to a root your own clients trust. A throwaway self-signed server certificate does not create a reusable issuing boundary, while a local certificate authority root gives controlled systems one trust anchor for certificates that will never be publicly trusted.
OpenSSL builds the local CA from an encrypted private key and a self-signed X.509 root certificate. A small configuration file supplies the subject and v3 CA extensions, so the root certificate carries critical Basic Constraints with CA:TRUE and Key Usage values for certificate and CRL signing.
Keep the root key offline or limited to the machine that issues internal certificates. pathlen:0 prevents this root from issuing subordinate CAs, and only local-ca/certs/local-ca.cert.pem should be copied to clients or trust stores. Public browsers and operating systems will not trust the root until an administrator installs it explicitly.
$ mkdir -p local-ca/private local-ca/certs $ chmod 700 local-ca/private
The private directory holds the CA signing key. The certs directory holds the public root certificate that clients may later trust.
[ req ] prompt = no distinguished_name = dn x509_extensions = v3_ca string_mask = utf8only [ dn ] C = US O = Example Corp CN = Example Local Root CA [ v3_ca ] basicConstraints = critical, CA:true, pathlen:0 keyUsage = critical, keyCertSign, cRLSign subjectKeyIdentifier = hash authorityKeyIdentifier = keyid:always,issuer
The v3_ca section makes the certificate a CA certificate and limits it to issuing end-entity certificates rather than subordinate CA certificates.
$ openssl genpkey -algorithm RSA -pkeyopt rsa_keygen_bits:4096 \ -aes-256-cbc -quiet -out local-ca/private/local-ca.key.pem Enter PEM pass phrase: Verifying - Enter PEM pass phrase:
The CA private key can sign every certificate that chains to this root. Use a strong passphrase and do not pass it as a command-line argument on shared systems.
$ chmod 400 local-ca/private/local-ca.key.pem
$ openssl req -new -x509 -sha256 -days 3650 \ -key local-ca/private/local-ca.key.pem \ -out local-ca/certs/local-ca.cert.pem \ -config local-ca/openssl-local-ca.cnf -extensions v3_ca Enter pass phrase for local-ca/private/local-ca.key.pem:
Change C, O, CN, and the validity period before creating a long-lived root for a real internal environment.
$ openssl x509 -in local-ca/certs/local-ca.cert.pem -noout \
-subject -issuer -dates -ext basicConstraints,keyUsage
subject=C=US, O=Example Corp, CN=Example Local Root CA
issuer=C=US, O=Example Corp, CN=Example Local Root CA
notBefore=Jun 5 20:36:42 2026 GMT
notAfter=Jun 2 20:36:42 2036 GMT
X509v3 Basic Constraints: critical
CA:TRUE, pathlen:0
X509v3 Key Usage: critical
Certificate Sign, CRL Sign
$ openssl verify -CAfile local-ca/certs/local-ca.cert.pem local-ca/certs/local-ca.cert.pem local-ca/certs/local-ca.cert.pem: OK
$ ls -l local-ca/certs local-ca/private local-ca/certs: total 4 -r--r--r-- 1 user user 1964 Jun 5 20:36 local-ca.cert.pem local-ca/private: total 4 -r-------- 1 user user 3446 Jun 5 20:36 local-ca.key.pem
Use local-ca/private/local-ca.key.pem only for issuing certificates. Distribute local-ca/certs/local-ca.cert.pem to clients and systems that should trust certificates signed by this local CA.