近期接触的MQTT相关知识。Including Authentication ,  mqtt-bench, topic designs, and some MQ products.

IoT Gateway Modbus/MQTT
The SS10680 gateway is an industrial device specifically designed to implement data collection systems, which operate according to the Internet of Things (IoT) paradigms;
it allows bidirectional communication between field equipment and the Cloud software platform.
It provides a Modbus RTU master interface on RS485 or Modbus TCP over Ethernet through which it interrogates devices distributed in the field.
The variables read by Modbus slave devices are sent to the Cloud via MQTT protocol with SSL / TLS client certificate authentication on variation or fixed time.

https://www.ibm.com/developerworks/cn/iot/library/iot-trs-secure-iot-solutions1/index.html
https://mosquitto.org/man/mosquitto-conf-5.html
When using pre-shared-key based encryption through the psk_hint and psk_file options, the client must provide a valid identity and key in order to connect to the broker before any MQTT communication takes place.
If use_identity_as_username is true, the PSK identity is used instead of the MQTT username for access control purposes.
If use_identity_as_username is false, the client may still authenticate using the MQTT username/password if using the password_file option.
Both certificate and PSK based encryption are configured on a per-listener basis.
Authentication plugins can be created to augment the password_file, acl_file and psk_file options with e.g. SQL based lookups.

How can I create a PSK connection between the Eclipse PAHO Java MQTT client and the Mosquitto broker?
The only MQTT clients that I know support TLS-PSK are those based on the mosquitto C/C++ libraries such as mosquitto_pub/mosquitto_sub.
As far as I know, none of the mainstream JVM providers include TLS-PSK support. It may be possible to add support from a third party, such as http://www.bouncycastle.org/
Yes, it is possible to pass the paho mqtt client a SocketFactory that does TLS-PSK using bouncy castle.

/etc/mosquitto$ sudo mosquitto_passwd -b pwfile usr2 pass3
/etc/mosquitto$ cat pwfile
usr1:$6$YpiQHrMGzHpryv0h$wDuGpp3gxkKo/aLauyROkIl5tQSd8HwCcUs8iBB05MydK3hE7pjfkqVCyho+AxnZLFFCvPyNYQZtLhvjepbs5w==
usr2:$6$rT7jnHtcFuPZ+6+P$Vpo/wB9GV+SKe3yK0cOswAwb0ZqPPfZdz5QnkAkEkaijyHroJYG3FigfbqvhsgWvJzUkc0CVSUxV8WPli92kYg==
/etc/mosquitto$ sudo mosquitto_passwd -b pwfile usr2 pass2
/etc/mosquitto$ cat pwfile
usr1:$6$YpiQHrMGzHpryv0h$wDuGpp3gxkKo/aLauyROkIl5tQSd8HwCcUs8iBB05MydK3hE7pjfkqVCyho+AxnZLFFCvPyNYQZtLhvjepbs5w==
usr2:$6$qeJjogsP2+LubLrX$fU85Si/pI+4wM9P408dPdeRDXD6/ABv0Wds79eJeUdxQ2kW+j5qIovPS2sgyy++dM2yWrtoY/wssltaSQZKPVA==
密码更新要重启broker

https://www.npmjs.com/package/seneca-mosca-auth
Authentication and Authorization for Mosca using Seneca and Seneca User.

Concurrent Connections 1024?
Till now I have achieved 74K concurrent connections on a broker.
I have configured the ulimit of broker server by editing sysctl.conf and limit.conf file.
# vi /etc/sysctl.conf
fs.file-max = 10000000
fs.nr_open = 10000000
net.ipv4.tcp_mem = 786432 1697152 1945728
net.ipv4.tcp_rmem = 4096 4096 16777216
net.ipv4.tcp_wmem = 4096 4096 16777216
net.ipv4.ip_local_port_range = 1000 65535

# vi /etc/security/limits.conf
* soft nofile 10000000
* hard nofile 10000000
root soft nofile 10000000
root hard nofile 10000000
After this reboot your system.

If you are using ubuntu 16.04, we need to make change in system.conf
# vim /etc/system/system.conf
DefaultLimitNOFILE=65536
Reboot, this will increase the connection limit

changing limits in /etc/sysctl.conf or /etc/security/limits.conf seems to have no effect for process launched as service: The limit has to be set in the file starting up the daemon.
At the beginning of /etc/init.d/mosquitto: ulimit -n 20000 #or more if need more….
in /etc/mosquitto/mosquitto.conf: max_connections -1 #or the max number of connection you want

% ps ax | grep mosquitto
9497 pts/44 S+ 0:00 ./mosquitto -c mosquitto.conf
9505 pts/10 S+ 0:00 grep –color=auto mosquitto
% cat /proc/9497/limits

https://github.com/takanorig/mqtt-bench
$ mqtt-bench -broker=tcp://192.168.1.100:1883 -action=pub -count=10000
$ mqtt-bench -broker=tcp://192.168.1.100:1883 -action=sub
Usage
Usage of mqtt-bench
-action=”p|pub or s|sub” : Publish or Subscribe (required)
-broker=”tcp://{host}:{port}” : URI of MQTT broker (required)
-broker-password=”” : Password for connecting to the MQTT broker
-broker-username=”” : Username for connecting to the MQTT broker
-tls=”” : TLS mode. ‘server:certFile’ or ‘client:rootCAFile,clientCertFile,clientKeyFile’
-qos=0 : MQTT QoS(0|1|2)
-retain=false : MQTT Retain
-topic=”/mqtt-bench/benchmark” : Base topic
-clients=10 : Number of clients
-count=100 : Number of loops per client
-size=1024 : Message size per publish (byte)
-pretime=3000 : Pre wait time (ms)
-intervaltime=0 : Interval time per message (ms)
-x=false : Debug mode

RabbitMQ is a very popular message broker written in Erlang that has support for MQTT among other protocols through a plugin.
This broker supports the AMQP protocol natively, the MQTT implementation is missing some important features such as QoS2.

Mosquitto is a really lightweight MQTT broker written in C.
Unfortunately Mosquitto does not support clustering, it makes scaling a bit difficult.
It is using only a single thread so can’t take advantage of multi core CPUs.

HiveMQ is the MQTT broker for the connected enterprise: The puzzle piece between constrained devices and enterprise systems.
Leverage its best-in-class performance and scalability to connect your devices today.
Enterprise Integrations enable you to handle huge throughput at lowest latency and further process your data.
Our MQTT server is scalable, secure and simple with state-of-the-art technology.

Client side TLS certs remove the need for username and passowrd, however most authentication
and authorization mechanisms on the broker side rely on these, or at least on the username.
To solve this issue the brokers that support client side certs usually has an option to use the CN field of the client cert as a username.
This feature enables us to use these certs instead of the username and password seamlessly.

Embed a unique identifier or the Client Id into the topic
It can be very helpful to include the unique identifier of the publishing client in the topic.
The unique identifier in the topic helps you identify who sent the message.
The embedded ID can be used to enforce authorization.
Only a client that has the same client ID as the ID in the topic is allowed to publish to that topic.
For example, a client with the client1 ID is allowed to publish to client1/status, but not permitted to publish to client2/status.

Use specific topics, not general ones
When you name topics, don’t use them in the same way as in a queue. Be as specific topics as possible.
For example, if you have three sensors in your living room, create topics for myhome/livingroom/temperature,
myhome/livingroom/brightness and myhome/livingroom/humidity.
Do not send all values over myhome/livingroom. Use of a single topic for all messages is a anti pattern.
Specific naming also makes it possible for you to use other MQTT features such as retained messages.
It is also possible to define ACLs based on pattern substitution within the topic.
The form is the same as for the topic keyword, but using pattern as the keyword.
pattern [read|write|readwrite] <topic>
The patterns available for substition are:
%c to match the client id of the client
%u to match the username of the client
Example:
pattern write sensor/%u/data
Allow access for bridge connection messages:
pattern write $SYS/broker/connection/%c/state

Topic names are:
Case sensitive
use UTF-8 strings.
Must consist of at least one character to be valid.
Except for the $SYS topic there is no default or standard topic structure.

protocol_prefix / src_id / dest_id / message_id / extra_properties
protocol_prefix is used to differentiate between different protocols / application that can be used at the same time
src_id is the ID of the mqtt client that publishes the message. It is expected to be the same as “client ID” used to connect to MQTT broker. It allows quick ACL control to check whether the client is allowed to publish specific topic.
dest_id is client ID of the “destination” unit, i.e. to whom the message is intended. Also allows quick ACL control on the broker of whether client is allowed to subscribe to a particular topic.
There can be reserved “destination” strings to specify that the message is broadcasted to anyone who is interested. For example all.

Some examples of topics are:
/home/llivingroom/bulb1/status
/home/door/sensor/battery
/home/door/sensor/battery/units
/home/outdoors/temperature
/home/outdoors/temperature/yesterday/max
/zigbee/0013a20040401122/dio3
/zigbee/0013a20040410034/adc7

/home/bedroom/temperature/last
/home/bedroom/temperature/last/timestamp
/home/bedroom/temperature/last24h/max
/home/bedroom/temperature/last24h/max/timestamp
/home/bedroom/temperature/last24h/min
/home/bedroom/temperature/last24h/min/timestamp
/home/bedroom/temperature/ever/max

/home/bedroom/temperature 21
/home/bedroom/temperature/units C
/home/bedroom/temperature/timestamp 2012-12-10T12:47:00+01:00

The decision should be made based on how are you using topics. If you need values together – post them into one topic, if you are using separately – put them into separate topics.

The choice for topic endpoints for high-scalability applications seems to be a small set of topics per thing (makes sense:
if you have millions of things, you want to minimize the switching burden on the broker), at least one “event” topic (where telemetry is published from thing to application)
and one “control” topic (where commands are received from the application by the thing).

Adding Users in MQTT Broker
There are 2 options for this.
Mosquitto reads the password file when it starts so will not pick up the changes when you run mosquitto_passwd. You can force mosquitto to re-read the file by sending the mosquitto broker a HUP signal
It is possible to do so. First you have to set your mosquitto.conf to save the pid in a file by specifying the pid_file.
pid_file your/pid/file
Then you can call
$kill -SIGHUP $(cat your/pid/file).
Or else if you already know the PID of the mosquitoo, then you can do
$kill -SIGHUP PID
This will send sighup signal and reload the pwfile.
The better option is to stop using the password file if you are going to add/remove users dynamically and use the mosquitto-auth-plugin which lets you use a database to store the usernames/passwords and the ACL entries.

分类: mqtt

发表评论

电子邮件地址不会被公开。