Skip to end of metadata
Go to start of metadata

You are viewing an old version of this page. View the current version.

Compare with Current View Page History

Version 1 Current »

This article explains how to configure HiveMQ. Enterprise Security Extension to use X509 certificates for authentication. For example, the Client certificates include a subject common name that is used for authentication and role-based permissions for authorization.

Pre-requisites

  1. Created Key-store and trust-stores certificates with subject common name configured. You can always refer to our documentation to know how to generate these certificates.

  2. Running setup of database realm (here we are using PostgreSQL)

\uD83D\uDCD8 Instructions

  1. The first step is to configure <tls-tcp-listener> in your hivemq config.xml. Please refer following example.

    <hivemq>
       <listeners>
            <tls-tcp-listener>
                <port>8883</port>
                <bind-address>0.0.0.0</bind-address>
                <tls>
                    <keystore>
                        <path>/path/to/hivemq.jks</path>
                        <password><your passsword></password>
                        <private-key-password><your passsword></private-key-password>
                    </keystore>
                    <truststore>
                        <path>/path/to/hivemq-trust-store.jks</path>
                        <password><your passsword></password>
                    </truststore>
                    <client-authentication-mode>REQUIRED</client-authentication-mode>
                </tls>
            </tls-tcp-listener>
        </listeners>
  2. Next step, make sure you have the database setup ready with the users, roles and permissions data.

    1. Make sure you have users.username matching the client’s certificate's common name in order to work authentication successfully. For authorization, roles and permissions are configured correctly.

    2. Please check our documentation for database schema and how to use a helper tool to insert data.

  3. Now configure ESE configuration file, i.e enterprise-security-extension.xml

    1. First configure the realm with your database type, name, host, password, db-username and db-password. For more details about different realms please check our documentation. Please refer to the following example of Postgres

          <realms>
              <!-- a postgresql db-->
              <sql-realm>
                  <name>postgres-backend</name>
                  <enabled>true</enabled>
                  <configuration>
                      <db-type>POSTGRES</db-type>
                      <db-name>hivemq-db</db-name>
                      <db-host>localhost</db-host>
                      <db-port>5432</db-port>
                      <db-username>postgres</db-username>
                      <db-password>hivemq</db-password>
                  </configuration>
              </sql-realm>
          </realms>
    2. Configure <pipelines> in order to authenticate and authorize the client before the client connection is accepted. You can also add preprocessors to do some modifications or processing to inputs before authentication and authorization happens.

      1. In the current scenario will be using <x509-preprocessor> to process and extract subject-common-name and set the ESE variable authentication-key for authentication.

        <x509-preprocessor prefix="{{" postfix="}}">
            <x509-extractions>
                <x509-extraction>
                    <x509-field>subject-common-name</x509-field>
                    <ese-variable>authentication-key</ese-variable>
                </x509-extraction>
            </x509-extractions>
        </x509-preprocessor>
      2. you can also add a logging preprocessor to debug the state of ESE variables. Please remember to add a logger in your logback.xml to see these log messages.
        Example to add <logging-preprocessor>:

        <logging-preprocessor>
            <message>x509 The content of the authentication-key ESE-Variable: ${authentication-key}</message>
            <level>debug</level>
            <name>demo.ese.logger</name>
        </logging-preprocessor>

        Example to add logger in logback.xml:

        <logger name="demo.ese.logger" level="debug"/>
      3. With the help of plain-preprocessor, set the authentication-byte-secret ESE variable from mqtt-password.

        <plain-preprocessor>
          <transformations>
              <transformation encoding="UTF8">
                  <from>mqtt-password</from>
                  <to>authentication-byte-secret</to>
              </transformation>
          </transformations>
        </plain-preprocessor>
    3. Once pipelines with the help of preprocessor are configured, the Next step is to configure authentication managers i.e <sql-authentication-manager>. An authentication manager is defined in a pipeline and handles the authentication processes of connecting MQTT clients by using the content of the authentication variables. Configure the realm name (this was set in step 3-a.)
      Example:

      <sql-authentication-manager>
          <realm>postgres-backend</realm>
      </sql-authentication-manager>
    4. In the ESE, authorization is done by authorization managers. An authorization manager is defined in a pipeline and handles the authorization processes of connecting MQTT clients by using the content of the authorization variables. Configure the realm name (this was set in step 3-a.), <use-authorization-key> and <use-authorization-role-key>. Here we are using role-based permissions hence set <use-authorization-role-key> to true and use-authorization-key to false;
      Example:

      <sql-authorization-manager>
          <realm>postgres-backend</realm>
          <use-authorization-key>false</use-authorization-key>
          <use-authorization-role-key>true</use-authorization-role-key>
      </sql-authorization-manager>

    5. after configuring all the above steps final enterprise-security-extension.xml will be as

      <?xml version="1.0" encoding="UTF-8" ?>
      <enterprise-security-extension
              xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
              xsi:noNamespaceSchemaLocation="enterprise-security-extension.xsd"
              version="1">
          <realms>
              <!-- a postgresql db-->
              <sql-realm>
                  <name>postgres-backend</name>
                  <enabled>true</enabled>
                  <configuration>
                      <db-type>POSTGRES</db-type>
                      <db-name>hivemq-db</db-name>
                      <db-host>localhost</db-host>
                      <db-port>5432</db-port>
                      <db-username>postgres</db-username>
                      <db-password>hivemq</db-password>
                  </configuration>
              </sql-realm>
          </realms>
          <pipelines>
              <!-- secure access to the mqtt broker -->
              <listener-pipeline listener="ALL">
                  <!-- authenticate over a sql db -->
                  <authentication-preprocessors>
                      
                       <x509-preprocessor prefix="{{" postfix="}}">
                          <x509-extractions>
                              <x509-extraction>
                                 <x509-field>subject-common-name</x509-field>
                                 <ese-variable>authentication-key</ese-variable>
                              </x509-extraction>
                          </x509-extractions>
                      </x509-preprocessor>
                      <logging-preprocessor>
                          <message>x509 The content of the authentication-key ESE-Variable: ${authentication-key}</message>
                          <level>debug</level>
                          <name>demo.ese.logger</name>
                      </logging-preprocessor>
                      <plain-preprocessor>
                          <transformations>
                              <transformation encoding="UTF8">
                                 <from>mqtt-password</from>
                                 <to>authentication-byte-secret</to>
                              </transformation>
                          </transformations>
                      </plain-preprocessor>
                      <logging-preprocessor>
                          <message>username The content of the authentication-key ESE-Variable: ${authentication-key} and passowrd: ${authentication-byte-secret}</message>
                          <level>debug</level>
                          <name>demo.ese.logger</name>
                      </logging-preprocessor>
                  </authentication-preprocessors>
      
                  <sql-authentication-manager>
                      <realm>postgres-backend</realm>
                  </sql-authentication-manager>
                  
                  <!-- authorize over a sql db -->
                  <sql-authorization-manager>
                      <realm>postgres-backend</realm>
                      <use-authorization-key>false</use-authorization-key>
                      <use-authorization-role-key>true</use-authorization-role-key>
                  </sql-authorization-manager>
              </listener-pipeline>
              <!-- secure access to the control center -->
          </pipelines>
      </enterprise-security-extension>
    6. Run HiveMQ broker and look for the log messages which mention that HiveMq Broker and ESE is started successfully.

      2022-12-14 15:34:21,020 INFO  - Started HiveMQ in 14569ms
      ...
      2022-12-14 15:34:59,346 INFO  - Started HiveMQ Enterprise Security Extension successfully in 369ms.
    7. You can quickly test your configurations with MQTT CLI.
      Subscribe to the authorised topic:

      mqtt sub -p 8883 -t topic/# -pw <password> --cafile hivemq-server-cert.pem --cert mqtt-client-cert-sub1.pem --key mqtt-client-key-sub1.pem

      Publish message to the authorised topic:

      mqtt pub -p 8883 -m "test message" -t topic/test -pw <password> --cafile hivemq-server-cert.pem --cert mqtt-client-cert-pub1.pem --key mqtt-client-key-pub1.pem

    8. You can also check access.log and hivemq.log to see the log entries

  • No labels