I am trying to connect to RabbitMQ over SSL. I have followed the RabbitMQ SSL documentation linked [here}(https://www.rabbitmq.com/ssl.html).
As per RabbitMQ SSL documentation connecting using SSLv3 and TLSv1 is not recommeded due to known vulnerabilities. Due to this I have disabled these protocols on RabbitMQ as per instructions.
I am using Spring AMQP 1.4.3 to connect to RabbitMQ.
ApplicationContext context = new GenericXmlApplicationContext("classpath:/testConfig/testrabbit-context.xml");
RabbitTemplate template = context.getBean(RabbitTemplate.class);
MessageProperties messageProperties = new MessageProperties();
org.springframework.amqp.core.Message amqpMessage = new org.springframework.amqp.core.Message("Test".getBytes(), messageProperties);
String routingKey = "TEST.businessevent.route";
template.send(routingKey, amqpMessage);
My config:
<rabbit:connection-factory id="rabbitConnectionFactory"
connection-factory="clientConnectionFactory"
host="localhost"
port="5671"
username="username"
password="password"
virtual-host="test_host" />
<rabbit:admin connection-factory="rabbitConnectionFactory" />
<rabbit:template id="rabbitTemplate"
connection-factory="rabbitConnectionFactory" exchange="test_topic" />
<rabbit:topic-exchange name="test_topic" durable="true" />
<bean id="clientConnectionFactory" class="org.springframework.amqp.rabbit.connection.RabbitConnectionFactoryBean">
<property name="useSSL" value="true" />
<property name="sslPropertiesLocation" value="/testconfig/rabbitSSL.properties"/>
</bean>
rabbitSSL.properties:
keyStore=file:/client/keycert.p12
trustStore=file:/lib/security/rabbitStore
keyStore.passPhrase=testpassword
trustStore.passPhrase=testpassword
However when I use the above code and config to connect to RabbitMQ over SSL I am getting a fatal alert: protocol_version.
When I looked at the org.springframework.amqp.rabbit.connection.RabbitConnectionFactoryBean class that Spring is using to connect to RabbitMQ, I can see that the protocol appears to be hard coded to SSLv3.
SSLContext context = SSLContext.getInstance("SSLv3");
context.init(kmf.getKeyManagers(), tmf.getTrustManagers(), null);
this.connectionFactory.useSslProtocol(context);
This code works fine if I do not disable SSLv3 on RabbitMQ. However I need to connect to RabbitMQ using Tlsv1.2. Can I do that using Spring AMQP 1.4.3 or do I need to use another version.
Thanks for any help you can provide me with this issue.
While searching for RabbitMQ remote access I came across the below Spring application.properties configuration settings that can be done in Spring to configure the RabbitMQ connections.
https://www.oodlestechnologies.com/blogs/Connect-to-SSL-enabled-RabbitMQ-server-Springboot/
spring.rabbitmq.host=hostURL
spring.rabbitmq.port = hostPort
spring.rabbitmq.username = username
spring.rabbitmq.password = password
spring.rabbitmq.virtual-host=virtualHost
spring.rabbitmq.ssl.enabled=true
spring.rabbitmq.ssl.algorithm=TLSv1.2
https://www.baeldung.com/spring-remoting-amqp#2-configuration
I have opened a JIRA Issue for this.
In the meantime, the RabbitConnectionFactoryBean is just a convenience class to make configuring an underlying connection factory more "Spring friendly" with defaults.
Instead, you can perform this initialization in your own code (perhaps using a #Bean declaration using Java Configuration).
Okay, I was trying to connect by Spring Boot application(2.1.4.RELEASE) that uses spring-boot-starter-amqp (2.1.4.RELEASE) to an AWS Managed instance of RabbitMQ aka Amazon MQ and it would fail with a similar error. What worked for me was setting these properties.
spring.rabbitmq.ssl.enabled=true
spring.rabbitmq.ssl.algorithm=TLSv1.3
Setting these properties explicitly was not required in an application that was using Spring Boot and spring-boot-starter-amqp (2.7.8) and they worked out of the box. Here's a mention of the same in Spring AMQP Documentation.
https://docs.spring.io/spring-amqp/reference/html/#rabbitconnectionfactorybean-configuring-ssl
Related
ActiveMQ, as per line 151 in AmqpWireFormat, refuses connections with a AMQP protocol version other than 1.0.0.
AMQP .NET Lite, as per line 411 in Connection, sends 0.1.0.0. At the same time it claims to do Full control of AMQP 1.0 protocol behavior.
Obviously ActiveMQ refuses connections from AMQP .NET Lite with "Connection attempt from non AMQP v1.0 client. AMQP,0,1,0,0".
The client does:
Address address = new Address("amqp://localhost:5672");
Connection connection = new Connection(address);
Session session = new Session(connection);
And ActiveMQ logs:
2017-03-28 09:11:28,403 | DEBUG | Transport Connection to: tcp://0:0:0:0:0:0:0:1:54352 failed: org.apache.activemq.transport.amqp.AmqpProtocolException: Connection from client using unsupported AMQP attempted | org.apache.activemq.broker.TransportConnection.Transport | ActiveMQ Transport: tcp:///0:0:0:0:0:0:0:1:54352#5672
org.apache.activemq.transport.amqp.AmqpProtocolException: Connection from client using unsupported AMQP attempted
at org.apache.activemq.transport.amqp.protocol.AmqpConnection.onAMQPData(AmqpConnection.java:339)[activemq-amqp-5.14.4.jar:5.14.4]
at org.apache.activemq.transport.amqp.AmqpProtocolDiscriminator.onAMQPData(AmqpProtocolDiscriminator.java:96)[activemq-amqp-5.14.4.jar:5.14.4]
at org.apache.activemq.transport.amqp.AmqpTransportFilter.onCommand(AmqpTransportFilter.java:107)[activemq-amqp-5.14.4.jar:5.14.4]
at org.apache.activemq.transport.TransportSupport.doConsume(TransportSupport.java:83)[activemq-client-5.14.4.jar:5.14.4]
at org.apache.activemq.transport.tcp.TcpTransport.doRun(TcpTransport.java:233)[activemq-client-5.14.4.jar:5.14.4]
at org.apache.activemq.transport.tcp.TcpTransport.run(TcpTransport.java:215)[activemq-client-5.14.4.jar:5.14.4]
at java.lang.Thread.run(Thread.java:745)[:1.8.0_112]
On the command line it says:
WARN | Connection attempt from non AMQP v1.0 client. AMQP,0,1,0,0
ActiveMQ then aborts the connection.
The ActiveMQ configuration includes:
<transportConnectors>
<transportConnector name="amqp" uri="amqp://0.0.0.0:5672" />
</transportConnectors>
This all looks to me like ActiveMQ expects version 1.0.0.0 and amqpnetlite sends 0.1.0.0.
Where to, from here?
By default ActiveMQ requires authentication. try
string queueName = "q1";
Connection connection = new Connection(new Address("amqp://user:pwd#localhost:5672"));
Session session = new Session(connection);
SenderLink sender = new SenderLink(session, "sender", queueName);
Message message = new Message("Hello World");
sender.Send(message);
connection.Close();
The user name and password should be in users.properties config file. Also it is recommended to use async API to avoid blocking I/O calls.
Both ActiveMQ and AMQP .NET Lite support the ISO/IEC Standard 1.0 version of AMQP. The protocol header "AMQP0100" indicates version 1.0 of the protocol. AMQP .NET Lite is known to work with ActiveMQ so I suspect you have some other configuration issue.
My assumption is that you haven't turned off the broker's enforcement of requiring the client to connect via a SASL handshake either via SASL anonymous or SASL plain depending on whether you've configured a real authentication plugin or not. I would bet that if you configured the broker by adding the options wireFormat.allowNonSaslConnections=true that it would probably work.
From the information you've provided the .NET client is not using SASL so the broker is rejecting it. The SASL header would be "AMQP3100"
how can I specify an AUTH credential when configuring the Apache Camel Redis component? All the operations I want to do (such as LPUSH, but be over an established connection that has already done an AUTH)
You can define bean and pass it into your connection URI.
<bean id="connectionFactory" class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory" p:host-name="server" p:port="6379" p:password="foobared" />
spring-redis://localhost:6379?connectionFactory=#connectionFactory&command=SUBSCRIBE&channels=foo
With rabbitmq client i can make it work with following bean inject well i heard CachingConnectionFactory has another constructor to apply a com.rabbitmq.client.ConnectionFactory, which will help to enable auto recovery, but it has limited attributes to go with it.
<bean id="rcf" class="com.rabbitmq.client.ConnectionFactory">
<property name="requestedHeartbeat" value="580" />
<property name="topologyRecoveryEnabled" value="true" />
<property name="automaticRecoveryEnabled" value="true" />
</bean>
But when it comes to spring amqp for rabbit , i found no options to do that.
I appreciate , Any help regarding the query i raised ..
This is really interesting and one of the important communication problem that we need solve when we are going to work under single Message Bus Architecture. Since, we are planning to abstracted out the internal details of Message Bus, it is necessary to provide what type of attributes that we need to enable in consumer as well as producer end.
This is my consumer.xml
<rabbit:connection-factory id="connectionFactory"
host="${rabbitmq.host}" virtual-host="${rabbitmq.vhost}" username="${rabbitmq.user}" password="${rabbitmq.password}" />
<rabbit:admin connection-factory="connectionFactory" />
<rabbit:queue id="mQueue" name="${rabbitmq.queue.m}" />
<rabbit:queue id="mrQueue" name="${rabbitmq.queue.mr}" />
Can you explain how to set auto recovery in this xml? Please add xml which will set auto recovery with above consumer xml
Spring AMQP has (and has always had) it's own connection recovery mechanism. The rabbit client added it much later and it's mechanism is incompatible with Spring AMQP. Setting automaticRecoveryEnabled will cause problems with Spring AMQP versions prior to 1.4.0.
1.4.0 and later are compatible with the rabbitmq settings, but still uses its own recovery mechanism.
You can change the recoveryInterval on the message listener container (default 5 seconds).
I try to run an embedded ActiveMQ with Jboss 7.4.3 by following the installation tips I find on several sites like:
https://developer.jboss.org/wiki/EmbedActiveMQInJBossAS7
https://developer.jboss.org/wiki/JBoss6EAPOr7xxToApacheActiveMQ56Or7
In general I put activemq-rar-5.11.1.rar in standalone/deployments and add a resource-adapter config entry in the standalone.xml.
In the extensions section I added
and in the entry
i added
<mdb>
<resource-adapter-ref resource-adapter-name="activemq-rar-5.11.1.rar" />
<bean-instance-pool-ref pool-name="mdb-strict-max-pool" />
</mdb>
to make ActiveMQ the default JMS provider.
I get no errors on startup, but in the logfile I see nothing else than
JBAS018559: "activemq-rar-5.11.1.rar" deployed (runtime-name: "activemq-rar-5.11.1.rar")
I see nothing in the jndi bindings and trying to access the connectionFactory
#Resource(mappedName = "java:jboss/activemq/QueueConnectionFactory")
private ConnectionFactory connectionFactory;
results in this error:
service jboss.naming.context.java.jboss.activemq.QueueConnectionFactory (fehlende) Dependents: ...
Have I missed anything?
I'm trying to use SSL with the JMX connector that Active MQ creates, but with no success. I'm able to get SSL working with the JVM platform JMX connector, but that requires storing keystore and truststore passwords plaintext, which is a no-go for our project.
Using the instructions here, I set up managementContext in activemq.xml as follows:
<managementContext>
<managementContext createConnector="true">
<property xmlns="http://www.springframework.org/schema/beans" name="environment">
<map xmlns="http://www.springframework.org/schema/beans">
<entry xmlns="http://www.springframework.org/schema/beans"
key="javax.net.ssl.keyStore"
value="${activemq.base}/conf/keystore.jks"/>
<entry xmlns="http://www.springframework.org/schema/beans"
key="javax.net.ssl.keyStorePassword"
value="${keystore.password}"/>
<entry xmlns="http://www.springframework.org/schema/beans"
key="javax.net.ssl.trustStore"
value="${activemq.base}/conf/truststore.jks"/>
<entry xmlns="http://www.springframework.org/schema/beans"
key="javax.net.ssl.trustStorePassword"
value="${truststore.password}"/>
</map>
</property>
</managementContext>
</managementContext>
This section seems to be completely ignored when the connector starts up. I can connect without credentials. I also tried using username and password authentication instead of ssl for JMX, as seen here, and that worked fine.
Has anyone seen this before? Any ideas? Thanks!
Have you enabled jmx ssl in the activemq launch scripts? On windows in the activemq-admin or activemq batch files, uncomment and modify the SUNJMX settings.
JMX authentiation is independent of whether ssl is used. It is controlled by the authenticate attribute. By default it will use the jmx access files in your jre, so re-point them with the system properties shown below. You may get an error message stating that the files themselves must be access controlled, so set them with chmod on unix or cacls on windows. I would suggest even turning off the ssl and getting the authentication to work first. You can test with jconsole with a remote connection to confirm that it wants credentials. Then follow-up with the ssl stuff.
set SUNJMX=-Dcom.sun.management.jmxremote=true -Dcom.sun.management.jmxremote.port=1199 -Dcom.sun.management.jmxremote.authenticate=true -Dcom.sun.management.jmxremote.ssl=true -Dcom.sun.management.jmxremote.local.only=false -Dcom.sun.management.jmxremote.password.file=%ACTIVEMQ_BASE%/conf/access/jmx.password -Dcom.sun.management.jmxremote.access.file=%ACTIVEMQ_BASE%/conf/access/jmx.access
I had the same issue regarding the ActiveMQ SSL configuration (keystore & password) in the XML not working.
My requirement was to enable remote JMX monitoring of ActiveMQ with SSL and authentication through a firewall.
I resolved it using a custom JMX connector (via a Java Agent), rather than using the JMX connector that Active MQ creates.
see: JMX connectivity through a firewall for an example (JMXAgent.java)
The important entries for configuring SSL in the JMXAgent.java are:
Map<String, Object> env = new HashMap<String, Object>();
SslRMIClientSocketFactory csf = new SslRMIClientSocketFactory();
SslRMIServerSocketFactory ssf = new SslRMIServerSocketFactory();
env.put(RMIConnectorServer.RMI_CLIENT_SOCKET_FACTORY_ATTRIBUTE, csf);
env.put(RMIConnectorServer.RMI_SERVER_SOCKET_FACTORY_ATTRIBUTE, ssf);
You can also specify your authentication files in the env Map:
env.put("jmx.remote.x.password.file", System.getProperty("password.file","<default_path>"));
env.put("jmx.remote.x.access.file", System.getProperty("access.file","<default_path>"));
The Java Agent needs to be compiled and put into a jar with a valid manifest file as described here
Add the following to the activemq launch configuration (depending on activemq version/ environment and run ActiveMQ:
-javaagent:<full_path_to_agent_jar_file> \
-Dpassword.file=<full_path_to_jmx.password_file> \
-Daccess.file=<full_path_to_jmx.access_file> \
-Djavax.net.ssl.keyStore=<full_path_to_keystore_file> \
-Djavax.net.ssl.keyStorePassword=<password>
You should then be able to connect through jconsole (with correct security parameters)
The remote JMX connection URL will be something like:
service:jmx:rmi://<host>:<rmi_server_port>/jndi/rmi://<host>:<port>/jmxrmi
Note - ports can be configured in the Java Agent.