【问题标题】:Postgresql could not accept SSL connection: sslv3 alert certificate unknownPostgresql 无法接受 SSL 连接:sslv3 警报证书未知
【发布时间】:2017-09-27 02:50:59
【问题描述】:

我正在使用 SpringBoot,配置 datasource.url = jdbc:postgresql://...../mydb?ssl=true&sslFactory=....nonValidating...

在我的 application.yml 中

port: 8443
ssl:
 enabled: true
 key-alias: PGSQLServerHostNameHere
 key-store: keystore.jks
 key-store-password:....
 key-store-type: JKS
 trust-store: #this one is irrelevant, it's just a...
 ### ... trust store for other restTemplate stuff
 trust-store-password: ....
 key-password: ....
 ciphers: "TLSv1.2"
 protocol: TLS

不过,Postgresql 也是在 SSL=on 的情况下设置和运行的。 ssl_ciphers='TLSv1.2'

但是在 PGSQL 日志中我得到:

Postgresql could not accept SSL connection: sslv3 alert certificate unknown

我在 prod 上的 Spring Boot 应用程序中遇到错误(我在本地的自签名证书不会发生此错误):

org.postgresql...PSQLException: SSL error: sun.security.validator.ValdiatorException: PKIX path building failed:
sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target

SSL 证书配置

我在 root.crt 中有用于 postgresql 服务器的签名证书(包括 Java 应用服务器的签名证书,其中包含正确的别名)。

我在 JKS 文件中有 postgresql 服务器的签名证书(别名:PGSQLServerHostNameHere)作为我的 keystore.jks 的“trustEntry”。

我的 keystore.jks 中有 privateKeyEntry 用于我自己的服务器。

我在 keystore.jks 中有根 CA。

SpringBoot 应用在我的本地机器上运行良好,带有自签名 JKS。

但是 Postgresql 是个问题...拒绝我来自 java 应用服务器的通信。

postgresql.conf:

ssl = on
ssl_ciphers = 'TLSv1.2'

(everything else is default)

pg_hba.conf

hostssl all all md5

【问题讨论】:

  • "我的 keystore.jks 中有 privateKeyEntry 用于我自己的服务器。" the culprit。您确定客户端没有将证书作为客户端身份验证器发送,并且 postgres 服务器因为不处理客户端证书身份验证而阻塞?
  • @dhke 不确定(我不是 SSL 专家)。我有另一个网站的客户端 RestTemplate 东西,我只需要一个 trustStore。对于 java Spring Boot 连接到我自己的 PGSQL,我相信我需要一个私钥 + 签名证书(使用 openssl 创建 pkcs12 文件),然后使用私钥将 pkcs12 导入 keytool jks,然后是 PGSQL 的签名证书(使用 keytool 导入)进入我的 keystore.jks 文件。我不知道客户端身份验证的东西。
  • 您拥有的 SSL 配置用于 HTTPS 部分,不用于其他任何内容 (afaik)。
  • @M.Deinum 你是说 SpringBoot 不会通过 -Djavax.net.ssl.keyStore=/path/to/keystore/keystore.jks 自动配置它吗?我还必须添加这些命令行选项吗?
  • 这正是我要说的。这些 SSL 设置用于配置 servlet 容器的 HTTPS 连接器,而不是用于一般 SSL。因此,这些属性位于 server 命名空间中。

标签: java postgresql ssl spring-boot


【解决方案1】:
Postgresql could not accept SSL connection: sslv3 alert certificate unknown
....
sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target

这意味着客户端无法接受来自服务器的证书,可能是因为颁发该证书的 CA 不在信任库中。并且客户端将此问题作为警报发送给服务器,以便服务器知道连接失败的原因。

但是 Postgresql 是个问题...拒绝我来自 java 应用服务器的通信。

不,您的 Java 应用程序拒绝与 Postgresql 通信,因为它不信任证书。您在 Postgresql 的错误消息中看到的正是您的 Java 应用程序发送的内容,作为它无法继续 TLS 握手的原因。

【讨论】:

  • 是的,我同意我认为错误的显示方式有点模糊。我认为你是对的。但是,我不知道如何解决它。我在“keystore.jks”中有java服务器的公共签名证书+私钥。我在“keystore.jks”中有 PGSQL 服务器的公共签名证书。 PGSQL服务器在root.crt(信任CAs)中有Java服务器的公共签名证书,包括里面的root+intermediary。还可能需要什么?双方都有彼此签署的公共证书。双方都配置了自己的私钥。双方都有RootCA+中介。这就是一切......我需要理论
  • @Dexter:我不熟悉 JDBC 的要求(比如证书是否必须具有特定主题)。此外,我无法从您的描述中看到证书的外观。您确定您使用的是正确的密钥库吗?
  • 这就是我找不到文档的地方。我有一个用于客户端通信到另一台服务器的 trustStore。 SSL 与 Postgresql 通信的密钥库。但也许这两者相互冲突。目前尚不清楚我被指示将我的密钥库+信任库放在哪里(假设它是 ssl.key-store),但也许这仅适用于 HTTPS 而不是 JDBC。也许教程/文档总是假设人们使用 JDK 的默认 CAcerts。
  • @SteffenUllrich 错误消息的字面意思是 PostgreSQL 无法接受连接,所以除非你建议 postgresql 是这里的客户端,否则你错了。
  • @JaroslavZáruba:正确,TLS 握手(以及 PostgreSQL 中的 SSL_accept)失败,因为客户端无法验证证书。因此,客户端以错误结束握手,并在 TLS 警报中告知服务器此问题。服务器记录了问题。
【解决方案2】:

我想唯一的方法是查看 JSSE 实现并将 -Djavax.net.ssl 类型命令添加到命令行或将其添加到 System.setProperty()

另外,您可以将其添加到JDBCssl_cert=... &ssl_key=...等的url中。

必须为 postgresql 找到正确的命令。没有很好的记录。

application.yml“ssl”属性与javax.net.ssl无关

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-04-02
    • 1970-01-01
    • 2018-01-24
    • 1970-01-01
    • 1970-01-01
    • 2020-12-05
    • 1970-01-01
    • 2012-06-29
    相关资源
    最近更新 更多