CA Server - OpenSSL

Oct 12, 2021 · 5 mins read
CA Server - OpenSSL

In the video below, we show how to create a Certificate Authority Server using OpenSSL


A number of IT devices are managed through a web browser but these are supplied with a self-signed certificate

Aside from the annoying warning from the web browser that the certificate is not trusted, it’s not a good security practice to use self-signed certificates

Instead, if you only use signed certificates from a certificate authority your web browser trusts, you are much more likely to spot a suspicious web site, whether private or public and avoid it

Once set up properly, the CA server can issue certificates to computers on your network and you can then connect to them securely through a web browser

We will be using an Ubuntu server for this installation but OpenSSL is available on other platforms

NOTE: In a large environment it is best to set up intermediary CA servers as well
However, given the lack of interest the likes of Google has in certificate revocation, we will only create a Root CA
Because if the intermediary server is compromised, it would be easier to replace the Root CA

NOTE: Google Chrome web browser insist on a Subject Alternate Name in the certificate, even if the server has only one name

Steps taken:

  1. Create the Root CA VM
    Create a VM to install Ubuntu server for instance
    (1vCPU, 1GB RAM, 16GB HDD, 1vNIC)
    During the install process, opt to encrypt the disk and to install OpenSSH
    However, do not install any other applications when prompted

  2. Basic configuration After enabling UFW, create folders for the CA

    mkdir -p ca/{private,certs,newcerts,csr}
    chmod -v 700 ca/private
    Create an index file and serial file for the CA
    touch ca/index  
    openssl rand -hex 16 > ca/serial  

  3. Create the Root CA private key

    cd ca
    openssl genrsa -aes256 -out private/root-ca.key 4096

  4. Create the CA config file

    nano root-ca.conf
    [ ca ]
    # 'man ca'
    # Used by the ca command
    default_ca = CA_default
    
    [ CA_default ]
    # Directory and file locations
    dir = .
    certs = $dir/certs
    new_certs_dir = $dir/newcerts
    database = $dir/index
    serial = $dir/serial
    RANDFILE = $dir/private/.rand
    # RANDFILE is for storing seed data for random number generation
    
    # Root CA certificate and key locations
    certificate = $dir/certs/root-ca.crt
    private_key = $dir/private/root-ca.key
    
    # Default message digest, we'll opt for SHA2 256bits
    default_md = sha256
    
    name_opt = ca_default
    cert_opt = ca_default
    default_days = 365
    preserve = no
    policy = policy_strict
    
    [ policy_strict ]
    countryName = supplied
    stateOrProvinceName = supplied
    organizationName = supplied
    organizationalUnitName = optional
    commonName = supplied
    emailAddress = optional
    
    [ req ]
    # 'man req'
    # Used by the req command
    default_bits = 2048
    distinguished_name = req_distinguished_name
    string_mask = utf8only
    default_md = sha256
    
    # Extensions to use for -x509
    x509_extensions = server_cert
    
    [ req_distinguished_name ]
    # Certificate signing request
    countryName = Country Name (2 letter code)
    stateOrProvinceName = State or Province Name
    localityName = Locality Name
    organizationName = Organization Name
    organizationalUnitName = Organizational Unit Name
    commonName = Common Name
    emailAddress = Email Address
    # Defaults
    countryName_default = GB
    stateOrProvinceName_default = England
    organizationName_default = TempLab
    
    [ v3_ca ]
    # ' man x509v3_config'
    # Extensions for root CA
    subjectKeyIdentifier = hash
    authorityKeyIdentifier = keyid:always,issuer
    basicConstraints  = critical, CA:TRUE
    keyUsage = critical, digitalSignature, cRLSign, keyCertSign
    
    [ usr_cert ]
    # ' man x509v3_config`
    # Extensions for client certificates
    basicConstraints = CA:FALSE
    nsCertType = client, email
    nsComment = "OpenSSL Generated Client Certificate"
    subjectKeyIdentifier = hash
    authorityKeyIdentifier = keyid,issuer
    keyUsage = critical, nonRepudiation, digitalSignature, keyEncipherment
    extendedKeyUsage = clientAuth, emailProtection
    
    [ server_cert ]
    # Extensions for server certificates
    basicConstraints = CA:FALSE
    nsCertType = server
    nsComment = "OpenSSL Generated Server Certificate"
    subjectKeyIdentifier = hash
    authorityKeyIdentifier = keyid,issuer:always
    keyUsage = critical, digitalSignature, keyEncipherment
    extendedKeyUsage  = serverAuth

  5. Create the root CA self-signed certificate

    openssl req -config root-ca.conf -extensions v3_ca -key private/root-ca.key -new -x509 -days 3650 -out certs/root-ca.crt

  6. Create a server private key

    openssl genrsa -out private/testserver.key 2048

  7. Create a server CSR, using a config file

    nano csr/testserver-csr.conf
    [ req ]
    # 'man req'
    # Used by the req command
    default_bits		= 2048
    distinguished_name	= req_distinguished_name
    req_extensions		= req_ext
    prompt				= no
    
    [ req_distinguished_name ] 
    # Certificate signing request
    countryName			= GB
    stateOrProvinceName	= England
    organizationName	= TempLab
    commonName			= test.templab.lan
    
    [ req_ext ]
    subjectAltName = @alt_names
    
    [ alt_names ]
    DNS.1 = test.templab.lan
    IP.1 = 172.16.21.20
    openssl req -new -key private/testserver.key -sha256 -out csr/testserver.csr -config csr/testserver-csr.conf
    Check for the SAN
    openssl req -noout -text -in csr/testserver.csr | grep -A 1 "Subject Alt"

  8. Sign the server certificate request

    openssl ca -config root-ca.conf -notext -in csr/testserver.csr -out certs/testserver.crt -extensions req_ext -extfile csr/testserver-csr.conf
    Check for the SAN
    openssl x509 -text -noout -in certs/testserver.crt | grep -A 1 "Subject Alt"

  9. Configure web browser to trust the root CA
    Firefox
    Settings | Privacy & Security | View Certificates | Authorities | Import
    Brave
    Settings | Privacy & Security | Security | Manage certificates | Authorities | Import

  10. Upload private key and certificate to the server, configure it to use these, then test on web browser

Sharing is caring!