配置“datasource”以连接到数字海洋上的托管postgres服务器,并使用ssl/tls加密

swvgeqrz  于 2021-06-30  发布在  Java
关注(0)|答案(1)|浏览(427)

我正在digitalocean.com上尝试托管数据库服务,创建了一个postgres示例。
digital ocean默认要求使用ssl(实际上是tls)加密进行远程连接。
如何配置jdbc DataSource 提供到这样一个数据库服务器的连接的实现?
这个问题类似于产生一个 DataSource 对象,但添加了ssl/tls加密的特定元素并远程使用托管数据库。

igetnqfo

igetnqfo1#

获取数据源实现

通常,jdbc驱动程序提供 javax.sql.DataSource .
有关更多详细信息,请参阅我对类似问题的回答。

pgsimpledatasource源

如果使用jdbc.postgresql.org中的jdbc驱动程序,则可以使用 org.postgresql.ds.PGSimpleDataSource 你的班级 DataSource 实施。
示例化类型为的对象 PGSimpleDataSource ,然后调用setter方法提供连接到数据库服务器所需的所有信息。digitalocean网站上的网页列出了特定数据库示例的所有这些信息。
基本上是这样的:

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" );

复数服务器名和端口号

不幸的是,这些方法的单一版本 setServerName 以及 setPortNumber 已弃用。虽然恼人,我们可能应该使用这些方法的复数版本( setServerNames & setPortNumbers )每个人都有一个数组。我们填充了一对单元素数组, String[] 以及 int[] ,服务器的地址和端口号使用数组文字:
{“您的服务器地址在这里”}
{您的端口号在这里}

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加密添加信息。

讽刺的是,不要调用setssl(true)

你会认为我们会打电话给 setSsl 方法和过程 true . 但是,不是。虽然违反直觉,设置为真会导致您的连接尝试失败。我不知道这是为什么。但反复试验使我避免了那个电话。

ca证书

为了让客户端java应用程序启动ssl/tls连接,jdbc驱动程序必须能够访问digital ocean使用的ca证书。在digital ocean admin页面上,单击 Download CA certificate 链接下载一个小文本文件。该文件将被命名为 ca-certificate.crt .
我们需要将该文件的文本作为字符串提供给jdbc驱动程序。执行以下操作将文件加载到文本字符串中。

// 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." ); }

通过调用将ca证书文本传递给jdbc驱动程序 DataSource::setSslCert . 注意我们没有打电话 setSslRootCert . 不要混淆这两个名称相似的方法。

dataSource.setSslCert( cert );

测试连接

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

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

完整示例代码

把这些放在一起,看看这样的东西。

// 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地址,这是digitalocean术语中的“可信源”。任何试图连接到postgres服务器的黑客都将被忽略,因为他们来自其他ip地址。
提示:单击此ip地址号码的数据输入字段内部,使网页自动检测并提供您的web浏览器当前使用的ip地址。如果您是在同一台计算机上运行java代码,请使用同一ip号作为您的单一可信源。
否则,请键入运行javajdbc代码的计算机的ip地址。

其他问题

我还没有详细说明,比如使用适当的安全协议来管理您的ca证书文件,或者通过获取 DataSource 对象,而不是硬编码。但希望上面的例子能帮助你开始。

相关问题