Add self signed certificate to ubuntu for use with curl - ssl

I'm developing a program where I have a virtual development server that runs with a self signed certificate. My program uses curl to connect to the server and pull information, but needs to do so with SSL. When I try to connect I get the error "SSL certificate problem, verify that the CA cert is OK." When running firefox I can add the certificate to just firefox, but that doesn't help me with curl. How do I add the certificate for curl to recognize?
curl 7.19.7 (x86_64-pc-linux-gnu) libcurl/7.19.7 OpenSSL/0.9.8k zlib/1.2.3.3 libidn/1.15
Protocols: tftp ftp telnet dict ldap ldaps http file https ftps
Features: GSS-Negotiate IDN IPv6 Largefile NTLM SSL libz
Ubuntu 10.04 Lucid Lynx 64bit

This is one way that worked for me:
First, get the CA cert from the development domain and save it to a file called 'logfile'. (Assumes port 443 for SSL)
openssl s_client -connect xxxxx.com:443 |tee logfile
Then, use the --cacert curl option to use the saved certificate file.
curl --cacert logfile **THE REST OF YOUR CURL COMMAND**
Source:
http://curl.haxx.se/docs/sslcerts.html

I'd copy the certificate to /usr/local/share/ca-certificates/.
Let me quote the man page for update-ca-certificates:
Furthermore all certificates with a .crt extension found below /usr/local/share/ca-certificates are also included as implicitly trusted.

Add your rootCA.pem in /usr/share/ca-certificates directory.
After that update your certificates with: update-ca-certificates --fresh command.
I just did that, and works fine.

First, in your Linux, you should add your CERTIFICATE.cert to /usr/local/share/ca-certificates/.
After that by adding --cacert CERTIFICATE.cert to your command, curl will automatically use this certificate in that request.
Exp:
curl --cacert CERTIFICATE.cert GET "URL".
Obviously, you can edit the request to have your desired request.

Related

curl: (60) server certificate verification failed - from one server but not on others

I've encountered a bizarre issue where SSL certificate verification is failing on one server, but nowhere else (other servers, my local computer, etc.)
I'm using https://vpnapi.io/. Both the API endpoint and the homepage have the same issue.
Command I'm running:
curl https://vpnapi.io/
The server in question is on Digital Ocean, but I've tried the same command on another Digital Ocean server, a server on another VPS provider, and my own computer. They all work.
Why is it failing on this one server? I'm not sure where to even begin looking.
Is it a problem on the server? A problem with vpnapi.io? A problem with Digital Ocean?
Note: other APIs work from this server.
Edit: Full error message below
curl: (60) server certificate verification failed. CAfile: /etc/ssl/certs/ca-certificates.crt CRLfile: none
More details here: http://curl.haxx.se/docs/sslcerts.html
curl performs SSL certificate verification by default, using a "bundle"
of Certificate Authority (CA) public keys (CA certs). If the default
bundle file isn't adequate, you can specify an alternate file
using the --cacert option.
If this HTTPS server uses a certificate signed by a CA represented in
the bundle, the certificate verification probably failed due to a
problem with the certificate (it might be expired, or the name might
not match the domain name in the URL).
If you'd like to turn off curl's verification of the certificate, use
the -k (or --insecure) option.
Edit: more info
I'm aware of the date issue as described by one answer here: Server certificate verification failed. CAfile: /etc/ssl/certs/ca-certificates.crt CRLfile: none (I checked the date on the system, it is correct)
OS is Ubuntu 16.04 (it works on my other Digital Ocean machine which runs Ubuntu 18.04, and on Mac)
curl version:
curl 7.47.0 (x86_64-pc-linux-gnu) libcurl/7.47.0 GnuTLS/3.4.10 zlib/1.2.8 libidn/1.32 librtmp/2.3
Protocols: dict file ftp ftps gopher http https imap imaps ldap ldaps pop3 pop3s rtmp rtsp smb smbs smtp smtps telnet tftp
Features: AsynchDNS IDN IPv6 Largefile GSS-API Kerberos SPNEGO NTLM NTLM_WB SSL libz TLS-SRP UnixSockets

The certificate chain issued by an untrusted authority

I am using the curl terminal and while issuing the following command :-
curl --anyauth --user admin:admin "https://localhost:8000/LATEST/search?q=caesar"
I am getting below alert :-
curl: (77) schannel: next InitializeSecurityContext failed: SEC_E_UNTRUSTED_ROOT (0x80090325) - The certificate chain was issued by an authority that is not trusted.
Please suggest. I have installed curl in Windows and also downloaded the .pem file and placed it in the same folder.
If your server has a self-signed cert, then by default curl doesn't know that it can trust that the server is who it says it is, and doesn't want to talk.
You can either:
import the cert into your trust store (best and most secure)
apply the -k or --insecure switch to ignore and continue. This may be fine for local development.
use a real cert, signed by a trusted CA
For local dev and a quick solution, run this line
set_config( config( ssl_verifypeer = 0L ) )
before
httr::GET(....)
but as suggested it's still preferable to use a real cert.

ArangoDB working together with letsenrcypt certificates

Is there anyoune out there who got a running arangoDB database working with a letsencrypt certificate? I just can't find out to geht this running.
ArangoDB is running on a digitalOcean droplet and I could get it running togehter with a self-signed certificate following this tutorial. So arangoDB is sucessfully running on port: 8530
Now my approach was replacing the self-signed certificate with a letsencrypt cert.
So I added a subdomain in DigitalOcean to the droplet. e.g.: db.example.com an then generated the cert-files:
sudo -H ./letsencrypt-auto certonly --standalone -d db.example.com
You will end up with 4 files: cert.pem chain.pem fullchain.pem privkey.pem
As I understood, these files are:
Private Key --------> privkey.pem
Public Key ---------> cert.pem
Certificate Chain --> chain.pem
As described in the tutorial I mentioned, you nee the certificate and the key in one file. So i did
cat chain.pem privkey.pem | sudo tee server.pem
to have a file containing the certificate and the private key.
Then I modified the file /etc/arangodb3/arangod.conf to let arango know where the keyfile is and modified the ssl section:
[ssl]
keyfile = /etc/letsencrypt/live/db.example.com/server.pem
But after restarting arango, the server is not available. When trying to connect the browser to: https://db.example.com:8530. Firewall settings for the droplet should all be ok, because I could access this address with the self-signed cetificate before.
I then tried to modify the endpoint in /etc/arangodb3/arangod.conf from
endpoint = ssl://0.0.0.0:8530
to
endpoint = ssl://db.example.com:8530
and also
tcp://db.example.com:8530
None of it was working. Has somebody out there an idea what I am doing wrong?
Please use the ip of the interface you want to use when specifying the endpoint e.g. endpoint = ssl://42.23.13.37:8530 (ip address should list your interfaces along with addresses in use). Then it could help to use the fullchain.pem to create the server.prm (cat fullchain.pem privkey.pem > server.pem). Make sure the resulting server.pem is accessible and readable by the arangodb user. If the server is still not starting correctly please provide logs of the server. To access the logs use systemctl -fu arangodb3.service or follow the logs with tail -f <logfile> if you use some custom location for logging.
I have just tested a setup with letsencrypt certificates and it was working after ensuring all above points.

Curl does not take into consideration the given certificate(using --cert option)

I am trying to call an URL using curl, I used below command:
curl https://testenvironment/login --cert Qa1Certificate.pem
The result I get is:
curl: (60) Peer certificate cannot be authenticated with known CA certificates
More details here: http://curl.haxx.se/docs/sslcerts.html
curl performs SSL certificate verification by default, using a "bundle"
of Certificate Authority (CA) public keys (CA certs). If the default
bundle file isn't adequate, you can specify an alternate file
using the --cacert option.
If this HTTPS server uses a certificate signed by a CA represented in
the bundle, the certificate verification probably failed due to a
problem with the certificate (it might be expired, or the name might
not match the domain name in the URL).
If you'd like to turn off curl's verification of the certificate, use
the -k (or --insecure) option.
The Qa1Certificate.pem is placed in the current directory, and I believe that it is not taken into consideration because when I run the same command with a file name which does not exist:
curl https://testenvironment/login --cert ThisFileDoesNotExist.pem
I get the same result.
I am aware that I can obtain what I need using the -k or --insecure options( or other ways of disabling curl's verification of the certificate), but I
want to find out how can I use the certificate in order to perform a successful GET to my test environment.
The test environment uses a self signed certificate which I obtained using openSSL.
TLDR: it's --cacert
From the man page, which should be on your system or on the web:
-E, --cert <certificate[:password]>
(TLS) Tells curl to use the specified client certificate file when getting a file with HTTPS, FTPS or another SSL-based protocol. [snip rest]
Note the words 'client certificate'. --cert is used to specify a certificate and possibly key to authenticate the client, NOT to verify the server.
Now consider another entry on the man page:
--cacert
(TLS) Tells curl to use the specified certificate file to verify the peer. The file may contain multiple CA certificates. The certificate(s) must be in PEM format. Normally curl is built to use a default file for this, so this option is typically used to alter that default file.
This is the option to specify a cert or certs to verify (and specifically to anchor) the server's cert. Since your server cert is selfsigned, the cert is its own anchor/root and effectively is a CA cert, even though the server isn't actually a CA.
That's why the error message you posted includes the words
you can specify an alternate file using the --cacert option.
It does not say --cert.
Whether the client cert (and key) is read depends on the middleware used by the specific build of curl you are running. IME if built with OpenSSL it does give an error if you specify --cert with a nonexistent filename, but a version built with NSS (on Ubuntu 14.04LTS) gives an error only if the server requests client auth, which most servers don't.

curl doesn't verify a certificate with exported site's certificate in Firefox passed by --cacert

I am not much of an expert in SSL, please excuse me if I use some SSL related terms incorrectly. For some reason I can't download a file by https with curl supplying it with this site's certificate with --cacert option.
I have an Intranet site accessible by https. It is possible to open this site in Firefox after accepting a untrusted (or self signed) SSL certificate. I exported this site's certificate from Firefox to a file. The I have removed all certificates from /etc/pki/tls/certs , so curl can't find certificates anywhere besides those in the file supplied by the --cacert option.
When I run curl with --cacert option specifying the certificate file it fails:
curl -v https://some-intranet-site.com/repodata/repomd.xml --cacert exported_certificate.cer
* Peer certificate cannot be authenticated with known CA certificates
curl: (60) Peer certificate cannot be authenticated with known CA certificates
More details here: http://curl.haxx.se/docs/sslcerts.html
When I export the Google's certificate and try to access https://gogole.com with curl it works:
curl https://google.com --cacert ~/dev/tmp/google.cert
<HTML><HEAD><meta http-equiv="content-type" content="text/html;charset=utf-8">
<TITLE>301 Moved</TITLE></HEAD><BODY>
<H1>301 Moved</H1>
The document has moved
here.
</BODY></HTML>
Could you give any explanation?
Thank you.
Using self-signed certificates is maybe not so good since you get warnings.
In any case, you should make sure the CN of the server certificate contains the server's DNS name. Also, make sure that the exported_certificate.cer is in PEM format. My guess is that your is in DER format. If PEM format then you read it in a regular text editor, if DER it is binary.
Finally, if you don't want to verify the server cert, so you can skip this with curl using "-k". So in your case, "curl -k -v https://some-intranet-site.com/repodata/repomd.xml"