WildFly 26.1中messaging-activemq基于HTTPS的JMS配置求助
问题描述
我正在运行WildFly 26.1,已添加messaging-activemq子系统,希望配置该子系统让远程客户端通过HTTPS传输连接并收发JMS消息。当前WildFly配置看似正常,但客户端尝试连接时始终抛出异常:
[01-17 16:06:36] [] Failed to connect to server xx.xxx.xx.227:443 javax.jms.JMSException: Failed to create session factory at org.apache.activemq.artemis.jms.client.ActiveMQConnectionFactory.createConnectionInternal(ActiveMQConnectionFactory.java:882) at org.apache.activemq.artemis.jms.client.ActiveMQConnectionFactory.createConnection(ActiveMQConnectionFactory.java:299) at com.tpt.common.jmsproxyclient.JMSProxyClient.connect(JMSProxyClient.java:282) at com.tpt.gelly.ConnectionNegotiator.establishConnection(ConnectionNegotiator.java:886) at com.tpt.gelly.ConnectionNegotiator.negotiateConnection(ConnectionNegotiator.java:1224) at com.tpt.gelly.Client.login(Client.java:1254) at com.tpt.gelly.Client$MultiLoginRunnable.runTraditional(Client.java:1190) at com.tpt.gelly.Client$MultiLoginRunnable.run(Client.java:1135) at com.tpt.ui.common.TPRunnable.run(TPRunnable.java:48) at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511) at java.util.concurrent.FutureTask.run(FutureTask.java:266) at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624) at java.lang.Thread.run(Thread.java:750) Caused by: ActiveMQNotConnectedException[errorType=NOT_CONNECTED message=AMQ219007: Cannot connect to server(s). Tried with all available servers.] at org.apache.activemq.artemis.core.client.impl.ServerLocatorImpl.createSessionFactory(ServerLocatorImpl.java:708) at org.apache.activemq.artemis.jms.client.ActiveMQConnectionFactory.createConnectionInternal(ActiveMQConnectionFactory.java:880) ... 13 more
客户端通过HTTP连接一切正常,但我无法确定HTTPS连接所需的配置。我想了解如何正确配置ActiveMQ Artemis和Undertow,以及客户端应用需要设置哪些属性才能实现HTTPS连接,同时也想知道在哪里可以找到相关的优质文档。
当前配置信息
ActiveMQ Artemis连接器与接收器配置(standalone.xml)
<subsystem xmlns="urn:jboss:domain:messaging-activemq:13.1"> <server name="default"> <!-- HTTPS connector/acceptor/factory --> <http-connector name="https-connector" socket-binding="https" endpoint="https-acceptor"> <param name="sslEnabled" value="true"/> </http-connector> <http-acceptor name="https-acceptor" http-listener="https"/> <connection-factory name="HttpsRemoteConnectionFactory" entries="java:jboss/exported/jms/HttpsRemoteConnectionFactory" connectors="https-connector"/> <!-- HTTPS throughput connector/acceptor --> <http-connector name="https-connector-throughput" socket-binding="https" endpoint="https-acceptor-throughput"> <param name="batch-delay" value="50"/> <param name="sslEnabled" value="true"/> </http-connector> <http-acceptor name="https-acceptor-throughput" http-listener="https"> <param name="batch-delay" value="50"/> <param name="direct-deliver" value="false"/> </http-acceptor> </server> </subsystem>
Undertow HTTP与HTTPS配置(standalone.xml)
<subsystem xmlns="urn:jboss:domain:undertow:12.0" default-server="default-server" default-virtual-host="default-host" default-servlet-container="default" default-security-domain="other" statistics-enabled="${wildfly.undertow.statistics-enabled:${wildfly.statistics-enabled:false}}"> <buffer-cache name="default"/> <server name="default-server"> <http-listener name="default" socket-binding="http" redirect-socket="https" enable-http2="true"/> <https-listener name="https" socket-binding="https" ssl-context="smsSSC" enable-http2="true"/> <host name="default-host" alias="localhost"> <location name="/" handler="welcome-content"/> <http-invoker http-authentication-factory="application-http-authentication"/> </host> </server> </subsystem>
客户端连接代码
Map<String, Object> params = new HashMap<>(); params.put(HTTP_UPGRADE_ENDPOINT_PROP_NAME, "https-acceptor"); params.put(ACTIVEMQ_SERVER_NAME, "default"); params.put(HTTP_UPGRADE_ENABLED_PROP_NAME, true); params.put(PORT_PROP_NAME, 443); params.put(HOST_PROP_NAME, "host"); params.put(SSL_ENABLED_PROP_NAME, true); TransportConfiguration transport = new TransportConfiguration("org.apache.activemq.artemis.core.remoting.impl.netty.NettyConnectorFactory", params); return ActiveMQJMSClient.createConnectionFactoryWithoutHA(JMSFactoryType.CF, transport);
iptables端口转发规则
/sbin/iptables -t nat -A PREROUTING -p tcp --dport https -j REDIRECT --to-port 8443 # any iptables cmds with 'mark' are to keep the local port closed outside /sbin/iptables -t mangle -A PREROUTING -p tcp --dport 8443 -j MARK --set-mark 1 /sbin/ip6tables -t mangle -A PREROUTING -p tcp --dport 8443 -j MARK --set-mark 1
解决方案
一、服务器端配置修正
移除冗余SSL参数
http-connector中配置的<param name="sslEnabled" value="true"/>是冗余的,因为http-acceptor已绑定Undertow的https-listener,而https-listener通过ssl-context已完成SSL配置,删除该参数避免冲突。验证SSL上下文有效性
检查ssl-context="smsSSC"的配置是否正确,确保密钥库、信任库的路径、密码无误,示例配置参考:<security> <ssl-contexts> <ssl-context name="smsSSC" trust-store="serverTrustStore" key-store="serverKeyStore"/> <key-stores> <key-store name="serverKeyStore"> <credential-reference clear-text="your-keystore-password"/> <implementation type="JKS"/> <file path="server.jks" relative-to="jboss.server.config.dir"/> </key-store> <key-store name="serverTrustStore"> <credential-reference clear-text="your-truststore-password"/> <implementation type="JKS"/> <file path="truststore.jks" relative-to="jboss.server.config.dir"/> </key-store> </key-stores> </ssl-contexts> </security>确认Socket Binding端口
确保socket-binding-group中的https端口为8443:<socket-binding-group name="standard-sockets" default-interface="public" port-offset="${jboss.socket.binding.port-offset:0}"> <socket-binding name="https" port="${jboss.https.port:8443}"/> </socket-binding-group>
二、客户端代码修正
修正HTTP升级端点参数
HTTP_UPGRADE_ENDPOINT_PROP_NAME对应的是HTTP上下文路径而非acceptor名称,默认路径为/messaging,需修改参数值:params.put(HTTP_UPGRADE_ENDPOINT_PROP_NAME, "/messaging");若服务器端显式配置了
http-acceptor的path参数,客户端需对应修改。添加传输类型参数
显式指定传输类型为HTTP:params.put(TransportConstants.TRANSPORT_TYPE_PROP_NAME, "http");替换占位符Host地址
将params.put(HOST_PROP_NAME, "host");中的"host"替换为实际服务器IP或域名(如xx.xxx.xx.227)。配置客户端SSL信任库(自签名证书场景)
若服务器使用自签名证书,客户端需添加信任库配置:params.put(TransportConstants.TRUST_STORE_PATH_PROP_NAME, "/path/to/client-truststore.jks"); params.put(TransportConstants.TRUST_STORE_PASSWORD_PROP_NAME, "truststore-password");
修正后的客户端代码示例:
Map<String, Object> params = new HashMap<>(); params.put(TransportConstants.HTTP_UPGRADE_ENDPOINT_PROP_NAME, "/messaging"); params.put(TransportConstants.ACTIVEMQ_SERVER_NAME, "default"); params.put(TransportConstants.HTTP_UPGRADE_ENABLED_PROP_NAME, true); params.put(TransportConstants.PORT_PROP_NAME, 443); params.put(TransportConstants.HOST_PROP_NAME, "xx.xxx.xx.227"); // 替换为实际服务器地址 params.put(TransportConstants.SSL_ENABLED_PROP_NAME, true); params.put(TransportConstants.TRANSPORT_TYPE_PROP_NAME, "http"); // 自签名证书场景添加信任库配置 params.put(TransportConstants.TRUST_STORE_PATH_PROP_NAME, "/path/to/truststore.jks"); params.put(TransportConstants.TRUST_STORE_PASSWORD_PROP_NAME, "your-password"); TransportConfiguration transport = new TransportConfiguration("org.apache.activemq.artemis.core.remoting.impl.netty.NettyConnectorFactory", params); return ActiveMQJMSClient.createConnectionFactoryWithoutHA(JMSFactoryType.CF, transport);
三、iptables规则补充
当前标记规则仅给8443流量打标,需添加DROP规则阻止外部访问:
# 阻止外部访问8443端口 /sbin/iptables -A INPUT -p tcp --dport 8443 -m mark --mark 1 -j DROP /sbin/ip6tables -A INPUT -p tcp --dport 8443 -m mark --mark 1 -j DROP
执行后保存iptables配置(根据系统使用service iptables save或netfilter-persistent save)。
四、相关文档参考
- WildFly官方文档Messaging ActiveMQ子系统章节:讲解连接器、接收器配置方式
- WildFly官方文档Undertow子系统章节:包含HTTPS监听器、SSL上下文配置说明
- ActiveMQ Artemis官方文档客户端配置章节:列出Netty连接器所有支持参数
- ActiveMQ Artemis官方文档HTTP传输章节:讲解HTTP升级原理与配置细节
内容的提问来源于stack exchange,提问作者Colonel Dork

