615

I am trying to make a curl request to one of our local development servers running a dev site with a self-signed SSL cert. I am using curl from the command line.

I saw some blog posts mentioning that you can add to the list of certificates or specify a specific (self signed) certificate as valid, but is there a catch-all way of saying "don't verify" the ssl cert - like the --no-check-certificate that wget has?

0

4 Answers 4

816

Yes. From the manpage:

-k, --insecure

(TLS) By default, every SSL connection curl makes is verified to be secure. This option allows curl to proceed and operate even for server connections otherwise considered insecure.

The server connection is verified by making sure the server's certificate contains the right name and verifies successfully using the cert store.

See this online resource for further details: https://curl.haxx.se/docs/sslcerts.html

See also --proxy-insecure and --cacert.

The reference mentioned in that manpage entry describes some of the specific behaviors of -k .

These behaviors can be observed with curl requests to test pages from BadSSL.com

curl -X GET https://wrong.host.badssl.com/
curl: (51) SSL: no alternative certificate subject name matches target host name 'wrong.host.badssl.com'

curl -k -X GET https://wrong.host.badssl.com/
..returns HTML content...
13
  • 22
    Love the fact that it has a one letter short option
    – kizzx2
    Jan 20, 2013 at 9:39
  • 3
    Is there any way in curl config to make this option default?
    – Wins
    Apr 5, 2016 at 8:48
  • 10
    @Wins, that would be a horrible idea. Right an alias if you need to use it repeatedly, so you know what it does and don't accidentally send your passwords unencrypted. alias insecure-curl="curl -k" Dec 5, 2016 at 15:12
  • 6
    @AlexanderHuszagh At work, I only use curl from a single server with a self-signed certificate; there is never a time I want to do full certificate checking. Just because something seems like a horrible idea in most cases doesn’t mean it always is.
    – Daniel H
    Jun 6, 2017 at 17:59
  • 10
    @DanielH That is why I suggested an alias: so you get the added convenience with the explicit knowledge that it is insecure. Workflows change: you should still know in some limited fashion when you are trading security for convenience, however. Jun 6, 2017 at 21:49
49

You may use the following command to apply the changes for all connections:

$ echo insecure >> ~/.curlrc

On Windows just create _curlrc text file with 'insecure' text in it in your %HOME%, %CURL_HOME%, %APPDATA%, %USERPROFILE% or %USERPROFILE%\Application Data directory.

Advantage of using above solution is that it works for all curl commands, but it is not recommended since it may introduce MITM attacks by connecting to insecure and untrusted hosts.

8
  • 86
    This seems like bad advice: disabling these checks for all connections should not be the default, even if you do this to yourself via per-user configuration. If you need to suppress security checks, at least do it piecemeal. May 22, 2014 at 21:07
  • 7
    Anytime I am using curl, I either control or trust the machine at the other end. Sep 3, 2014 at 18:00
  • 17
    @EricHartford: Well, good for you, but that still doesn't make it a good general advice imho. One might use curl, for instance when downloading homebrew on osx and end up with a modified version of the tools because he enabled this as a default blindly.
    – ereOn
    Oct 19, 2014 at 3:02
  • 13
    Also @EricHartford are you sure you always do trusted curl stuff? Have you ever ran any bash install script you got off of internet? Granted, you can be in the black there anyway, but this increases the chances.
    – Zlatko
    May 8, 2015 at 6:56
  • 2
    this is the real @EricHartford. The previous message was posted by someone else impersonating me. Because I trusted all machines ;-) Jul 18, 2019 at 4:19
15

You are using a self-signed cert. Why don't you appended the CA to your trusted CA bundle (Linux) or add to the trusted Certificate store (windows)? Or simply use --cacert /Path/to/file with the contents of your trusted self-signed cert file.

The other answers are answering the question based on the wget comparable. However the true ask is how do I maintain a trusted connection with a self-signed cert using curl. Based on many comments security is the top concern in any one of these answers, and the best answer would be to trust the self-signed cert and leave curls security checks intact.

1
  • Good suggestion. Unfortunately on Windows at least curl still had an issue with my trusted CA and self-signed cert combo (works great in browsers and iOS) due to a failed revocation check. The --ssl-no-revoke option takes care of that though. Jun 9, 2021 at 15:22
6

Adding to user3258557 's answer, let's say that you need to test some fake server of your own with your own root CA etc. And you just don't want to use curl's -k option.

First, let's create a RSA key for your Root CA:

openssl genrsa -des3 -out rootCA.key 4096

Then, using that key, let's sign a certificate for our own CA:

openssl req -x509 -new -nodes -key rootCA.key -sha256 -days 1024 -out rootCA.crt

Now, you have a Root CA with private Key and Certificate.

Let's now generate keys and certificates for our own websites:

openssl genrsa -out mainsite.net.key 2048

Now, before creating the certificate, we will need a Certificate Signing Request (CSR) first. Then our Root CA will "sign" the CSR and generate the certificate for our website.

openssl req -new -key mainsite.net.key -out mainsite.net.csr

Let's finally create the certificate for our website:

openssl x509 -req -in mainsite.net.csr -CA rootCA.crt -CAkey rootCA.key -CAcreateserial -out mainsite.net.crt -days 500 -sha256

For ease of use, let's generate a .pem file using our .crt and .key files as:

cat mainsite.net.key mainsite.net.crt > mainsite.net.pem

Now, you can run a simple server with this .pem file. Say this server is running at 127.0.0.1:12345

For curl request, you can just do this:

curl --cacert "rootCA.crt" https://127.0.0.1:12345/

Going a step further, if you want to host multiple sites on a port using SNI, you can generate the key for each site, sign the CSR's and use a curl request like below:

curl --resolve subsite1.mainsite.net:12345:127.0.0.1 -X GET --cacert "rootCA.crt" --cert "subsite1.mainsite.net.crt" --key "subsite1.mainsite.net.key" https://subsite1.mainsite.net:12345/

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .