出站连接的 SSL 配置在 websphere-liberty 17.0.0.2 中不起作用
SSL config for outbound connections doesn't work in websphere-liberty 17.0.0.2
我正在尝试将 websphere-liberty 服务器配置为对所有出站连接(实际上是 REST 调用)使用默认密钥库和信任库,并为入站使用自定义密钥和信任库。但是当尝试调用外部 REST 服务时,它会因 SSLHandshakeException 而失败。在日志中我可以看到它使用我的自定义信任库而不是默认信任库。
下面是我的server.xml
<?xml version="1.0" encoding="UTF-8"?>
<server description="Default server">
<featureManager>
<feature>appSecurity-2.0</feature>
<feature>transportSecurity-1.0</feature>
<feature>jaxrs-2.0</feature>
<feature>json-1.0</feature>
<feature>javaMail-1.5</feature>
<!--<feature>ssl-1.0</feature>-->
</featureManager>
<sslDefault sslRef="saasSSLConfig" outboundSSLRef="outboundSSLConfig" />
<ssl id="saasSSLConfig" keyStoreRef="saasKeyStore" trustStoreRef="saasTrustStore" clientAuthentication="true" sslProtocol="TLSv1" />
<keyStore id="saasKeyStore" location="/opt/ibm/wlp/output/defaultServer/resources/security/sbs_endpoint_keystore.jks" password="pwd" />
<keyStore id="saasTrustStore" location="/opt/ibm/wlp/output/defaultServer/resources/security/serverTruststore.jks" password="pwd" />
<ssl id="outboundSSLConfig" keyStoreRef="defaultKeyStore" trustStoreRef="defaultTrustStore" />
<basicRegistry id="basic" realm="BasicRealm">
<!-- <user name="yourUserName" password="" /> -->
</basicRegistry>
<httpEndpoint id="defaultHttpEndpoint" host="*" httpPort="9080" httpsPort="9443" />
<applicationManager autoExpand="true"/>
</server>
顺便说一句,如果将 saasSSLConfig 更改为使用 defaultTrustStore 而不是 saasTrustStore,那么一切正常。
服务器版本:
WebSphere Application Server 17.0.0.2 (1.0.17.cl170220170523-1818) on IBM J9 VM, version pxa6480sr4fp7-20170627_02 (SR4 FP7) (en_US)
错误:
[ERROR] CWPKI0022E: SSL HANDSHAKE FAILURE: A signer with SubjectDN CN=*.api.ibm.com, O=International Business Machines, L=Armonk, ST=New York, C=US was sent from the target host. The signer might need to be added to local trust store /opt/ibm/wlp/output/defaultServer/resources/security/serverTruststore.jks, located in SSL configuration alias saasSSLConfig. The extended error message from the SSL handshake exception is: PKIX path building failed: java.security.cert.CertPathBuilderException: PKIXCertPathBuilderImpl could not build a valid CertPath.;
SSLHandshakeException invoking https://dev.api.ibm.com/scx/test/sbs/customer/222222222: java.security.cert.CertificateException: PKIXCertPathBuilderImpl could not build a valid CertPath.
在您的配置中,我没有看到 defaultKeyStore 和 defaultTrustStore 的 keyStore 元素。如果缺少它们,将导致 outboundSSLConfig 成为无效的 SSL 配置。您能否添加它们,看看是否可行。
Liberty 不会自动加载 cacerts。如果需要,您可以创建一个 keyStore 元素来指向它。所以在你上面的例子中,你可以创建这样的配置。
<ssl id="outboundSSLConfig" keyStoreRef="cacertKeyStore" />
<keyStore id="cacertKeyStore" location=<fill in path to your jdk cacerts file> password="changeit" />
我假设您不需要此配置的密钥,因此我在 outboundSSLConfig 上简化为仅一个 keyStoreRef。它将使用 keyStoreRef 指向的密钥和信任。
我正在尝试将 websphere-liberty 服务器配置为对所有出站连接(实际上是 REST 调用)使用默认密钥库和信任库,并为入站使用自定义密钥和信任库。但是当尝试调用外部 REST 服务时,它会因 SSLHandshakeException 而失败。在日志中我可以看到它使用我的自定义信任库而不是默认信任库。
下面是我的server.xml
<?xml version="1.0" encoding="UTF-8"?>
<server description="Default server">
<featureManager>
<feature>appSecurity-2.0</feature>
<feature>transportSecurity-1.0</feature>
<feature>jaxrs-2.0</feature>
<feature>json-1.0</feature>
<feature>javaMail-1.5</feature>
<!--<feature>ssl-1.0</feature>-->
</featureManager>
<sslDefault sslRef="saasSSLConfig" outboundSSLRef="outboundSSLConfig" />
<ssl id="saasSSLConfig" keyStoreRef="saasKeyStore" trustStoreRef="saasTrustStore" clientAuthentication="true" sslProtocol="TLSv1" />
<keyStore id="saasKeyStore" location="/opt/ibm/wlp/output/defaultServer/resources/security/sbs_endpoint_keystore.jks" password="pwd" />
<keyStore id="saasTrustStore" location="/opt/ibm/wlp/output/defaultServer/resources/security/serverTruststore.jks" password="pwd" />
<ssl id="outboundSSLConfig" keyStoreRef="defaultKeyStore" trustStoreRef="defaultTrustStore" />
<basicRegistry id="basic" realm="BasicRealm">
<!-- <user name="yourUserName" password="" /> -->
</basicRegistry>
<httpEndpoint id="defaultHttpEndpoint" host="*" httpPort="9080" httpsPort="9443" />
<applicationManager autoExpand="true"/>
</server>
顺便说一句,如果将 saasSSLConfig 更改为使用 defaultTrustStore 而不是 saasTrustStore,那么一切正常。
服务器版本:
WebSphere Application Server 17.0.0.2 (1.0.17.cl170220170523-1818) on IBM J9 VM, version pxa6480sr4fp7-20170627_02 (SR4 FP7) (en_US)
错误:
[ERROR] CWPKI0022E: SSL HANDSHAKE FAILURE: A signer with SubjectDN CN=*.api.ibm.com, O=International Business Machines, L=Armonk, ST=New York, C=US was sent from the target host. The signer might need to be added to local trust store /opt/ibm/wlp/output/defaultServer/resources/security/serverTruststore.jks, located in SSL configuration alias saasSSLConfig. The extended error message from the SSL handshake exception is: PKIX path building failed: java.security.cert.CertPathBuilderException: PKIXCertPathBuilderImpl could not build a valid CertPath.;
SSLHandshakeException invoking https://dev.api.ibm.com/scx/test/sbs/customer/222222222: java.security.cert.CertificateException: PKIXCertPathBuilderImpl could not build a valid CertPath.
在您的配置中,我没有看到 defaultKeyStore 和 defaultTrustStore 的 keyStore 元素。如果缺少它们,将导致 outboundSSLConfig 成为无效的 SSL 配置。您能否添加它们,看看是否可行。
Liberty 不会自动加载 cacerts。如果需要,您可以创建一个 keyStore 元素来指向它。所以在你上面的例子中,你可以创建这样的配置。
<ssl id="outboundSSLConfig" keyStoreRef="cacertKeyStore" />
<keyStore id="cacertKeyStore" location=<fill in path to your jdk cacerts file> password="changeit" />
我假设您不需要此配置的密钥,因此我在 outboundSSLConfig 上简化为仅一个 keyStoreRef。它将使用 keyStoreRef 指向的密钥和信任。