Configure Apache Client Certificate Authentication for proxy - apache

I have 3 Backend API servers(HTTPS), API servers have different authorization permissions for different users based on user certificate, I am configuring apache to load balance the 3 backend servers, like below
<VirtualHost *:zzzz>
SSLEngine on
SSLCertificateFile /path/to/server.crt
SSLCertificateKeyFile /path/to/server.key
SSLCACertificateFile /path/to/ca.crt
SSLProxyEngine on
SSLProxyVerify none
SSLProxyCheckPeerCN off
SSLProxyCheckPeerName off
SSLProxyCheckPeerExpire off
<Proxy balancer://api_server>
BalancerMember https://xx.xx.xx.xx:yyyy
BalancerMember https://xx.xx.xx.xx:yyyy
</Proxy>
ProxyPass / balancer://api_server/
</VirtualHost>
The problem is that when a client request apache, with certificates, only the request goes to the API server, not the certificates, and API server responses unauthorized user, I tried using SSLProxyMachineCertificateFile, but it only accepts one set of certificate, and every time passes the same certificate, but in this case, the authorization happens only based on certificates.
Is there a way to blindly forward HTTPS request to API? or any other suggestions is warmly welcomed.

Transforming the comment into an answer since it solved the OP's question.
The user talks to Apache, then Apache talks to the balanced machines. That's the point of a proxy, it ensures clients do not talk to servers directly. So from the balanced server perspective, Apache is the client.
Only way I can see doing that is to use a layer 4 network load balancer which does not do SSL offloading. i.e. not Apache

Try switching to AJP instead of HTTP proxy, as explained in the Apache doc : https://httpd.apache.org/docs/2.4/en/mod/mod_proxy_ajp.html
If I understand well what you're saying, you need the client certificate to be forwarded, which is a feature of AJP :
Request Packet Structure
?ssl_cert 0x07 String

Related

Apache HTTP VM Behind HTTPS Lets Encrypt

I've read a lot of questions and answers which seem exactly the same as mine, but I can't seem to get my setup to work. I have a VM running Apache with only HTTP support at 192.168.2.101:32773. I can access it on my local network as such just fine. I now am ready to expose it through my Apache web server that has Lets Encrypt setup to generate SSL certificates. So I added this to my server conf file:
<VirtualHost *:32773>
ServerName server.com
SSLEngine on
SSLProxyEngine On
SSLCertificateFile /etc/letsencrypt/live/server.com/fullchain.pem
SSLCertificateKeyFile /etc/letsencrypt/live/server.com/privkey.pem
ProxyRequests Off
ProxyPreserveHost On
ProxyPass / http://192.168.2.101:32773/
ProxyPassReverse / http://192.168.2.101:32773/
</VirtualHost>
However, I get an ERR_SSL_PROTOCOL_ERROR when I try to load it up as https://server.com:32773. If I however change my address to http://server.com:32773, it loads just fine. Anything look wrong in this snippet? Thanks!
HTTP and HTTPS need to be on different ports. Typically HTTPS is served on port 443.
This is embarrassing... At some point I changed my port forward rules to point 32773 directly to 192.168.2.101 so I could validate that the rules were working at all. The above config worked as soon as I realized I wasn't even sending traffic to my Apache SSL enabled server.

ERR:insecure response with apache

Apache server is proxying requests to express server running on 9999
<VirtualHost *:443>
ServerName api.aonesalons.com
SSLEngine on
SSLCertificateFile /home/ec2-user/aonesalons.com.pem
SSLCertificateKeyFile /home/ec2-user/aonesalons.com.key
# <Proxy *>
# Order allow,deny
# Allow from all
# </Proxy>
ProxyPreserveHost On
ProxyRequests Off
ProxyPass / http://localhost:9999/
ProxyPassReverse / http://localhost:9999/
</VirtualHost>
If I hit, api.aonesalons.com in browser, my request goes to the server.
from my application frontend, that is also served over https by apache, when any of the api url's are called,
it always returns
ERR_FAILED or ERR_INSECURE_CONNECTION
Edit:
In browser console in security tab, the certificate is valid totally. I have tried proxying requests to the https version of the express server as well but no difference. It started happening after moving to https.
As soon I start to use Cloudflare as a proxy for api.aonesalons.com, api.aonesalons.com returns my client end application and doesn't hit my API's. I am using apache to proxy api.aonesalons.com to 9999 server and *.aonesalons.com to client folder with static application content
From the SSLLabs report for api.aonesalons.com:
Trusted - No - NOT TRUSTED
A closer look at the certificate shows:
Subject - CloudFlare Origin Certificate
Issuer - CloudFlare, Inc.
This is not a certificate intended for direct access by the public. It is trusted only by Clouldflare itself and is intended to secure the path between the Cloudflare CDN and the server protected by this CDN, see Introducing CloudFlare Origin CA.
In browser console, in security tab, certificate is valid totally.
I don't know what you did to you browser but maybe you explicitly trusted the Cloudflare CA. When visiting the site with a browser I get the expected warning:
NET::ERR_CERT_AUTHORITY_INVALID
My guess is that you've tried to protect your site with the Cloudflare CDN but failed to adjust the DNS settings properly in order to let Cloudflare manage the relevant parts of your DNS.

apache https to http Nginx

My configuration is as follows - 1 unix server with two http servers running at the same time:
apache server on ports 80 and 443
Nginx server on port 8200 (www.myserver.com:8200)
The problem is that when I log in to Nginx site I need to authorize there. Doing this over internet with no SSL is not wise... I would like to connect to my apache server with SSL, be transparently redirected to another site and authorize still having encrpyted connection.
Nginx works via http so no ssl there... I would like to have url
https://www.myserver.com/duplicati to be proxied to http://www.myserver.com:8200
Effectively I want to have:
encrypted connection from the web client to www.myserver.com
proxy connection from https://www.myserver.com/duplicati to http://www.myserver.com:8200 (unencrypted), but limited to 1 physical machine which I don't care much about encryption (or actually lack of it)
What I did was the following
What I did was the following Apache config:
ProxyRequests Off
<Proxy *>
Order deny,allow
Allow from all
</Proxy>
ProxyPass /duplicati/ http://127.0.0.1:8200/ngax/
ProxyPassReverse /duplicati/ http://127.0.0.1:8200/ngax/
<Location /duplicati/>
ProxyPassReverse /
Order deny,allow
Allow from all
</Location>
Header edit Location ^http://127.0.0.1:8200/ngax/ https://127.0.0.1:8200/ngax/
still no luck with that config....
It looks like a simple thing to do but after 5h of struggle I need to send my very first post to Stackoverflow community ;-)
Could you kindly help me with it?

Mutual TLS with Apache proxy to Tomcat

The setup I am working with involves an Apache server acting as a proxy to a tomcat server which serves several web applications. I have enabled mutual TLS on apache and I can successfully connect to one of my tomcat web applications and verify the client certificate. However, I want to take this one step further... At the moment in my ssl.conf I have a default HTTPS VirtualHost configuration which looks like this:
<VirtualHost *:443>
....
SSLEngine on
SSLCertificateFile /path/to/www_yoursite_com.crt
....
#other SSL options...
</VirtualHost>
In my modproxy.conf I have a configuration as follows:
ProxyPass /webApp1 https://localhost:1234/webApp1
ProxyPassReverse /webApp1 https://localhost:1234/webApp1
ProxyPass /webApp2 https://localhost:1234/webApp2
ProxyPassReverse /webApp2 https://localhost:1234/webApp2
where 1234 is the https port configured on a connector element on tomcat's server.xml file.
Let's assume that I only want mTLS for webApp1, the problem with this configuration is that I need a client cert on my browser even if I am accessing webApp2 so in other words I want to enable mTLS only for one web application. Even better, I would like to enable mTLS for a specific URL within my web application (is this even possible??), so for example I want mTLS required when someone hits https://myserver.com/webApp1/test/mtlsEndpoint but not on https://myserver.com/webApp1/test/otherEndpoint.
Is it possible to achieve this with another VirtualHost config for SSL on my ssl.conf ? I am going to test this tomorrow (trying to achieve this with another VirtualHost config that will proxy mTLS to my webApp1) but thought I should ask here as well to avoid trial and error and reinventing the wheel maybe this is easier than I am thinking ?
Yes, you just need separate SSL directives for webApp1 and webApp2. SSL directives can be configured in Apache right down to the directory level.

Apache 2.4 SSL Config

I've got a question regarding ssl config for apache 2.4. I got the following ssl settings for my vhost. There are more than 1 Directory but the config is mostly the same, only IPs are different. If I active the the three commented lines the apache should check the requests against the cert and not just pass the request through, correct? I assume the apache breakts the encryption for all requests from the internet and re-encrypts again to pass the request on. Am I right? Is there a way to not break the encryption and just delegate the cert checks to the next system?
RequestHeader set ClientProtocol HTTPS
SSLEngine On
SSLProtocol ALL -SSLv2 -SSLv3
SSLProxyEngine On
SSLProxyProtocol ALL -SSLv2 -SSLv3
SSLHonorCipherOrder On
SSLCipherSuite ECDHE-RSA-AES128-SHA256:AES128-GCM-SHA256:HIGH:!MD5:!aNULL:!EDH
SSLCertificateFile /path/to/file.crt
SSLCertificateKeyFile /path/to/file.key
<Directory /folder-name>
#SSLVerifyClient optional_no_ca
#SSLVerifyDepth 1
#SSLOptions +OptRenegotiate +ExportCertData
ProxyPass https://10.20.30.40:8443/
ProxyPassReverse https://10.20.30.40:8443/
</Directory>
Thanks for your help guys and regards. Sebastian
Yes, this Apache acting as a proxy terminates SSL. It then makes or reuses a pooled SSL connection to the backend.
There's no way to truly let the backend think it's handshaking with the client unless it accessed apache as a forward proxy using the mod_proxy_connect module.
Some application servers accept the body of the client certificate in a proprietary header, making that identity available in the backend server. But they are not actually authenticating it in the handshake like the proxy/apache has done.