WSO2 APIM 4.2.0配置公网SSL证书时出现localhost无匹配SAN的SSL握手错误及500页面问题求助
WSO2 APIM 4.2.0配置公网SSL证书时出现localhost无匹配SAN的SSL握手错误及500页面问题求助
问题描述
我安装了WSO2 APIM 4.2.0,使用公网域名xxx.xxx.x,并配置了wso2carbon.jks和client-truststore.jks证书,但登录admin、devportal和publisher控制台时一直弹出500错误(页面无法显示)。我试过给自签名SSL证书添加包含localhost的Subject Alternative Name(SAN),临时解决了问题,但这显然不是合规方案——公网SSL证书根本不能把localhost加进SAN里。
相关错误日志如下:
Caused by: javax.net.ssl.SSLHandshakeException: No subject alternative DNS name matching localhost found. at java.base/sun.security.ssl.Alert.createSSLException(Alert.java:131) at java.base/sun.security.ssl.TransportContext.fatal(TransportContext.java:376) at java.base/sun.security.ssl.TransportContext.fatal(TransportContext.java:319) at java.base/sun.security.ssl.TransportContext.fatal(TransportContext.java:314) at java.base/sun.security.ssl.CertificateMessage$T12CertificateConsumer.checkServerCerts(CertificateMessage.java:654) at java.base/sun.security.ssl.CertificateMessage$T12CertificateConsumer.onCertificate(CertificateMessage.java:473) at java.base/sun.security.ssl.CertificateMessage$T12CertificateConsumer.consume(CertificateMessage.java:369) at java.base/sun.security.ssl.SSLHandshake.consume(SSLHandshake.java:392) at java.base/sun.security.ssl.HandshakeContext.dispatch(HandshakeContext.java:478) at java.base/sun.security.ssl.SSLEngineImpl$DelegatedTask$DelegatedAction.run(SSLEngineImpl.java:1082) at java.base/sun.security.ssl.SSLEngineImpl$DelegatedTask$DelegatedAction.run(SSLEngineImpl.java:1069) at java.base/java.security.AccessController.doPrivileged(Native Method) at java.base/sun.security.ssl.SSLEngineImpl$DelegatedTask.run(SSLEngineImpl.java:1016) at java.base/java.util.ArrayList.forEach(ArrayList.java:1541) at java.net.http/jdk.internal.net.http.common.SSLFlowDelegate.lambda$executeTasks$3(SSLFlowDelegate.java:1073) at java.net.http/jdk.internal.net.http.HttpClientImpl$DelegatingExecutor.execute(HttpClientImpl.java:153) at java.net.http/jdk.internal.net.http.common.SSLFlowDelegate.executeTasks(SSLFlowDelegate.java:1068) at java.net.http/jdk.internal.net.http.common.SSLFlowDelegate.doHandshake(SSLFlowDelegate.java:1034) at java.net.http/jdk.internal.net.http.common.SSLFlowDelegate$Reader.processData(SSLFlowDelegate.java:442) at java.net.http/jdk.internal.net.http.common.SSLFlowDelegate$Reader$ReaderDownstreamPusher.run(SSLFlowDelegate.java:264) at java.net.http/jdk.internal.net.http.common.SequentialScheduler$SynchronizedRestartableTask.run(SequentialScheduler.java:175) at java.net.http/jdk.internal.net.http.common.SequentialScheduler$CompleteRestartableTask.run(SequentialScheduler.java:147) at java.net.http/jdk.internal.net.http.common.SequentialScheduler$SchedulableTask.run(SequentialScheduler.java:198) at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128) at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628) ... 1 more Caused by: java.security.cert.CertificateException: No subject alternative DNS name matching localhost found. at java.base/sun.security.util.HostnameChecker.matchDNS(HostnameChecker.java:212) at java.base/sun.security.util.HostnameChecker.match(HostnameChecker.java:103) at java.base/sun.security.ssl.X509TrustManagerImpl.checkIdentity(X509TrustManagerImpl.java:455) at java.base/sun.security.ssl.X509TrustManagerImpl.checkIdentity(X509TrustManagerImpl.java:415) at java.base/sun.security.ssl.X509TrustManagerImpl.checkTrusted(X509TrustManagerImpl.java:283) at java.base/sun.security.ssl.X509TrustManagerImpl.checkServerTrusted(X509TrustManagerImpl.java:141) at java.base/sun.security.ssl.CertificateMessage$T12CertificateConsumer.checkServerCerts(CertificateMessage.java:632) ... 21 more
解决方案
这种情况我碰到过好多次,核心问题就是WSO2 APIM内部组件(网关、发布者、门户、身份服务这些)默认用localhost互相通信,但你的公网证书没这个SAN,所以握手直接失败了。下面是合规的解决步骤,不用动证书就能搞定:
把所有内部通信地址换成你的公网域名
打开APIM安装目录下的repository/conf/deployment.toml,把所有出现localhost的内部服务地址全换成你的公网域名xxx.xxx.x,重点改这些地方:- 网关环境配置:
[apim.gateway.environment] service_url = "https://xxx.xxx.x:${mgt.transport.https.port}/services/" ws_endpoint = "ws://xxx.xxx.x:${passthru.ws.port}" wss_endpoint = "wss://xxx.xxx.x:${passthru.wss.port}" - 发布者和开发者门户的内部API地址:
[apim.publisher] internal_api_url = "https://xxx.xxx.x:${mgt.transport.https.port}/api/am/publisher/v1/" [apim.devportal] internal_api_url = "https://xxx.xxx.x:${mgt.transport.https.port}/api/am/devportal/v1/" - 身份服务的回调地址:
[identity.oauth2] callback_url = "https://xxx.xxx.x:${mgt.transport.https.port}/commonauth"
记得搜遍整个
deployment.toml,别漏了任何一处localhost。- 网关环境配置:
确认证书配置没问题
- 检查你的公网证书已经正确导入到
wso2carbon.jks和client-truststore.jks里,而且证书的SAN确实包含你的公网域名xxx.xxx.x。 - 可以用这条命令查看证书详情:
keytool -list -v -keystore <你的wso2carbon.jks路径> -alias <证书别名>
- 检查你的公网证书已经正确导入到
清缓存重启服务
- 删除APIM安装目录下的
tmp和repository/work文件夹,把旧缓存清干净。 - 重启WSO2 APIM服务,让新配置生效。
- 删除APIM安装目录下的
这样改完之后,内部组件之间就全用公网域名通信了,完全匹配证书的SAN,既解决了500错误,又符合公网证书的规范,根本不需要在证书里加localhost。
备注:内容来源于stack exchange,提问作者Andres Tinoco
相关产品推荐
相关产品推荐

