配置一个“数据源"以使用SSL/TLS加密连接到Digital Ocean上的托管Postgres服务器 [英] Configure a `DataSource` to connect to a managed Postgres server on Digital Ocean with SSL/TLS encryption

查看:99
本文介绍了配置一个“数据源"以使用SSL/TLS加密连接到Digital Ocean上的托管Postgres服务器的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在托管数据库服务 ://en.wikipedia.org/wiki/DigitalOcean"rel =" nofollow noreferrer> DigitalOcean.com ,创建了

I am trying the managed database service on DigitalOcean.com, having created a Postgres instance.

Digital Ocean默认要求使用 SSL (实际上是 TLS )加密.

Digital Ocean defaults to requiring remote connections be made with SSL (actually TLS) encryption.

如何配置 JDBC

How does one configure a JDBC DataSource implementation for providing connections to such a database server?

此问题类似于 以编程方式为Postgres JDBC生产DataSource对象 但添加了SSL/TLS加密和远程使用托管数据库的特定元素.

This Question is similar to Produce a DataSource object for Postgres JDBC, programmatically but adds the specific elements of SSL/TLS encryption and using a managed database remotely.

推荐答案

获得DataSource实现

通常,您的 JDBC驱动程序提供了

Obtaining a DataSource implementation

Usually your JDBC driver provides an implementation of javax.sql.DataSource.

有关更多详细信息,请参见有关类似问题的我的答案.

For more details, see my Answer to a similar Question.

如果从 jdbc.postgresql.org 使用JDBC驱动程序,则可以使用

If using the JDBC driver from jdbc.postgresql.org, you can use the org.postgresql.ds.PGSimpleDataSource class as your DataSource implementation.

实例化一个类型为PGSimpleDataSource的对象,然后调用setter方法以提供连接到数据库服务器所需的所有信息. DigitalOcean网站上的网页列出了您特定数据库实例的所有这些信息.

Instantiate an object of type PGSimpleDataSource, then call setter methods to provide all the info needed to connect to your database server. The web page on the DigitalOcean site lists all these pieces of info for your particular database instance.

基本上是这样:

PGSimpleDataSource dataSource = new PGSimpleDataSource();

dataSource.setServerName( "your-server-address-goes-here" );
dataSource.setPortNumber( your-port-number-goes-here );
dataSource.setDatabaseName( "defaultdb" );
dataSource.setUser( "doadmin" );
dataSource.setPassword( "your-password-goes-here" );

多个服务器名称和端口号

不幸的是,方法setServerNamesetPortNumber的单数形式已被弃用.令人烦恼的是,我们可能应该使用这些方法的复数形式(setServerNames& setPortNumbers),每个方法都带有一个数组.我们使用服务器的地址和

Plural server names and port numbers

Unfortunately, the singular version of the methods setServerName and setPortNumber are deprecated. While annoying, we should probably use the plural version of those methods (setServerNames & setPortNumbers) that each take an array. We populate a pair of single-element arrays, String[] and int[], with our server’s address and port number using array literals:

  • {您的服务器地址在此处" }
  • {您的端口号在此处}
PGSimpleDataSource dataSource = new PGSimpleDataSource();

String[] serverAddresses = { "your-server-address-goes-here" };
dataSource.setServerNames( serverAddresses );
int[] serverPortNumbers = { your-port-number-goes-here };
dataSource.setPortNumbers( serverPortNumbers );
dataSource.setDatabaseName( "defaultdb" );
dataSource.setUser( "doadmin" );
dataSource.setPassword( "your-password-goes-here" );

SSL/TLS加密

最后,我们需要添加问题中涉及的SSL/TLS加密的信息.

SSL/TLS encryption

Lastly we need to add info for the SSL/TLS encryption addressed in the Question.

您会认为我们会称

You would think we would call the setSsl method and pass true. But, no. While counter-intuitive, setting that to true will cause your connection attempts to fail. I do not know why that is. But trial-and-error led me to avoid that call.

为了使客户端Java应用程序启动SSL/TLS连接,JDBC驱动程序必须有权访问Digital Ocean使用的 CA证书.在您的Digital Ocean管理页面上,单击Download CA certificate链接以下载一个很小的文本文件.该文件将被命名为ca-certificate.crt.

In order for your client-side Java app to initiate the SSL/TLS connection, the JDBC driver must have access to the CA certificate used by Digital Ocean. On your Digital Ocean admin page, click the Download CA certificate link to download a tiny text file. That file will be named ca-certificate.crt.

我们需要将该文件的文本作为字符串提供给JDBC驱动程序.执行以下操作,将文件加载到文本字符串中.

We need to feed the text of that file to our JDBC driver as a string. Do the following to load the file into a text string.

// Get CA certificate used in TLS connections.
Path path = Paths.get( "/Users/basilbourque/Downloads/ca-certificate.crt" );
String cert = null;
try
{
    cert = Files.readString( path , StandardCharsets.UTF_8 );
    System.out.println( "cert = " + cert );
}
catch ( IOException ex )
{
    throw new IllegalStateException( "Unable to load the TLS certificate needed to make database connections." );
}
Objects.requireNonNull( cert );
if ( cert.isEmpty() ) {throw new IllegalStateException( "Failed to load TLS cert." ); }

通过调用

Pass that CA certificate text to your JDBC driver with a call to DataSource::setSslCert. Note that we are not calling setSslRootCert. Do not mix up the two similarly-named methods.

dataSource.setSslCert( cert );

测试连接

最后,我们可以使用配置的DataSource对象建立与数据库的连接.该代码将如下所示:

Testing the connection

Lastly, we can use the configured DataSource object to make a connection to the database. That code will look like this:

// Test connection
try (
        Connection conn = dataSource.getConnection() ;
        // …
)
{
    System.out.println( "DEBUG - Postgres connection made. " + Instant.now() );
    // …
}
catch ( SQLException e )
{
    e.printStackTrace();
}

完整的示例代码

将所有内容放在一起,会看到类似的内容.

Complete example code

Putting all that together, see something like this.

// Get CA certificate used in TLS connections.
Path path = Paths.get( "/Users/basilbourque/Downloads/ca-certificate.crt" );
String cert = null;
try
{
    cert = Files.readString( path , StandardCharsets.UTF_8 );
    System.out.println( "cert = " + cert );
}
catch ( IOException ex )
{
    throw new IllegalStateException( "Unable to load the TLS certificate needed to make database connections." );
}
Objects.requireNonNull( cert );
if ( cert.isEmpty() ) {throw new IllegalStateException( "Failed to load TLS cert." ); }

// PGSimpleDataSource configuration
PGSimpleDataSource dataSource = new PGSimpleDataSource();

String[] serverAddresses = { "your-server-address-goes-here" };
dataSource.setServerNames( serverAddresses );
int[] serverPortNumbers = { your-port-number-goes-here };
dataSource.setPortNumbers( serverPortNumbers );
dataSource.setSslCert( cert );
dataSource.setDatabaseName( "defaultdb" );
dataSource.setUser( "doadmin" );
dataSource.setPassword( "your-password-goes-here" );

// Test connection
try (
Connection conn = dataSource.getConnection() ;
// …
)
{
System.out.println( "DEBUG - Postgres connection made. " + Instant.now() );
// …
}
catch ( SQLException e )
{
e.printStackTrace();
}

受信任的来源

在DigitalOcean.com上创建Postgres实例时,将可以限制进入的连接请求.您可以指定Postgres服务器期望的单个IP地址,这是Digital Ocean术语中的可信来源".任何试图连接到您的Postgres服务器的黑客都将被忽略,因为它们源自其他IP地址.

Trusted source

When creating your Postgres instance on DigitalOcean.com, you will be offered the ability to restrict incoming connection requests. You can specify a single IP address to be expected by the Postgres server, a "trusted source" in Digital Ocean's lingo. Any hackers attempting to connect to your Postgres server will be ignored as they originate from other IP addresses.

提示:在此IP地址编号的数据输入字段内单击,以使网页自动检测并提供您的Web浏览器当前正在使用的IP地址.如果您是从同一台计算机上运行Java代码,请使用相同的IP地址作为单个受信任的源.

Tip: Click inside the data-entry field for this IP address number to have the web page automatically detect and offer the IP address being currently used by your web browser. If you are running your Java code from the same computer, use that same IP number as your single trusted source.

否则,请输入运行Java JDBC代码的计算机的IP地址.

Otherwise, type in the IP address of the computer running your Java JDBC code.

我还没有解决复杂的问题,例如用于管理CA证书文件的适当安全协议,或通过从 hard -编码.但希望上面的示例可以帮助您入门.

I have not addressed elaborations, such as proper security protocols to use to manage your CA certificate file, or such as externalizing your connection info by getting a DataSource object from a JNDI server rather than hard-coding. But hopefully the examples above help you get started.

这篇关于配置一个“数据源"以使用SSL/TLS加密连接到Digital Ocean上的托管Postgres服务器的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆