/
How to configure ESE to authenticate clients using client certificates and authorize using postgresSQL(without username/password)

How to configure ESE to authenticate clients using client certificates and authorize using postgresSQL(without username/password)

This article provides a detailed guide on configuring the HiveMQ Enterprise Security Extension to authenticate clients using X.509 certificates. Specifically, client certificates containing a subject common name are used for authentication, while role-based permissions are applied for authorization. As a result, there is no need for the client to provide a username or password during the authentication process.

Pre-requisites

  1. Created Key-store and trust-store 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)

 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 roles and permissions data.

    1. Make sure you have roles.name matching the client’s certificate's common name in order to work authorization successfully and also have the right permissions assigned to the role.

    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. the Next step is to configure authentication managers i.e <allow-all-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. )
      Example: For the current scenario, authentication will be done by the certificates hence skip the authentication using SQL realm when not using username/password. We will use <allow-all-authentication-manager/>

      <allow-all-authentication-manager/>

       

    3. Configure <pipelines> to authorize the client, You can also add preprocessors to do some modifications or processing to inputs before authorization happens.

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

        Note: you can use any other x509 field for extraction. For this article’s scenario, we have used the subject-common-name.

        <authorization-preprocessors> <x509-preprocessor prefix="{{" postfix="}}"> <x509-extractions> <x509-extraction> <x509-field>subject-common-name</x509-field> <ese-variable>authorization-role-key</ese-variable> </x509-extraction> </x509-extractions> </x509-preprocessor> </authorization-preprocessors>
      2. you can also add a logging preprocessor to debug the state of ESE variables in <authorization-preprocessors>. 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 authorization-role-key ESE-Variable: ${authorization-role-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"/>
    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"> <allow-all-authentication-manager/> <authorization-preprocessors> <x509-preprocessor prefix="{{" postfix="}}"> <x509-extractions> <x509-extraction> <x509-field>subject-common-name</x509-field> <ese-variable>authorization-role-key</ese-variable> </x509-extraction> </x509-extractions> </x509-preprocessor> <logging-preprocessor> <message>x509 The content of the authorization-key ESE-Variable: ${authorization-key}</message> <level>debug</level> <name>demo.ese.logger</name> </logging-preprocessor> </authorization-preprocessors> <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> </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/# --cafile hivemq-server-cert.pem --cert mqtt-client-cert-sub1.pem --key mqtt-client-key-sub1.pem -d -h localhost

      Publish message to the authorised topic:

      mqtt pub -p 8883 -m "test message" -t topic/test --cafile hivemq-server-cert.pem --cert mqtt-client-cert-pub1.pem --key mqtt-client-key-pub1.pem -d -h localhost

       

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

 Related articles

Related content