How to create a private Root CA

Reference

https://roll.urown.net/ca/ca_root_setup.html

This article describes how to create a private Root CA which can be used to sign CSR from other servers. E.g. 192.168.2.200 has been setup as a private root CA and clients will only need to import a single public cert of 192.168.2.200 for the certs signed by it to be valid.

Check location of Open SSL conf

openssl version -d

Create Root CA directory structure

sudo mkdir -p etc/httpd/ssl/root-ca/{certreqs,certs,crl,newcerts,private}
cd etc/httpd/ssl/root-ca

Set permission for private key

sudo chmod 700 private

Create data files needed to keep track of issued certificates and serial numbers

sudo touch root-ca.index
sudo echo 00 > root-ca.crlnum

Create serial file to store next incremental serial number

sudo openssl rand -hex 16 > root-ca.serial

Create Root CA configuration file

sudo vim root-ca.cnf
# 
# OpenSSL configuration for the Root Certification Authority.
#
 
#
# This definition doesn't work if HOME isn't defined.
CA_HOME                 = .
RANDFILE                = $ENV::CA_HOME/private/.rnd
 
#
# Default Certification Authority
[ ca ]
default_ca              = root_ca
 
#
# Root Certification Authority
[ root_ca ]
dir                     = $ENV::CA_HOME
certs                   = $dir/certs
serial                  = $dir/root-ca.serial
database                = $dir/root-ca.index
new_certs_dir           = $dir/newcerts
certificate             = $dir/root-ca.crt.pem
private_key             = $dir/private/root-ca.key.pem
default_days            = 1826 # Five years
crl                     = $dir/root-ca.crl
crl_dir                 = $dir/crl
crlnumber               = $dir/root-ca.crlnum
name_opt                = multiline, align
cert_opt                = no_pubkey
copy_extensions         = copy
crl_extensions          = crl_ext
default_crl_days        = 180
default_md              = sha256
preserve                = no
email_in_dn             = no
policy                  = policy
unique_subject          = no
 
#
# Distinguished Name Policy for CAs
[ policy ]
countryName             = optional
stateOrProvinceName     = optional
localityName            = optional
organizationName        = supplied
organizationalUnitName  = optional
commonName              = supplied
 
#
# Root CA Request Options
[ req ]
default_bits            = 4096
default_keyfile         = private/root-ca.key.pem
encrypt_key             = yes
default_md              = sha256
string_mask             = utf8only
utf8                    = yes
prompt                  = no
req_extensions          = root-ca_req_ext
distinguished_name      = distinguished_name
subjectAltName          = @subject_alt_name
 
#
# Root CA Request Extensions
[ root-ca_req_ext ]
subjectKeyIdentifier    = hash
subjectAltName          = @subject_alt_name
 
#
# Distinguished Name (DN)
[ distinguished_name ]
organizationName        = example.net
commonName              = 192.168.2.200 Root Certification Authority
 
#
# Root CA Certificate Extensions
[ root-ca_ext ]
basicConstraints        = critical, CA:true
keyUsage                = critical, keyCertSign, cRLSign
#nameConstraints         = critical, @name_constraints
subjectKeyIdentifier    = hash
subjectAltName          = @subject_alt_name
authorityKeyIdentifier  = keyid:always
issuerAltName           = issuer:copy
authorityInfoAccess     = @auth_info_access
crlDistributionPoints   = crl_dist
 
#
# Intermediate CA Certificate Extensions
[ intermed-ca_ext ]
basicConstraints        = critical, CA:true, pathlen:0
keyUsage                = critical, keyCertSign, cRLSign
subjectKeyIdentifier    = hash
subjectAltName          = @subject_alt_name
authorityKeyIdentifier  = keyid:always
issuerAltName           = issuer:copy
authorityInfoAccess     = @auth_info_access
crlDistributionPoints   = crl_dist
 
#
# CRL Certificate Extensions
[ crl_ext ]
authorityKeyIdentifier  = keyid:always
issuerAltName           = issuer:copy
 
#
# Certificate Authorities Alternative Names
[ subject_alt_name ]
URI                     = http://ca.example.net/
email                   = certmaster@example.net
 
#
# Name Constraints
[ name_constraints ]
permitted;DNS.1         = 192.168.2.200
permitted;DNS.2         = example.org
permitted;DNS.3         = lan
permitted;DNS.4         = onion
permitted;email.1       = example.net
permitted;email.2       = example.org
 
#
# Certificate download addresses for the root CA
[ auth_info_access ]
caIssuers;URI           = http://ca.example.net/certs/example.net_Root_Certification_Authority.cert.pem
 
#
# CRL Download address for the root CA
[ crl_dist ]
fullname                = URI:http://ca.example.net/crl/example.net_Root_Certification_Authority.crl
 
# EOF
Change the active OpenSSL configuration

Change the active OpenSSL configuration

export OPENSSL_CONF=./root-ca.cnf

Generate private key

sudo openssl req -new -out root-ca.csr.pem

Generate Certificate Signing Request

sudo openssl req -new \ -key private/root-ca.key.pem \ -out root-ca.csr.pem

Self-sign Root Certificate

sudo openssl rand -hex 16 > root-ca.serial
sudo openssl ca -selfsign \

-in root-ca.csr.pem \

-out root-ca.crt.pem \

-extensions root-ca_ext \

-startdate `date +%y%m%d000000Z -u -d -1day` \

-enddate `date +%y%m%d000000Z -u -d +10years+1day`