Legacy web applications: use Client Certificate Authentication, OCSP and add LDAP integration...all of this from your web server.
Hi friends,
Here we are again with another little post, but first things first... a new music recommendation so we can enjoy this damn life, Benson Boone - “Beautiful Things” (January 18, 2024)...”Please stay, I want you, I need you, oh God, Don't take, These beautiful things that I've got, Oh-oh-oh-oh, oh, oh!!!!” AHHHHH come on!
In today’s era of cybersecurity, controlling access to sensitive tools — or really, any tool — requires a robust, layered authentication mechanism. Here’s a fresh guide to securing an 'old/legacy' application with no authentication mechanisms, like NfSen, by using Apache’s ability to authenticate clients with certificates and verify user presence in an LDAP directory.
I know some of these legacy applications are like worn-out underwear, possibly with a hole — or, if you're really pushing it, with multiple holes — but still very comfortable.
However, just like with those panties or boxers, it's a good idea to limit their exposure. I also recommend controlling where your sexy underwear can be seen. Please, do not expose them directly on untrusted eyes or networks...ha,ha,ha...
While SSL/TLS client certificates validate the identity of the connecting client, I believe some level of integration with LDAP is necessary to check if the client is part of your organization's user directory. This pseudo dual-layer authentication enhances access control.
The Configuration
Below is an Apache configuration for setting up certificate-based client authentication and the use of Online Certificate Status Protocol, combined with LDAP-based user verification for accessing NfSen.
<VirtualHost *:10443>
ServerName apache2servername.home.arpa
DocumentRoot /var/www
# SSL Configuration
SSLEngine on
SSLCertificateFile /etc/apache2/certs/apache2servername.home.arpa.crt
SSLCertificateKeyFile /etc/apache2/certs/apache2servername.home.arpa.key
SSLCACertificateFile /etc/apache2/certs/internalpki.crt
SSLVerifyClient require
SSLVerifyDepth 2
SSLUserName SSL_CLIENT_S_DN_CN
SSLOCSPEnable on
SSLOCSPOverrideResponder on
SSLOCSPDefaultResponder http://ocspservername.home.arpa:80/ejbca/publicweb/status/ocsp
SSLUseStapling on
# Protocol and Cipher Reinforcement
SSLProtocol +TLSv1.3 +TLSv1.2
SSLCipherSuite ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256
SSLHonorCipherOrder on
SSLCompression off
# Security Headers
Header always set Strict-Transport-Security "max-age=31536000; includeSubDomains; preload"
Header always set X-Content-Type-Options "nosniff"
Header always set X-Frame-Options "SAMEORIGIN"
Header always set X-XSS-Protection "1; mode=block"
Header always set Content-Security-Policy "default-src 'self'; script-src 'self' 'unsafe-inline'; style-src 'self' 'unsafe-inline'; img-src 'self' data:; frame-src 'self';"
Header always set Permissions-Policy "geolocation=(), microphone=(), camera=(), fullscreen=(), payment=(), usb=()"
# Directory Configuration for /nfsen
<Directory /var/www/nfsen>
AuthName "Restricted Content"
AuthType Basic
AuthBasicProvider ldap
AuthLDAPURL ldaps://ldapservername.home.arpa:636/dc=home,dc=arpa?uid?sub?(objectClass=*)
Options -Indexes +FollowSymlinks
AllowOverride None
<RequireAll>
Require ssl-verify-client
Require ldap-user theusername
</RequireAll>
</Directory>
# Logging
LogLevel warn
ErrorLog ${APACHE_LOG_DIR}/error.log
CustomLog ${APACHE_LOG_DIR}/access.log combined
CustomLog ${APACHE_LOG_DIR}/ssl_request.log "%t %h %{SSL_PROTOCOL}x %{SSL_CIPHER}x \"%r\" %b"
</VirtualHost>
I still need to make some improvements, especially regarding the Content-Security-Policy, but for now, this is the compromise reached between security and my wife killing me because I keep wasting time on nonsense.
Certificate Authentication and the Use of OCSP
Apache, when configured correctly, can handle SSL/TLS certificate authentication, and it can also leverage the Online Certificate Status Protocol (OCSP) to verify the status of the client certificates.
Apache’s SSL configuration allows you to require clients to present a valid certificate before granting access to protected resources. This is typically done using the SSLVerifyClient directive, which controls whether and how Apache should request and verify client certificates.
OCSP is a protocol used to check the revocation status of a certificate in real time. Instead of checking a certificate against a certificate revocation list (CRL), which can be cumbersome and slow, OCSP allows Apache to query a CA's OCSP responder for real-time information about the status of a certificate. You can configure Apache to use OCSP stapling, where the server obtains and caches the OCSP response from the CA and "staples" it to the SSL/TLS handshake, improving performance and security.
How Certificate Authentication and OCSP Work Together:
Once a certificate is verified the server will check if the username extracted from certificate exists in the LDAP directory. From the previous apache configuration:
SSLUserName SSL_CLIENT_S_DN_CN → This attribute will be used as the username for:
Require ldap-user theusername
TEST ACCESS 1: CERTIFICATE OK, USER EXISTS IN LDAP
In this test we will access to nfsen application using the homemqttclient02 user certificate. The certificate is valid and the user “homemqttclient02” exists in the LDAP directory.
Here is the web server log example related to the certificate validation and status (OCSP):
[Thu Dec 05 10:40:33.240593 2024] [ssl:debug] [pid 1221547:tid 1221547] ssl_util_ocsp.c(97): [client 192.168.0.49:55074] AH01973: connecting to OCSP responder 'debiansrv01-pki01.home.arpa:80'
[Thu Dec 05 10:40:33.241390 2024] [ssl:debug] [pid 1221547:tid 1221547] ssl_util_ocsp.c(125): [client 192.168.0.49:55074] AH01975: sending request to OCSP responder
…
[Thu Dec 05 10:40:33.268068 2024] [ssl:debug] [pid 1221547:tid 1221547] ssl_util_ocsp.c(283): [client 192.168.0.49:55074] AH01987: OCSP response: got 1306 bytes, 2580 total
[Thu Dec 05 10:40:33.269297 2024] [ssl:info] [pid 1221547:tid 1221547] [client 192.168.0.49:55074] AH03239: OCSP validation completed, certificate status: good (0, -1) [subject: CN=homemqttclient02,O=HOME,C=ES / issuer: CN=debiansrv01pkisubca-G1,O=HOME,C=ES / serial: 62D7C490EAE5603DC6A6CE31F28B41F99BEE08E1 / notbefore: Jan 27 06:02:53 2024 GMT / notafter: Jan 23 06:02:52 2025 GMT]
Here is the web server log example related to the LDAP authorization:
[Thu Dec 05 10:40:33.270899 2024] [authnz_ldap:debug] [pid 1221547:tid 1221547] mod_authnz_ldap.c(692): [client 192.168.0.49:55074] AH01700: ldap authorize: Creating LDAP req structure
[Thu Dec 05 10:40:33.427019 2024] [authnz_ldap:debug] [pid 1221547:tid 1221547] mod_authnz_ldap.c(740): [client 192.168.0.49:55074] AH01703: auth_ldap authorize: require user: authorization successful
[Thu Dec 05 10:40:33.427067 2024] [authz_core:debug] [pid 1221547:tid 1221547] mod_authz_core.c(815): [client 192.168.0.49:55074] AH01626: authorization result of Require ldap-user homemqttclient02: granted
TEST ACCESS 2: CERTIFICATE OK, USER DOESN’T EXIST IN LDAP
In this test we will try access to nfsen application using the homemqttclient02 user certificate. The certificate is valid, but the user “homemqttclient02” doesn’t exist in the LDAP directory.
Here is the web server log example related to the certificate status (OCSP):
[Thu Dec 05 11:47:32.420300 2024] [authz_core:debug] [pid 1225868:tid 1225868] mod_authz_core.c(815): [client 192.168.0.49:53984] AH01626: authorization result of Require ssl-verify-client : granted
Here is the web server log example related to the LDAP authorization, in this case the user isn’t in the directory:
[Thu Dec 05 11:47:32.420418 2024] [authnz_ldap:debug] [pid 1225868:tid 1225868] mod_authnz_ldap.c(692): [client 192.168.0.49:53984] AH01700: ldap authorize: Creating LDAP req structure
[Thu Dec 05 11:47:32.587259 2024] [authnz_ldap:debug] [pid 1225868:tid 1225868] mod_authnz_ldap.c(707): [client 192.168.0.49:53984] AH01701: auth_ldap authorise: User DN not found, User not found
[Thu Dec 05 11:47:32.587333 2024] [authz_core:debug] [pid 1225868:tid 1225868] mod_authz_core.c(815): [client 192.168.0.49:53984] AH01626: authorization result of Require ldap-user homemqttclient02: denied
[Thu Dec 05 11:47:32.587343 2024] [authz_core:debug] [pid 1225868:tid 1225868] mod_authz_core.c(815): [client 192.168.0.49:53984] AH01626: authorization result of <RequireAll>: denied
[Thu Dec 05 11:47:32.587352 2024] [authz_core:debug] [pid 1225868:tid 1225868] mod_authz_core.c(815): [client 192.168.0.49:53984] AH01626: authorization result of <RequireAny>: denied
TEST ACCESS 3: CERTIFICATE KO, USER EXISTS IN LDAP
In this test we will try access to nfsen application using the homemqttclient02 user certificate. The certificate is not valid, it’s revoked, and the user “homemqttclient02” exists in the LDAP directory.
Here’s how an alpha HEMBRA/MACHO revokes certificates — we’re the best!
Here is the web server log example related to the certificate status (OCSP):
[Thu Dec 05 12:14:08.691433 2024] [ssl:error] [pid 1228985:tid 1228985] [client 192.168.0.49:47108] AH03239: OCSP validation completed, certificate status: revoked (1, 1) [subject: CN=homemqttclient02,O=HOME,C=ES / issuer: CN=debiansrv01pkisubca-G1,O=HOME,C=ES / serial: 62D7C490EAE5603DC6A6CE31F28B41F99BEE08E1 / notbefore: Jan 27 06:02:53 2024 GMT / notafter: Jan 23 06:02:52 2025 GMT]
[Thu Dec 05 12:14:08.691537 2024] [ssl:info] [pid 1228985:tid 1228985] [client 192.168.0.49:47108] AH02276: Certificate Verification: Error (23): certificate revoked [subject: CN=homemqttclient02,O=HOME,C=ES / issuer: CN=debiansrv01pkisubca-G1,O=HOME,C=ES / serial: 62D7C490EAE5603DC6A6CE31F28B41F99BEE08E1 / notbefore: Jan 27 06:02:53 2024 GMT / notafter: Jan 23 06:02:52 2025 GMT]
After this check no LDAP verification is done.
Conclusion
As you can imagine, a very important point here is the use of a PKI that allows you to enjoy sex..but.. WHAT THE HELL IS THIS! sorry, enjoy technologically speaking, the other kind of enjoyment is outside this universe.
If you've read any of my posts, you know I'm a fan of EJBCA --> “EJBCA gives you time-proven flexibility and robustness. Unlike other open-source certificate authority and PKI solutions, EJBCA is platform-independent and can be scaled up and down to match your needs.”
The EJBCA Community Edition fits well for this kind of setup (in this case a lab), but remember, production is a whole different league, and you should consider the Enterprise flavor. We’re HEMBRA/MACHO ALPHAS, but we’re not idiots... well, maybe I am, just a little.
By the way, let’s not forget our friend OpenLDAP. Without it, we’re like a scientist at a flat-earther conference—no one knows who we are.
Of course, remember that you must load the client certificate in the browser you use to access the web applications.
With the above setup, you’ve established a robust security mechanism to protect access to legacy web applications like NfSen. By combining certificate-based authentication with pseudo LDAP verification, only authenticated and authorized users can access your system...of course, not always is possible.
Documentation