Create a CA
Create the file and directory structure
mkdir -p /root/ca/{certs,crl,newcerts,private} /root/ca/intermediate/{certs,crl,csr,newcerts,private}
chmod 700 /root/ca/private /root/ca/intermediate/private
:>/root/ca/index.txt; :>/root/ca/intermediate/index.txt
echo 1000 > /root/ca/serial; echo 1000 > /root/ca/intermediate/serial
echo 1000 > /root/ca/intermediate/crlnumber
Create the root certificate
Paste the following contents into /root/ca/root_ca.cnf
# OpenSSL root CA configuration file.
# Copy to `/root/ca/root_ca.cnf`.
[ ca ]
default_ca = CA_default
[ CA_default ]
# Directory and file locations.
dir = /root/ca
certs = $dir/certs
crl_dir = $dir/crl
new_certs_dir = $dir/newcerts
database = $dir/index.txt
serial = $dir/serial
RANDFILE = $dir/private/.rand
# The root key and root certificate.
private_key = $dir/private/root_ca.key
certificate = $dir/certs/root_ca.crt
# For certificate revocation lists.
crlnumber = $dir/crlnumber
crl = $dir/crl/ca.crl.pem
crl_extensions = crl_ext
default_crl_days = 30
# SHA-1 is deprecated, so use SHA-2 instead.
default_md = sha256
name_opt = ca_default
cert_opt = ca_default
default_days = 375
preserve = no
policy = policy_strict
[ policy_strict ]
# The root CA should only sign intermediate certificates that match.
# See the POLICY FORMAT section of `man ca`.
countryName = optional
stateOrProvinceName = optional
organizationName = optional
organizationalUnitName = optional
commonName = supplied
emailAddress = optional
[ policy_loose ]
# Allow the intermediate CA to sign a more diverse range of certificates.
# See the POLICY FORMAT section of the `ca` man page.
countryName = optional
stateOrProvinceName = optional
localityName = optional
organizationName = optional
organizationalUnitName = optional
commonName = supplied
emailAddress = optional
[ req ]
# Options for the `req` tool (`man req`).
default_bits = 2048
distinguished_name = req_distinguished_name
string_mask = utf8only
# SHA-1 is deprecated, so use SHA-2 instead.
default_md = sha256
# Extension to add when the -x509 option is used.
x509_extensions = v3_ca
[ req_distinguished_name ]
# See <https://en.wikipedia.org/wiki/Certificate_signing_request>.
commonName = Common Name
countryName = Country Name (2 letter code)
stateOrProvinceName = State or Province Name
localityName = Locality Name
0.organizationName = Organization Name
organizationalUnitName = Organizational Unit Name
emailAddress = Email Address
# Optionally, specify some defaults.
countryName_default =
stateOrProvinceName_default =
localityName_default =
0.organizationName_default =
organizationalUnitName_default =
emailAddress_default =
[ v3_ca ]
# Extensions for a typical CA (`man x509v3_config`).
subjectKeyIdentifier = hash
authorityKeyIdentifier = keyid:always,issuer
basicConstraints = critical, CA:true
keyUsage = critical, cRLSign, keyCertSign
[ v3_intermediate_ca ]
# Extensions for a typical intermediate CA (`man x509v3_config`).
subjectKeyIdentifier = hash
authorityKeyIdentifier = keyid:always,issuer
basicConstraints = critical, CA:true, pathlen:0
keyUsage = critical, cRLSign, keyCertSign
[ usr_cert ]
# Extensions for client certificates (`man x509v3_config`).
basicConstraints = CA:FALSE
subjectKeyIdentifier = hash
authorityKeyIdentifier = keyid,issuer
keyUsage = critical, nonRepudiation, digitalSignature, keyEncipherment
extendedKeyUsage = clientAuth, emailProtection
[ server_cert ]
# Extensions for server certificates (`man x509v3_config`).
basicConstraints = CA:FALSE
subjectKeyIdentifier = hash
authorityKeyIdentifier = keyid,issuer:always
keyUsage = critical, nonRepudiation, digitalSignature, keyEncipherment
extendedKeyUsage = serverAuth
[ crl_ext ]
# Extension for CRLs (`man x509v3_config`).
authorityKeyIdentifier=keyid:always
[ ocsp ]
# Extension for OCSP signing certificates (`man ocsp`).
basicConstraints = CA:FALSE
subjectKeyIdentifier = hash
authorityKeyIdentifier = keyid,issuer
keyUsage = critical, digitalSignature
extendedKeyUsage = critical, OCSPSigning
Create the root CA key
openssl genpkey -aes256 -algorithm ED25519 -out private/root_ca.key
chmod 400 private/root_ca.key
Create the root CA certificate
openssl req -config root_ca.cnf -new -x509 -extensions v3_ca -days 14600 -key private/root_ca.key -out certs/root_ca.crt
Common Name []:Pwned Global Root CA
Country Name (2 letter code) []:
State or Province Name []:
Locality Name []:
Organization Name []:
Organizational Unit Name []:
Email Address []:
chmod 444 certs/root_ca.crt
Verify the root certificate
openssl x509 -text -noout -in certs/root_ca.crt
Create the intermediate certificate
Paste this into /root/ca/intermediate/intermediate_ca.cnf
# OpenSSL intermediate CA configuration file.
# Copy to `/root/ca/intermediate/intermediate_ca.cnf`
[ ca ]
default_ca = CA_default
[ CA_default ]
# Directory and file locations.
dir = /root/ca/intermediate
certs = $dir/certs
crl_dir = $dir/crl
new_certs_dir = $dir/newcerts
database = $dir/index.txt
serial = $dir/serial
RANDFILE = $dir/private/.rand
# The root key and root certificate.
private_key = $dir/private/intermediate_ca.key
certificate = $dir/certs/intermediate_ca.crt
# For certificate revocation lists.
crlnumber = $dir/crlnumber
crl = $dir/crl/intermediate.crl.pem
crl_extensions = crl_ext
default_crl_days = 30
# SHA-1 is deprecated, so use SHA-2 instead.
default_md = sha256
name_opt = ca_default
cert_opt = ca_default
default_days = 375
preserve = no
policy = policy_loose
copy_extensions = copy
[ policy_strict ]
# The root CA should only sign intermediate certificates that match.
# See the POLICY FORMAT section of `man ca`.
countryName = optional
stateOrProvinceName = optional
organizationName = optional
organizationalUnitName = optional
commonName = supplied
emailAddress = optional
[ policy_loose ]
# Allow the intermediate CA to sign a more diverse range of certificates.
# See the POLICY FORMAT section of the `ca` man page.
countryName = optional
stateOrProvinceName = optional
localityName = optional
organizationName = optional
organizationalUnitName = optional
commonName = supplied
emailAddress = optional
[ req ]
# Options for the `req` tool (`man req`).
default_bits = 2048
distinguished_name = req_distinguished_name
string_mask = utf8only
# SHA-1 is deprecated, so use SHA-2 instead.
default_md = sha256
# Extension to add when the -x509 option is used.
x509_extensions = v3_ca
[ req_distinguished_name ]
# See <https://en.wikipedia.org/wiki/Certificate_signing_request>.
commonName = Common Name
countryName = Country Name (2 letter code)
stateOrProvinceName = State or Province Name
localityName = Locality Name
0.organizationName = Organization Name
organizationalUnitName = Organizational Unit Name
emailAddress = Email Address
# Optionally, specify some defaults.
countryName_default =
stateOrProvinceName_default =
localityName_default =
0.organizationName_default =
organizationalUnitName_default =
emailAddress_default =
[ v3_ca ]
# Extensions for a typical CA (`man x509v3_config`).
subjectKeyIdentifier = hash
authorityKeyIdentifier = keyid:always,issuer
basicConstraints = critical, CA:true
keyUsage = critical, cRLSign, keyCertSign
[ v3_intermediate_ca ]
# Extensions for a typical intermediate CA (`man x509v3_config`).
subjectKeyIdentifier = hash
authorityKeyIdentifier = keyid:always,issuer
basicConstraints = critical, CA:true, pathlen:0
keyUsage = critical, cRLSign, keyCertSign
[ usr_cert ]
# Extensions for client certificates (`man x509v3_config`).
basicConstraints = CA:FALSE
subjectKeyIdentifier = hash
authorityKeyIdentifier = keyid,issuer
keyUsage = critical, nonRepudiation, digitalSignature, keyEncipherment
extendedKeyUsage = clientAuth, emailProtection
[ server_cert ]
# Extensions for server certificates (`man x509v3_config`).
basicConstraints = CA:FALSE
subjectKeyIdentifier = hash
authorityKeyIdentifier = keyid,issuer:always
keyUsage = critical, nonRepudiation, digitalSignature, keyEncipherment
extendedKeyUsage = serverAuth
#authorityInfoAccess = OCSP;URI:http://ocsp2.example.com
[ crl_ext ]
# Extension for CRLs (`man x509v3_config`).
authorityKeyIdentifier=keyid:always
[ ocsp ]
# Extension for OCSP signing certificates (`man ocsp`).
basicConstraints = CA:FALSE
subjectKeyIdentifier = hash
authorityKeyIdentifier = keyid,issuer
keyUsage = critical, digitalSignature
extendedKeyUsage = critical, OCSPSigning
Create the intermediate CA key
cd /root/ca/intermediate
openssl genpkey -aes256 -algorithm ED25519 -out private/intermediate_ca.key
chmod 400 private/intermediate_ca.key
Create the intermediate CA CSR
openssl req -config intermediate_ca.cnf -new -key private/intermediate_ca.key -out csr/intermediate_ca.csr
Common Name []:Pwned Global Intermediate CA
Country Name (2 letter code) []:
State or Province Name []:
Locality Name []:
Organization Name []:
Organizational Unit Name []:
Email Address []:
Sign the intermediary CA CSR to create the intermediate cert
cd /root/ca
openssl ca -config root_ca.cnf -extensions v3_intermediate_ca -days 3650 \
-notext -in intermediate/csr/intermediate_ca.csr -out intermediate/certs/intermediate_ca.crt
chmod 444 intermediate/certs/intermediate_ca.crt
Verify the intermediate CA cert
openssl x509 -noout -text -in intermediate/certs/intermediate_ca.crt
Create chain file
cat intermediate/certs/intermediate_ca.crt certs/root_ca.crt > intermediate/certs/ca-chain.pem
Create server (leaf) certificate
Create a key for your certificate
cd /root/ca
openssl genpkey -algorithm ED25519 -out intermediate/private/www.example.com.key
chmod 400 intermediate/private/www.example.com.key
Create the certificate sign request
openssl req -config intermediate/intermediate_ca.cnf -key intermediate/private/www.example.com.key -new \
-out intermediate/csr/www.example.com.csr -addext "subjectAltName = DNS:example.com,DNS:www.example.com"
Common Name []:www.example.com
Country Name (2 letter code) []:
State or Province Name []:
Locality Name []:
Organization Name []:
Organizational Unit Name []:
Email Address []:
Sign the certificate
openssl ca -config intermediate/intermediate_ca.cnf -extensions server_cert -days 365 \
-notext -in intermediate/csr/www.example.com.csr -out intermediate/certs/www.example.com.crt
Verify the certificate
openssl x509 -text -noout -in intermediate/certs/www.example.com.crt
Create the fullchain cert
cat intermediate/certs/www.example.com.crt intermediate/certs/ca-chain.pem > intermediate/certs/www.example.com.pem