网络上很多有关ActiveMQ使用SSL连接的文章,基本都是参考官网的配置,而后自己写出一个demo发现发送成功了就算实现了SSL。但是根据redhat关于ActiveMQ安全性的资料:
https://access.redhat.com/documentation/en-US/Fuse_ESB/4.3.1/html-single/Apache_ActiveMQ_Security_Guide/index.html
其实SSL协议是有单向和双向之分的。
单向和双向的主要区别是:
- 单向需要的是在broker上配置broker.ks,在客户端上配置client.ts,client每次建立SSL连接时会从服务端拿到证书并判断是否受信。
- 双向则需要在客户端配置client.ts和client.ks,服务端配置上broker.ks和broker.ts,通信时必须双方都认可才能建立通信。
在ActiveMQ.xml中的配置项NeedClientAuth就是单向还是双向通信的开关。
附上单向通信时的java发送端demo
package com.icbc.dmqs;
import javax.jms.Connection;
import javax.jms.MessageProducer;
import javax.jms.Session;
import javax.jms.TextMessage;
import org.apache.activemq.ActiveMQSession;
import org.apache.activemq.ActiveMQSslConnectionFactory;
import org.apache.activemq.command.ActiveMQQueue;
public class SSLexample {
public static void main(String[] args) throws Exception {
String trustStore = "client1.ts";
String pass = "password";
String url = "failover:(ssl://localhost:61617)";
ActiveMQSslConnectionFactory connectionFactory = new ActiveMQSslConnectionFactory(url);
connectionFactory.setTrustStore(trustStore);
connectionFactory.setTrustStorePassword(pass);
Connection connection = connectionFactory.createConnection();
connection.start();
ActiveMQSession session = (ActiveMQSession) connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
ActiveMQQueue q = new ActiveMQQueue("test");
MessageProducer producer = session.createProducer(q);
TextMessage msg = session.createTextMessage();
msg.setText("test");
producer.send(msg);
producer.close();
session.close();
connection.close();
}
}
而此时我的broker端的activemq.xml中的配置为:
<sslContext>
<sslContext keyStore="file:${activemq.base}/conf/broker1.ks"
keyStorePassword="password"
/>
</sslContext>
<transportConnectors>
<transportConnector name="ssl" uri="ssl://0.0.0.0:61617?maximumConnections=1000&wireFormat.maxFrameSize=104857600"/>
</transportConnectors>
如果使用单向认证,那么客户端建议仍然使用密码+client.ts的方式来登录MQ,这样可以减少每个client上线时都需要配置broker.ts的工作量。
网友评论