curl with `-k` and without `-k`

Suku picture Suku · Jan 26, 2017 · Viewed 8.3k times · Source

When I am opening a url using curl without -k, my request is passing and I am able to see the expected result.

$ curl -vvv https://MYHOSTNAME/wex/archive.info -A SUKU$RANDOM
*   Trying 10.38.202.192...
* Connected to MYHOSTNAME (10.38.202.192) port 443 (#0)
* TLS 1.2 connection using TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384
* Server certificate: *.MYCNAME
* Server certificate: ProdIssuedCA1
* Server certificate: InternalRootCA
> GET /wex/archive.info HTTP/1.1
> Host: MYHOSTNAME
> User-Agent: SUKU19816
> Accept: */*
> 
< HTTP/1.1 200 OK
< Server: nginx/1.10.2
< Date: Thu, 26 Jan 2017 01:08:40 GMT
< Content-Type: text/html;charset=ISO-8859-1
< Content-Length: 19
< Connection: keep-alive
< Set-Cookie: JSESSIONID=1XXXXXXXX3E58093E816FE62D81; Path=/wex/; HttpOnly
< X-WebProxy-Id: 220ffb81872a
< 




status=Running
* Connection #0 to host MYHOSTNAME left intact

But when I am opening same url with -k its failing. To me its not making any sense since in my understanding the purpose of -k is only to skip certificate verification

$ curl -vvv https://MYHOSTNAME/wex/archive.info -A SUKU$RANDOM -k
*   Trying 10.38.202.192...
* Connected to MYHOSTNAME (10.38.202.192) port 443 (#0)
* Server aborted the SSL handshake
* Closing connection 0
curl: (35) Server aborted the SSL handshake

Request flow:

  1. SSL termination is happening on HAPROXY machine
  2. HAPROXY will forward request to nginx

Answer

sideshowbarker picture sideshowbarker · Jan 26, 2017

For troubleshooting this kind of problem, the --resolve option can be useful:

curl -k -I --resolve www.example.com:80:192.0.2.1 https://www.example.com/

Provide a custom address for a specific host and port pair. Using this, you can make the curl requests(s) use a specified address and prevent the otherwise normally resolved address to be used. Consider it a sort of /etc/hosts alternative provided on the command line. The port number should be the number used for the specific protocol the host will be used for. It means you need several entries if you want to provide address for the same host but different ports.

Especially if the site you’re trying to fetch from uses SNI: In that case you can use the --resolve option to specify the server name that gets used in the TLS client hello.

One troubleshooting step to try: update curl or compile it yourself from the sources and retry. For one thing, some curl versions (e.g., MacOS) supposedly don’t send SNI for -k/--insecure.

If that’s the issue you’ve hit and you can’t replace curl, there’s a workaround you can use that essentially involves creating your own CA and private keys and CSRs, and tweaks to your haproxy.

After setting it up, then in place of specifying -k/--insecure, you use --cacert or --capath:

curl https://example.com/api/endpoint --cacert certs/servers/example.com/chain.pem
curl https://example.com/api/endpoint --capath certs/ca

If the issue you’ve hit is due to SNI, you may also troubleshoot it with a site like https://sni.velox.ch/:

curl --insecure https://sni.velox.ch/

Otherwise, if it’s not SNI, then I recall seeing somewhere that -k/--insecure may not work as expected with some proxy configurations. So if you are going through some kind of proxy from the client side and you could somehow test directly without the proxy, that might be worth exploring.