KB Article #179839

Connection from gateway shows a handshake failure, but the site is accessible via curl

Problem


An HTTPS site that is accessible from tools on the same host like curl fails with an error like the following when API Gateway or Manager tries to connect to it:


DEBUG 01/Jan/2018:00:00:00.001 connected to 10.0.0.1:443
DEBUG 01/Jan/2018:00:00:00.001 new connection 0x000000000000, settings source service-wide defaults (allow 1.1=no, idleTimeout=15000, activeTimeout=30000, maxConnections=128, contentLength: req=no, res=no)
DEBUG 01/Jan/2018:00:00:00.001 Start SSL connection
DEBUG 01/Jan/2018:00:00:00.001 push SSL protocol on to connection, SSL options: 385875972
DATA 01/Jan/2018:00:00:00.001 [SSL_connect, 0x5000] before/connect initialization.
DATA 01/Jan/2018:00:00:00.001 [SSL_connect, 0x1210] SSLv2/v3 write client hello A.
ERROR 01/Jan/2018:00:00:00.007 [SSL alert read 0x228, 0x1220]: handshake failure [fatal].
ERROR 01/Jan/2018:00:00:00.007 [SSL_connect, 0x1220]: error - SSLv2/v3 read server hello A.


Resolution


This is generally due to not having configured the gateway or API Manager with a remote host that tells it to send the SNI (server name indication) TLS extension, which curl and web browsers do for you by default. KB 178248 has instructions on how to create a remote host that sends the SNI extension. Note that you do need to have the full certificate chain of the remote site imported into the trust stores to be able to validate the remote site's certificate, which is required for SNI to work in the gateway. General information on remote hosts can be found in the Policy Developer Guide for API Gateway or the User Guide for API Manager appropriate for your version.


Note that the error itself is just saying that the SSL handshake failed and there are many possible causes for this, such as cipher mismatches, firewall issues, etc. You can prove that SNI is the culprit by doing tests with openssl s_client. A command line version of OpenSSL comes bundled with the gateway that should be used for this testing to prevent version differences from affecting the test results.


To prove that SNI is the issue, you can run these two commands. The only difference is that the second command sends the SNI extension to the server:


openssl s_client -connect HOSTNAME:PORT
openssl s_client -connect HOSTNAME:PORT -servername HOSTNAME


It will prove that SNI is the problem if the first one fails with a handshake failure and the second command is successful.


Finally, note that "SSLv2/v3 write client hello A" in the error messages does not indicate that SSLv2 or SSLv3 is in use. This sample was, in fact, attempting to establish a TLS 1.2 connection. This is related to some internal OpenSSL function names that are used for both SSL and TLS and to the compatibility considerations mentioned in Appendix E of RFC 5246.