Authentication Using Apache HTTPD
Published: 2021-08-25 07:51:39

## Table Of Contents
   * [Standard Authentication vs Mutual Authentication](#intro)
   * [Standard (One-Way) SSL Authentication](#oneway)
   * [Two-way (mutual) SSL Authentication](#twoway)


In this short article authentication of a client using Apache HTTPD will be described.

# Standard Authentication vs Mutual Authentication <a name="intro"></a>

Standard authentication (also known as one-way SSL authentication) is an authentication protocol in which only the client verifies the server certificate. Mutual authentication (two-way SSL authentication), on the other hand, is the authentication protocol in which two parties authenticate each other. It is the default mode of authentication in some protocols (such as IKE, SSH) and optional in some others (such as TLS).

# Standard (One-Way) SSL Authentication <a name="oneway"></a>

## Server Side

### Requirements
* An Apache HTTPD installation with mod_ssl
* Self-signed or CA signed server certificate

### Preparing the Certificate
* Create root certificate
   * openssl req -new -x509 -extensions v3_ca -keyout cakey.key -out cacert.pem
* Create server key and sign request
   * openssl req -new -nodes -out server-req.pem -keyout server-key.key
* Self sign the certificate
   * openssl ca -out server-cert.pem -infiles server-req.pem

```
Here, only a summary of certificate preparation steps provided. You can find many detailed documents about this process on the internet. Note that self-signed certificates are only for test purposes. Using them at production is discouraged.
```

### Apache HTTPD Implementation
* Configure "ssl.conf" file and add the following lines at the end of the "VirtualHost" section.

```
# SSL CONFIGURATION – SERVER SIDE
# Enable the single way SSL authentication
SSLEngine on

# Apache client CA certificate
SSLCertificateFile "/etc/httpd/conf/server-cert.pem"

# Apache client CA certificate private key file
SSLCertificateKeyFile  "/etc/httpd/conf/server-key.key"

# END OF SSL CONFIGURATION – SERVER SIDE
```
* Restart apache HTTPD for changes to be applied
   * systemctl restart httpd

## Client-Side (Proxy)
There is no special action to be taken at the client-side.

# Two-way (mutual) SSL Authentication <a name="twoway"></a>

## Server Side

### Requirements
* An Apache HTTPD installation with mod_ssl
* Self-Signed or CA Signed server certificate

### Prepare Certificate
* Create root certificate
   * openssl req -new -x509 -extensions v3_ca -keyout cakey.key -out cacert.pem
* Create server key and sign request
   * openssl req -new -nodes -out server-req.pem -keyout server-key.key
* Self sign the certificate
   * openssl ca -out server-cert.pem -infiles server-req.pem

```
Here, only a summary of certificate preparation steps provided. You can find many detailed documents about this process on the internet. Note that self-signed certificates are only for test purposes. Using them at production is discouraged.
```

### Apache HTTPD Implementation
* Configure "ssl.conf" file and add the following lines at the end of the "VirtualHost" section.

```
# SSL CONFIGURATION – SERVER SIDE
# Enable the single way SSL authentication
SSLEngine on

# Apache client CA certificate
SSLCertificateFile "/etc/httpd/conf/server-cert.pem"

# Apache client CA certificate private key file
SSLCertificateKeyFile  "/etc/httpd/conf/server-key.key"

# END OF SSL CONFIGURATION – SERVER SIDE
```
* Restart apache HTTPD for changes to be applied
   * systemctl restart httpd

## Client-Side (Proxy)

### Requirements
* An Apache HTTPD installation with mod_ssl and mod_proxy
* Self-Signed or CA Signed certificate from the server
* Self-Signed or CA Signed certificate for client
* CN of the server certificate

### Prepare Certificates
* Generate key longer than or equal to 2048 bits
   * openssl genrsa -aes256 -out partner-domain.key 2048
```crmsh
CN is very important here. Check the sample below. CN is provided by the server as 'partner-domain'.

Country Name (2 letter code) [XX]:TR
State or Province Name (full name) []:Marmara
Locality Name (eg, city) [Default City]:Istanbul
Organization Name (eg, company) [Default Company Ltd]:Telenity
Organizational Unit Name (eg, section) []:Telenity
Common Name (eg, your name or your server's hostname) []:partner-domain
Email Address []:
Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []:
An optional company name []:
```

* Generate certificate sign request
   * openssl req -key partner-domain.key -new -sha256 -out partner-domain.csr
* Convert key to RSA key
   * openssl rsa -in partner-domain.key -outform pem > partner-domain-rsa.key
```
Apache HTTPD only supports keys encoded in PKCS1 RSA, DSA or EC formats. Keys encoded in PKCS8 format (ie. starting with "-----BEGIN PRIVATE KEY-----") must be converted to a supported format.
```

* Sign the certificate
   * Self-Sign: openssl x509 -signkey partner-domain.key -in partner-domain.csr -req -out partner-domain.crt
   * CA-Sign: Send CSR file to the Authentication server provider.

### Apache HTTPD Implementation
* Merge the key and the certificate received from server
   * cat partner-domain-rsa.key partner-domain.ca > partner-domain-includekey.pem
```
The order of the key and the certificate does not matter. Two restrictions are

1. RSA key must be used
2. The merged file name must denote that it contains both the key and the certificate.
```

* Configure "ssl.conf" file and add the following lines at the end of the "VirtualHost" section.

```
# SSL CONFIGURATION – CLIENT SIDE
# Enable SSL Client on this virtualhost (the traffic to the backends can be encrypted)
SSLProxyEngine on
 
# It’s mandatory for apache to authenticate the backends’ certificate.
SSLProxyVerify require
 
# Specify the depth of the check if the certificate has an CA approval
SSLVerifyDepth  10
 
# If CN and hostname will not match below configs must be off. Default values are on
SSLProxyCheckPeerCN off
SSLProxyCheckPeerName off
 
# Apache client CA certificate (certificate of who released your client certificate)
SSLProxyMachineCertificateFile "/etc/httpd/conf/partner-domain-includekey.pem"
# Backends’ CA certificates (list of certificates of who released your backends’ certificates)
SSLProxyCACertificateFile "/etc/httpd/conf/thirdparty-cert-provided-by-server.cert.pem"
 
# END OF SSL CONFIGURATION – CLIENT SIDE
```

```
Refer to the official Apache documentation at https://httpd.apache.org/docs/current/mod/mod_ssl.html.
```

* Add the related proxy definition inside "proxy.conf" file
```
ProxyPass        /secureendpoint https://api.partner-domain/secureapi
ProxyPassReverse /secureendpoint https://api.partner-domain/secureapi
```

* Restart apache HTTPD for changes to be applied
   * systemctl restart httpd