当前位置: 首页 > 知识库问答 >
问题:

SSL在Artemis上实现,但是具有无效信任存储和用户凭据的客户端能够连接到代理

巫马山
2023-03-14
<acceptors>
<!-- Acceptor for every supported protocol -->
     <acceptor name="artemis">tcp://0.0.0.0:61616?tcpSendBufferSize=1048576;tcpReceiveBufferSize=1048576;amqpMinLargeMessageSize=102400;protocols=CORE,AMQP,STOMP,HORNETQ,MQTT,OPENWIRE;useEpoll=true;amqpCredits=1000;amqpLowCredits=300;amqpDuplicateDetection=true;supportAdvisory=false;suppressInternalManagementObjects=false</acceptor>

     <!-- AMQP Acceptor.  Listens on default AMQP port for AMQP traffic.-->
     <acceptor name="amqp">tcp://0.0.0.0:5672?tcpSendBufferSize=1048576;tcpReceiveBufferSize=1048576;protocols=AMQP;useEpoll=true;amqpCredits=1000;amqpLowCredits=300;amqpMinLargeMessageSize=102400;amqpDuplicateDetection=true</acceptor>

     <!-- STOMP Acceptor. -->
     <acceptor name="stomp">tcp://0.0.0.0:61613?tcpSendBufferSize=1048576;tcpReceiveBufferSize=1048576;protocols=STOMP;useEpoll=true</acceptor>

     <!-- HornetQ Compatibility Acceptor.  Enables HornetQ Core and STOMP for legacy HornetQ clients. -->
     <acceptor name="hornetq">tcp://0.0.0.0:5445?anycastPrefix=jms.queue.;multicastPrefix=jms.topic.;protocols=HORNETQ,STOMP;useEpoll=true</acceptor>

     <!-- MQTT Acceptor -->
     <acceptor name="mqtt">tcp://0.0.0.0:1883?tcpSendBufferSize=1048576;tcpReceiveBufferSize=1048576;protocols=MQTT;useEpoll=false</acceptor>
     
     <!-- SSL Acceptor -->
    <acceptor name="netty-ssl-acceptor">tcp://0.0.0.0:61617?tcpSendBufferSize=1048576;tcpReceiveBufferSize=1048576;sslEnabled=true;keyStorePath=E:/apache-artemis-2.18.0/bin/localBroker/etc/sprink.jks;keyStorePassword=changeit;trustStorePath=E:/apache-artemis-2.18.0/bin/localBroker/etc/sprinktrust.ts;trustStorePassword=changeit;needClientAuth=true;protocols=CORE,AMQP,STOMP,HORNETQ,MQTT,OPENWIRE</acceptor>

 </acceptors>
import org.apache.activemq.artemis.jms.client.ActiveMQConnectionFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.jms.annotation.EnableJms;
import org.springframework.jms.config.DefaultJmsListenerContainerFactory;
import org.springframework.jms.core.JmsTemplate;


import javax.jms.JMSException;


@Configuration
@EnableJms
public class MQTTConfig {

    @Value("${activemq.broker-url}")
    private String brokerUrl;

    @Value("${activemq.ssl-url}")
    private String sslUrl;

    @Value("${JMS_BROKER_TRUSTSTORE}")
    private String pathToTrustStore;

    @Value("${JMS_BROKER_KEYSTORE}")
    private String pathToKeystore;

    @Value("${JMS_BROKER_TRUSTSTORE_PASSWORD}")
    private String truststorePassword;

    @Value("${JMS_BROKER_KEYSTORE_PASSWORD}")
    private String keystorePassword;

    /**
     * Initialise the connection factory that will be used
     */

    @Bean
    public ActiveMQConnectionFactory artemisSSLConnectionFactory() {
        ActiveMQConnectionFactory artemisConnectionFactory = new ActiveMQConnectionFactory("tcp://localhost:61617?&" + "sslEnabled=true&" +
                "trustStorePath=" + pathToTrustStore + "&trustStorePassword=changeit&needClientAuth=true");
        artemisConnectionFactory.setUser("user");
        artemisConnectionFactory.setPassword("password");
        return artemisConnectionFactory;
    }

    /**
     * Initialise {@link JmsTemplate} as required
     */
    @Bean
    public JmsTemplate jmsTemplate() throws JMSException {
        JmsTemplate jmsTemplate = new JmsTemplate();
        jmsTemplate.setConnectionFactory(artemisSSLConnectionFactory());
        jmsTemplate.setExplicitQosEnabled(true);

        //setting PuSubDomain to true configures JmsTemplate to work with topics instead of queues
        jmsTemplate.setPubSubDomain(true);
        jmsTemplate.setDeliveryMode(DeliveryMode.NON_PERSISTENT);
        jmsTemplate.setDeliveryPersistent(true);
        return jmsTemplate;
    }

    /**
     * Initialise {@link DefaultJmsListenerContainerFactory} as required
     */
    @Bean
    public DefaultJmsListenerContainerFactory jmsListenerContainerFactory() throws JMSException {
        DefaultJmsListenerContainerFactory factory = new DefaultJmsListenerContainerFactory();
        factory.setConnectionFactory(artemisSSLConnectionFactory());
        //setting PuSubDomain to true configures the DefaultJmsListenerContainerFactory to work with topics instead of queues
        factory.setPubSubDomain(true);
        return factory;
    }

}

artemis-users.properties文件如下所示

admin = ENC(1024...)
system=manager
user=password
guest=password

artemis-roles.properties定义了以下角色

admins = admin
users=user

管理员和用户在broker.xml中被授予特权,如下所示

<security-settings>
   <security-setting match="#">
      <permission type="createNonDurableQueue" roles="admins, users"/>
      <permission type="deleteNonDurableQueue" roles="admins, users"/>
      <permission type="createDurableQueue" roles="admins, users"/>
      <permission type="deleteDurableQueue" roles="admins, users"/>
      <permission type="createAddress" roles="admins, users"/>
      <permission type="deleteAddress" roles="admins, users"/>
      <permission type="consume" roles="admins, users"/>
      <permission type="browse" roles="admins, users"/>
      <permission type="send" roles="admins, users"/>
      <!-- we need this otherwise ./artemis data imp wouldn't work -->
      <permission type="manage" roles="admins"/>
   </security-setting>
</security-settings>

通过上述设置,任何客户机使用任何信任存储或用户名和密码都可以在端口61617上连接到代理,并生成和使用消息。我错过了什么,让这种情况发生?

共有1个答案

楚嘉
2023-03-14

事情是这样运作的。

首先,Artemis上的login.config文件有一个GuestLoginModule,该链接称它链接到PropertiesLoginModule,并且guest模块允许没有凭据甚至无效凭据的客户端连接到代理。现在,默认情况下,GuestLoginModule如下所示

org.apache.activemq.artemis.spi.core.security.jaas.GuestLoginModule sufficient
   debug=false
   org.apache.activemq.jaas.guest.user="admin"
   org.apache.activemq.jaas.guest.role="admins";

请注意,客人被视为管理员。我的artemis-users.properties文件已经定义了一个guest用户(如我在上面的原始文章中所见),所以我在artemis-roles.properties文件中创建了一个“guest”组,并将这个guest用户分配给这个组。然后,我更改了GuestLoginModule中的管理映射,以便该模块引用Guests。GuestLoginModule现在如下所示

org.apache.activemq.artemis.spi.core.security.jaas.GuestLoginModule sufficient
   debug=false
   org.apache.activemq.jaas.guest.user="guest"
   org.apache.activemq.jaas.guest.role="guests";

broker.xml文件中的安全设置可以根据相关用例修改以适应guest功能,我的文件没有guest用户的任何用例,所以guest没有权限。

完成后,我尝试连接到代理,并得到null证书链异常。通过在连接工厂配置中包含密钥存储来修复此问题。因为needClientAuth设置为true(启用了dual auth),Artemis需要客户机通过绑定从根CA派生的密钥对来构建相关的密钥库,所以我的连接工厂配置从

@Bean
public ActiveMQConnectionFactory artemisSSLConnectionFactory() {
    ActiveMQConnectionFactory artemisConnectionFactory = new ActiveMQConnectionFactory("tcp://localhost:61617?&" + "sslEnabled=true&" +
            "trustStorePath=" + pathToTrustStore + "&trustStorePassword=changeit&needClientAuth=true");
    artemisConnectionFactory.setUser("user");
    artemisConnectionFactory.setPassword("password");
    return artemisConnectionFactory;
}

@Bean
public ActiveMQConnectionFactory artemisSSLConnectionFactory() {
    ActiveMQConnectionFactory artemisConnectionFactory = new ActiveMQConnectionFactory("tcp://localhost:61617?&" + "sslEnabled=true&" +
            "trustStorePath=" + pathToTrustStore + "&trustStorePassword=changeit&keyStorePath="+ pathToKeystore +"&keyStorePassword=changeit&needClientAuth=true");
    artemisConnectionFactory.setUser("user");
    artemisConnectionFactory.setPassword("password");
    return artemisConnectionFactory;
}

这里唯一的区别是增加了密钥库路径和密码。当代理只是配置中的truststore时,它没有连接。如果需要一种方式auth,只需省略acceptor中的needClientAuth字段,因为它在默认情况下被设置为false。

这才是最终奏效的办法。

 类似资料:
  • 我在artemis代理中添加了一个mqtt拦截器,以便拦截mqtt客户端连接: 我的客户端apache paho通过这个端口“WS://0.0.0.0:61614”连接到代理。 我的问题是只截获发布到主题的消息。 为什么不截获连接消息?

  • 我想知道以下问题的答案: 1)如果Ignite服务器重新启动,我需要重新启动客户端(web应用程序)。是否有任何方法可以在服务器重新启动时重新连接到服务器。我知道当服务器重新启动时,它分配了一个不同的ID,因此当前现有的连接变得过时。是否有方法克服这个问题,如果是的话,哪一个版本的Ignite支持这个功能。目前我使用1.7版本 3)如果我有一个大对象要缓存,我发现序列化和反序列化在Ignite中需

  • 我有一些通过ActiveMQ和几个Java客户机使用SSL/TLS的自签名证书。代理keystore包含根证书,代理truststore包含客户端的公钥。客户机密钥库包含绑定到PKCS12文件中的客户机公钥和私钥(按密钥库的要求),客户机信任库包含根证书 现在,这个配置工作得很好。我的问题是,即使使用不匹配的客户端证书和密钥,它也能正常工作,但在代理和客户端保留相同的根证书。只有当我使用不匹配的根

  • 我是PHP领域的新手,在连接到MQTT时遇到了一些问题。 错误为:stream_socket_client():无法连接到TCP://...*:8083(连接超时) 在下面的代码中面临问题:

  • 我对javax有问题。websocket(使用Eclipse IDE和Jetty 9服务器)。我写了ClientEndDoint(带有所有注释)。这段代码可以与“ws://”配合使用,但我在尝试使用“wss://”时遇到了问题。 我试图做它与SSLContext,但不知道如何我可以添加SSLContextFactory到我的会话或套接字容器。 或者我如何可以使所有连接可信? StackTrace: