Ruby SSL error - sslv3 alert unexpected message
Just to answer my own question.
The problem seems to be with how Ruby negotiates SSL connections. There's an error in Xpiron's TLS mechanism, and it throws an error instead of retrying to other SSL versions.
If you force the SSL version to 3.0, it works:
require 'net/http'
url = URI.parse('https://www.xpiron.com/schedule')
req = Net::HTTP::Get.new(url.path)
sock = Net::HTTP.new(url.host, 443)
sock.use_ssl = true
sock.ssl_version="SSLv3"
sock.start do |http|
response = http.request(req)
end
I also created an issue on Ruby's bug tracker.
sslv3 alert unexpected message when using soap4r
We ended up dropping soap4r, it is severely out of date. Switching libraries, while not ideal, solved the problem. For anyone running into issues similar to this, I recommend switching to savon. It was actually easier than I thought it would be
OpenSSL::SSL::SSLError in UsersController#create (SSL_connect returned=1 errno=0 state=unknown state: unknown protocol)
It appears to be related to a known bug in ubuntu 12.04 when using openssl 1.0.1 as described in the last answer here:
OpenSSL::SSL::SSLError Ubuntu 12.04 only
You can find more information about the bug on Ubuntu's bug tracker https://bugs.launchpad.net/ubuntu/+source/openssl/+bug/965371
Apparently, if you force the use of SSLv3, the error should disappear.
Ruby SSL error - sslv3 alert unexpected message
You might also want to check out if leotechnosoft.net
is blocking port 25 when using SSL as some hosting providers sometimes block port 25 by default. When you're using SSL try with port 465 instead.
OpenSSL::SSL::SSLError: SSL_connect returned=1 errno=0 state=unknown state: unknown protocol
The problem appears to be that your target site, aristo4stu3.bgu.ac.il
, is picky about SSL/TLS handshaking. I got two different results with the following OpenSSL command with different versions of OpenSSL:
openssl s_client -connect aristo4stu3.bgu.ac.il:443
This does connect with the stock OpenSSL 0.9.8x on OS X 10.7.5. However, it does not connect using OpenSSL 1.0.1e - in that case the server just closes the connection (by sending a Close Notify alert) immediately after receiving the Client Hello.
I captured packets with Wireshark, and the difference between what these two versions send is that 0.9.8x is sending an SSLv2 Client Hello advertising support through TLS 1.0, while 1.0.1e is sending a TLSv1 Client Hello advertising support through TLS 1.2.
If I tell 1.0.1e not to use TLS:
openssl s_client -connect aristo4stu3.bgu.ac.il:443 -no_tls1
This connects successfully with an SSLv3 Client Hello advertising support through SSL 3.0.
Incidentally, my local ruby does make a successful connection with open-uri
to your site:
$ irb
>> require 'open-uri'
=> true
>> open('https://aristo4stu3.bgu.ac.il')
=> #<StringIO:0x10271fa90>
>> require 'openssl'
=> false
>> OpenSSL::OPENSSL_VERSION
=> "OpenSSL 0.9.8r 8 Feb 2011"
>>
So the indicated approaches seem to be:
- Upgrade the server to handle more Client Hello variants, or
- Install a ruby that uses an older OpenSSL library, or
- Change your program to send a different Client Hello.
It does not appear that the open-uri
module has an option to set the SSL/TLS version used to communicate. If you can't modify the server you may need to use a different module or library to establish the connection, or perhaps find a way to patch the openssl
module so it uses a different Client Hello.
OpenSSL::SSL::SSLError Ubuntu 12.04 only
What is your current SSL_Cert_file environmental variable set to?
Try setting the SSL_Cert_file environmental variable to:
export SSL_CERT_FILE=/etc/ssl/certs/ca-certificates.crt
If that doesn't work and you are using RVM maybe setting the path to: ~/.rvm/usr/ssl/cert.pem
Before you make any changes just note down what the path currently is so that you can set it back if needed.
OpenSSL::SSL::SSLError: SSL_connect SYSCALL returned=5 errno=0 state=SSLv3 read server hello A
This is a problem at the server site. It looks like the server is exclusively accepting TLS 1.2 and does not show the usual behavior when the client requests something lesser (like downgrading or sending SSL alert) but instead just closes the connection.
TLS 1.2 is not supported by OpenSSL 0.9.8 and additionally your code enforces SSLv3. You get TLS 1.2 only when upgrading to OpenSSL 1.0.1.
Some browsers will also fail to connect to this server, even if they have ways to work around such broken servers. But while Firefox will only try to downgrade the connection to lesser SSL version (which often helps) Chrome manages to connect with TLS 1.2.
Edit: I've analyzed the issue further and now I cannot get a connection with TLS1.2 anymore but I can get a connection with TLS1.0 or SSL3.0, but only if the ciphers is hard coded to RC4-SHA. I've tried others like AES128-SHA or DES-CBC3-SHA and they don't work.
So while it looks like a really messed up system explicitly setting
http.ssl_version = 'TLSv1' -- or SSLv3, but TLSv1 is better
http.ssl_cipher = 'rc4-sha'
should work. I'm not a ruby user so the exact syntax might differ, but I've tested with OpenSSL s_client.
Related Topics
Rails Unable to Convert Unpermitted Parameters to Hash
How to Add to a Serialized Array
Combine Array of Array into All Possible Combinations, Forward Only, in Ruby
How to Enable Tls V1.2 in Ruby? If So, How
How to Easily Parse a Url with Parameters in a Rails Test
How to Ftp in Ruby Without First Saving the Text File
How to Test Exception Raising in Rails/Rspec
How to Set Private Instance Variable Used Within a Method Test
Rails 3.1 Absolute Url to an Image
How to Compile Ruby to Byte Code as with Python
Storing Arrays in Database Using Activerecord
How Does Ruby's Sort_By {Rand} Work