So I've upgraded an app from rails 2.2 to 2.3.12 and my last remaining issue is the problem of facebook connect integration.
I am using the oauth2 gem for this and well I keep getting the following error
OpenSSL::SSL::SSLError (SSL_connect returned=1 errno=0 state=SSLv3 read server certificate B: certificate verify failed):
I've tried to follow the descriptions on the oauth2 wiki page just to end up with anohter error that was solved by forking the project and adapting the code. read here.
I do not have the issue on my development server but only in production.
my client code looks as follows
def client
ca_file = File.join('/etc/ssl/cacert.pem')
#client ||= OAuth2::Client.new( 'app_id', 'app_secret', {
:site => {
:url=>'https://graph.facebook.com',
:ssl=>{
:verify => OpenSSL::SSL::VERIFY_PEER,
:ca_file => ca_file
}
},
:adapter => :NetHttp
})
#client
end
I've confirmed about a hundred times now that my cacert.pem file is there and that
the rights are ok.
Any ideas on where to begin debugging are welcome.
SOLVED
I moved this site on to a new server running Debian 6.0 (sqeeze) instead of 5.0 (etch) and this solved my problem. My take on this is that I got a newer version of OpenSSL:
Debian 6.0: OpenSSL 0.9.8o 01 Jun 2010
Debian 5.0: OpenSSL 0.9.8g 19 Oct 2007
I can't guarantee that this was the issue but since it's now working with no code changes. I assume it is.
Related
I have small Rails app that performs various checks on our platform and sends me an email in case of an issue. Everything was running fine until today i started getting alerts about the following error:
SSL_connect returned=1 errno=0 state=error: certificate verify failed (certificate has expired)
Now the problem is the certificate in question is valid, it gets automatically renewed (Let's encrypt) and this code has been untouched for a couple of years and never had any issues before and suddenly this started to happen.
The code that throws the exception:
def get_request url
uri = URI.parse(url)
http = Net::HTTP.new(uri.host, uri.port)
http.use_ssl = true
#more than 10 seconds this is too slow
http.open_timeout = 10
http.read_timeout = 10
request = Net::HTTP::Get.new(uri.request_uri)
response = http.request(request)
if response.code.to_i == 200
return true
else
puts "Failed to GET #{url}: #{response.code.to_i}"
return false
end
end
If i open the site in the browser, it shows the secure connection without issues and shows that is using a valid certificate, furthermore if i check with certbot i get the following: Expiry Date: 2021-11-22 17:48:58+00:00 (VALID: 52 days) so clearly the certificate is valid, why suddenly rails is throwing a tantrum about it?
Note that i have restarted Nginx just in case, that didn't help.
Additional info: Ubuntu 16.04.5, OpenSSL 1.0.2g 1 Mar 2016, Rails 4.2, Ruby 2.6.5
EDIT:
This error also happens with a different url, which also has a valid certificate.
EDIT 2:
I've isolated the problem, it is related to Let's Encrypt DST Root CA X3 that has expired. A lot of people are dealing with this issue, i'll report my solution once i find one.
So after reading through this long thread of the Let's Encrypt community, the solution for my case ended up being to remove the DST Root CA X3 certificate:
sudo rm /usr/share/ca-certificates/mozilla/DST_Root_CA_X3.crt
sudo update-ca-certificates
After that no more errors from openssl.
I'm trying to connect a webcrawler that accesses a certain site via SSL and queries my data on that site. The authentication of this site is via a self-signed Digital Certificate. At the moment I want to access the site, I upload this certificate in .pfx format to my api, convert it to .pem, and when I try to access the site with this certificate, the response comes with status 403 (forbidden ).
However, when I try to access the site through a browser with the certificate in .pfx format I usually get it.
I already tried using Mechanize, and it worked for a while (until a few months ago it worked), but then it started to give the error:
SSL_connect returned = 1 errno = 0 state = SSLv3 read finished A: sslv3 alert bad certificate
The site is old, it does not receive updates frequently.
After that I already tried to use the net / http lib and the error persisted, I tried to use the httprb gem and lastly I tried with Faraday. All attempts ended either in that error quoted above or with the response status == 403.
What can I do to be able to connect? Is there something wrong with my script? Is it missing any information I need to get through?
Code:
# Faraday customs method:
class FaradayHttp
def with_openssl
system "openssl pkcs12 -in my-certificate-path -out certificate-output-path -nodes -password pass:certificate-password"
def cert_object
OpenSSL::X509::Certificate.new File.read("certificate-output-path")
end
# create PKey
def key_object
OpenSSL::PKey.read File.read("certificate-output-path")
end
faraday = Faraday::Connection.new 'https://example-site.com',
:ssl => {
certificate: cert_object,
private_key: key_object,
version: :SSLv3,
verify: false
}
faraday
end
end
# Controller that try to connect with the ssl server:
agent = FaradayHttp.new.with_openssl
page = agent.get '/login_path'
# mypki will prompt you for certificates
require 'mypki'
# faraday will use certificates from mypki
require 'faraday'
faraday = Faraday::Connection.new 'https://example-site.com'
faraday.get '/login_path'
Currently running into an issue where my background workers which are communicating with elasticsearch via elasticsearch-client are running into SSL errors inside Faraday.
The error is this:
SSL_connect returned=1 errno=0 state=SSLv3 read server hello A: sslv3 alert handshake failure
The configuration works fine some of the time (around ~50%) and it has never failed for me inside of a console sessions.
The trace of the command is this:
curl -X GET 'https://<host>/_alias/models_write?pretty
The client config is this
Thread.current[:chewy_client] ||= begin
client_configuration[:reload_on_failure] = true
client_configuration[:reload_connections] = 30
client_configuration[:sniffer_timeout] = 0.5
client_configuration[:transport_options] ||= {}
client_configuration[:transport_options][:ssl] = { :version => :TLSv1_2 }
client_configuration[:transport_options][:headers] = { content_type: 'application/json' }
client_configuration[:trace] = true
client_configuration[:logger] = Rails.logger
::Elasticsearch::Client.new(client_configuration) do |f|
f.request :aws_signers_v4,
credentials: AWS::Core::CredentialProviders::DefaultProvider.new,
service_name: 'es',
region: ENV['ES_REGION'] || 'us-west-2'
end
end
As you can see I explicitly set the ssl version to TSLv1_2, but still getting an SSLv3 error.
Thought maybe it was a race condition issue. So ran a script spawning about 10 processes with 50 threads each and calling the sidekiq perform method inside and still not able to reproduce.
I am using the managed AWS 2.3 Elasticsearch if that is at all relevant.
Any help or guidance in the right direction would be greatly appreciated, I would be happy to attach as much info as needed.
Figured it out. The problem was that the elasticsearch-ruby gem autoloads in an http adapter that it detects if one is not specified. The one used in my console was not the one getting auto loaded into sidekiq.
The sidekiq job was using the HTTPClient adapter which did not respect the SSL version option. Thus I was getting this error. After explicitly defining the faraday adapter it worked.
I am making a Ruby On Rails application and I am attempting to use the Google Plus API's for user sign in. To do this I am using Signet an OAuth helper library. I am looking at this code as an example of Signet with Google APIs.
Here is my code:
require "signet/oauth_2/client"
require "google/api_client"
oathClient = Signet::OAuth2::Client.new(
:authorization_uri => "https://accounts.google.com/o/oauth2/auth",
:token_credential_uri => "https://accounts.google.com/o/oauth2/token",
:client_id => Rails.application.secrets.gapi_client_id,
:client_secret => Rails.application.secrets.gapi_client_secret,
:redirect_uri => Rails.application.secrets.gapi_redirect_uri,
:scope => "https://www.googleapis.com/auth/plus.login")
gapi_client = Google::APIClient.new(
:application_name => "Branches",
:application_version => "0.0.1")
oathClient.code = request.body.read
oathClient.fetch_access_token!#Error on this line
gapi_client.authorization = oathClient
An error occurs on the second to last line:
oathClient.fetch_access_token!
This is the error:
SSL_connect returned=1 errno=0 state=SSLv3 read server certificate B: certificate verify failed
I have done some research and it seams like this is caused by the lack of certificate information. However none of the solution's shown address this issue when dealing with Signet.
OS: Windows 8 x64
RoR version: 4.1.1
Signet Version: 0.5.1
Google API Client Version: 0.6.2
Looks related to https://github.com/googleapis/google-api-ruby-client/issues/235, where the solutions were:
update openssl
if you're using a custom .pem file, set it with: export SSL_CERT_FILE=/path/to/custom/certificate/authority.pem
I am using omniauth and twitter login for my site. However, whenever I try to login, it gave this error:
Started GET "/auth/failure?message=service_unavailable" for 98.83.218.118 at 2011-11-12 11:27:58 -0500
Processing by SessionsController#failure as HTML
Parameters: {"message"=>"service_unavailable"}
The only clue I have is that it might be an SSL error.
However, I have no idea on how to debug the cause of the error.
Here is my current configuration for twitter:
Rails.application.config.middleware.use OmniAuth::Builder do
provider :twitter, 'REDACTED', 'REDACTED'
end
It looks like ssl issue in my project.
For development mode you can off ssl. Then you can work without this issue.
add this in develoment.rb:
OpenSSL::SSL::VERIFY_PEER = OpenSSL::SSL::VERIFY_NONE
And about how fix SSL certificates:
Twitter API SSL Root CA Certificate
I don't really like the solution suggested in at twitter dev support (as linked by Yahor Zhuchkou), which suggest downloading just a bunch of certificates from an unsecure server.
And while turning of verify peer will work in production that isn't really a solution. What you need to do is to point omniauth to the correct PEM file, which should contain something like, the Verisign Root Certificate which backs Twitter's own certificate (i:/C=US/O=VeriSign, Inc./OU=Class 3 Public Primary Certification Authority - G2/OU=(c) 1998 VeriSign, Inc. - For authorized use only/OU=VeriSign Trust Network):
-----BEGIN CERTIFICATE-----
MIIDAjCCAmsCEH3Z/gfPqB63EHln+6eJNMYwDQYJKoZIhvcNAQEFBQAwgcEx
CzAJBgNVBAYTAlVTMRcwFQYDVQQKEw5WZXJpU2lnbiwgSW5jLjE8MDoGA1UE
CxMzQ2xhc3MgMyBQdWJsaWMgUHJpbWFyeSBDZXJ0aWZpY2F0aW9uIEF1dGhv
cml0eSAtIEcyMTowOAYDVQQLEzEoYykgMTk5OCBWZXJpU2lnbiwgSW5jLiAt
IEZvciBhdXRob3JpemVkIHVzZSBvbmx5MR8wHQYDVQQLExZWZXJpU2lnbiBU
cnVzdCBOZXR3b3JrMB4XDTk4MDUxODAwMDAwMFoXDTI4MDgwMTIzNTk1OVow
gcExCzAJBgNVBAYTAlVTMRcwFQYDVQQKEw5WZXJpU2lnbiwgSW5jLjE8MDoG
A1UECxMzQ2xhc3MgMyBQdWJsaWMgUHJpbWFyeSBDZXJ0aWZpY2F0aW9uIEF1
dGhvcml0eSAtIEcyMTowOAYDVQQLEzEoYykgMTk5OCBWZXJpU2lnbiwgSW5j
LiAtIEZvciBhdXRob3JpemVkIHVzZSBvbmx5MR8wHQYDVQQLExZWZXJpU2ln
biBUcnVzdCBOZXR3b3JrMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDM
XtERXVxp0KvTuWpMmR9ZmDCOFoUgRm1HP9SFIIThbbP4pO0M8RcPO/mn+SXX
wc+EY/J8Y8+iR/LGWzOOZEAEaMGAuWQcRXfH2G71lSk8UOg013gfqLptQ5GV
j0VXXn7F+8qkBOvqlzdUMG+7AUcyM83cV5tkaWH4mx0ciU9cZwIDAQABMA0G
CSqGSIb3DQEBBQUAA4GBAFFNzb5cy5gZnBWyATl4Lk0PZ3BwmcYQWpSkU01U
bSuvDV1Ai2TT1+7eVmGSX6bEHRBhNtMsJzzoKQm5EWR0zLVznxxIqbxhAe7i
F6YM40AIOw7n60RzKprxaZLvcRTDOaxxp5EJb+RxBrO6WVcmeQD2+A2iMzAo
1KpYoJ2daZH9
-----END CERTIFICATE-----
(If you're using Ubuntu you may find it here: /etc/ssl/certs/Verisign_Class_3_Public_Primary_Certification_Authority_-_G2.pem )
Don't know why omniauth or ruby openssl implementation isn't finding this, but you can explicitly link to this pem file with the following option:
provider :twitter, 'REDACTED', 'REDACTED', {
:client_options => {:ca_file => '/etc/ssl/certs/Verisign_Class_3_Public_Primary_Certification_Authority_-_G2.pem'}
}