I am trying to use cURL to post to an API that just started using SNI (so they could host multiple ssl certs on 1 IP address).
My cURL stopped working as a result of this move to SNI. They explained that it's because cURL is getting *.domain-a.com back instead of *.domain-b.com so the SSL fails.
This seems to be a bug in cURL because the API URL has no errors when visited from a browser.
Using this code, it does work:
exec('curl -k -d "parameters=here", https://urlhere.com/', $output); print_r($output);
However, using -k is bad because it doesn't verify the SSL cert.
Using this code, does NOT work:
exec('curl -d "parameters=here", https://urlhere.com/', $output); print_r($output);
So my question is, how can I use curl with SNI and still verify the SSL (not have to use -k). Is there another setting in PHP or a cURL option I can set to work around this?
Server Name Indication (SNI) is an extension to the TLS protocol. It allows a client or browser to indicate which hostname it is trying to connect to at the start of the TLS handshake. This allows the server to present multiple certificates on the same IP address and port number.
Enable SNI feature on the SSL virtual server. Navigate to Traffic Management > Load Balancing > Virtual Servers > Select the virtual server and click Edit >SSL Parameters and check SNI Enable.
Server Name Indication (SNI), an extension to the SSL/TLS protocol, allows multiple SSL certificates to be hosted on a single unique IP address. SNI does this by inserting the HTTP header (virtual domain) in the SSL/TLS handshake.
Server Name Indication (SNI) allows the server to safely host multiple TLS Certificates for multiple sites, all under a single IP address. It adds the hostname of the server (website) in the TLS handshake as an extension in the CLIENT HELLO message.
To be able to use SNI, three conditions are required:
Note that Curl's debug code (-v
) only displays the major version number (mainly to distinguish between SSLv2 and SSLv3+ types of messages, see ssl_tls_trace
), so it will still display "SSLv3" when you use TLS 1.0 or above (because they're effectively SSL v3.1 or above, 3 is the same major version number).
You could check that your installed version of curl can use SNI using Wireshark. If you make a connection using curl -1 https://something
, if you expand the "Client Hello" message, you should be able to see a "server_name
" extension.
I'm not sure which SSL/TLS version is used by default (depending on your compilation options) when you use curl
without -1
(for TLS 1.0) or -3
(for SSLv3), but you can try to force -1
on your command, since it won't work with SSLv3 anyway.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With