LinuxQuestions.org

LinuxQuestions.org (/questions/)
-   Linux - Server (https://www.linuxquestions.org/questions/linux-server-73/)
-   -   Apache 2.4 as reverse proxy for certificate based authentication (https://www.linuxquestions.org/questions/linux-server-73/apache-2-4-as-reverse-proxy-for-certificate-based-authentication-4175599270/)

lpwevers 02-08-2017 07:05 AM

Apache 2.4 as reverse proxy for certificate based authentication
 
Dear experts,

I'm provided with a challenge that still, after hours of searching and trying is still not fixed. What I'm trying to do is the following:

I have a commercial product called Syslink Xandria, which is basically a web application hosted in the Jetty application server. (Version 8.x). For security, I'm trying to setup authentication using client certificates. Now, I did manage to set this up in the Xandria server. However it only works if I contact the server directly. For the internal network this is fine, however, for outside access we access it using a reverse proxy server in the DMZ.

Now that's where the problems start. I can't seem to get the reverse proxy to pass the client certificate on to the backend server. My reverse proxy is apache 2.4 running on Linux. For this particular VHost I have the following configuration:

Code:

<VirtualHost *:443>
    Timeout 5400
    ProxyTimeout 5400

    ServerAdmin            support@xxxxx.nl
    ServerName              xandria.xxxxx.nl
    ServerAlias            digs107.xxxxx.local
    SSLEngine              on
    SSLProtocol            all -SSLv2 -SSLv3
    SSLCipherSuite          ALL:!aNULL:!eNULL:!SSLv2:!LOW:!EXP:!MD5:@STRENGTH
    SSLCertificateFile      /etc/apache2/ssl.crt/xandria.crt
    SSLCertificateKeyFile  /etc/apache2/ssl.key/xandria.key
    SSLCertificateChainFile /etc/apache2/ssl.crt/xxxxx-CAconcatenated.pem
    SSLCACertificateFile    /etc/apache2/ssl.crt/xxxxx-CAconcatenated.pem
    SSLVerifyClient        optional
    SSLVerifyDepth          4
    SSLProxyEngine          On
    SSLProxyVerify          none
    RequestHeader          set X-Forwarded-Proto 'https'
    SSLProxyCheckPeerCN    off
    SSLProxyCheckPeerName  off
    SSLProxyVerify          none
    SSLProxyCheckPeerCN    off
    SSLProxyCheckPeerName  off
    SSLProxyCheckPeerExpire off
    ProxyPreserveHost      On
    ProxyBadHeader          Ignore

    <Location />
      ProxyPass            https://digs107/ retry=0 timeout=5 KeepAlive=On
      ProxyPassReverse      https://digs107/
    </Location>
</VirtualHost>

I've heard of people getting similar constructions to work, however, in their configuration they could use normal http traffic on the internal network. I however can't as the vendor of Xandria does not allow certificate based logins when coming over an unencrypted line.

If anyone can help that will be greatly appreciated.

r3sistance 02-08-2017 07:31 AM

What does "curl -v -k https://digs107" return from the Apache Proxy box? First thing to verify is that the box itself can connect. If that works, drop the insecure flag (-k) and try again, if the first works and second doesn't then it's an issue verifying the certificate on digs107.

lpwevers 02-09-2017 03:47 AM

Quote:

Originally Posted by r3sistance (Post 5667097)
What does "curl -v -k https://digs107" return from the Apache Proxy box? First thing to verify is that the box itself can connect. If that works, drop the insecure flag (-k) and try again, if the first works and second doesn't then it's an issue verifying the certificate on digs107.

Hi,

Thanks for the tip. Indeed there seems to be an issue with the certificate on the digs107 server:
Code:

curl -v -k https://digs107
* Rebuilt URL to: https://digs107/
* Hostname was NOT found in DNS cache
*  Trying 172.29.38.107...
* Connected to digs107 (172.29.38.107) port 443 (#0)
* successfully set certificate verify locations:
*  CAfile: none
  CApath: /etc/ssl/certs/
* SSLv3, TLS handshake, Client hello (1):
* SSLv3, TLS handshake, Server hello (2):
* SSLv3, TLS handshake, CERT (11):
* SSLv3, TLS handshake, Server key exchange (12):
* SSLv3, TLS handshake, Request CERT (13):
* SSLv3, TLS handshake, Server finished (14):
* SSLv3, TLS handshake, CERT (11):
* SSLv3, TLS handshake, Client key exchange (16):
* SSLv3, TLS change cipher, Client hello (1):
* SSLv3, TLS handshake, Finished (20):
* SSLv3, TLS change cipher, Client hello (1):
* SSLv3, TLS handshake, Finished (20):
* SSL connection using TLSv1.2 / ECDHE-RSA-AES128-SHA256
* Server certificate:
*        subject: emailAddress=sales@xxxxxx.nl; C=NL; ST=Noord-Brabant; L=Eindhoven; O=xxxxx - DEMO; OU=Operations; CN=xandria.xxxxx.nl
*        start date: 2016-12-15 12:36:03 GMT
*        expire date: 2025-10-29 13:36:03 GMT
*        issuer: emailAddress=sales@xxxxx.nl; C=NL; L=Eindhoven; O=xxxxx; OU=Operations; CN=xxxxx Demo Signing CA
*        SSL certificate verify result: unable to get local issuer certificate (20), continuing anyway.
> GET / HTTP/1.1
> User-Agent: curl/7.37.0
> Host: digs107
> Accept: */*
>
< HTTP/1.1 302 Found
< Date: Thu, 09 Feb 2017 09:44:49 GMT
< Strict-Transport-Security: max-age=2000; includeSubDomains
< Location: https://digs107/xn/xangui/rtm/rtm.zul
< Content-Length: 0
<
* Connection #0 to host digs107 left intact

Code:

curl -v https://digs107
* Rebuilt URL to: https://digs107/
* Hostname was NOT found in DNS cache
*  Trying 172.29.38.107...
* Connected to digs107 (172.29.38.107) port 443 (#0)
* successfully set certificate verify locations:
*  CAfile: none
  CApath: /etc/ssl/certs/
* SSLv3, TLS handshake, Client hello (1):
* SSLv3, TLS handshake, Server hello (2):
* SSLv3, TLS handshake, CERT (11):
* SSLv3, TLS alert, Server hello (2):
* SSL certificate problem: unable to get local issuer certificate
* Closing connection 0
curl: (60) SSL certificate problem: unable to get local issuer certificate
More details here: http://curl.haxx.se/docs/sslcerts.html

curl performs SSL certificate verification by default, using a "bundle"
 of Certificate Authority (CA) public keys (CA certs). If the default
 bundle file isn't adequate, you can specify an alternate file
 using the --cacert option.
If this HTTPS server uses a certificate signed by a CA represented in
 the bundle, the certificate verification probably failed due to a
 problem with the certificate (it might be expired, or the name might
 not match the domain name in the URL).
If you'd like to turn off curl's verification of the certificate, use
 the -k (or --insecure) option.

I'll see if I can find a way to fix this.

Oh, if I provide the CA on the command line using the --cacert option it actually works:
Code:

curl -v --cacert ../ssl.crt/xxxxx-CAconcatenated.pem https://xandria.xxxxx.nl
* Rebuilt URL to: https://xandria.xxxxx.nl/
* Hostname was NOT found in DNS cache
*  Trying 172.29.38.107...
* Connected to xandria.xxxxxx.nl (172.29.38.107) port 443 (#0)
* successfully set certificate verify locations:
*  CAfile: ../ssl.crt/xxxxx-CAconcatenated.pem
  CApath: /etc/ssl/certs/
* SSLv3, TLS handshake, Client hello (1):
* SSLv3, TLS handshake, Server hello (2):
* SSLv3, TLS handshake, CERT (11):
* SSLv3, TLS handshake, Server key exchange (12):
* SSLv3, TLS handshake, Request CERT (13):
* SSLv3, TLS handshake, Server finished (14):
* SSLv3, TLS handshake, CERT (11):
* SSLv3, TLS handshake, Client key exchange (16):
* SSLv3, TLS change cipher, Client hello (1):
* SSLv3, TLS handshake, Finished (20):
* SSLv3, TLS change cipher, Client hello (1):
* SSLv3, TLS handshake, Finished (20):
* SSL connection using TLSv1.2 / ECDHE-RSA-AES128-SHA256
* Server certificate:
*        subject: emailAddress=sales@xxxxx.nl; C=NL; ST=Noord-Brabant; L=Eindhoven; O=xxxxx - DEMO; OU=Operations; CN=xandria.xxxxx.nl
*        start date: 2016-12-15 12:36:03 GMT
*        expire date: 2025-10-29 13:36:03 GMT
*        common name: xandria.xxxxx.nl (matched)
*        issuer: emailAddress=sales@xxxxx.nl; C=NL; L=Eindhoven; O=xxxxx; OU=Operations; CN=xxxxx Demo Signing CA
*        SSL certificate verify ok.
> GET / HTTP/1.1
> User-Agent: curl/7.37.0
> Host: xandria.xxxxx.nl
> Accept: */*
>
< HTTP/1.1 302 Found
< Date: Thu, 09 Feb 2017 09:56:19 GMT
< Strict-Transport-Security: max-age=2000; includeSubDomains
< Location: https://xandria.xxxxx.nl/xn/xangui/rtm/rtm.zul
< Content-Length: 0
<
* Connection #0 to host xandria.xxxxx.nl left intact

Note that I did change the name from digs107 to the full name xandria.xxxxx.nl. I've added this to the hosts file to match te correct IP address. If I used the digs107 name, I'd get a name mismatch on certificate. I've also updated this in the apache configuration, but alas, that did not fix it.

r3sistance 02-09-2017 04:17 AM

Your apache configuration should ignore that it is an insecure certificate as you have SSLProxyVerify set to none but I'd suspect that it isn't actually ignoring the issue.

lpwevers 02-09-2017 04:46 AM

Quote:

Originally Posted by r3sistance (Post 5667670)
Your apache configuration should ignore that it is an insecure certificate as you have SSLProxyVerify set to none but I'd suspect that it isn't actually ignoring the issue.

Well actually, I believe that is working. When use a browser to access the server, I'm actually asked which certificate I'd like to use. I guess that's the doing of the lines:
Code:

SSLVerifyClient        optional
SSLVerifyDepth          4

The backend server is configured in such a way that If I try to access it and do not present a certificate, it will show me a login page where I can enter a username / password.

When I access it in a browser, and select the proper client certificate, the backend server does indeed show me the login page. So there is communication, but the certifcate is not passed on for authentication.


All times are GMT -5. The time now is 10:10 AM.