How to connect with PostgreSQL database over SSL?

流过昼夜 提交于 2020-06-11 03:03:45

问题


I have created my own certificate and configured postgresql.conf file:

...
#authentication_timeout = 1min          # 1s-600s
ssl = true                              # (change requires restart)
ssl_ciphers = 'HIGH:MEDIUM:+3DES:!aNULL' # allowed SSL ciphers
                                        # (change requires restart)
#ssl_prefer_server_ciphers = on         # (change requires restart)
#ssl_ecdh_curve = 'prime256v1'          # (change requires restart)
ssl_cert_file = '/etc/ssl/certs/company/database/certificate'           # (change requires restart)
ssl_key_file = '/etc/ssl/certs/company/database/key'            # (change requires restart)
ssl_ca_file = '/usr/share/ca-certificates/company/ca/certificate'                        # (change requires restart)
#ssl_crl_file = ''                      # (change requires restart)
#password_encryption = on
#db_user_namespace = off
#row_security = on
...

Then, I allow my server to connect with my database, pg_hba.conf:

...
hostssl    postgres             postgres             XXX.XXX.XXX.XXX/0            md5
...

So, I can connect to it via psql command line:

psql (9.5.3)
SSL connection (protocol: TLSv1.2, cipher: ECDHE-RSA-AES256-GCM-SHA384, bits: 256, compression: off)
Type "help" for help.

postgres=#

But, when I try to open a connection with the database via my java application, even when I provide the truststore with my database certificate included, I keep getting no connection with it:

mvn package -Djavax.net.ssl.trustStore=/opt/app/truststore -Djavax.net.ssl.trustStorePassword=changeit

Exception:

2016-05-23 16:28:32,900 WARN [com.mchange.v2.resourcepool.BasicResourcePool] - <Having failed to acquire a resource, com.mchange.v2.resourcepool.BasicResourcePool@75fa1be3 is interrupting all Threads waiting on a resource to check out. Will try again in response to new client requests.>
2016-05-23 16:28:32,900 WARN [com.mchange.v2.resourcepool.BasicResourcePool] - <com.mchange.v2.resourcepool.BasicResourcePool$ScatteredAcquireTask@2be057bf -- Acquisition Attempt Failed!!! Clearing pending acquires. While trying to acquire a needed new resource, we failed to succeed more than the maximum number of allowed acquisition attempts (30). Last acquisition attempt exception: >
java.lang.NullPointerException
    at org.postgresql.Driver.parseURL(Driver.java:532)
    at org.postgresql.Driver.acceptsURL(Driver.java:431)
    at java.sql.DriverManager.getDriver(DriverManager.java:299)
    at com.mchange.v2.c3p0.DriverManagerDataSource.driver(DriverManagerDataSource.java:285)
    at com.mchange.v2.c3p0.DriverManagerDataSource.getConnection(DriverManagerDataSource.java:161)
    at com.mchange.v2.c3p0.WrapperConnectionPoolDataSource.getPooledConnection(WrapperConnectionPoolDataSource.java:161)
    at com.mchange.v2.c3p0.WrapperConnectionPoolDataSource.getPooledConnection(WrapperConnectionPoolDataSource.java:147)
    at com.mchange.v2.c3p0.impl.C3P0PooledConnectionPool$1PooledConnectionResourcePoolManager.acquireResource(C3P0PooledConnectionPool.java:202)
    at com.mchange.v2.resourcepool.BasicResourcePool.doAcquire(BasicResourcePool.java:1138)
    at com.mchange.v2.resourcepool.BasicResourcePool.doAcquireAndDecrementPendingAcquiresWithinLockOnSuccess(BasicResourcePool.java:1125)
    at com.mchange.v2.resourcepool.BasicResourcePool.access$700(BasicResourcePool.java:44)
    at com.mchange.v2.resourcepool.BasicResourcePool$ScatteredAcquireTask.run(BasicResourcePool.java:1870)
    at com.mchange.v2.async.ThreadPoolAsynchronousRunner$PoolThread.run(ThreadPoolAsynchronousRunner.java:696)
2016-05-23 16:28:32,901 WARN [com.mchange.v2.resourcepool.BasicResourcePool] - <Having failed to acquire a resource, com.mchange.v2.resourcepool.BasicResourcePool@75fa1be3 is interrupting all Threads waiting on a resource to check out. Will try again in response to new client requests.>

Via psql everything seems to be working fine, not with my application. Any suggestion ?

EDIT:

My props.properties file:

uatDb.user=postgres
uatDb.password=password
uatDb.driverClass=org.postgresql.Driver
uatDb.jdbcUrl=jdbc:postgresql://<server_name>:1234/uat?ssl=true
uatDb.port=5443
uatDb.name=uat
uatDb.host=<server_name>

回答1:


url=jdbc:postgresql://<host_url_or_ip>:<port>/<db_name>?currentSchema=<schema_name>&sslmode=verify-ca&sslfactory=org.postgresql.ssl.DefaultJavaSSLFactory

Note: if schema_name is public, it is not required. But port even if is default i.e. 5432, you have to provide it.

For sslmode values ref: https://jdbc.postgresql.org/documentation/head/ssl-client.html set sslfactory=org.postgresql.ssl.DefaultJavaSSLFactory to enable validation.

For non-validating ssl connection, you can use sslfactory=org.postgresql.ssl.NonValidatingFactory

But remember, once you enable SSL validation, it may require a root CA certificate.

You have various options as follows (may not be exhaustive. but these worked for me.)

  1. You can place it in its default place i.e ~/Postgres/root.crt OR
  2. Set PGSSLROOTCERT env variable to its path OR
  3. import into a truststore and pass it path as: -Djavax.net.ssl.trustStore=[trust_store_path] -Djavax.net.ssl.trustStorePassword=[trust_store_password]. If you are using default truststore i.e. JRE's cacerts these two env variables are not required.

Ref:

https://jdbc.postgresql.org/documentation/head/ssl-client.html

https://www.postgresql.org/docs/9.0/libpq-ssl.html




回答2:


Need a keystore too I believe. Since ssl=true should require a private key for your self-signed cert. I also would add "nonValidating SSLFactory" setting

?ssl=true&sslfactory=org.postgresql.ssl.NonValidatingFactory

Also your port setting for server_name:1234 does not match 5432.

"parseUrl" is a null error, maybe there's a variable somewhere in the JDBC url that is incorrectly set.




回答3:


If you don't need to verify database client, just comment out ssl_ca_file in postgresql.conf.

ssl_ca_file - trusted certificate authorities, checks that client certificate is signed by a trusted certificate authority.

Your database URL should look like this:

url=jdbc:postgresql://host:5432/db_name?ssl=true&sslmode=require

Refer to PostgreSQL JDBC docs for more details on sslmode.

Otherwise, in case you need to verify the database client, you should add sslcert=... and sslkey=... parameters to your database URL.



来源:https://stackoverflow.com/questions/37394078/how-to-connect-with-postgresql-database-over-ssl

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!