I have a ruby on rails webapp sending requests to a third party SOAP API. When I request like:
endpoint = "https://www.booking-manager.com/cbm_web_service2/services/CBM?wsdl"
client = Savon.client(wsdl: endpoint,
#log_level: :info,
log_level: :debug,
log: true,
pretty_print_xml: true,
open_timeout: 300,
read_timeout: 300)
message = {'in0' => xxx,
'in1' => 'xxxx',
'in2' => 'xxx'}
response = client.call(:get_bases, message: message)
I´m getting next error:
HTTPI::SSLError (SSL_connect returned=1 errno=0 state=error: certificate verify failed (certificate has expired)):
The webapp is running under:
Mac OSX Big Sur 11.6.1
ruby 3.0.3p157 (2021-11-24 revision 3fb7d2cadc) [x86_64-darwin20]
I have this issue for weeks and I don´t know what else to do. According to many posts, I tested
openssl s_client -showcerts -host valid-isrgrootx1.letsencrypt.org -port 443
and got:
CONNECTED(00000005)
depth=1 O = Digital Signature Trust Co., CN = DST Root CA X3
verify error:num=10:certificate has expired
notAfter=Sep 30 14:01:15 2021 GMT
verify return:0
depth=1 O = Digital Signature Trust Co., CN = DST Root CA X3
verify error:num=10:certificate has expired
notAfter=Sep 30 14:01:15 2021 GMT
verify return:0
depth=3 O = Digital Signature Trust Co., CN = DST Root CA X3
verify error:num=10:certificate has expired
notAfter=Sep 30 14:01:15 2021 GMT
verify return:0
---
Certificate chain
0 s:/CN=origin.letsencrypt.org
i:/C=US/O=Let's Encrypt/CN=R3
so, according to this: https://community.letsencrypt.org/t/help-thread-for-dst-root-ca-x3-expiration-september-2021/149190/970
I manually updated the file /etc/ssl/cert.pem to remove the DST Root CA X3 certificate. After that, I think that I moved one step forward. When running:
openssl s_client -showcerts -host valid-isrgrootx1.letsencrypt.org -port 443
Now, I don´t get the error and I think looks good:
CONNECTED(00000005)
depth=2 C = US, O = Internet Security Research Group, CN = ISRG Root X1
verify return:1
depth=1 C = US, O = Let's Encrypt, CN = R3
verify return:1
depth=0 CN = origin.letsencrypt.org
verify return:1
---
Certificate chain
0 s:/CN=origin.letsencrypt.org
i:/C=US/O=Let's Encrypt/CN=R3
However, unfortunately the error in my ruby app still remains the same. According to this, I understand ruby is running an openssl that is not getting the information from this certs. I´m not skilled with this at all and don´t know if this makes sense.
I just read other posts and checking openssl version
I got LibreSSL 2.8.3
which openssl
/usr/bin/openssl
In my /usr/local/opt
I see three openssl versions folders:
I updated my .zshrc
file and now openssl version notifies
OpenSSL 3.0.1 14 Dec 2021 (Library: OpenSSL 3.0.1 14 Dec 2021)
and ruby seems to be using:
ruby -ropenssl -e "puts OpenSSL::OPENSSL_VERSION"
OpenSSL 1.1.1l 24 Aug 2021
I´m aware that the ruby OpenSSL version is 1.1.1 and the system is running 3.0.1. I don´t know how to update ruby to run OpenSSL 3.0.1, although I´m not sure if this can be the root problem. I´m lost at this point.
UPDATE I think I´m narrowing the issue down. My guess is that Ruby is using a version of openSSL, in this case 1.1.1, that is pointing to /Users/Rober/.rbenv/versions/3.0.3/openssl/ssl/certs bundler instead of pointing to /etc/ssl/cert.pem
irb
irb(main):001:0> require "openssl"
=> true
irb(main):002:0> puts OpenSSL::OPENSSL_VERSION
OpenSSL 1.1.1l 24 Aug 2021
=> nil
irb(main):003:0> puts "SSL_CERT_FILE: %s" % OpenSSL::X509::DEFAULT_CERT_FILE
irb(main):004:0> puts "SSL_CERT_DIR: %s" % OpenSSL::X509::DEFAULT_CERT_DIR
SSL_CERT_FILE: /Users/Rober/.rbenv/versions/3.0.3/openssl/ssl/cert.pem
SSL_CERT_DIR: /Users/Rober/.rbenv/versions/3.0.3/openssl/ssl/certs
This file /Users/Rober/.rbenv/versions/3.0.3/openssl/ssl/cert.pem
, unfortunately when I check the content is in the format:
-----BEGIN CERTIFICATE-----
certificate chain
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
-----END CERTIFICATE-----
I mean, in this file /etc/ssl/cert.pem I could read some readable headers that helped identify the certificate to remove, but in this case the headers are not present, so it´s not possible.
I think that I probably just need to config ruby to run openssl to point to this file /etc/ssl/cert.pem. According to mamy posts, I just added export SSL_CERT_FILE="/etc/ssl/cert.pem"
to my .zshrc
file, but still getting
OpenSSL::X509::DEFAULT_CERT_FILE
SSL_CERT_FILE: /Users/Rober/.rbenv/versions/3.0.3/openssl/ssl/cert.pem
SOLUTION Thanks to @JanGaraj that provided the right solution to this problem in my other production post: SSL_connect returned=1 errno=0 state=error: certificate verify failed in ruby and Ubuntu 14.04
Just to summarize, apart from the points depicted above, I just needed to update my web service request specifying my ca-certificates file, like: Savon.client(ssl_ca_cert_file: "/etc/ssl/certs/ca-certificates.crt ")
The solution to this question was provided in another post by @jangaraj
It looks like you are using Ubuntu 14 and Savon 2 client. Savon 2 client doc: https://www.savonrb.com/version2/globals.html
ssl_ca_cert_file
Sets the SSL ca cert file to use.
Savon.client(ssl_ca_cert_file: "lib/ca_cert.pem")
I would point ssl_ca_cert_file to /etc/ssl/certs/ca-certificates.crt explicitly.