Skip to content

Instantly share code, notes, and snippets.

@eugene-taylashev
Last active April 14, 2020 02:09
Show Gist options
  • Save eugene-taylashev/4165c5675abe35aca2f566990978b11e to your computer and use it in GitHub Desktop.
Save eugene-taylashev/4165c5675abe35aca2f566990978b11e to your computer and use it in GitHub Desktop.
mini How-To: two-way TLS v1.3 for Apache server

TLS for Apache

Purpose: describe steps to configure an Apache HTTP server and cURL as clients for a two-way verification over TLS v1.3

Updated on: Apr 13, 2020

Prerequisites:

  • A server's private key, a CA chain certificate and a server's X.509 certificate with  Extended Key Usage (EKU) 'TLS Web Server Authentication'  and proper 'Subject Alternative Name' like 'DNS:srv.example.com'.

  • A client's private key and X.509 certificate with EKU 'TLS Web Client Authentication'

Out of Scope: The following will not be covered

  • Generating a server and a client X.509 certificates
  • Installing and starting an Apache HTTP server

Test environment: This mini How-To has been tested with the following:

* Apache/2.4.29 on Ubuntu 18.04.4 LTS * curl 7.69.1 with OpenSSL/1.1.1f

Preparation

Step 1: Copy the server's private key, the X.509 certificate and a CA-chain file to your OpenSSL's directories. You can find the OpenSSL root directory for your distribution with the command $openssl version -d But typically it is /etc/ssl/. Run the following as root:

#mv ./srv.key /etc/ssl/private/
#mv ./srv.crt /etc/ssl/certs/
#mv ./ca-chain.pem /etc/ssl/certs/

Step 2: Verify ownership and permission (the group ssl-cert for certificate management could be different for your distro):

#chown root:ssl-cert /etc/ssl/private/srv.key
#chmod 440 /etc/ssl/private/srv.key
#chown root:root /etc/ssl/certs/srv.crt /etc/ssl/certs/ca-chain.pem
#chmod 644 /etc/ssl/certs/srv.crt /etc/ssl/certs/ca-chain.pem

Step 3: Enable the Apache httpd's ssl-site (these steps could be different for your distro):

* Enable modules: 

#cd /etc/apache2/mods-enabled/
#ln -s ../mods-available/ssl.load ssl.load
#ln -s ../mods-available/ssl.conf ssl.conf
#ln -s ../mods-available/socache\_shmcb.load socache\_shmcb.load

* Enable the SSL site: 

#cd /etc/apache2/sites-enabled
#ln -s ../sites-available/default-ssl.conf default-ssl.conf

Case 1: A client verifies the server (one-way TLS v1.3)

Step 4: Configure the Virtual Host by editing the file /etc/apache2/sites-enabled/default-ssl.conf:

      <VirtualHost _default_:443>
      ....
          SSLEngine           on
          SSLProtocol         TLSv1.2 TLSv1.3
          SSLCertificateFile   /etc/ssl/certs/srv.crt
          SSLCertificateKeyFile /etc/ssl/private/srv.key
          SSLCertificateChainFile /etc/ssl/certs/ca-chain.pem

Step 5: Start the server: #systemctl start apache2

Step 6: From another host verify the TLS connectivity using OpenSSL: openssl s_client -showcerts -connect srv.example.com:443

Connect with cURL : curl -v --cacert /etc/ssl/certs/ca-chain.pem https://srv

Case 2: A client and the server verify each other (two-way TLS v1.3)

Step 7: For client authentication add to the file /etc/apache2/sites-enabled/default-ssl.conf:

      <VirtualHost _default_:443>
      ....
          SSLVerifyClient require
          SSLVerifyDepth  10

* For more granular access control to a directory add :

<Directory "/var/www/sam">
  SSLOptions +StdEnvVars
     `<RequireAny>
        # See https://httpd.apache.org/docs/current/mod/mod_ssl.html
        Require expr %{SSL_CLIENT_S_DN_O} == "EXAMPLE"
        #%{SSL_CLIENT_S_DN_O}  eq "My Org" 
        #and %{SSL_CLIENT_S_DN_OU} eq "My Team"
        #and %{SSL_CLIENT_S_DN_CN} eq "<ca-signed-cert>.mycompany.com"
     </RequireAny>

</Directory>

* For client specific directory-level access control add: 

<Directory "/var/www/app_developers">
 <IfDefine SSL>
   SSLRequireSSL
   SSLRequire %{SSL_CLIENT_S_DN_CN} eq "App Developers"
 </IfDefine>

</Directory>

Step 8: From another host verify the two-way TLS connectivity using cURL:

curl -v --cacert /etc/ssl/certs/ca-chain.pem \
--key /etc/ssl/private/client.key --cert /etc/ssl/certs/client.crt \
https://srv

See Also:

  • TBDef
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment