Rails/Ubuntu: SSLv3 read server certificate B: certificate verify failed - ruby-on-rails

Two days ago, I started seeing this error on the production server of my app (on staging everything works fine). I found a lot of topics here on SO, but none of them solved this issue for me.
Here's the piece of code that's causing this error message:
#client = Savon.client(wsdl: wsdl_url)
##client = Savon.client(wsdl: wsdl_url, ssl_verify_mode: :none) # this sovles the problem, but I don't want to skip the verification
On SO, I also found that a possible solution might be to create an initializer file and put there the following:
require 'open-uri'
require 'net/https'
module Net
class HTTP
alias_method :original_use_ssl=, :use_ssl=
def use_ssl=(flag)
#self.ca_path = Rails.root.join('lib/ca-bundle.crt').to_s
self.ssl_version = :TLSv1_2 # added
self.ca_file = '/etc/ssl/certs/ca-certificates.crt' # the file exists
self.verify_mode = OpenSSL::SSL::VERIFY_PEER
self.original_use_ssl = flag
end
end
end
But this, unfortunately, didn't solve the error. I also tried to reinstall the certificate on the production Ubuntu (14.04) server
sudo apt-get install openssl ca-certificates
The package has been upgraded, but the error is unfortunately still here.
Any tips what could I do yet and get rid of the error?
EDIT: How or where should I start debugging?

Run openssl s_client -showcerts -connect server_you_are_connecting_to.com:443 and examine the certificate. After this you should find yourself in one of the following situations:
The certificate is valid (has valid expiry date and common name), but it is signed by the certificate authority (CA) that isn't trusted by your system. If that's the case, you would need to add the CA's certificate to the trusted store or update the ca-bundle package on your system.
The certificate is invalid (is expired or has the wrong common name). If disabling peer SSL certificate verification isn't an option for you, then you can implement your own certificate verification callback, for example as described here -- in this case the code wouldn't be relying on system's trusted store, but rather check that the peer server uses a specific certificate.
Hope this helps.

I also started getting this error a few days ago.
Removing geocoder fixed the issue.
Per Heroku support, sometimes these errors occur when an external provider changes their SSL configuration.
Reply to comment:
Nothing in logs specifically saying geocoder, but I saw in my error reports (via exception notifier gem) that the app crashed, with this error, on lines making a request to geocoder.
I also had a callback on the users model, and noticed the app crashed anytime a user was saved/updated.
Lucky guess I suppose.

Related

How can I build an SSL cert/chain for the Rails pg gem to fix PG::ConnectionBad (SSL SYSCALL error: Connection reset by peer (0x00002746/10054))

My company seems to have recently made some sort of change to the Cisco Endpoint Ark blah blah blah setup on our corporate Windows laptops, and the SSL configuration has killed the ability of one of my programs to talk to a Postgres server hosted at Azure. E.g.,
C:\Users\xxxxx\Projects\stuff_and_things>rails c
Loading production environment (Rails 6.0.3.4)
irb(main):001:0> User.first
Traceback (most recent call last):
1: from (irb):1
PG::ConnectionBad (SSL SYSCALL error: Connection reset by peer (0x00002746/10054))
For 3 years, just specifying sslmode: require has been all I've needed for the pg gem to connect to my database server. I've played with the various sslmode and sslrootcert keywords in my database.yml file, but nothing I've tried has worked, and I'm not getting any hints or error messages about what the problem actually is. Rails can't get far enough in this process to even give me any messages in the log.
From other things I've read, I think I need to build a new, single cert that includes the whole chain of trust in one file, and specify that as root.crt, but I can't find any reference about how to do that. I know Rails is "old and busted" now, so finding any tips about this has been really difficult.
Does anyone have any clearer insight on how I could make the Rails pg gem happy again, or at least any way I could get better error messages from the process?
I recalled that I've had to work around this kind of SSL issue on our laptops before, to get bundler working. Thanks to that pointer to RubyInstaller's SSL FAQ, I got that to work after adding Cisco's Umbrella root and 2048 cert .pem's to the right place, and run a script that comes with RubyInstaller to rehash the cert stack. Notably, I was helped in this process through bundler's error messages, which told me that I needed those particular certs to satisfy the chain of trust.
Weighing in at 240KB, I finally realized that the .pem file that RubyInstaller's script had produced -- which is still keeping bundler happy -- was, in fact, the complete trust chain I needed to make the pg gem happy as well, so, in my database.yml, I've used:
sslmode: verify-full
sslrootcert: C:\Ruby25-x64\ssl\cert.pem
And this seems to have made Rails happy again. Now I have to figure out how I'm going to keep these settings separate between my Windows and Linux machines hitting the same production server...

Net/IMAP SSL error, 2.1.5 and 2.2.1, but 2.1.0 and 2.1.2 works

I have the problem that my development machine does not want to connect to my IMAP accounts any more. I know I must have changed something, but cannot think of anything relevant. But what I found is, that with ruby 2.1.0 and 2.1.2 my application works, but with 2.1.5 and 2.2.1 [edit: 2.2.2 failing, too] it does not work.
So I started debugging and extracted the parts that actually connect and throw the SSL error. The shortened script is the following:
require 'net/imap'
#imap = nil
begin
#imap = Net::IMAP.new("mail.example.com", {port: 143})
#imap.starttls({}, true)
#imap.login("username", "password")
rescue => e
puts e
end
The result with 2.0.0 and 2.1.2 is empty, so it worked. But with 2.1.5 and 2.2.1 [edit: and 2.2.2] I get the following error:
SSL_write: certificate verify failed
Of course I immediately checked the server's keychain, but it seems okay. It results in
Verify return code: 0 (ok)
though it has the line
verify error:num=20:unable to get local issuer certificate
but I read that this error is "normal". I cannot explain this error, as I included the certificates correctly with my dovecot server, but when searching the web it looks like everyone else is getting this line with most certificates, too, and it works. Also, like mentioned before, the verify return code is 0, so everything should work.
Do you have an idea if this is a problem with the mentioned line or if it's a bug with newer ruby versions? I could not find any clear search results regarding this.
PS: I need to use starttls, "ssl: true" gives me an unknown protocol error, as I enabled tls only.
edit2: I re-checked again. On the production server, 2.1.5 works. Could it be a problem with CA certificates on the development server or something? But why do older versions work then and newer don't?
--- edit: output as requested ---
I changed my real domain to domain.com in the bin. The host is a sub domain and the certificate a subdomain wildcard certificate from RapidSSL (*.domain.com).
http://pastebin.com/9BGK4w1w
Finally solved it by reinstalling OS X. For some reason it was a problem with my system, though I triple-checked everything from OpenSSL to rvm, Ruby, system-wide installed authority certificates and so on.
Thanks for your help :-)

Mac verify failure on ruby on rails

I am getting an error with my ruby on rails application.
I am trying to use this repository :https://github.com/nomad/dubai to generate a pkpass.
However, I am getting a pcks12Error::Mac verify failure at this step:
Dubai::Passbook.certificate, Dubai::Passbook.password = "/resources/certificate.p12", "mypassword"
# Example.pass is a directory with files "pass.json", "icon.png" & "icon#2x.png"
File.open("Example.pkpass", 'w') do |f|
f.write Dubai::Passbook::Pass.new("Example.pass").pkpass.string
end
I looked on the web but founded nothing about this kind of error in RoR.
EDIT:
I am pretty sure that this is an OpenSSL error. My certificates are coming from another machine. Is that thing can influence this error? Do I have to create a certificate on my machine? To configure OpenSSL?
I founded the answer by myself.
In the Dubai gem, you just have to change the read() by a binread().
It solved my mac verify failure.

Heroku SSL EndPoint -- update cert gives Internal server error

I have a COMODO wildcard SSL certificate that I am trying to replace my old SSL certificate with.
I followed the guides here:
https://devcenter.heroku.com/articles/ssl-endpoint
http://ryan.mcgeary.org/2011/09/16/how-to-add-a-dnsimple-ssl-certificate-to-heroku/
Based off of these, I combined them in to one .pem:
cat STAR_[domain]_com.crt /
EssentialSSLCA_2.crt /
ComodoUTNSGCCA.crt /
UTNAddTrustSGCCA.crt /
AddTrustExternalCARoot.crt >> STAR_[domain]_com-bundle.pem
I then ran:
heroku certs:update STAR_[domain]_com-bundle.pem server.key
and I receive:
Updating SSL Endpoint hyogo-2759.herokussl.com for [heroku-app]... failed
! Internal server error.
! Run `heroku status` to check for known platform issues.
Thanks for your time
So, the skinny is that Heroku's error messages were not very good and/or were not expecting what I gave them, hence the Internal Server Error lacking any specifics.
Heroku got back to me and said they will look in to better error messages for this, but I doubt that will happen.
The solution:
Instead of using the .pem extension, use .crt

OpenSSL::SSL::SSLError on Heroku [duplicate]

This question already has answers here:
SSL Error When installing rubygems, Unable to pull data from 'https://rubygems.org/
(26 answers)
Closed 8 years ago.
I'm trying to authenticate a user via Facebook or Twitter, get them to fill out their information, and then click save (thus creating a user record). I'm getting an OpenSSL error on that final step -- after clicking save. This happens at the Devise RegistrationsController#create method.
So I'm getting this error in my Rails application, hosted on Heroku:
2012-07-28T18:25:13+00:00 app[web.1]: OpenSSL::SSL::SSLError (SSL_connect returned=1 errno=0 state=SSLv3 read server certificate B: certificate verify failed)
I've seen plenty of solutions, none of them work. Here are some things I've tried:
1) Installing the certified gem
2) Upgrading the Heroku gem to v2.30, pushing again
3) This:
Rails.application.config.middleware.use OmniAuth::Builder do
provider :twitter, TWITTER_KEY, TWITTER_SECRET, {:client_options => {:ssl => {:ca_file => "/usr/lib/ssl/certs/ca-certificates.crt"}}}
provider :facebook, FACEBOOK_KEY, FACEBOOK_SECRET, {:scope => "publish_actions,user_location,email", :client_options => {:ssl => {:ca_file => "/usr/lib/ssl/certs/ca-certificates.crt"}}}
end
It seems like one problem could be that this cert file doesn't actually exist -- I've seen it in several places, and it seems like that is the default path to the ca_cert file for Heroku, but I could be wrong.
Oddly enough, this is happening after I've already authenticated via FB/Twitter, and am trying to create a user's account. Why would this be, and how can I solve/debug this? Sincerely confused.
Update: I added this line to the Omniauth initializer, and now it "works". Thus I've diagnosed the problem is with Omniauth. However, I'd like to still have the SSL verification... this obviously leaves a security gap.
OpenSSL::SSL::VERIFY_PEER = OpenSSL::SSL::VERIFY_NONE
After some searching here is what I found:
If you’re using Ruby to open connections to an external server over https, eg. the Facebook Graph API, you may run into the following error:
OpenSSL::SSL::SSLError:SSL_connectreturned=1errno=0state=SSLv3readservercertificateB:certificateverifyfailed
This error is due to Ruby not being able to find the certification authority certificates (CA Certs) used to verify the authenticity of secured web servers. The solution is to download the this ca-bundle.crt into your application’s lib/ directory:
Then add the following code to config/initializers/fix_ssl.rb:
require 'open-uri'
require 'net/https'
module Net
class HTTP
alias_method :original_use_ssl=, :use_ssl=
def use_ssl=(flag)
self.ca_file = Rails.root.join('lib/ca-bundle.crt').to_s
self.verify_mode = OpenSSL::SSL::VERIFY_PEER
self.original_use_ssl = flag
end
end
end
This should force ruby to use the CA bundle from your application’s lib/ directory.
Taken from: http://jimneath.org/2011/10/19/ruby-ssl-certificate-verify-failed.html
UPDATE:
You may need to use self.ca_path= instead of self.ca_file= depending on your system.
It sounds like you've got the right openssl configuration in OmniAuth, but perhaps your CA certs path isn't correct?
You can check that on your heroku servers by running:
heroku run bash
... and then running openssl to display the proper path:
$ openssl version -a
OpenSSL 1.0.0e 6 Sep 2011
OPENSSLDIR: "/usr/lib/ssl"
... You should find the ca_certificates.crt file at $OPENSSLDIR/certs/ca-certificates.crt
I would confirm that path an update your code to match.

Resources