2

I've been trying to use an SSL (SAN) certificate for our internal Rails app.

I have created the certificate files using OpenSSL and have them working nicely with Apache:

<VirtualHost *:443>
  ServerName server-name
  RailsEnv uat

  DocumentRoot /var/www/server-name/current/public
  <Directory /var/www/server-name/current/public>
    AllowOverride All
    Options -MultiViews
  </Directory>

  SSLEngine on
  SSLCertificateFile /etc/apache2/ssl/hostname.cer
  SSLCertificateKeyFile /etc/apache2/ssl/hostname.key
</VirtualHost>

This works fine.

My issue is when using open-uri to communicate with some of the Rails controllers, i get the error message:

require "net/https"

uri = URI.parse("https://server-name.domain.com/controller.json?date=2013-09-03") 
http = Net::HTTP.new(uri.host, uri.port)
http.use_ssl = true
http.start {
  http.request_get(uri.path) {|res|
    print res.body
  }
}

OpenSSL::SSL::SSLError: SSL_connect returned=1 errno=0 state=SSLv3 read server certificate B: certificate verify failed

I have seen many StackOverflow articles which suggest simply turning off SSL verification, using:

http.verify_mode = OpenSSL::SSL::VERIFY_NONE

But I do not consider this a satisfactory approach. I have also seen articles which suggest i need to point open-uri to /etc/ssl/certs/ca-certificates.crt which is clearly for public certificates. So for my self signed certificate, i tried the following:

uri = URI.parse("https://server-name.domain.com/controller.json?date=2013-09-03") 
http = Net::HTTP.new(uri.host, uri.port)
if uri.scheme == "https"  # enable SSL/TLS
  http.use_ssl = true
  http.verify_mode = OpenSSL::SSL::VERIFY_PEER
  http.ca_file = "/etc/apache2/ssl/host-name.cer"
end
http.start {
  http.request_get(uri.path) {|res|
    print res.body
  }
}

Which worked.

My question is, how do i tell OpenSSL / OpenURI to always look in the /etc/apache2/ssl/ directory in addition to its current search path? I don't want to specify the path (which will change as the host name changes depending where we are working from) in each request i make.

Thanks

4

1 回答 1

6

Extracted from here:

If there’s already a CA bundle on disk that you want to use, point SSL_CERT_FILE or SSL_CERT_DIR environment variables to it, or set the ca_file= or ca_path= properties in Net::HTTP.

So all you have to do is this

ENV['SSL_CERT_FILE'] = "your certificate path"

and all should work.

You might find this resource useful:

于 2013-09-16T10:28:29.290 回答