Linux Admin - Create SSL Certificates

TLS and SSL Background

TLS is the new standard for socket layer security, proceeding SSL. TLS offers better encryption standards with other security and protocol wrapper features advancing SSL. Often, the terms TLS and SSL are used interchangeably. However, as a professional CentOS Administrator, it is important to note the differences and history separating each.

SSL goes up to version 3.0. SSL was developed and promoted as an industry standard under Netscape. After Netscape was purchased by AOL (an ISP popular in the 90's otherwise known as America Online) AOL never really promoted the change needed for security improvements to SSL.

At version 3.1, SSL technology moved into the open systems standards and was changed to TLS. Since copyrights on SSL were still owned by AOL a new term was coined: TLS - Transport Layer Security. So it is important to acknowledge that TLS is in fact different from SSL. Especially, as older SSL technologies have known security issues and some are considered obsolete today.

Note − This tutorial will use the term TLS when speaking of technologies 3.1 and higher. Then SSL when commenting specific to SSL technologies 3.0 and lower.

SSL vs TLS Versioning

The following table shows how TLS and SSL versioning would relate to one another. I have heard a few people speak in terms of SSL version 3.2. However, they probably got the terminology from reading a blog. As a professional administrator, we always want to use the standard terminology. Hence, while speaking SSL should be a reference to past technologies. Simple things can make a CentOS job seeker look like a seasoned CS Major.

- 3.0
1.0 3.1
1.1 3.2
1.2 3.3

TLS performs two main functions important to the users of the Internet today: One, it verifies who a party is, known as authentication. Two, it offers end-to-end encryption at the transport layer for upper level protocols that lack this native feature (ftp, http, email protocols, and more).

The first, verifies who a party is and is important to security as end-to-end encryption. If a consumer has an encrypted connection to a website that is not authorized to take payment, financial data is still at risk. This is what every phishing site will fail to have: a properly signed TLS certificate verifying website operators are who they claim to be from a trusted CA.

There are only two methods to get around not having a properly signed certificate: trick the user into allowing trust of a web-browser for a self-signed certificate or hope the user is not tech savvy and will not know the importance of a trusted Certificate Authority (or a CA).

In this tutorial, we will be using what is known as a self-signed certificate. This means, without explicitly giving this certificate the status of trusted in every web browser visiting the web-site, an error will be displayed discouraging the users from visiting the site. Then, it will make the user jump though a few actions before accessing a site with a self-signed certificate. Remember for the sake of security this is a good thing.

Install and Configure openssl

openssl is the standard for open-source implementations of TLS. openssl is used on systems such as Linux, BSD distributions, OS X, and even supports Windows.

openssl is important, as it provides transport layer security and abstracts the detailed programming of Authentication and end-to-end encryption for a developer. This is why openssl is used with almost every single open-source application using TLS. It is also installed by default on every modern version of Linux.

By default, openssl should be installed on CentOS from at least version 5 onwards. Just to assure, let's try installing openssl via YUM. Just run install, as YUM is intelligent enough to let us know if a package is already installed. If we are running an older version of CentOS for compatibility reasons, doing a yum -y install will ensure openssl is updated against the semi-recent heart-bleed vulnerability.

When running the installer, it was found there was actually an update to openssl.

[root@centos]# yum -y install openssl
Resolving Dependencies
--> Running transaction check
---> Package openssl.x86_64 1:1.0.1e-60.el7 will be updated
---> Package openssl.x86_64 1:1.0.1e-60.el7_3.1 will be an update
--> Processing Dependency: openssl-libs(x86-64) = 1:1.0.1e-60.el7_3.1 for 
package: 1:openssl-1.0.1e-60.el7_3.1.x86_64
--> Running transaction check
---> Package openssl-libs.x86_64 1:1.0.1e-60.el7 will be updated
---> Package openssl-libs.x86_64 1:1.0.1e-60.el7_3.1 will be an update
--> Finished Dependency Resolution 
Dependencies Resolved

 Package                               Arch
 Version                            Repository                        Size 
openssl                               x86_64                          
1:1.0.1e-60.el7_3.1                 updates                           713 k
Updating for dependencies:

Create Self-signed Certificate for OpenLDAP

This is a method to create a self-signed for our previous OpenLDAP installation.

To create an self-signed OpenLDAP Certificate.

openssl req -new -x509 -nodes -out /etc/openldap/certs/myldaplocal.pem -keyout
/etc/openldap/certs/myldaplocal.pem -days 365

[root@centos]# openssl req -new -x509 -nodes -out /etc/openldap/certs/vmnet.pem 
-keyout /etc/openldap/certs/vmnet.pem -days 365 
Generating a 2048 bit RSA private key
writing new private key to '/etc/openldap/certs/vmnet.pem'
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
Country Name (2 letter code) [XX]:US
State or Province Name (full name) []:Califonia
Locality Name (eg, city) [Default City]:LA
Organization Name (eg, company) [Default Company Ltd]:vmnet
Organizational Unit Name (eg, section) []:
Common Name (eg, your name or your server's hostname) []:centos
Email Address []

Now our OpenLDAP certificates should be placed in /etc/openldap/certs/

[root@centos]# ls /etc/openldap/certs/*.pem 
/etc/openldap/certs/vmnetcert.pem  /etc/openldap/certs/vmnetkey.pem

As you can see, we have both the certificate and key installed in the /etc/openldap/certs/ directories. Finally, we need to change the permissions to each, since they are currently owned by the root user.

[root@centos]# chown -R  ldap:ldap /etc/openldap/certs/*.pem
[root@centos]# ls -ld /etc/openldap/certs/*.pem
-rw-r--r--. 1 ldap ldap 1395 Feb 20 10:00 /etc/openldap/certs/vmnetcert.pem 
-rw-r--r--. 1 ldap ldap 1704 Feb 20 10:00 /etc/openldap/certs/vmnetkey.pem

Create Self-signed Certificate for Apache Web Server

In this tutorial, we will assume Apache is already installed. We did install Apache in another tutorial (configuring CentOS Firewall) and will go into advanced installation of Apache for a future tutorial. So, if you have not already installed Apache, please follow along.

Once Apache HTTPd can be installed using the following steps −

Step 1 − Install mod_ssl for Apache httpd server.

First we need to configure Apache with mod_ssl. Using the YUM package manager this is pretty simple −

[root@centos]# yum -y install mod_ssl

Then reload your Apache daemon to ensure Apache uses the new configuration.

[root@centos]# systemctl reload httpd

At this point, Apache is configured to support TLS connections on the local host.

Step 2 − Create the self-signed ssl certificate.

First, let's configure our private TLS key directory.

[root@centos]# mkdir /etc/ssl/private 
[root@centos]# chmod 700 /etc/ssl/private/

Note − Be sure only the root has read/write access to this directory. With world read/write access, your private key can be used to decrypt sniffed traffic.

Generating the certificate and key files.

[root@centos]# sudo openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout 
/etc/ssl/private/self-gen-apache.key -out /etc/ssl/certs/self-sign-apache.crt 
Generating a 2048 bit RSA private key
Country Name (2 letter code) [XX]:US
State or Province Name (full name) []:xx
Locality Name (eg, city) [Default City]:xxxx
Organization Name (eg, company) [Default Company Ltd]:VMNET
Organizational Unit Name (eg, section) []:
Common Name (eg, your name or your server's hostname) []:centos.vmnet.local
Email Address []:


Note − You can use public IP Address of the server if you don't have a registered domain name.

Let's take a look at our certificate −

[root@centos]# openssl x509 -in self-sign-apache.crt -text -noout
      Version: 3 (0x2)
      Serial Number: 17620849408802622302 (0xf489d52d94550b5e)
   Signature Algorithm: sha256WithRSAEncryption
   Issuer: C=US, ST=UT, L=xxxx, O=VMNET, CN=centos.vmnet.local
      Not Before: Feb 24 07:07:55 2017 GMT
      Not After : Feb 24 07:07:55 2018 GMT
   Subject: C=US, ST=UT, L=xxxx, O=VMNET, CN=centos.vmnet.local
   Subject Public Key Info:
      Public Key Algorithm: rsaEncryption
         Public-Key: (2048 bit)

Here is an explanation for each option we used with the openssl command −

Command Action
req -X509 Use X.509 CSR management PKI standard for key management.
-nodes Do not secure our certificate with a passphrase. Apache must be able to use the certificate without interruption of a passphrase.
-days 2555 Tells the validity of the certificate to 7 years or 2555 days. Time period can be adjusted as needed.
-newkey rsa:2048 Specified to generate both key and certificate using RSA at 2048 bits in length.

Next, we want to create a Diffie-Heliman group for negotiating PFS with clients.

[centos#] openssl dhparam -out /etc/ssl/certs/dhparam.pem 2048

This will take from 5 to 15 minutes.

Perfect Forward Secrecy − Used to secure session data in case the private key has been compromised. This will generate a key used between the client and the server that is unique for each session.

Now, add the Perfect Forward Secrecy configuration to our certificate.

[root@centos]# cat /etc/ssl/certs/dhparam.pem | tee -a /etc/ssl/certs/self-sign-apache.crt

Configure Apache to Use Key and Certificate Files

We will be making changes to /etc/httpd/conf.d/ssl.conf

We will make the following changes to ssl.conf. However, before we do that we should back the original file up. When making changes to a production server in an advanced text editor like vi or emcas, it is a best practice to always backup configuration files before making edits.

[root@centos]# cp /etc/httpd/conf.d/ssl.conf ~/

Now let's continue our edits after copying a known-working copy of ssl.conf to the root of our home folder.

  • Locate
  • Edit both DocumentRoot and ServerName as follows.
\\# General setup for the virtual host, inherited from global configuration
DocumentRoot "/var/www/html"
ServerName centos.vmnet.local:443

DocumentRoot this is the path to your default apache directory. In this folder should be a default page that will display a HTTP request asking for the default page of your web server or site.

ServerName is the server name that can be either an ip address or the host name of the server. For TLS, it is a best practice to create a certificate with a host name. From our OpenLdap tutorial, we created a hostname of centos on the local enterprise domain: vmnet.local

Now we want to comment the following lines out.


#   SSL Protocol support:
# List the enable protocol levels with which clients will be able to
# connect.  Disable SSLv2 access by default:
 ~~~~> #SSLProtocol all -SSLv2
#   SSL Cipher Suite:
#   List the ciphers that the client is permitted to negotiate.
#   See the mod_ssl documentation for a complete list.
 ~~~~> #SSLCipherSuite HIGH:MEDIUM:!aNULL:!MD5:!SEED:!IDEA

Then let Apache know where to find our certificate and private/public key pair.

Specify path to our self-signed certificate file

#   Server Certificate:
# Point SSLCertificateFile at a PEM encoded certificate.  If
# the certificate is encrypted, then you will be prompted for a
# pass phrase.  Note that a kill -HUP will prompt again.  A new
# certificate can be generated using the genkey(1) command.
~~~~> SSLCertificateFile /etc/ssl/certs/self-sign-apache.crt
specify path to our private key file
#   Server Private Key:
#   If the key is not combined with the certificate, use this
#   directive to point at the key file.  Keep in mind that if
#   you've both a RSA and a DSA private key you can configure
#   both in parallel (to also allow the use of DSA ciphers, etc.)
~~~~> SSLCertificateKeyFile /etc/ssl/private/self-gen-apache.key

Finally, we need to allow inbound connections to https over port 443.