0

Ubuntu server 14.04.

I must connect to an application outside of my network, through https. I'm using apache2 to build a communication on the https layer.

On the other side it is requested a client certificate authentication. I installed in my Ubuntu all the certificate chain. The CA, intermediate and also their public certificate.

A practical example:

curl -lv https://this-application/receiving-link

* Hostname was NOT found in DNS cache
*   Trying 111.222.333.444...
* Connected to application-something (111.222.333.444) 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 expect exactly this result.

I loaded all the certificate chain + public (pem format and hashed, softlinked) here: /etc/apache2/mytrustedclientcerts

curl -lvvvvv --capath "/etc/apache2/mytrustedclientcerts/" https://this-application/receiving-link

* Hostname was NOT found in DNS cache
*   Trying 111.222.333.444...
* Connected to application-something (111.222.333.444) port 443 (#0)
* successfully set certificate verify locations:
*   CAfile: none
  CApath: /etc/apache2/mytrustedclientcerts/
* 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 ECDHE-RSA-AES256-GCM-SHA384
* Server certificate:
*        information about the certificate here
*        ...
*        ...
*        ...
*        ...
*        SSL certificate verify ok.
> GET /b2b/httpReceiver HTTP/1.1
> User-Agent: curl/7.35.0
> Host: application-something.com
> Accept: */*
> 
< HTTP/1.1 200 OK
< Date: Mon, 04 Jun 2018 13:16:20 GMT
* Server Server is not blacklisted
< Server: Server
< Content-Length: 155
< test: some_thing
< test: 0:1
< Content-Type: text/html; charset=ISO-8859-1
< 
<html><head><title>Server</title></head>
<body><h1>Hello</h1>
Ready.
</body></html>
* Connection #0 to host application-something.com left intact

Perfection. This is how I see if I'm able to connect, and I do.

Now it's Apache2 turn.

I added to my sites-enabled configuration.conf:

SSLCACertificatePath  "/etc/apache2/mytrustedclientcerts/"
SSLVerifyDepth 10
SSLVerifyClient optional #this must be optional because of many reasons

Just like I did in the test server, where the connection worked right after the change. In this prod server (both of them Ubuntu 14.04) just does not work.

I read in my application log:

06/04/18 11:42:31 SenderModule: Connecting to: https://this-application/receiving-link [message-for-sending-hash]
06/04/18 11:42:32 SenderModule: Failed to connect to partner using SSL certificate. Please run the SSL certificate checker utility to identify the issue: https://this-application/receiving-link [message-for-sending-hash]

I tried to verify the certificate too:

openssl verify -verbose -x509_strict -CApath /etc/apache2/mytrustedclientcerts/ /etc/apache2/mytrustedclientcerts/4.https_public.pem

Which says:

/etc/apache2/mytrustedclientcerts/4.https_public.pem: OK

I restarted Apache2 for applying the changes - I do not want to use the '-k' option on CURL because that is not the point.

I'm asking if someone knows why Apache2 is not able to get these certificate and using them. Probably I missed something from the documentation: https://httpd.apache.org/docs/2.4/mod/mod_ssl.html#sslcacertificatepath but honestly I don't think so.. Any help is appreciated!

  • How is the connection to the backend server established from the end client? If this is a reverse proxy setup you are missing the SSLProxyCACertificateFile and the corresponding directives. – Gerald Schneider Jun 4 '18 at 13:51
  • Sorry, I copied the wrong line. The directive to authenticate apache against other servers via client certificate is SSLProxyMachineCertificateFile. – Gerald Schneider Jun 4 '18 at 14:06
  • @GeraldSchneider hi, yes i do use reverseproxy, not sure about them but I guess so. The configuration.conf for apache used in the test server was copied to the production server. I was expecting it to "just work" because the 2 servers have the same application/settings. In test, the SSLProxyCACertificateFile is not set because we don't use it. Ok i see it now your update. Never heard of this SSLProxyMachineCertificateFile, not sure though i should find the solution here but i'll try have a look! thanks for now! – Nihvel Jun 4 '18 at 14:15
  • Tried using SSLProxyMachineCertificatePath and apache does not restart. It hangs. I'm in production and I don't feel like testing it more and having the service down for some time. – Nihvel Jun 5 '18 at 9:39
0

This is not what I wanted but at least I have it working now.

My goal was to tell Apache2 to use a folder made appositely for certificates that I wanted Apache2 only to trust and connect and not the whole system. This folder was /etc/apache2/mytrustedclientcerts/. Just like I did with CURL.

Due to the fact that I needed to have the connection ready, I trusted the certificates globally in the system:

  • Copied the encoded version of the certificate in .crt extension, inside /etc/ssl/cert
  • Ran the little script that I prepared for hashing and Linking the certificates (see it below).

After this, the HTTPS connection with Apache worked. Still, not what I wanted, but at least it works.

#!/bin/bash
hash=$(openssl x509 -noout -hash -in "$1")
if [ $(ls -1 "${hash}."* 2>/dev/null | wc -l) -gt 0 ]; then
  inc=$(ls -t "${hash}."* | head -1 | awk -F"." '{print $2}')
  ((inc+=1))
else
  inc=0
fi
ln -s "$1" "${hash}.${inc}"
  • I still use SSLCACertificatePath in Apache but this point to /etc/ssl/certs/. I think that my system hanged for a while, because after I Trusted it globally it still didn't work. It took some time after this change to finally have the message sent using Apache. I do not know if it was because of /etc/ssl/certs or what else. As long as it works I'm happy. – Nihvel Jun 5 '18 at 14:51

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.