rocketMq问题排查

RocketMQ TLS 如何配置

2020-09-22  本文已影响0人  liuliuzo

介绍

目前RocketMQ只能通过JVM参数的形式启用TLS配置,由于不同版本间RocketMQ的配置差异很大本文使用 version 4.7.1作为样例。

Windows

下载rocketmq集群包

RocketMQ下载
添加两个文件server.bat 和 borker.bat

server.bat

C:\work\rocketmq4.7.1\bin\mqnamesrv.cmd

borker.bat

C:\work\rocketmq4.7.1\bin\mqbroker.cmd -c C:\work\rocketmq4.7.1\conf\broker-0.properties -n localhost:9876 autoCreateTopicEnable=true

然后启动nameserver和borker
如下入所示:


image.png

下载rocketmq-console

rocketmq-console
启动console

mvn spring-boot:run
#OR
mvn clean package -Dmaven.test.skip=true
java -jar target/rocketmq-console-ng-1.0.0.jar

如下入所示:


image.png

RocketMQ TlsSystemConfig类

我们先来看下TlsSystemConfig类的参数情况

/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.apache.rocketmq.remoting.netty;

import io.netty.handler.ssl.SslContext;
import org.apache.rocketmq.remoting.common.TlsMode;

public class TlsSystemConfig {
    public static final String TLS_SERVER_MODE = "tls.server.mode";
    public static final String TLS_ENABLE = "tls.enable";
    public static final String TLS_CONFIG_FILE = "tls.config.file";
    public static final String TLS_TEST_MODE_ENABLE = "tls.test.mode.enable";

    public static final String TLS_SERVER_NEED_CLIENT_AUTH = "tls.server.need.client.auth";
    public static final String TLS_SERVER_KEYPATH = "tls.server.keyPath";
    public static final String TLS_SERVER_KEYPASSWORD = "tls.server.keyPassword";
    public static final String TLS_SERVER_CERTPATH = "tls.server.certPath";
    public static final String TLS_SERVER_AUTHCLIENT = "tls.server.authClient";
    public static final String TLS_SERVER_TRUSTCERTPATH = "tls.server.trustCertPath";

    public static final String TLS_CLIENT_KEYPATH = "tls.client.keyPath";
    public static final String TLS_CLIENT_KEYPASSWORD = "tls.client.keyPassword";
    public static final String TLS_CLIENT_CERTPATH = "tls.client.certPath";
    public static final String TLS_CLIENT_AUTHSERVER = "tls.client.authServer";
    public static final String TLS_CLIENT_TRUSTCERTPATH = "tls.client.trustCertPath";


    /**
     * To determine whether use SSL in client-side, include SDK client and BrokerOuterAPI
     */
    public static boolean tlsEnable = Boolean.parseBoolean(System.getProperty(TLS_ENABLE, "false"));

    /**
     * To determine whether use test mode when initialize TLS context
     */
    public static boolean tlsTestModeEnable = Boolean.parseBoolean(System.getProperty(TLS_TEST_MODE_ENABLE, "true"));

    /**
     * Indicates the state of the {@link javax.net.ssl.SSLEngine} with respect to client authentication.
     * This configuration item really only applies when building the server-side {@link SslContext},
     * and can be set to none, require or optional.
     */
    public static String tlsServerNeedClientAuth = System.getProperty(TLS_SERVER_NEED_CLIENT_AUTH, "none");
    /**
     * The store path of server-side private key
     */
    public static String tlsServerKeyPath = System.getProperty(TLS_SERVER_KEYPATH, null);

    /**
     * The  password of the server-side private key
     */
    public static String tlsServerKeyPassword = System.getProperty(TLS_SERVER_KEYPASSWORD, null);

    /**
     * The store path of server-side X.509 certificate chain in PEM format
     */
    public static String tlsServerCertPath = System.getProperty(TLS_SERVER_CERTPATH, null);

    /**
     * To determine whether verify the client endpoint's certificate strictly
     */
    public static boolean tlsServerAuthClient = Boolean.parseBoolean(System.getProperty(TLS_SERVER_AUTHCLIENT, "false"));

    /**
     * The store path of trusted certificates for verifying the client endpoint's certificate
     */
    public static String tlsServerTrustCertPath = System.getProperty(TLS_SERVER_TRUSTCERTPATH, null);

    /**
     * The store path of client-side private key
     */
    public static String tlsClientKeyPath = System.getProperty(TLS_CLIENT_KEYPATH, null);

    /**
     * The  password of the client-side private key
     */
    public static String tlsClientKeyPassword = System.getProperty(TLS_CLIENT_KEYPASSWORD, null);

    /**
     * The store path of client-side X.509 certificate chain in PEM format
     */
    public static String tlsClientCertPath = System.getProperty(TLS_CLIENT_CERTPATH, null);

    /**
     * To determine whether verify the server endpoint's certificate strictly
     */
    public static boolean tlsClientAuthServer = Boolean.parseBoolean(System.getProperty(TLS_CLIENT_AUTHSERVER, "false"));

    /**
     * The store path of trusted certificates for verifying the server endpoint's certificate
     */
    public static String tlsClientTrustCertPath = System.getProperty(TLS_CLIENT_TRUSTCERTPATH, null);

    /**
     * For server, three SSL modes are supported: disabled, permissive and enforcing.
     * For client, use {@link TlsSystemConfig#tlsEnable} to determine whether use SSL.
     * <ol>
     *     <li><strong>disabled:</strong> SSL is not supported; any incoming SSL handshake will be rejected, causing connection closed.</li>
     *     <li><strong>permissive:</strong> SSL is optional, aka, server in this mode can serve client connections with or without SSL;</li>
     *     <li><strong>enforcing:</strong> SSL is required, aka, non SSL connection will be rejected.</li>
     * </ol>
     */
    public static TlsMode tlsMode = TlsMode.parse(System.getProperty(TLS_SERVER_MODE, "permissive"));

    /**
     * A config file to store the above TLS related configurations,
     * except {@link TlsSystemConfig#tlsMode} and {@link TlsSystemConfig#tlsEnable}
     */
    public static String tlsConfigFile = System.getProperty(TLS_CONFIG_FILE, "/etc/rocketmq/tls.properties");
}

服务端配置 (Name server and Broker)

JVM Properties

system propertie value desc default value
tls.server.mode disabled
permissive
enforcing
disabled: SSL is not supported
permissive: SSL is optional, server in this mode can serve client connections with or without SSL
enforcing: SSL is required, non SSL connection will be rejected
permissive
tls.enable true/false The flag to determine whether use SSL in client-side false
tls.config.file The path of the tls related configuration file. /etc/rocketmq/tls.properties

Configuration File Properties

tls.test.mode.enable=true|false                     # The flag to determine whether use test mode when initialize TLS context. default is true
tls.server.need.client.auth=none|require|optional   # Indicates how SSL engine respect to client authentication, default is none
tls.server.keyPath=                                 # The store path of server-side private key
tls.server.keyPassword=                             # The password of the server-side private key
tls.server.certPath=                                # The store path of server-side X.509 certificate chain in PEM format              
tls.server.authClient=true|false                    # To determine whether verify the client endpoint's certificate strictly. default is false
tls.server.trustCertPath=                           # The store path of trusted certificates for verifying the client endpoint's certificate
 
tls.client.keyPath=                                 # The store path of client-side private key
tls.client.keyPassword=                             # The password of the client-side private key
tls.client.certPath=                                # The store path of client-side X.509 certificate chain in PEM format
tls.client.authServer=true|false                    # To determine whether verify the server endpoint's certificate strictly
tls.client.trustCertPath=                           # The store path of trusted certificates for verifying the server endpoint's certificate

客户端配置

JVM Properties

system propertie value desc default value
tls.enable The flag to determine whether use SSL in client-side false
tls.config.file The path of the tls related configuration file. /etc/rocketmq/tls.properties

Configuration File Properties

tls.client.keyPath=                                 # The store path of client-side private key
tls.client.keyPassword=                             # The password of the client-side private key
tls.client.certPath=                                # The store path of client-side X.509 certificate chain in PEM format
tls.client.authServer=true|false                    # To determine whether verify the server endpoint's certificate strictly
tls.client.trustCertPath=                           # The store path of trusted certificates for verifying the server endpoint's certificate

3.代码中控制Producer/Consumer

public void setUseTLS(boolean useTLS) // 使用RMQ TLS api

4.修改启动文件的启动参数(以下是linux下修改文件方式)

1.Add ENV parameter into rocketmq/bin/runserver.sh
JAVA_OPT="${JAVA_OPT} -Dtls.server.mode=enforcing -Dtls.config.file=${BASE_DIR}/conf/tls.properties"
2.Add ENV parameter into rocketmq/bin/runbroker.sh
JAVA_OPT="${JAVA_OPT} -Dtls.server.mode=enforcing -Dtls.config.file=${BASE_DIR}/conf/tls.properties"
JAVA_OPT="${JAVA_OPT} -Dtls.enable=true"
3.Client Settings:
-Dtls.enable=true -Dtls.client.keyPath=C:\asvagent\secrets\MQCert.key -Dtls.client.certPath=C:\asvagent\secrets\MQCert.cer -Dtls.client.trustCertPath=C:\asvagent\secrets\MQRootCA -Dtls.test.mode.enable=false

以下是RocketMQ githhub 转载


categories:


Many of use scenarios require end-to-end security, aka, it's mandatory to encrypt data during transmission even if both
parties are in the private network. Apache RocketMQ can be configured to achieve this goal leveraging TLS.

Server

RocketMQ server may be configured to serve in one of the following three modes in terms of SSL via the following Java
option -Dorg.apache.rocketmq.remoting.ssl.mode=permissive.

  1. disabled
    This mode support insecure connection only. Incoming SSL handshake will be rejected and connection will be closed.
  2. permissive
    This is the default value. This mode supports both SSL and non-SSL connections.
  3. enforcing
    This mode supports SSL connection only. non-SSL connection will be rejected.

By default, if we enable SSL(the latter two modes described above), RocketMQ will attempt to read
/etc/rocketmq/ssl.properties for further specific SSL configuration items, aka, certificate/key/trust certificate
chain files. Location of ssl.properties can also be overridden by Java option:
-Dorg.apache.rocketmq.remoting.ssl.config.file=/path/to/your/ssl.properties

Here is a sample ssl.properties file:

    client.keyCertChainFile=/Users/lizhanhui/work/openssl/certs/client.crt
    client.keyFile=/Users/lizhanhui/work/openssl/private/client.pem
    client.password=changeit
    client.trustManager=/Users/lizhanhui/work/openssl/cacert.pem
    server.keyCertChainFile=/Users/lizhanhui/work/openssl/certs/server.crt
    server.keyFile=/Users/lizhanhui/work/openssl/private/server.pem
    server.password=changeit
    server.trustManager=/Users/lizhanhui/work/openssl/cacert.pem
    server.auth.client=required

Meaning of each item is self-explanatory.
Note: all certificate files are in X509 format and all key files are in PKCS8 format.
If specified ssl.properties file is absent, RocketMQ will use a self-signed key-certificate pair.
Note: Latest JDK releases have disabled a few algorithms(MD5withRSA for example), check it out.

Client

Similar to server, client can configure SSL using custom key/certificate pair, the only difference is, client only
need to configure the following items in ssl.properties:

   client.keyCertChainFile=/Users/lizhanhui/work/openssl/certs/client.crt
   client.keyFile=/Users/lizhanhui/work/openssl/private/client.pem
   client.password=changeit
   client.trustManager=/Users/lizhanhui/work/openssl/cacert.pem

Also, we need programmatically enable SSL for client as below:

    public class ExampleProducer {
        public static void main(String[] args) throws Exception {
            DefaultMQProducer producer = new DefaultMQProducer("please_rename_unique_group_name");
            producer.setUseTLS(true);
            producer.start();       
            // Send messages as usual.       
            producer.shutdown();
        }    
    }

感谢同事:yueqian,chendi

上一篇 下一篇

猜你喜欢

热点阅读