Configure Load balancer and certificate authentication in Apache

Parmeshwor Thapa
Sep 7, 2018 · 3 min read

Install Apache on Centos

[root@thapa ~]# yum install httpd mod_ssl

Test run and check status

[root@thapa ~]# /usr/sbin/apachectl start[root@thapa ~]# netstat -tupln
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name
tcp 0 0 0.0.0.0:443 0.0.0.0:* LISTEN 7848/httpd
tcp 0 0 0.0.0.0:80 0.0.0.0:* LISTEN 7848/httpd

What if service fails to start ?

[root@thapa ~]# /usr/sbin/apachectl start
Job for httpd.service failed because the control process exited with error code. See "systemctl status httpd.service" and "journalctl -xe" for details.

Check the logs with either of two commands

[root@thapa ~]# systemctl status httpd
[root@thapa ~]# journalctl -f --since "1 hour ago"

Address already in use

(98)Address already in use: AH00072: make_sock: could not bind to address 0.0.0.0:80

you cannot

[root@thapa ~]# /usr/sbin/apachectl start -p 8081Passing arguments to httpd using apachectl is no longer supported.You can only start/stop/restart httpd using this script.If you want to pass extra arguments to httpd, edit the/etc/sysconfig/httpd config file.Job for httpd.service failed because the control process exited with error code. See "systemctl status httpd.service" and "journalctl -xe" for details.

make another port (8080) listen you

[root@thapa ~]# pwd
/etc/httpd/conf
[root@thapa ~]# cp httpd.conf httpd.conf.original
[root@thapa ~]# vi httpd.conf
...
# Listen: Allows you to bind Apache to specific IP addresses and/or
# ports, instead of the default. See also the <VirtualHost>
# directive.
#
# Change this to Listen on specific IP addresses as shown below to
# prevent Apache from glomming onto all bound IP addresses.
#
#Listen 12.34.56.78:80
Listen 8080

rerun the service

[root@thapa ~]# apachectl configtest
[root@thapa ~]# /usr/sbin/apachectl stop
[root@thapa ~]# /usr/sbin/apachectl start
[root@thapa ~]# netstat -tupln|grep httpd

by the way to enable apache on system restart

[root@thapa ~]# sudo /sbin/chkconfig httpd on

Not Secure h̶t̶t̶p̶s̶://example.hostname can be accessed. lets make it Secured

[root@thapa ~]# pwd
/etc/httpd/conf.d
[root@thapa ~]# cp ssl.conf ssl.conf.original

locate .key generated during csr request and certificate procured from digicert

Key :                      example.hostname.key
Primary certificate : example.hostname.cer
Intermediate Certificate : DigiCertCA2.cer
Root Certificate : TrustedRoot.cer
Certificate chain : example.hostname.chain.pem

to create example.hostname.chain.pem file,
maintain below sequence of execution.

[root@thapa ~]# cat example.hostname.cer > example.hostname.chain.pem
[root@thapa ~]# cat DigiCertCA2.cer >> example.hostname.chain.pem
[root@thapa ~]# cat TrustedRoot.cer >> example.hostname.chain.pem

edit ssl.conf and rerun the service

<VirtualHost *:443>

# General setup for the virtual host, inherited from global configuration
#DocumentRoot "/var/www/html"
ServerName yourpage.com:443
# Server Certificate:
SSLCertificateFile /etc/httpd/conf.d/certs/example.hostname.cer
# Server Private Key:
SSLCertificateKeyFile /etc/httpd/conf.d/certs/example.hostname.key
...
</VirtualHost>

Secure https://example.hostname can be accessed . Allow only https

[root@thapa ~]# vi /etc/httpd/conf/httpd.conf

<Directory>
SSLRequireSSL
</Directory>

Client Authentication

<VirtualHost *:443>

# General setup for the virtual host, inherited from global configuration
# DocumentRoot "/var/www/html"
ServerName example.hostname:443
# Server Certificate:
SSLCertificateFile /etc/httpd/conf.d/certs/example.hostname.cer
# Server Private Key:
SSLCertificateKeyFile /etc/httpd/conf.d/certs/example.hostname.key
# Server Certificate Chain:
SSLCertificateChainFile /etc/httpd/conf.d/certs/example.hostname.chain.pem
# Certificate Authority (CA):
SSLCACertificateFile /etc/httpd/conf.d/certs/issuer.pem
...
</VirtualHost>

how to create this issuer.pem

[root@thapa ~]# cat DigiCertCA2.cer > issuer.pem
[root@thapa ~]# cat TrustedRoot.cer >> issuer.pem

see what is inside certificate

[root@thapa ~]# openssl x509 -in example.hostname.pem -text

add client authentication, validate common name of client certificate.
you can generate certificate for example.client-hostname and use that in client side.

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

<Location />
SSLRequire (%{SSL_CLIENT_S_DN_CN} in { "example.client-hostname"})
</Location>
...
</VirtualHost>

restart service. import example.hostname.p12 format client certificate in browser (firefox).

[root@thapa ~]# openssl pkcs12 -export -in example.client-hostname.chain.pem -inkey example.hostname.key -out example.client-hostname.p12

If you have load balancer then simply replace * by load balancer ip

<VirtualHost 192.168.13.10:443>
...
...
</VirtualHost>

Use apache as proxy and run application behind apache.

<VirtualHost 192.168.13.10:443>
...

SSLProxyEngine On
SSLProxyCheckPeerCN on
SSLProxyCheckPeerExpire on
ProxyPreserveHost On
#ProxyRequests Off
ProxyPass / https://app.hostname.com:8983/
ProxyPassReverse / https://app.hostname.com:8983/
</VirtualHost>

Parmeshwor Thapa

Written by

Welcome to a place where words matter. On Medium, smart voices and original ideas take center stage - with no ads in sight. Watch
Follow all the topics you care about, and we’ll deliver the best stories for you to your homepage and inbox. Explore
Get unlimited access to the best stories on Medium — and support writers while you’re at it. Just $5/month. Upgrade