How do I configure Apache to support SSL mutual authentication?

Solution Verified - Updated

Environment

  • Red Hat Enterprise Linux (RHEL) 6+
  • Red Hat Software Collections (RHSCL) 2.0+
  • Red Hat JBoss Web Server (JWS) 2.0+
  • Red Hat JBoss Core Services (JBCS) 2.4.6+
  • Apache httpd
    • 2.2
    • 2.4

Issue

  • How do I configure Apache to support SSL mutual authentication?

Resolution

  1. Generate the necessary SSL certificates and keys

    • Server

      1. Generate private key

        openssl genrsa -out server_key.pem 3072
        
      2. Generate public key

        openssl req -new -key server_key.pem -x509 -out server_cert.pem -days 999
        

      The file server_cert.pem is now a self signed certificate. For further detail on how to crate a proper server certificate refer to Creating a Certificate Signing Request

    • Client

      1. Generate private key

        openssl genrsa -out client_key.pem 3072
        
      2. Generate public key

        openssl req -new -key client_key.pem -x509 -out client_cert.pem -days 999
        
      3. Now, depending on the use case, the client certificate may be signed or left as it is.

        • If using unsigned client certificates, each of the certificates issued will need to be added to the trusted certificates repository of the Apache httpd server. This is more simple but may be unpractical if there are many different clients.

        • If using signed certificates, only the certificate used for signing (the root certificate) needs to be added as trusted. To sign the certificate, follow these steps:

          1. Create the root certificate. Note this is only required the first time a client certificate is going to be used. After that, the root certificate can be reused to sign as many client certificates as needed

            openssl genrsa -out CA.key 3072
            openssl req -new -x509 -days 9999 -key CA.key -out CA.crt
            
          2. Sign the client certificate using the root certificate

            openssl x509 -req -days 9999 -in client_cert.pem -CA CA.crt -CAkey CA.key -set_serial 1 -out client_cert_signed.pem
            
      4. Convert client key and certificate file into a single pkcs12 file suitable for the browser

        openssl pkcs12 -export -in client_cert.pem -inkey client_key.pem -out client.p12
        

        Remember to use -in client_cert_signed.pem instead if the client certificate was signed.

      5. Import client.p12 into the browser.

      6. Now add the certificate as trusted by copying it into the server's SSLCACertificateFile. If using the normal client certificate

        cat client_cert.pem >> trusted_certs.pem
        

        Or, if the certificate was signed, add the root certificate instead

        cat CA.crt >> trusted_certs.pem
        

        Note that, for signed certificates, this is only required the first time you issue a client certificate. Once the root certificate is trusted, it is no longer needed to modify the trusted_certs.pem as long as client certificates are signed using the same root certificate.

  2. Enable the SSL client certificate verification

       SSLEngine on
       SSLCertificateFile server_cert.pem
       SSLCertificateKeyFile server_key.pem
    
       # These options are required to setup SSL mutual auth
       SSLVerifyClient require
       SSLVerifyDepth 1
    
       # This file contains the pem formatted client certificates that are considered trusted
       SSLCACertificateFile trusted_certs.pem
    

    SSLCACertificateFile can be replaced with SSLCACertificatePath.

    SSLCACertificateFile specifies a single file that contains all of the trusted client certificates.

    SSLCACertificatePath specifies a path to a directory where the trusted client certificates are each stored in their own files. The file names used for certificates must be hashed properly (see 60529).

Diagnostic Steps

To make sure that Apache works correctly after configuring mutual authentication you can:

  • Connect with a browser after importing the p12 client certificate file.

    After connecting to the server, the browser will usually raise a dialog asking whether the stored certificate should be sent to the server for authentication. After accepting this, navigation should proceed normally.

  • If browser is not available, use openssl command with -cert and -key options

    openssl s_client -connect myserver:443 -CAfile /path/to/server_key.pem -cert /path/to/client.crt -key /path/to/client.key
    

    Note that this command will only accept the original certificate and key files and will not work with a p12 certificate file. If this is the only file available the original certificate and key files can be recovered with the following commands

    openssl pkcs12 -in client.p12 -out /path/to/client.crt -nodes
    openssl pkcs12 -in client.p12 -out /path/to/client.key -nodes -nocerts
    
  • Or curl command with --cert and --key:

    curl --cert /path/to/client.crt --key /path/to/client.key --cacert /path/to/ca.crt https://myserver:443
    
Components
Category
Tags

This solution is part of Red Hat’s fast-track publication program, providing a huge library of solutions that Red Hat engineers have created while supporting our customers. To give you the knowledge you need the instant it becomes available, these articles may be presented in a raw and unedited form.