I am running WildFly 26.1 and have added the messaging-activemq
subsystem to it. I want to configure it so that I can attach a remote client over https
transport an send JMS messages back and forth. The way I have configured WildFly seems to work fine, but when I try to attach my client I always get an exception:
[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
If the client tries to connect over http
everything works, but I am unable to figure out what is needed to get a connection over https
. I would like to know how I configure ActiveMQ Artemis and Undertow correctly and what properties must be set in the client application to make the connection over https
. I would also like to know where I can find some good documentation for both ActiveMQ Artemis and Undertow configuration as well as ActiveMQ Artemis client connector properties.
The WildFly standalone.xml
configuration for ActiveMQ Artemis connectors and acceptors that I am using is:
<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>
The Undertow configuration for http
& https
in that same file is:
<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>
The client code trying to connect remotely is below. I don't use JNDI because we don't want to open up another port externally. The property name constants come from org.apache.activemq.artemis.core.remoting.impl.netty.TransportConstants
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);
I don't know if this has anything to do with the problem, but the https
socket-binding
is 8443
in the WildFly configuration and we use sbin/iptables
to reroute port 443
to 8443
and then block 8443
from external access using /sbin/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
<http-connector name="https-connector" socket-binding="https" endpoint="https-acceptor">
<param name="enabled-protocols" value="TLSv1.2"/>
<param name="keyStoreType" value="JKS"/>
<param name="trustStorePassword" value="artemisexample"/>
<param name="verify-host" value="false"/>
<param name="keyStorePassword" value="artemisexample"/>
<param name="trustStorePath" value="${some_path}/cacerts"/>
<param name="trustStoreType" value="PKCS12"/>
<param name="ssl-enabled" value="true"/>
<param name="keyStorePath" value="${some_path}/artemis.example.keystore"/>
</http-connector>
This is a sample connector ^^ for WildFly to an https-acceptor with simple configuration:
<http-acceptor name="https-acceptor" http-listener="undertow-https"/>
and
<https-listener name="undertow-https" socket-binding="https" ssl-context="server-ssl-context"/>
This looks very close to what you are doing