Message communication - MQTT security authentication and testing

Posted by mfouts on Mon, 31 Jan 2022 10:15:52 +0100

EMQX security certification

The connection authentication and access control of EMQ X message server are provided by a series of authentication plugins, and their names comply with emqx_auth_ In EMQ X, these two functions refer to:
Connection authentication: EMQ X checks whether the client on each connection has the permission to access the system. If not, the connection will be disconnected;
Access control: EMQ X checks the permissions of each publish / subscribe of the client to allow / deny corresponding operations;

The plug-in of EMQ X message server authentication supports three methods: user name, password, ClientID or anonymous authentication. The system turns on anonymous authentication by default. We can configure the plug-in to turn on the authentication chain:

Special attention should be paid to:

  • When Username authentication is enabled, the system will ignore Client ID authentication and anonymous authentication;
  • When Client ID authentication is enabled, the system will ignore anonymous authentication;

1. Default method - anonymous authentication

After the setup is completed, the device end can connect directly to the MQTT server without any identity authentication.

Use mqtt FX is tested as an mqtt client:

After setting, click Connect:

Test subscription topic:

Test release message

After publishing, check whether you have received it (the client has subscribed to this topic):

The advantages and disadvantages of this non authentication method are very obvious:

  • Advantages: simple client connection, which is conducive to programming;
  • Disadvantages: there is no security at all. Any device can connect and publish messages, which is vulnerable to attack;

2. Username authentication plug-in

emqx_auth_username provides the username authentication function. At present, it only supports connection authentication. The client is authenticated through username and password. When storing the password, this plug-in will encrypt the plaintext according to the configured hash algorithm and store it.

Stop service EMQX:
Stop the service before configuring the plug-in:

cd emqx
./bin/emqx stop

Configure Username plug-in

Log in to the server where EMQ-X is deployed and edit this file in the EMQX Directory:

cd emqx/
vim ./etc/plugins/emqx_auth_username.conf

Modify the official example, configure a username and password, and change the encryption method to plain (direct text transmission for convenience):

Start EMQ-X service

./bin/emqx start

Open the Username plug-in
There are two ways to open plug-ins:

  • Start directly from the command line:
    ./bin/emqx_ctl plugins load emqx_auth_username

  • Launch in DashBoard:
    Click the "plug-in" column on the left side of the DashBoard to find emqx_auth_username plug-in, click Start (here I have started the command line, so the display stops):

Client login test

Click Connect to log in successfully:

If the username or password is slightly modified, you cannot log in:

After the test, this user name authentication method is highly recommended:

Advantages: just assign username and password to the client. If they do not correspond, they will not be connected, which is convenient for testing;
Disadvantages: each device needs to allocate authentication information manually or API request, and the establishment stage is complex

Username authentication plug-in adds users

Open the background management system panel: http://localhost:18083/#/plugins
Click emqx_auth_username management function

You can add users manually

After adding users manually, you can connect and log in with the new user name and password

3. EMQX uses MYSQL authentication plug-in

The MYSQL certification of EMQ open source version is free
Use steps:

1) Configure EMQ MYSQL

First, we need to configure MYSQL in emq Conf can use MYSQL authentication plug-in
If it is a compressed package installation, we only need to find the extracted emqx/etc/plugins/emqx_auth_mysql.conf.


The official MYSQL authentication database table is shown below

DROP TABLE IF EXISTS `mqtt_acl`;

CREATE TABLE `mqtt_acl` (
  `id` int(11) unsigned NOT NULL AUTO_INCREMENT,
  `allow` int(1) DEFAULT NULL COMMENT '0: deny, 1: allow',
  `ipaddr` varchar(60) DEFAULT NULL COMMENT 'IpAddress',
  `username` varchar(100) DEFAULT NULL COMMENT 'Username',
  `clientid` varchar(100) DEFAULT NULL COMMENT 'ClientId',
  `access` int(2) NOT NULL COMMENT '1: subscribe, 2: publish, 3: pubsub',
  `topic` varchar(100) NOT NULL DEFAULT '' COMMENT 'Topic Filter',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

LOCK TABLES `mqtt_acl` WRITE;

INSERT INTO `mqtt_acl` (`id`, `allow`, `ipaddr`, `username`, `clientid`, `access`, `topic`)
VALUES
	(1,1,NULL,'$all',NULL,2,'#'),
	(2,0,NULL,'$all',NULL,1,'$SYS/#'),
	(3,0,NULL,'$all',NULL,1,'eq #'),
	(4,1,'127.0.0.1',NULL,NULL,2,'$SYS/#'),
	(5,1,'127.0.0.1',NULL,NULL,2,'#'),
	(6,1,NULL,'dashboard',NULL,1,'$SYS/#');

UNLOCK TABLES;


DROP TABLE IF EXISTS `mqtt_user`;

CREATE TABLE `mqtt_user` (
  `id` int(11) unsigned NOT NULL AUTO_INCREMENT,
  `username` varchar(100) DEFAULT NULL,
  `password` varchar(100) DEFAULT NULL,
  `salt` varchar(35) DEFAULT NULL,
  `is_superuser` tinyint(1) DEFAULT 0,
  `created` datetime DEFAULT NULL,
  PRIMARY KEY (`id`),
  UNIQUE KEY `mqtt_username` (`username`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8mb4;

After configuration, you can start MYSQL authentication and log in to the dashboard of port 18083.

Successful startup means that our MYSQL configuration is successful.
The reasons for failure may be as follows:
1.auth.mysql.username and auth mysql. The # numbers in front of the two configuration fields of password are not removed.
2.URL address error
3.3306 database port is not open
4. Firewall or ECS security group

2) Test connection certification


Then we use the official MQTTX tool to test the connection


Note: if the account and password are correct or the connection fails, it may be a configuration problem. Check emqx_auth_mysql.conf

You can see that the password encryption method here is sha256, which means that the password when we connect is encrypted before matching with the value of the password field in the database. Here, we can change plain text not encrypted, or we can change the field of the database to the field encrypted by sha256.
Here I choose not to encrypt
Insert picture description here

Restart the mysql authentication plug-in and reconnect to make the connection successful.

4. Test ACL permission control

Go to ACL permission control and use the database mqtt_acl data sheet. Quoted here Description of fields in the table in the official document

ACL rule table

CREATE TABLE `mqtt_acl` (
  `id` int(11) unsigned NOT NULL AUTO_INCREMENT,
  `allow` int(1) DEFAULT 1 COMMENT '0: deny, 1: allow',
  `ipaddr` varchar(60) DEFAULT NULL COMMENT 'IpAddress',
  `username` varchar(100) DEFAULT NULL COMMENT 'Username',
  `clientid` varchar(100) DEFAULT NULL COMMENT 'ClientId',
  `access` int(2) NOT NULL COMMENT '1: subscribe, 2: publish, 3: pubsub',
  `topic` varchar(100) NOT NULL DEFAULT '' COMMENT 'Topic Filter',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

Field description of rule table:
Allow: disable (0), allow (1)
ipaddr: set IP address
username: the user name of the connecting client. If the value here is set to $all, it means that the rule applies to all users
clientid: the Client ID of the connected client
access: allowed operations: subscription (1), publication (2), subscription and Publication (3)
Topic: the controlled topic. Wildcards can be used, and placeholders can be added to the topic to match the client information. For example, t/%c will replace the topic with the Client ID of the current client when matching
%u: User name
%c: Client ID

The following example data is configured by default:

-- All users cannot subscribe to system topics
INSERT INTO mqtt_acl (allow, ipaddr, username, clientid, access, topic) VALUES (0, NULL, '$all', NULL, 1, '$SYS/#');

-- Allow 10.59.1.100 Clients on subscribe to system topics
INSERT INTO mqtt_acl (allow, ipaddr, username, clientid, access, topic) VALUES (1, '10.59.1.100', NULL, NULL, 1, '$SYS/#');

-- Prohibit client subscriptions /smarthome/+/temperature theme
INSERT INTO mqtt_acl (allow, ipaddr, username, clientid, access, topic) VALUES (0, NULL, '$all', NULL, 1, '/smarthome/+/temperature');

-- Allow client subscriptions to include themselves Client ID of /smarthome/${clientid}/temperature theme
INSERT INTO mqtt_acl (allow, ipaddr, username, clientid, access, topic) VALUES (1, NULL, '$all', NULL, 1, '/smarthome/%c/temperature');

If you want to restrict a user named ceshi to subscribe to aaa topics, what should you do

1. We add a data in the data table

This data can be interpreted as: we want to allow admin users to subscribe to aaa topics
2. Connect user subscription test
After connecting, we found that ceshi users can focus on any topic, and the data added in the table does not take effect.
This is where there are misunderstandings
ACL authentication is traversed in order during traversal. I set it here to allow him to subscribe. In fact, it is equivalent to no setting.
We should first turn off all subscriptions of admin users, and then turn on the 123 / # topic subscription permission of admin users.
Then we add a close statement before the data table subscribes to aaa

3. Test effect
This completes the requirement that admin users can only subscribe to aaa topics.

  • Test subscription failed (subscribe to any topic)
  • Test subscription succeeded
  1. Finally, different operations allowed by acces s can be used for testing, but it should be noted that ACL authentication is traversed in order during traversal, and pay attention to the execution order of ACL authentication.
    If you need to allow subscriptions to two topics, you only need to add a new data topic

    This allows the client to subscribe to two topic s at the same time.

5. Uniqueness of ClientID

When connecting the EMQX client, the clientId in the connection attribute is unique. If you log in to the client twice with the same clientId, the later logged in client will squeeze the previous client off the line and the previous client will disconnect.

Test that the same user logs in to the same clientId

  • Login with js client
  • Use mtqq FX login

Test different users to log in to the same clientId

In the same situation as the above, the previously logged in client is pushed off the line.

6. emqx use HTTP interface

EMQ X provides HTTP API s to integrate with external systems, such as querying client information, publishing messages and creating rules.
The HTTP API service of EMQ X listens to port 8081 by default, which can be accessed through etc / plugins / emqx_ management. The conf configuration file modifies the listening port or enables HTTPS listening. All API calls after EMQ X 4.0.0 (opens new window) start with api/v4.
In addition to the help page, all URI s return resources in application/json format, and each request requires HTTP basic authentication. The default user is admin / public.


Interface security
The HTTP API of EMQ X uses the Basic authentication (opens new window) method, and the id and password must be filled in AppID and AppSecret respectively. The default AppID and AppSecret are admin/public. You can modify and add AppID/AppSecret by selecting "management" - > "application" in the left menu bar of Dashboard.

Please refer to the official API document for details

7. mysql data storage used by emqx

The mysql data persistence plug-in using emqx must use emqx Enterprise Edition.

Use details refer to: https://blog.csdn.net/feixiangsmile/article/details/111152477

Topics: Java Database MySQL Spring