APACHE web server and SSL authentication

This tutorial describes configuration techniques of module the Apache SSL module, which extends the functionality of Apache web server to support SSL protocol. The tutorial will deal with authentication of server (One-way SSL authentication), as well as it will also include authentication of clients by using certificates (Two-way SSL authentication).

In this tutorial you will learn:

  • How does SSL authentication work?
  • How to configure one way SSL authentication
  • How to configure two way SSL authentication
  • How to generate an SSL certificate
  • How to import a certificate authority into a web browser
APACHE web server and SSL authentication
APACHE web server and SSL authentication
Software Requirements and Linux Command Line Conventions
Category Requirements, Conventions or Software Version Used
System Any Linux distro
Software Apache web server, SSL module
Other Privileged access to your Linux system as root or via the sudo command.
Conventions # – requires given linux commands to be executed with root privileges either directly as a root user or by use of sudo command
$ – requires given linux commands to be executed as a regular non-privileged user

How does SSL authentication work?

If you have decided to enable the SSL ( Secure Sockets Layer ) protocol on your web server it may be because you would like to extend its functionality to achieve an integrity and confidentiality for a data transferred on unsecured networks. However, this protocol with the combination of PKI ( Public Key Infrastructure ) principles can also along the side of integrity and confidentiality provide authentication between both sides involved in the client-server communication.

One-way SSL authentication allows a SSL client to confirm an identity of SSL server. However, SSL server cannot confirm an identity of SSL client. This kind of SSL authentication is used by HTTPS protocol and many public servers around the world this way provides services such as webmail or Internet banking.

The SSL client authentication is done on a “application layer” of OSI model by the client entering an authentication credentials such as username and password or by using a grid card.

Two-way SSL authentication also known as mutual SSL authentication allows SSL client to confirm an identity of SSL server and SSL server can also confirm an identity of the SSL client. This type of authentication is called client authentication because SSL client shows its identity to SSL server with a use of the client certificate.

Client authentication with a certificate can add yet another layer of security or even completely replace authentication method such us user name and password.

In the following sections of this tutoorial, we will discuss configuration of both types of SSL authentication one-way SSL authentication and two-way SSL authentication.

Issuing OpenSSL certificates

This section briefly describes a procedure to create all required certificates using an openssl application. The whole process of issuing openssl certificates is simple. However, in case when a larger amount of issued certificates is required below described procedure would be inadequate, and therefore, I recommend for that case use OpenSSL‘s CA module.

The reader is expected to have a basic knowledge of PKI, and for that reason all steps will be described just briefly. Please follow this link if you wish to refresh your knowledge about Public key infrastructure.
  1. All certificates will be issued by using OpenSSL application and openssl.cnf configuration file. Please save this file into a directory from which you would run all openssl commands. Please note that this configuration file is optional, and we use it just to make the whole process easier.
    [ req ]
    default_md = sha1
    distinguished_name = req_distinguished_name
    [ req_distinguished_name ]
    countryName = Country
    countryName_default = SK
    countryName_min = 2
    countryName_max = 2
    localityName = Locality
    localityName_default = Bratislava
    organizationName = Organization
    organizationName_default = Linuxconfig Enterprises
    commonName = Common Name
    commonName_max = 64
    [ certauth ]
    subjectKeyIdentifier = hash
    authorityKeyIdentifier = keyid:always,issuer:always
    basicConstraints = CA:true
    crlDistributionPoints = @crl
    [ server ]
    basicConstraints = CA:FALSE
    keyUsage = digitalSignature, keyEncipherment, dataEncipherment
    extendedKeyUsage = serverAuth
    nsCertType = server
    crlDistributionPoints = @crl
    [ client ]
    basicConstraints = CA:FALSE
    keyUsage = digitalSignature, keyEncipherment, dataEncipherment
    extendedKeyUsage = clientAuth
    nsCertType = client
    crlDistributionPoints = @crl
    [ crl ]
  2. As a first step you need to generate self-signed certificate CA. Once prompted for value of “Common Name” insert string “Test CA”:

    # openssl req -config ./openssl.cnf -newkey rsa:2048 -nodes -keyform PEM -keyout ca.key -x509 -days 3650 -extensions certauth -outform PEM -out ca.cer

    If you have not encountered any complications running the above command you would find in your current directory a file ca.key with private key of certificate authority (CA) and ca.cer with its self-signed certificate.

  3. In the next step you need to generate private SSL key for the server:
    # openssl genrsa -out server.key 2048
  4. To generate Certificate Signing Request in PKCS#10 format you would use a following linux command as a common name you can specify its hostname – for example “localhost”.
    # openssl req -config ./openssl.cnf -new -key server.key -out server.req
  5. With self-signed certificate authority issue server certificate with serial number 100:
    # openssl x509 -req -in server.req -CA ca.cer -CAkey ca.key -set_serial 100 -extfile openssl.cnf -extensions server -days 365 -outform PEM -out server.cer
  6. New file server.key contains server’s private key and file server.cer is a certificate itself. Certificate Signing Request file server.req is not needed any more so it can be removed.
    # rm server.req
  7. Generete private key for SSL client:
    # openssl genrsa -out client.key 2048
  8. As for the server also for client you need to generate Certificate Signing Request and as a Common Name, I have used string: “Linuxconfig.org”.
    # openssl req -config ./openssl.cnf -new -key client.key -out client.req
  9. With your self-signed Certificate Authority, issue a client certificate with serial number 101:
    # openssl x509 -req -in client.req -CA ca.cer -CAkey ca.key -set_serial 101 -extfile openssl.cnf -extensions client -days 365 -outform PEM -out client.cer
  10. Save client’s private key and certificate in a PKCS#12 format. This certificate will be secured by a password and this password will be used in the following sections to import the certificate into the web browser’s certificate manager:

    # openssl pkcs12 -export -inkey client.key -in client.cer -out client.p12
  11. File client.p12 contains a private key and the client’s certificate, therefore files client.key, client.cer and client.req are no longer needed, so these files can be deleted.
    # rm client.key client.cer client.req

One-way SSL authentication

Once the server’s private key and certificate are ready, you can begin with SSL configuration of Apache web server. In many cases, this process is comprised of 2 steps – enabling mod_ssl and creating virtual host for port 443/TCP.

  1. Enabling mod_ssl is very easy, all you need to do is execute the following commands:
    # a2enmod ssl
    # systemctl restart
  2. You may copy and paste the following Apache configuration file, and either keep it the way it is or make the necessary changes you see fit.
    <VirtualHost _default_:443>
           ServerAdmin webmaster@localhost
            DocumentRoot /var/www
                    Options FollowSymLinks
                    Options Indexes FollowSymLinks MultiViews
            ScriptAlias /cgi-bin/ /usr/lib/cgi-bin/
                    Options +ExecCGI -MultiViews +SymLinksIfOwnerMatch
            LogLevel warn
            ErrorLog /var/log/apache2/error.log
            CustomLog /var/log/apache2/ssl_access.log combined
            SSLEngine on
            SSLCertificateFile    /etc/apache2/ssl/server.cer
            SSLCertificateKeyFile /etc/apache2/ssl/server.key
  3. In the example above directive SSLEngine on enables SSL support virtual host. Directive SSLCertificateFile defines a full path of the server’s certificate and finally directive SSLCertificateKeyFile defines a full path to server’s private key. If the private key is secured by password this password will be only needed when starting apache web server.

  4. Any changes to https.conf file such as the changes above require a web server restart. If you encounter some problems during the restart it is likely that this is due to configuration errors in your Apache conf file. The actual error should appear in deamon’s error log. Do not forget to first move your SSL files to the appropriate directory.

    # mkdir -p /etc/apache2/ssl
    # mv server.cer server.key /etc/apache2/ssl
    # systemctl restart apache2
  5. Testing of a functionality of our new configuration can be done by using a web browser. The first attempt to for connection most certainly displays an error message, that the attempt to verify server’s certificate failed because, the issuer of the certificate is unknown.

    The issuer of the certificate is unknown, resulting in an error
    The issuer of the certificate is unknown, resulting in an error
  6. Importing CA’s certificate into the web browser’s using its Certificate manager will solve this problem. To add a certificate into a Mozilla Firefox browser navigate to Setings > Privacy and Security > Certificates > View certificates.

    Importing the certificate file we generated earlier
    Importing the certificate file we generated earlier
  7. Be sure to check the “Trust this CA to identify websites” box during the process.

    Make sure you allow this certificate authority to identify websites
    Make sure you allow this certificate authority to identify websites
  8. Next attempt to connect the web server should be successful.
    Successful one way authentication to the website
    Successful one way authentication to the website

    If you want to avoid the need of importing a CA’s certificate into the web browser, you can buy server certificate from some commercial authority, which certificates are distributed by the web browser.

Two-way SSL authentication

  1. If you have decided that you will require certificate authentication from every client, all you need to do is to add following lines into a virtual host configuration file:
    SSLVerifyClient require
    SSLVerifyDepth 10
    SSLCACertificateFile /etc/apache2/ssl/ca.cer

    SSLVerifyClient require directive ensures that clients which do not provide a valid certificate from some of the trusted Certificate authorities would not be able to communicate with SSL server. Some CA rely on another CA, which may rely yet on another and so on.

    Directive SSLVerifyDepth 10 specifies how far down in the chain of CA reliance, the server will accept CA signed certificate as valid. If, for instance, SSLVerifyDepth directive will hold value 1 then the client’s certificate must be signed directly by your trusted CA. In this article, the client’s certificate is signed directly by CA and therefore the only sensible value for SSLVerifyDepth directive is 1.

    Last directive SSLCACertificateFile specifies a full path to a Certificate Authority certificate by which a client’s certificate was signed.

  2. Do not forget to restart your apache web server after any change made to its configuration files:
    # systemctl restart apache2
  3. If you try to connect to the SSL server without a client certificate an error message will pop up:

    Certificate error message in Firefox
    Certificate error message in Firefox
  4. All what needs to be done is to import previously created a client certificate in PKCS#12 form into to firefox’s certificate manager under “Your Certificates” section. This task can be done by navigating to menu then Setings > Privacy and Security > Certificates > View certificates.

    During the import, you will be asked to enter a password which had been set during the creation of the certificate. Depending on the browser version you use, you may also need to set main password for software token, which is used by the browser to safely store certificates.

  5. If you make another attempt to connect to the SSL server, browser will automatically pop-up an appropriate certificate for SSL server authentication. After the selection of a valid certificate, the connection to the SSL server will be granted.

Closing Thoughts

If you have not heard about Two-way SSL authentication yet, it is likely that after reading this article you asked yourself why is this type of SSL authentication not used often in the production environment. The answer is simple – cryptic operations used during SSL connections are difficult to process in regard to the web server resources.

It is possible to boost web server performance by so called SSL accelerators ( cards containing a processor optimized for cryptic operations). However, in many cases SSL accelerators are more expensive than the server itself and therefore, Two-way SSL authentication is not attractive to use in the web server environment.

Comments and Discussions
Linux Forum