Technology Musings

Hot-Patching Ruby for TLS 1.2

JB

Authorize.net recently started denying TLS requests that were less than 1.2.  I thought I was fine, but I had one server running CentOS 5.  It was not fine.  I had a very ancient Rails application on an ancient box unable to connect to Authorize.net.

Anyway, if you are in a similar situation, here is how I solved it.  This may not be exact, but should hopefully get you far enough along to figure it out yourself:

p.p1 {margin: 0.0px 0.0px 0.0px 0.0px; font: 12.0px 'Helvetica Neue'; color: #454545} p.p2 {margin: 0.0px 0.0px 0.0px 0.0px; font: 12.0px 'Helvetica Neue'; color: #454545; min-height: 14.0px}

For authorize.net's TLS upgrade, it is based on your server's OpenSSL library version.  To see if you are compatible, run the following command:

 

    openssl s_client -connect secure.authorize.net:443

 

If you get a one-line error message like this:


    6641:error:14077410:SSL routines:SSL23_GET_SERVER_HELLO:sslv3 alert handshake failure:s23_clnt.c:586:

 

Then you are NOT compatible.  To fix, you need to either update your OpenSSL in Linux or get the latest OpenSSL from here - https://www.openssl.org/source/

 

For building, you may have to configure it something like this:


    export CFLAGS=-fPIC
    ./config shared
    make
    make install     # this one as root

 

I also copied the generated shared libs into /lib64.  In theory, after updating, it would be best to rebuild ruby from source.  However, absent that, there is a trick you can do:

 

Create a new file, I called mine ruby_openssl in the same directory as the old ruby.  The file should have the following contents:

 

    #!/bin/sh
    export LD_PRELOAD=/lib64/libssl.so.1.0.0:/lib64/libcrypto.so.1.0.0
    exec /opt/ruby-1.8.7-p352/bin/ruby $*

 

The LD_PRELOAD should go to the shared files that were installed by installing OpenSSL, wherever you happened to install them.

 

Then, in your apache config, reference your new ruby_newopenssl wherever you were referencing ruby.