Cookie consent

This website uses cookies to personalise content and to analyse traffic.

Basic (mandatory) - Cookies needed to store user preferences.
Marketing (optional) - Marketing cookies are used to track users activity and to provide them with personalized advertisements.

You can learn about cookies on our Privacy Policy page.
Cookie settings can be changed at any time by clicking the icon located at the beginning of the navigation bar at the top of the page.

LINUX
  ADMIN
    SMART
      GUIDE

Installing and customizing OpenSSL

OpenSSL is typically installed by default in Linux distributions. Currently, two different versions can be found, the new 3.0.* or the former 1.1.1*, based on distribution choice. For the sake of our discussion, they are equivalent. In Ubuntu, simply run apt list openssl to check the installed version.


root@myhost:~# apt list openssl
Listing... Done
openssl/jammy-updates,jammy-security,now 3.0.2-0ubuntu1.7 amd64 [installed]

The base directory of OpenSSL is typically /etc/ssl, in which the subdirectories certs and private are installed by default. The first one contains the updated list of public Certificate Authority (CA) certificates and the self-signed certificate ssl-cert-snakeoil.pem automatically created by the system installation procedure, while the second one is dedicated to private keys and, just after system installation, only contains ssl-cert-snakeoil.key.


root@myhost:~# cd /etc/ssl
root@myhost:/etc/ssl# ls -la
total 77
drwxr-xr-x  4 root root         5 Nov 14 15:50 .
drwxr-xr-x 69 root root       150 Nov 14 16:05 ..
drwxr-xr-x  2 root root       259 Apr 24  2022 certs
-rw-r--r--  1 root root     12419 Oct 27 19:06 openssl.cnf
drwx--x---  2 root ssl-cert     3 Apr 24  2022 private

Notice that the directory private can be entered only by the root user and by all the other users belonging to the ssl-cert group. This is for security reasons, since it contains the private keys.

Now we need to create some more directories to effectively set up our CA and the related certificates. Specifically, we need a cacerts directory for our public CA certificate, a reqs directory for certificate requests, a mycerts and a newcerts directory for storing our public certificates, and a crl directory for the certificate revocation list.


root@myhost:~# cd /etc/ssl
root@myhost:/etc/ssl# mkdir cacerts newcerts reqs mycerts crl
root@myhost:/etc/ssl# ls -la
total 90
drwxr-xr-x  9 root root         9 Nov 15 12:08 .
drwxr-xr-x 69 root root       150 Nov 14 16:05 ..
drwxr-xr-x  2 root root         2 Nov 15 12:08 cacerts
drwxr-xr-x  2 root root       259 Apr 24  2022 certs
drwxr-xr-x  2 root root         2 Nov 15 12:08 crl
drwxr-xr-x  2 root root         2 Nov 15 12:08 mycerts
drwxr-xr-x  2 root root         2 Nov 15 12:23 newcerts
-rw-r--r--  1 root root     12419 Oct 27 19:06 openssl.cnf
drwx--x---  2 root ssl-cert     3 Apr 24  2022 private
drwxr-xr-x  2 root root         2 Nov 15 12:08 reqs

As an additional security measure, the access to the directories can be restricted as follows:


root@myhost:/etc/ssl# chmod 711 cacerts crl mycerts newcerts
root@myhost:/etc/ssl# chmod 700 reqs
root@myhost:/etc/ssl# ls -la
total 90
drwxr-xr-x  9 root root         9 Nov 15 12:08 .
drwxr-xr-x 69 root root       150 Nov 14 16:05 ..
drwx--x--x  2 root root         2 Nov 15 12:08 cacerts
drwxr-xr-x  2 root root       259 Apr 24  2022 certs
drwx--x--x  2 root root         2 Nov 15 12:08 crl
drwx--x--x  2 root root         2 Nov 15 12:08 mycerts
drwx--x--x  2 root root         2 Nov 15 12:23 newcerts
-rw-r--r--  1 root root     12419 Oct 27 19:06 openssl.cnf
drwx--x---  2 root ssl-cert     3 Apr 24  2022 private
drwx------  2 root root         2 Nov 15 12:08 reqs

Now we can focus on the file openssl.cnf that is the base configuration file used by the command openssl. It is provided as a basic starting point, so we need to customize it to meet with modern certificate standards.

Run the command nano openssl.cnf, search for the block [ CA_default ] and modify the fields as highlighted in red in the following (press ctrl o and then Enter when you want to save).


[ CA_default ]
dir             = /etc/ssl              # Where everything is kept
certs           = $dir/certs            # Where the issued certs are kept
crl_dir         = $dir/crl              # Where the issued crl are kept
database        = $dir/index.txt        # database index file.
#unique_subject = no                    # Set to 'no' to allow creation of
                                        # several certs with same subject.
new_certs_dir   = $dir/newcerts         # default place for new certs.
certificate     = $dir/cacerts/cacert.pem       # 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/crl/crl.pem          # The current CRL
private_key     = $dir/private/cakey.pem   # The private key
x509_extensions = usr_cert              # The extensions to add to the cert
# Comment out the following two lines for the "traditional"
# (and highly broken) format.
name_opt        = ca_default            # Subject Name options
cert_opt        = ca_default            # Certificate field options
# Extension copying option: use with caution.
# copy_extensions = copy
# Extensions to add to a CRL. Note: Netscape communicator chokes on V2 CRLs
# so this is commented out by default to leave a V1 CRL.
# crlnumber must also be commented out to leave a V1 CRL.
# crl_extensions        = crl_ext
default_days    = 7300                  # how long to certify for
default_crl_days= 730                    # how long before next CRL
default_md      = sha256                # use public key default MD
preserve        = no                    # keep passed DN ordering
# A few difference way of specifying how similar the request should look
# For type CA, the listed attributes must be the same, and the optional
# and supplied fields are just that :-)
policy          = policy_match

Then do the same for the block [ req ].


[ req ]
default_bits            = 4096
default_md              = sha256
default_keyfile         = privkey.pem
distinguished_name      = req_distinguished_name
attributes              = req_attributes
x509_extensions = v3_ca # The extensions to add to the self signed cert
# Passwords for private keys if not present they will be prompted for
# input_password = secret
# output_password = secret
string_mask = utf8only
# req_extensions = v3_req # The extensions to add to a certificate request

Some defaults for your company can be added in the block [ req_distinguished_name ] (see the examples in red color).


[ req_distinguished_name ]
countryName                     = Country Name (2 letter code)
countryName_default             = US
countryName_min                 = 2
countryName_max                 = 2

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

localityName                    = Locality Name (eg, city)
localityName_default            = San Francisco

0.organizationName              = Organization Name (eg, company)
0.organizationName_default      = My Company

organizationalUnitName          = Organizational Unit Name (eg, section)
#organizationalUnitName_default =

commonName                      = Common Name (e.g. server FQDN or YOUR name)
commonName_max                  = 64

emailAddress                    = Email Address
emailAddress_max                = 64
emailAddress_default            = netadmin@mycompany.com

The commonName field represents the unique identifier of a certificate, so each issued certificate must have its own unique one.

Now continue to the block [ v3_ca ] where key usages for the CA key are set, and add the following red line.


[ v3_ca ]

# Extensions for a typical CA

# PKIX recommendation.
subjectKeyIdentifier=hash
authorityKeyIdentifier=keyid:always,issuer
basicConstraints = critical,CA:true

# Key usage: this is typical for a CA certificate. However since it will
# prevent it being used as an test self-signed certificate it is best
# left out by default.
# keyUsage = cRLSign, keyCertSign
keyUsage = digitalSignature, cRLSign, keyCertSign

Finally, what remains to be defined are key usages and additional parameters required by client certificates, that is, certificates to be used by servers (machines offering services) and users (people asking for services). Those parameters will be added during the signing process carried out by the CA, so we will need to go back to the block [ usr_cert ] and to add two different sections, one for server certificates and another one for user certificates, that will need to be selectively commented/uncommented and set before issuing the certificate, depending on its final use.

In the block below, the rows needed for issuing a server certificate are represented in red color and uncommented, while the rows needed for issuing a user certificate are depicted in orange and commented out. So, this set up is for a server certificate. If a user certificate is to be issued, the server section must be commented out and the user section uncommented.


[ 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

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

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

##### for SERVER certificate ######
nsCertType = server
keyUsage = digitalSignature, keyEncipherment
extendedKeyUsage = serverAuth, clientAuth, ipsecIKE
subjectAltName = DNS:myhost.mycompany.com, DNS:www.mycompany.com

##### for USER certificate ######
#nsCertType = client, email
#keyUsage = nonRepudiation, digitalSignature, keyEncipherment, dataEncipherment
#extendedKeyUsage = clientAuth, emailProtection
#subjectAltName = email:mary.white@mycompany.com, email:mary@mycompany.com

# 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

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

Looking at the server section, the Key Usage (KU) is set to digitalSignature and keyEncipherment, stating that the certificate can be used to apply a digital signature for entity authentication and to encrypt a symmetric key to be exchanged between two entities, respectively. The Extended Key Usage (EKU) could be set to only serverAuth, stating that the entity can only act as service provider. If clientAuth is also added, the entity can use the same certificate to ask for services. This is useful if, as an example, you are setting up a mail server that needs to connect to an LDAP server for users authentication; if both of serverAuth and clientAuth are set, the same certificate can be used to authenticate both towards people using mail service and towards the LDAP server. Moreover, if the certificate has to be used to set up an IPsec connection, the ipsecIKE token needs to be added.

For the user section, things are more or less the same. In the KU, nonRepudiation and dataEncipherment are added to also include data signing and encryption qualifications. In the EKU, only clientAuth is specified because a person can only act as a client; emailProtection is also added to qualify the certificate for email signing and encryption.

Finally, the subjectAltName indicates alternative names for which the certificate has to be considered valid, in addition to the certificate commonName. It is a comma separated list of tokens followed by the parameter value. For server usage, the DNS: is the most important token, specifying alternative names in terms of DNS name resolution. In the above example, the server certificate to be created can also authenticate servers whose IP address verifies to either of myhost.mycompany.com and www.mycompany.com, in addition to the certificate common name that, for servers, is typically a DNS name itself. For user usage, the most commonly used token is email: that allows to link the certificate to the user's email addresses, thus permitting the commonName field to be set to the natural name of the person (Mary White in the example).

The nsCertType field is an old Netscape-specific extension, that is currently no longer used but can be added the same.

In the [ usr_cert ], additional parameters can also be specified. The nsComment allows to include a generic comment, while nsCaRevocationUrl permits to specify the complete URL of the certificate revocation list, provided that a public web server responding to the address is set up.


[ usr_cert ]

...

nsComment         = "OpenSSL Generated Certificate"
nsCaRevocationUrl = http://ca.mycompany.com/crl.pem

We have now configured the OpenSSL environment and we can proceed to the next section to create our CA.

DISCLAIMER

The material and methods reported in Linux Admin Smart Guide, even if tested, are provided without any guarantee. All the commands are run as privileged (root) user, so it is highly recommended to try them first on non-production machines and, in any case, to always do backups first. Linux Admin Smart Guide is not responsible for any damage or data loss caused by misformulated commands or inadvertently launched commands.

To gain a root shell, run the command sudo su -l from the shell of a regular user who is included in the sudoers list, or simply the command su -l and then providing the root password.


< Prev Next >