There are a number of articles out there that describe the process. But many seem to leave out small bits and pieces of the final solution. I am trying to cover all the bits and pieces I have learned as I have had to solve this problem for some of my own projects. 

Select where you will be holding this CA folder. I am using one separate CA for each site hosted to prevent certificate cross-contamination. There were also issues in the past where NGINX did not like to play with non-root certificate authorities.

When you choose where you want to put your CA for the service you may want to choose a common location. Especially if you are going to run multiple sites on your server. Some common places to consider putting the files include your /etc/nginx folder or the /opt folder.

You will notice that I do not have my key files encrypted. This is because I plan to have scripts be able to generate and manage my user certificates. If you are backing up your keys or storing them outside of the CA make sure you encrypt your keys. By encrypting your keys you will have to store your password for the key somewhere close by to allow recovery for the OpenSSL commands to work with the keys.  Ideally, you would now use AES256 for saving your keys. Always protect your key files, especially the root key since if you lose that key its game over and you will have to rebuild everything from scratch. If you are going to export your keys or allow your users to retrieve their keys you should password protect and encrypt your keys.

I am using one local CA for each site I plan to protect this way due to the challenges of getting a hierarchy of key chains to protect sites. If you use a common CA for multiple sites then one certificate could authenticate to more than one site. [Find the article that refers to this issue. ]

If you do choose to use one chain for a number of sites you will want to make sure the root and all intermediate certificates are included in the CA file sent to NGINX, you will also need to make sure that in the CRL file you include all the CRL files for each Root, intermediate, and final CA. If you fail to include those CRL.pem files in the one CRL.PEM file then you will find the CA authentication will fail. 

It is possible to use one configuration file to hold the configurations for multiple CAs. You would just need to make sure you specify the CA section to use when working with the CA. For simplicity, I am using one openssl.cnf file for each CA.

Also, note that when backing up the CA. Make sure to backup the entire CA. You will need key all the files to get your CA backed up and running when restored to a new location.

This part is based on the following posting.

https://arcweb.co/securing-websites-nginx-and-client-side-certificate-authentication-linux/

Going with this article I had issues getting the CRL list to behave properly and NGINX would not allow my certs to work. If you do all these items manually you will wind up with an unworkable CRL file and NGINX will not allow you certs to work with the site.

 

Important: Many users start our thinking that the user certificate is in any way related to the SSL certificate used to secure the website. This is a false assumption. The user's certificate authority can be completely separate and distinct from the CA used to sign your website traffic.

 

All the OpenSSL paths are relative to the root of the CA folder.

 

Create your CA (Certificate authority)

 

Create your openssl.conf file with the following components.

 

[ ca ]
default_ca = CA_default                 # The name of the CA configuration to be used. 
                                        # can be anything that makes sense to you.
[ CA_default ]
dir = /etc/nginx/clientssl/devmorgue    # Directory where everything is kept
certs = $dir/certs/users                # Directory where the issued certs are kept
crl_dir = $dir/crl                      # Directory where the issued crl are kept
database = $dir/index.txt               # database index file.
#unique_subject = no                    # Set to 'no' to allow creation of
                                        # several certificates with same subject.
new_certs_dir = $dir/newcerts           # Default directory for new certs.

certificate = $dir/certs/ca.crt         # The CA certificate
serial = $dir/serial                    # The current serial number
crlnumber = $dir/crlnumber              # The current crl number
                                        # must be commented out to leave a V1 CRL
crl = $dir/private/crl.pem              # The current CRL
private_key = $dir/private/ca.key       # The private key
RANDFILE    = $dir/private/.rand        # private random number file

x509_extensions = usr_cert              # The extentions to add to the cert

name_opt = ca_default                   # Subject Name options
cert_opt = ca_default                   # Certificate field options

default_days    = 365                   # how long to certify for
default_crl_days= 30                    # how long before next CRL
default_md    = sha256                  # use public key default MD
preserve    = no                        # keep passed DN ordering

policy = policy_match

####################################################################
# For the CA policy
[ policy_match ]
countryName = match
stateOrProvinceName = match
organizationName = match
organizationalUnitName = optional
commonName = supplied
emailAddress = optional

# For the 'anything' policy
# At this point in time, you must list all acceptable 'object'
# types.
[ policy_anything ]
countryName = optional
stateOrProvinceName = optional
localityName = optional
organizationName = optional
organizationalUnitName = optional
commonName = supplied
emailAddress = optional

####################################################################
[ req ]
default_bits       = 4096
default_keyfile    = cakey.pem
distinguished_name = ca_distinguished_name
x509_extensions    = ca_extensions
string_mask        = utf8only

####################################################################
[ ca_distinguished_name ]
countryName         = Country Name (2 letter code)
countryName_default = US

stateOrProvinceName         = State or Province Name (full name)
stateOrProvinceName_default = Ohio

localityName                = Locality Name (eg, city)
localityName_default        = Toledo

organizationName            = Organization Name (eg, company)
organizationName_default    = example.com

organizationalUnitName         = Organizational Unit (eg, division)
organizationalUnitName_default = Server Research Department

commonName        = Common Name (e.g. server FQDN or YOUR name)
commonName_default = Test CA

emailAddress         = Email Address
emailAddress_default = This email address is being protected from spambots. You need JavaScript enabled to view it.

[ usr_cert ]

# These extensions are added when 'ca' signs a request.

# This goes against PKIX guidelines but some CAs do it and some software
# requires this to avoid interpreting an end user certificate as a CA.

basicConstraints=CA:FALSE

# Here are some examples of the usage of nsCertType. If it is omitted
# the certificate can be used for anything *except* object signing.

# This is OK for an SSL server.
# nsCertType                    = server

# For an object signing certificate this would be used.
# nsCertType = objsign

# For normal client use this is typical
# nsCertType = client, email

# and for everything including object signing:
# nsCertType = client, email, objsign

# This is typical in keyUsage for a client certificate.
# keyUsage = nonRepudiation, digitalSignature, keyEncipherment

# This will be displayed in Netscape's comment listbox.
nsComment                       = "OpenSSL Generated Certificate

# PKIX recommendations harmless if included in all certificates.
subjectKeyIdentifier=hash
authorityKeyIdentifier=keyid,issuer

# This stuff is for subjectAltName and issuerAltname.
# Import the email address.
# subjectAltName=email:copy
# An alternative to produce certificates that aren't
# deprecated according to PKIX.
# subjectAltName=email:move

# Copy subject details
# issuerAltName=issuer:copy

#nsCaRevocationUrl              = http://www.domain.dom/ca-crl.pem
#nsBaseUrl
#nsRevocationUrl
#nsRenewalUrl
#nsCaPolicyUrl
#nsSslServerName

# This is required for TSA certificates.
# extendedKeyUsage = critical,timeStamping

In the new CA create a series of folders. 

Create the folders required for the CA. The “-p” flag in the mkdir tells the utility to create the full hierarchy specfified. This is for the certs/users folder.

mkdir -p certs/users newcerts private

This should have a folder set like so

Certs
    Users
Newcerts
Private

Create the index.txt file

touch index.txt

Create a serial number file. This contains a single number with the serial number for the next certificate. Many articles will tell you to just but 01 into here.

echo 1001 > serial

Create the CRL number file. This will be used when revoking certificates. But does need to exist.

echo 01 > crlnumber

Create the index.txt.attr file for the index.txt file.

touch index.txt.attr

Make sure all the files and folders are read and writable by the user accounts that will manage them. Whatever user will be running or executing the OpenSSL command should own the folder and its contents. Keep in mind you do what to protect this folder from accounts that should not be messing with it. Do not put it in any path that a web server would have access to. There will be files in this hierarchy that MUST be kept private.

Create your CA Private Key. ( This must be kept safe but will also need to be readable for the purposes of generating certificates.) I am using 4096 bits.

openssl genrsa -out private/ca.key 4096

This is what an unencrypted 4096 bit should look like. If you omit the length you may get a file much smaller. This example file was generated and discarded so do not expect to see this particular key ever again.

-----BEGIN RSA PRIVATE KEY----- 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 -----END RSA PRIVATE KEY-----

When you generate your private key you may get a warning about unable to write to random file. “ unable to write 'random state'

e is 65537 (0x010001) “ If you are doing this on Linux or a system with a random number generator this is fine. Openssl will try to fetch a random number from the build in random generator. See https://www.openssl.org/docs/faq.html#USER1 for more information about this.

My code does not include a passphrase. It is strongly considered to be good practice to encrypt the key with a passphrase.

The command to do this is a minor change but every time you wish to access your key you will be required to supply this passphrase. I have in my example AES256 as it is one of the strongest hashing methods. When you encrypt the key you will have to present the password each time unless you add the “ -passout pass:<mypassword>” to the line, or “-passout

file:{Some filename}” for open ssl to read the password. 

 

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

 

This is what an encrypted 4096-bit private key would look like. This particular key was generated for example but has been deleted shortly afterward.

 

-----BEGIN RSA PRIVATE KEY----- Proc-Type: 4,ENCRYPTED DEK-Info: AES-256-CBC,CB4E87231E4D49C98BAABED94937A995   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 -----END RSA PRIVATE KEY-----    

Create your new root cert

We will not create our root certificate for the service. This is the certificate we will use when we sign client certificates. The length of time is set to far in the future assuming to prevent from having to renew the root CA certificate anytime soon.

openssl req -new -x509  -days 10958 -key private/ca.key -out certs/ca.crt

You will have to answer the certificate creation questions. This will generate your root certificate.

Verify your certificate.

openssl x509 -noout -text -in certs/ca.crt

Information related to the creation of CRL (Certificate Revocation Lists) was found at https://jamielinux.com/docs/openssl-certificate-authority/certificate-revocation-lists.html

Create your CRL (Certificate Revocation List)

openssl ca -config openssl.cnf -gencrl -out private/crl.pem

Check your CRL file 

openssl crl -inform PEM -text -noout -in private/crl.pem

This post was helpful in checking this out.

https://langui.sh/2010/01/10/parsing-a-crl-with-openssl/

 

Add configuration of the user CA to NGINX

Configure NGINX to use the new CA for user authentication. Add these three lines to your NGINX configuration.

ssl_client_certificate /etc/nginx/clientssl/{websitename}/certs/ca.crt;
ssl_crl /etc/nginx/clientssl/{websitename}/private/crl.pem;
ssl_verify_client on;

You could use “ ssl_verify_client optional;” if you want the site to check the passed cert.

After making these changes make sure you check your configuration Then restart NGINX.

Note ssl_verify has an option of either On or Optional. If you choose Optional the traffic will still go through even without a certificate and it will be up to your application to check for the certificate. If you want to use the SSL certificate as an enhanced security option the Optional may be worthwhile. But if you want absolute security then On is your option.

At this point, you should not be able to get to your website and you should be getting a 400 Bad Request. With the message “No required SSL certificate was sent”.

 A recent discovery about different browsers when testing this.Wakanda Backend access with Safari not working when using certificate based authentication. based authentication from javascript when the backend port is different than the frontend port. 

Creating the user's certificate

 

Now we will create our first user certificate and test that the website will play nicely.

I will create a combination of the users key and CSR in one line. This could also be done in two lines.

openssl req -out certs/users/{username}.csr -new -newkey rsa:4096 -nodes -keyout certs/users/{username}.key

Take a look at the key and make sure it’s the right length.

cat certs/users/{username}.key

Then take a look at the CSR. Make sure the CSR is correct before signing it.

openssl req -text -noout -verify -in certs/users/{username}.csr

Now we will sign the certificate.

openssl ca -config openssl.cnf -cert certs/ca.crt -keyfile private/ca.key -in certs/users/{username}.csr

At this point in time, you will have to sign the certificate.

The new certificate will be placed in newcerts with the serial number.pem as the name of the file. This will match the serial.old.

Move the newly created certificate to your certs/users folder.

 

mv newcerts/1001.pem certs/users/{username}.crt

 

Serial will update to a new number to be used for the next certificate.

Copy the newly minted certificate to your certificates/users folder and rename to match the key.

 

Now check the certificate.

 

openssl x509 -noout -text -in certs/users/{username}.crt

 

Now we will export the certificate and user key into a p12 file.

 

openssl pkcs12 -export -clcerts -in certs/users/{username}.crt -inkey certs/users/{username}.key -out certs/users/{username}.p12

 

Note that while you can leave the password empty by just hitting the return key some athe apple keychain importer will not accept a p12 file with no password.

 

Check that the p12 file is working.

openssl pkcs12 -in certs/users/{username}.p12 -info

 

Deliver the certificate to the user.

Copy the root certificate and p12 file together and take to client computer.

 

Install the CA certificate into your system and trust the certificate. Depending on the operating system you may need to install this in the root certificates of your operating system. On Mac OS computers you can use the .mobileconfig file to install your root certificates and in doing so it will automatically install and trust the root certificates provided in the .mobileconfig file.

 

Once the certificate and CA is installed you should be able to refresh the page and have your certificate work in your local browser.

 

Remember after installing your new certificate you may need restart your browser to make sure the page loads and looks for the proper certificate to send. This is required for safari.

 

Firefox uses its own certificate system and will need to be manually installed for the user. It will not trust the certificate stores built into any running operating system.

Special extra techniques to install certificates in Firefox and Google Chrome.

 

If the certificate is working properly then you should be able to load your web page.

 

Note : Client side certificates work well in all modern browsers, but Safari has an issue where it will not check the Client SSL certificate for AJAX requests sent to a server after the main page is loaded. This may case issues with system like Wakanda who use a different port to handle data requests that the main server port.

 

Revoking a certificate.

 

Sometimes we will need to revoke a certificate that has gone rogue or for a user of office that is no longer allowed to access services.

 

First we will revoke the certificate for the user. This will kill their access to the service.

 

openssl ca -config openssl.cnf -revoke certs/users/{username}2.crt -keyfile private/ca.key -cert certs/ca.crt

 

Now at this point the certificate is revoked but we will also need to update the certificate revocation list so that NGINX of other parties checking the CRL (Certificate Revocation lIst) will know about the revocation.

You may want to run this function for each CA as a cron script either daily, or hourly depending on the security requirements of your organization. Running this in a cron function makes sure that the certificate is permanently revoked  even if the CRL generation step was missed.

 

openssl ca -config openssl.cnf -keyfile private/ca.key -cert certs/ca.crt -out private/ca.crl -crldays 1095