Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Use cURL with SNI (Server Name Indication)

Tags:

php

curl

ssl

sni

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?

like image 445
Justin Avatar asked Oct 17 '12 19:10

Justin


People also ask

Why do we need server name indication SNI )?

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.

How do you set up SNI?

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.

What is a SNI header?

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.

Can SNI be an IP address?

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.


1 Answers

To be able to use SNI, three conditions are required:

  • Using a version of Curl that supports it, at least 7.18.1, according to the change logs.
  • Using a version of Curl compiled against a library that supports SNI, e.g. OpenSSL 0.9.8j (depending on the compilation options some older versions).
  • Using TLS 1.0 at least (not SSLv3).

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.

like image 135
Bruno Avatar answered Oct 04 '22 05:10

Bruno