jruby / activerecord-jdbc-adapter

JRuby's ActiveRecord adapter using JDBC.
BSD 2-Clause "Simplified" License
462 stars 385 forks source link

ActiveRecord::JDBCError FATAL: connection requires a valid client certificate #1077

Open NCCastillo opened 4 years ago

NCCastillo commented 4 years ago

Our jruby rails app is receiving "ActiveRecord::JDBCError: FATAL: connection requires a valid client certificate" when trying to connect to postgres over ssl. I know there is some configuration to be done on the java side to allow a truststore/keystore.

I have tried to implement this and I am sure I am missing some configuration. I found this note which states:

# JRuby/JVM needs to be started with :
      #  -Djavax.net.ssl.trustStore=mystore -Djavax.net.ssl.trustStorePassword=...

Does anyone know how to implement this?

This is what I have done so far: jruby version: jruby 9.2.7.0 (2.5.3) 2019-04-09 8a269e3 OpenJDK 64-Bit Server VM 25.252-b09 on 1.8.0_252-b09 +jit [linux-x86_64]

Rails version: Rails 5.0.7.2

active record jdbc adapater: activerecord-jdbc-adapter (50.7-java)

Setting up keystore:

# adopted from https://stackoverflow.com/questions/31055623/google-cloud-sql-with-ssl-from-compute-engine-and-or-external-network

1)Convert server ca to der format 
  openssl x509 -outform der -in server-ca.pem -out server-ca.der

2)Create your own keystore 
  keytool -keystore mykeystore -alias postgresssl -import -file server-ca.der

3)Convert x509 certificate and private key to a pkcs12 file:
  openssl pkcs12 -export -in client-cert.pem -inkey client-key.pem -out client.p12

4)Convert the pkcs12 file to a java keystore:
  keytool -importkeystore -srckeystore client.p12 -srcstoretype PKCS12 -destkeystore keystore.jks -deststoretype JKS

On the rails side:

# database.yml
default: &default
  adapter: postgresql
  encoding: unicode
  username: <%= ENV["username"] %>
  password: <%= ENV["password"] %>
  host: <%= ENV["database_host"] %>
  database: <%= ENV["database_name"] %>

# Am I missing configs here? This is our config in a normal rails environment
production:
  <<: *default
  sslmode: allow
  sslrootcert: <path to ssl root cert>
  sslkey: <path to ssl key>
  sslcert: <path to ssl cert>

Start rails with java options to point to keystore:

#Pass java options with paths to truststore and keystore which were created as described above 

bundle exec jruby -J-Djavax.net.ssl.trustStore=truststorepathhere -J-Djavax.net.ssl.trustStorePassword=passwordhere -J-Djavax.net.ssl.keyStore=keystorepathhere -J-Djavax.net.ssl.keyStorePassword=keystorepasswordhere -S rails s

Any suggestion would be greatly appreciated. I feel like I am close but I have been banging my head on this for a few days now.

dr-itz commented 3 years ago

The PG JDBC driver pgjdbc has its own properties, see: https://jdbc.postgresql.org/documentation/head/connect.html#connection-parameters. From a cursory look, this seems to match what you mention above.

For activerecord-jdbc-adapter, passing these options is a little different, they need to be in a properties block:

production:
  <<: *default
  properties:
    sslmode: allow
    sslrootcert: <path to ssl root cert>
    sslkey: <path to ssl key>
    sslcert: <path to ssl cert>

(we do understand the sslmode outside of properties, but nothing else). That being said, I never tried a connection with a client certificate.