...
The first step is to configure
<tls-tcp-listener>
in your hivemqconfig.xml
. Please refer following example.Code Block <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>
Next step, make sure you have the database setup ready with the users, roles and permissions data.
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.Please check our documentation for database schema and how to use a helper tool to insert data.
Now configure ESE configuration file, i.e
enterprise-security-extension.xml
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
Code Block <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>
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.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.Code Block <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>
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>:Code Block <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:
Code Block <logger name="demo.ese.logger" level="debug"/>
With the help of plain-preprocessor, set the authentication-byte-secret ESE variable from mqtt-password.
Code Block <plain-preprocessor> <transformations> <transformation encoding="UTF8"> <from>mqtt-password</from> <to>authentication-byte-secret</to> </transformation> </transformations> </plain-preprocessor>
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:Code Block <sql-authentication-manager> <realm>postgres-backend</realm> </sql-authentication-manager>
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:Code Block <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>
after configuring all the above steps final
enterprise-security-extension.xml
will be asCode Block <?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>
Run HiveMQ broker and look for the log messages which mention that HiveMq Broker and ESE is started successfully.
Code Block 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.
You can quickly test your configurations with MQTT CLI.
Subscribe to the authorised topic:Code Block language bash 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 -d -h localhost
Publish message to the authorised topic:
Code Block language bash 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 -d -h localhost
You can also check
access.log
andhivemq.log
to see the log entries
...
Filter by label (Content by label) | |||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|