Skip to content

Logback 手册 - 第十三章:使用 SSL

🏷️ Logback 手册


来源:https://logback.qos.ch/manual/usingSSL.html
作者:Ceki Gülcü,Sébastien Pennec,Carl Harris
版权所有©2000-2022 QOS.ch Sarl

本文档基于 创作公用协议署名 - 非商业性使用 - 相同方式共享 2.5 许可


The whole difference between construction and creation is exactly this: that a thing constructed can only be loved after it is constructed; but a thing created is loved before it exists.

构造和创造之间的全部区别就在于这一点:构造出来的东西只有在构造好之后才会被爱;但是创造出来的东西,在它存在之前就已经被爱了。

—查尔斯·狄更斯


Logback 支持在套接字附加程序和远程接收器之间传递日志事件时使用安全套接字层(SSL)。当使用启用了 SSL 的附加程序和相应接收器时,序列化的日志事件会通过安全通道传递。

SSL 和组件角色

Logback 组件,例如附加程序和接收器,可以在网络连接初始化方面扮演服务器角色或客户端角色。当扮演服务器角色时,Logback 组件被动地监听来自远程客户端组件的连接。反之,扮演客户端角色的组件会向远程服务器组件发起连接。例如,扮演 客户端 角色的附加程序连接到扮演 服务器 角色的接收器。或者扮演 客户端 角色的接收器连接到扮演 服务器 角色的附加程序。

组件角色通常由组件类型确定。例如,SSLServerSocketAppender 是一个扮演服务器角色的附加程序组件,而 SSLSocketAppender 是一个扮演客户端角色的附加程序组件。因此,开发人员或应用程序管理员可以配置 Logback 组件以支持所需的网络连接初始化方向。

连接初始化方向在 SSL 的上下文中具有重要意义,因为在 SSL 中,服务器组件必须拥有 X.509 凭证以标识自己给连接的客户端。客户端组件在连接到服务器时使用服务器的证书来验证服务器是否可信。因此,开发人员或应用程序管理员必须了解 Logback 组件的角色,以便正确配置服务器的密钥库(包含服务器的 X.509 凭证)和客户端的信任库(包含在验证服务器信任时使用的自签名根证书)。

当为 SSL 配置 双向身份验证 时,服务器组件和客户端组件都必须拥有有效的 X.509 凭证,其信任可以被其各自的对等方断言。双向身份验证在服务器组件中配置,因此开发人员或应用程序管理员必须了解哪些组件扮演服务器角色。

在本章中,我们使用术语 服务器组件 或简称 服务器 来指称 Logback 组件,例如扮演服务器角色的附加程序或接收器。我们使用术语 客户端组件 或简称 客户端 来指称扮演客户端角色的组件。

SSL 和 X.509 证书

为了使用启用 SSL 的 Logback 组件,您需要拥有 X.509 凭证(私钥、相应证书和 CA 认证链),以标识您作为 SSL 服务器的组件。如果您希望使用双向身份验证,则还需要为作为 SSL 客户端的组件提供凭证。

尽管可以使用商业认证机构(CA)颁发的凭证,但您也可以使用从您自己的内部 CA 颁发的证书,甚至是自签名证书。以下是所需的所有内容:

  1. 服务器组件必须配置具有服务器的私钥、相应证书和 CA 认证链(如果未使用自签名证书)的密钥库。
  2. 客户端组件必须配置具有信任的根 CA 证书或服务器的自签名根证书的信任库。

配置 SSL 的 Logback 组件

Java 安全套接字扩展(JSSE)和用于实现 Logback SSL 支持的 Java 加密架构(JCA)具有许多可配置选项,以及一个可插拔的提供程序框架,允许替换或增强平台的内置 SSL 和加密功能。启用 SSL 的 Logback 组件提供了完全指定 SSL 引擎和加密提供程序的所有可配置方面的能力,以满足您的独特安全需求。

使用 JSSE 系统属性进行基本 SSL 配置

幸运的是,对于大多数启用 SSL 的 Logback 组件,几乎所有可配置的 SSL 属性都有合理的默认值。在大多数情况下,只需要配置一些 JSSE 系统属性即可。

本节剩余部分描述了大多数环境中需要的特定 JSSE 属性。有关设置 JSSE 系统属性以自定义 JSSE 的更多信息,请参见 JSSE 参考指南,其中包含有关设置 JSSE 系统属性以自定义 JSSE 的信息。

如果您正在使用任何扮演服务器角色的 Logback 启用了 SSL 的附加程序或接收器组件(例如 SSLServerSocketReceiverSSLServerSocketAppenderSimpleSSLSocketServer),则需要配置提供位置、类型和密码的 JSSE 系统属性来包含含私钥和证书的密钥库。

服务器密钥库配置的系统属性

属性名称描述
javax.net.ssl.keyStore指定包含您的服务器组件的私钥和证书的文件的文件系统路径。
javax.net.ssl.keyStoreType指定密钥库类型。如果未指定此属性,则假定平台的默认类型(JKS)。
javax.net.ssl.keyStorePassword指定访问密钥库所需的密码。

有关在启动使用 Logback 的启用了 SSL 的服务器组件的应用程序时设置这些系统属性的示例,请参见下面的 示例

如果您的服务器组件正在使用由商业认证机构(CA)签名的证书,则 您可能不需要在使用启用了 SSL 的客户端组件的应用程序中提供任何 SSL 配置。当为服务器组件使用商业签名的证书时,通常只需要设置运行服务器组件的 JVM 的系统密钥库属性即可。

如果您使用自签名的服务器证书或您的服务器证书由 Java 平台默认信任库中没有根证书之一签名的认证机构(CA)签名(例如,当您的组织拥有自己的内部认证机构时),则需要配置 JSSE 系统属性以提供包含服务器证书或签署服务器证书的认证机构(CA)的受信任根证书的位置、类型和密码。这些属性需要在使用启用了 SSL 的客户端组件的每个应用程序中设置

客户端信任库配置的系统属性

属性名称描述
javax.net.ssl.trustStore指定包含您的服务器组件的证书或由签署服务器证书的认证机构(CA)颁发的受信任根证书的文件的文件系统路径。
javax.net.ssl.trustStoreType指定信任库类型。如果未指定此属性,则假定平台的默认类型(JKS)。
javax.net.ssl.trustStorePassword指定访问信任库所需的密码。

有关在启动使用 Logback 的启用了 SSL 的客户端组件的应用程序时设置这些系统属性的示例,请参见下面的 示例

高级 SSL 配置

在某些情况下,仅使用 JSSE 系统属性进行基本 SSL 配置可能不够。例如,如果您在 Web 应用程序中使用 SSLServerSocketReceiver 组件,您可能希望使用不同的凭据来标识远程日志记录客户端的日志服务器,而不是您的 Web 服务器用来向 Web 客户端标识自己的凭据。您可能希望在日志服务器上使用 SSL 客户端身份验证,以确保只有真实且经授权的远程记录器可以连接。或者您的组织可能对组织网络上可使用的 SSL 协议和密码套件有严格的政策限制。对于这些任何需求,您需要利用 Logback 的高级 SSL 配置选项。

在配置支持 SSL 的 Logback 组件时,您可以在组件的配置中使用 ssl 属性来指定 SSL 配置。

例如,如果您希望使用 SSLServerSocketReceiver 并配置密钥库属性以用于日志服务器的凭据,您可以使用以下配置。

这个配置指定了密钥库的位置为应用程序类路径根目录下的 logging-server-keystore.jks。您也可以使用 file: URL 来指定密钥库的位置。

如果您希望在应用程序的 Logback 配置中使用 SSLSocketAppender,但又不想使用 JSSE 的 javax.net.ssl.trustStore 属性更改应用程序的默认信任库,您可以按照以下方式配置 appender。

这个配置指定了信任库的位置为应用程序类路径根目录下的 logging-server-truststore.jks。您也可以使用 file: URL 来指定信任库的位置。

SSL 配置属性

JSSE 公开了大量可配置的选项,而 Logback 的 SSL 支持使几乎所有这些选项都可以在启用 SSL 的组件配置中指定。在使用 XML 配置时,SSL 属性通过在组件配置中嵌套一个 <ssl> 元素来引入到这些组件中。该配置元素对应于 SSLConfiguration 类。

在为您的组件配置 SSL 时,您只需要为默认值不足的 SSL 属性进行配置即可。过度指定 SSL 配置通常是难以诊断问题的原因。

下表描述了顶级 SSL 配置属性。其中许多属性引入了其他子属性,在描述了顶级属性之后,将在接下来的表格中描述这些子属性。

属性名称类型描述
keyManagerFactoryKeyManagerFactoryFactoryBean指定用于创建 KeyManagerFactory 的配置。如果未配置此属性,则将使用 Java 平台的默认工厂。详见下文的 Key Manager Factory 配置
keyStoreKeyStoreFactoryBean指定用于创建 KeyStore 的配置。此属性创建的 KeyStore 应包含一个 X.509 凭证(包括私钥、对应的证书和 CA 证书链)。本地 SSL 对等体将向远程 SSL 对等体呈现此凭证。

当配置 SSL 客户端(例如 SSLSocketAppender)时,仅在远程对等体配置为要求客户端身份验证时才需要 keyStore 属性。

当配置 SSL 服务器(例如 SimpleSSLSocketServer)时,keyStore 属性指定包含服务器凭证的密钥库。如果未配置此属性,则必须配置 JSSE 的 javax.net.ssl.keyStore 系统属性以提供服务器密钥库的位置。有关设置 JSSE 系统属性的更多信息,请参阅 自定义 JSSE 主题的 JSSE 参考指南

详见下文的 Key Store 配置
parametersSSLParametersConfiguration指定 SSL 会话协商中使用的各种参数。详见下文的 SSL 参数配置
protocolString指定将用于创建 SSLContext 的 SSL 协议。请参阅 JSSE 参考指南 中的 标准名称 规范。如果未配置此属性,则将使用 Java 平台的默认协议。
providerString指定将用于创建 SSLContext 的 JSSE 提供程序的名称。如果未配置此属性,则将使用 Java 平台的默认 JSSE 提供程序。
secureRandomSecureRandomFactoryBean指定用于创建 SecureRandom(安全随机数生成器)的配置。如果未配置此属性,则将使用 Java 平台的默认生成器。详见下文的 安全随机数生成器配置
trustManagerFactoryTrustManagerFactoryFactoryBean指定用于创建 TrustManagerFactory 的配置。如果未配置此属性,则将使用 Java 平台的默认工厂。详见下文的 信任管理器工厂
trustStoreKeyStoreFactoryBean指定用于验证远程 SSL 对等体的身份的 KeyStore 的配置。此属性创建的 KeyStore 应包含一个或多个“信任锚点” —— 在密钥库中标记为“受信任”的自签名证书。通常,信任库包含自签名的 CA 证书。

此属性指定的信任库将覆盖 JSSE 的 javax.net.ssl.trustStore 系统属性和平台的默认信任库。有关设置 JSSE 系统属性的更多信息,请参阅 自定义 JSSE 主题的 JSSE 参考指南

Key Store Configuration

KeyStoreFactoryBean 指定了创建包含 X.509 凭证的 KeyStore 所需的配置。这个工厂 bean 的属性可以在 SSL 配置keyStoretrustStore 属性中使用。

属性名称类型描述
locationString指定密钥库的位置的 URL。使用 file: URL 来指定文件系统上密钥库的位置。使用 classpath: URL 来指定类路径上可以找到的密钥库。如果 URL 没有指定方案,假定为 classpath:
passwordString指定访问密钥库所需的密码。
providerString指定将用于创建 KeyStore 的 JCA 提供程序的名称。如果未配置此属性,则将使用 Java 平台的默认密钥库提供程序。
typeString指定 KeyStore 类型。请参阅 Java 密码体系结构 规范中的 标准名称。如果未配置此属性,则将使用 Java 平台的默认密钥库类型。

Key Manager Factory Configuration

KeyManagerFactoryFactoryBean 指定了创建 KeyManagerFactory 所需的配置。通常情况下,不需要显式配置密钥管理工厂,因为平台默认的工厂对大多数需求都是足够的。

属性名称类型描述
algorithmString指定 KeyManagerFactory 算法名称。请参阅 JSSE 参考指南 中的 标准名称。如果未配置此属性,则将使用 Java 平台的默认密钥管理算法。
providerString指定将用于创建 SecureRandom 生成器的 JCA 提供程序的名称。如果未配置此属性,则将使用 Java 平台的默认 JSSE 提供程序。

Secure Random Generator Configuration

SecureRandomFactoryBean 指定了创建 SecureRandom 生成器所需的配置。通常情况下,不需要显式配置安全随机生成器,因为平台默认的生成器对大多数需求都是足够的。

属性名称类型描述
algorithmString指定 SecureRandom 算法名称。请参阅 Java 密码体系结构 规范中的 标准名称。如果未配置此属性,则将使用 Java 平台的默认随机数生成算法。
providerString指定将用于创建 SecureRandom 生成器的 JCA 提供程序的名称。如果未配置此属性,则将使用 Java 平台的默认 JSSE 提供程序。

SSL 参数配置

SSLParametersConfiguration 允许自定义允许的 SSL 协议、密码套件和客户端身份验证选项。

属性名称类型描述
hostnameVerificationboolean指定客户端是否验证服务器的凭据。默认情况下,不执行任何验证。
excludedCipherSuitesString指定在会话协商期间禁用的 SSL 密码套件的逗号分隔列表。此属性用于过滤 SSL 引擎支持的密码套件,使与此属性匹配的任何密码套件都被禁用。

此属性指定的逗号分隔列表中的每个字段可以是简单字符串或正则表达式。

有关密码套件名称的列表,请参见 JSSE 参考指南 中的 标准名称 规范。
includedCipherSuitesString指定在会话协商期间启用的 SSL 密码套件的逗号分隔列表。此属性用于过滤 SSL 引擎支持的密码套件,使只有与此属性匹配的密码套件被启用。

此属性指定的逗号分隔列表中的每个字段可以是简单字符串或正则表达式。

有关密码套件名称的列表,请参见 JSSE 参考指南 中的 标准名称 规范。
excludedProtocolsString指定在会话协商期间禁用的 SSL 协议的逗号分隔列表。此属性用于过滤 SSL 引擎支持的协议,使与此属性匹配的任何协议都被禁用。

此属性指定的逗号分隔列表中的每个字段可以是简单字符串或正则表达式。

有关协议名称的列表,请参见 JSSE 参考指南 中的 标准名称 规范。
includedProtocolsString指定在会话协商期间启用的 SSL 协议的逗号分隔列表。此属性用于过滤 SSL 引擎支持的协议,使只有与此属性匹配的协议被启用。

此属性指定的逗号分隔列表中的每个字段可以是简单字符串或正则表达式。

有关协议名称的列表,请参见 JSSE 参考指南 中的 标准名称 规范。
needClientAuthboolean将此属性设置为 true,以配置服务器要求有效的客户端证书。当为诸如 SSLSocketAppender 之类的客户端组件配置时,此属性将被忽略。
wantClientAuthboolean将此属性设置为 true,以配置服务器请求客户端证书。当为诸如 SSLSocketAppender 之类的客户端组件配置时,此属性将被忽略。

信任管理器工厂配置

TrustManagerFactoryFactoryBean 指定创建 TrustManagerFactory 所需的配置。通常情况下,不需要显式配置信任管理器工厂,因为平台的默认工厂适用于大多数需求。

属性名称类型描述
algorithmString指定 TrustManagerFactory 算法名称。请参见 JSSE 参考指南 中的 标准名称 规范。如果未配置此属性,则将使用 Java 平台的默认密钥管理器算法。
providerString指定用于创建 SecureRandom 生成器的 JCA 提供程序的名称。如果未配置此属性,则将使用 Java 平台的默认 JSSE 提供程序。

示例

使用 JSSE 系统属性

可以使用 JSSE 系统属性来指定包含服务器的 X.509 凭据的密钥库的位置和密码,或者指定包含客户端组件用于验证服务器信任的自签名根 CA 证书的信任库的位置和密码。

指定服务器的密钥库

运行服务器组件时,需要指定包含服务器凭据的密钥库的位置和密码。使用 JSSE 系统属性可以完成这项任务。以下示例显示了可用于启动 Logback 附带的 SimpleSSLSocketServer 的命令行示例。

bash
java -DkeyStore=/etc/logback-server-keystore.jks \
     -DkeyStorePassword=changeit -DkeyStoreType=JKS \
     ch.qos.logback.net.SimpleSSLSocketServer 6000 /etc/logback-server-config.xml

请注意,在使用 JSSE keyStore 系统属性时,要指定密钥库的路径。在 logback.xml 中指定位置时,则指定密钥库的 URL。

虽然此示例启动了 Logback 附带的独立服务器应用程序,但可以指定相同的系统属性以启动使用 SSL 启用的 Logback 服务器组件的任何应用程序。

指定客户端的信任库

使用客户端组件时,需要指定包含用于验证服务器信任的根 CA 证书的信任库的位置和密码。使用 JSSE 系统属性可以完成这项任务。以下示例显示了可用于启动名为 com.example.MyLoggingApplication 的应用程序的命令行示例,该应用程序使用一个或多个 Logback 的 SSL 启用客户端组件。

bash
java -DtrustStore=/etc/logback-client-truststore.jks \
     -DtrustStorePassword=changeit -DtrustStoreType=JKS \
     com.example.MyLoggingApplication

请注意,在使用 JSSE trustStore 系统属性时,要指定密钥库的路径。在 logback.xml 中指定位置时,则指定信任库的 URL。

创建和使用自签名的服务器组件凭据

要生成自签名证书,可以使用 Java 运行时环境(JRE)附带的 keytool 实用程序。以下说明介绍了为服务器组件创建包含自签名 X.509 凭据的密钥库及创建用于客户端组件的信任库的过程。

创建服务器组件凭据:

以下命令将在名为 server.keystore 的文件中生成自签名客户端凭据。

bash
keytool -genkey -alias server -dname "CN=my-logging-server" \
    -keyalg RSA -validity 365 -keystore server.keystore
Enter keystore password: <Enter password of your choosing>
Re-enter new password: <Re-enter same password>
Enter key password for <my-logging-server>
    (RETURN if same as keystore password):  <Press RETURN>

dname 中使用的名称 my-logging-server 可能是您选择的任何有效名称。您可能希望使用服务器主机的完全限定域名。validity 参数指定从当前日期开始到凭据过期的日历天数。

在生产环境中,特别重要的是为包含服务器凭据的密钥库选择强密码。此密码保护服务器的私钥,防止被未经授权的人使用。请记住此密码,因为您需要在后续步骤和配置服务器时使用它。

为客户端组件创建信任库:

为了在客户端组件的配置中使用,需要从上一步创建的密钥库中导出服务器的证书,并将其导入到信任库中。以下命令将导出证书并将其导入到名为 server.truststore 的信任库中。

bash
keytool -export -rfc -alias server -keystore server.keystore \
    -file server.crt
Enter keystore password: <Enter password you chose for in previous step>

keytool -import -alias server -file server.crt -keystore server.truststore
Enter keystore password: <Enter password of your choosing>
Re-enter new password: <Re-enter same password>
Owner: CN=my-logging-server
Issuer: CN=my-logging-server
Serial number: 6e7eea40
Valid from: Sun Mar 31 07:57:29 EDT 2013 until: Mon Mar 31 07:57:29 EDT 2014

   ...

Trust this certificate? [no]:  <Enter "yes">

第一条命令将从密钥库中导出服务器的证书(但不包括服务器的私钥)到名为 server.crt 的文件中。第二步创建了一个名为 server.truststore 的新信任库,其中包含服务器证书。

在生产环境中,特别重要的是为与服务器密钥库选择不同的信任库选择强密码。请记住此密码,因为您需要在配置附加程序客户端时使用它。

配置服务器组件:

您需要将 server.keystore 文件复制到服务器应用程序的配置中。密钥库可以与应用程序的类路径资源放在一起,也可以简单地放置在服务器主机的文件系统上。在配置中指定密钥库的位置时,您将使用适当的 classpath: URL 或 file: URL。以下是一个示例服务器配置:

示例:服务器组件配置

xml
<configuration debug="true">
  <appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
    <encoder>
      <pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger - %msg%n</pattern>
    </encoder>
  </appender>

  <root level="DEBUG">
    <appender-ref ref="CONSOLE" />
  </root>

  <server class="ch.qos.logback.classic.net.server.SSLServerSocketReceiver">
    <ssl>
      <keyStore>
        <location>classpath:server.keystore</location>
        <password>${server.keystore.password}</password>
      </keyStore>
    </ssl>
  </server>
</configuration>

此示例假设密钥库位于应用程序类路径的根目录。

请注意,此配置使用 server.keystore.password 替换变量指定了密钥库密码。这种方法可以避免将密码存储在任何配置文件中。例如,您的应用程序可以在启动时在控制台提示输入此密码,然后在配置日志系统之前使用输入的密码设置 server.keystore.password 作为系统属性。

配置客户端组件:

您需要将 server.truststore 文件复制到每个使用以客户端模式运行的 SSL 启用组件的应用程序配置中。信任库可以与应用程序的类路径资源放在一起,也可以简单地放置在文件系统上。在配置中指定信任库的位置时,您将使用适当的 classpath: URL 或 file: URL。以下是一个示例附加程序客户端配置:

示例:附加程序客户端配置

xml
<configuration debug="true">
  <appender name="SOCKET" class="ch.qos.logback.classic.net.SSLSocketAppender">
    <remoteHost>${host}</remoteHost>
    <ssl>
      <trustStore>
        <location>classpath:server.truststore</location>
        <password>${server.truststore.password}</password>
      </trustStore>
    </ssl>
  </appender>

  <root level="DEBUG">
    <appender-ref ref="SOCKET" />
  </root>
</configuration>

此示例假设信任库位于应用程序类路径的根目录。

请注意,此配置使用 server.truststore.password 替换变量指定了信任库密码。这种方法可以避免将密码存储在任何配置文件中。例如,您的应用程序可以在启动时在控制台提示输入此密码,然后在配置日志系统之前使用输入的密码设置 server.truststore.password 作为系统属性。

审计 SSL 配置

在需要安全通信的设置中,通常需要审计使用 SSL 的组件的配置,以验证符合本地安全策略。Logback 中的 SSL 支持通过在 Logback 初始化时提供详细的 SSL 配置日志记录来满足此需求。您可以使用配置中的 debug 属性启用审计日志记录:

xml
<configuration debug="true">

  ...

</configuration>

启用 debug 属性后,在初始化日志系统时将记录生成的 SSL 配置的相关方面。以下是 SSL 配置审核日志的一个代表性示例。

示例:SSL 配置审核日志

txt
06:46:31,941 |-INFO in SSLServerSocketReceiver@4ef18d37 - SSL protocol 'SSL' provider 'SunJSSE version 1.6'
06:46:31,967 |-INFO in SSLServerSocketReceiver@4ef18d37 - key store of type 'JKS' provider 'SUN version 1.6': file:src/main/java/chapters/appenders/socket/ssl/keystore.jks
06:46:31,967 |-INFO in SSLServerSocketReceiver@4ef18d37 - key manager algorithm 'SunX509' provider 'SunJSSE version 1.6'
06:46:31,973 |-INFO in SSLServerSocketReceiver@4ef18d37 - secure random algorithm 'SHA1PRNG' provider 'SUN version 1.6'
06:46:32,755 |-INFO in SSLParametersConfiguration@4a6f19d5 - enabled protocol: SSLv2Hello
06:46:32,755 |-INFO in SSLParametersConfiguration@4a6f19d5 - enabled protocol: SSLv3
06:46:32,755 |-INFO in SSLParametersConfiguration@4a6f19d5 - enabled protocol: TLSv1
06:46:32,756 |-INFO in SSLParametersConfiguration@4a6f19d5 - enabled cipher suite: SSL_RSA_WITH_RC4_128_MD5
06:46:32,756 |-INFO in SSLParametersConfiguration@4a6f19d5 - enabled cipher suite: SSL_RSA_WITH_RC4_128_SHA
06:46:32,756 |-INFO in SSLParametersConfiguration@4a6f19d5 - enabled cipher suite: TLS_RSA_WITH_AES_256_CBC_SHA

这里显示的输出已经缩减以简洁起见,但通常会包括协议、提供者、算法和密码套件的完整列表,以及配置中使用的密钥库和信任库资源的位置。

虽然这些审核日志都不是特别敏感的信息,但安全最佳实践建议在验证配置后,在生产环境中禁用此日志记录。当删除 debug 属性或将其设置为 false 时,审核日志将被禁用。

解决 SSL 异常

当 SSL 配置错误时,通常会导致客户端和服务器组件无法协商一个可接受的会话。当客户端尝试连接服务器时,通常会抛出异常。

异常消息的内容取决于您查看的是客户端日志还是服务器日志。这主要是由于会话协商过程中错误报告的固有协议限制。因此,为了解决会话协商问题,通常需要查看客户端和服务器的日志。

服务器证书不可用

在启动服务器组件时,日志中出现以下异常:

txt
javax.net.ssl.SSLException: No available certificate or key corresponds to the SSL cipher suites which are enabled

在大多数情况下,这意味着您未配置包含服务器私钥和对应证书的密钥库的位置。

解决方案

使用服务器组件的 ssl 属性的 keyStore 属性或 Key Store 系统属性,必须指定包含服务器私钥和证书的密钥库的位置和密码。

客户端不信任服务器

当客户端尝试连接服务器时,日志中出现以下异常:

txt
javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path building failed

这个问题是由于服务器提供了客户端不信任的证书。最常见的原因是您正在使用自签名的服务器证书(或由您组织的内部认证机构签名的服务器证书),并且您没有配置客户端引用包含服务器自签名证书的信任库(或签署您的服务器证书的 CA 的受信任根证书)。

如果您的服务器证书过期或已被吊销,也可能会出现此问题。如果您可以访问服务器日志,每次客户端尝试连接时,您可能会看到以下异常被记录:

txt
javax.net.ssl.SSLHandshakeException: Received fatal alert: ...

异常消息的其余部分通常会提供一个代码,指示客户端拒绝服务器证书的原因。

代码描述
certificate_unknown通常表示客户端的信任库未正确配置。
certificate_expired表示服务器证书已过期,需要替换。
certificate_revoked表示签发证书的认证机构(CA)已吊销服务器证书,需要替换证书。

解决方案

如果服务器的日志消息报告 certificate_unknown,那么您必须使用 Trust Store 系统属性 或 appender 组件的 ssl 属性的 trustStore 属性,在配置中指定包含服务器自签名证书或颁发证书机构根证书的信任存储的位置和密码。

如果服务器的日志消息报告 certificate_expiredcertificate_revoked,则服务器需要一个新的证书。新的证书和相关的私钥需要放置在服务器配置中指定的密钥库中。如果使用自签名服务器证书,则还需要将服务器的证书放置在 appender 客户端配置中指定的信任存储中。

服务器不信任客户端

注意:只有在显式配置服务器请求客户端证书(使用 needClientAuthwantClientAuth 属性)时,才会出现此问题

当客户端尝试连接到日志服务器时,您会在客户端的日志中看到以下异常:

txt
javax.net.ssl.SSLHandshakeException: Received fatal alert: ...

异常消息的其余部分通常会提供一个代码,指示服务器拒绝了客户端的证书的原因。

代码描述
certificate_unknown通常表示服务器的信任存储未正确配置。
certificate_expired表示客户端的证书已过期,需要替换。
certificate_revoked表示颁发证书机构(CA)已撤销客户端的证书,需要替换证书。

解决方案

如果客户端的日志消息报告 bad_certificate,那么您必须使用服务器组件的 ssl 属性的 Trust Store 系统属性trustStore 属性,在配置中指定包含客户端自签名证书或颁发证书机构根证书的信任存储的位置和密码。

如果服务器的日志消息报告 certificate_expiredcertificate_revoked,则客户端需要一个新的证书。新的证书和相关的私钥需要放置在客户端配置中指定的密钥库中。如果使用自签名客户端证书,则还需要将客户端的证书放置在服务器配置中指定的信任存储中。

客户端和服务器无法达成协议

注意:只有在显式在配置中 排除包含 SSL 协议时,才会出现此问题

当客户端尝试连接到服务器时,您会在日志中看到以下异常:

txt
javax.net.ssl.SSLHandshakeException: Received fatal alert: handshake_failure

服务器的日志消息通常更详细。例如:

txt
javax.net.ssl.SSLHandshakeException: SSLv2Hello is disabled

通常,这意味着您已从其中一个对等方中排除了协议,而没有从另一个对等方中排除。

解决方案

检查服务器和客户端上的 excludedProtocolsincludedProtocols 属性指定的值。

客户端和服务器无法达成密码套件协议

注意:只有在显式在配置中 排除包含 SSL 密码套件时,才会出现此问题

当客户端尝试连接到服务器时,您会在日志中看到以下异常:

txt
javax.net.ssl.SSLHandshakeException: Received fatal alert: handshake_failure

服务器的日志消息通常更详细:

txt
javax.net.ssl.SSLHandshakeException: no cipher suites in common

这意味着您已配置了服务器和客户端的密码套件,以使得它们各自启用的密码套件的交集为空。

解决方案

检查服务器和客户端上的 excludedCipherSuitesincludedCipherSuites 属性指定的值。