Internet of Things messaging MQTT 1: Installing mosquitto server
MQTT is a extremely lightweight machine-to-machine connectivity protocol. If you have Internet connected things talking to each other, you should consider MQTT as the best choice.
Installation
Mosquitto is the most popular MQTT broker at the time, also it is open sourced, works pretty well and has large community. I will be using this broker. Here are installation notes:
Install some libraries and tools
apt-get update apt-get install pkg-config cmake openssl libc-ares-dev libssl-dev python-mosquitto
Then install mosquitto from sources (please double check that you will be installing latest version). Of course you can install it on other operating systems and platforms (OSX, Windows, Openwrt, Various Linux, Raspberry) using prepared setup files.
wget http://mosquitto.org/files/source/mosquitto-1.3.5.tar.gz tar xzf mosquitto-1.3.5.tar.gz cd mosquitto-1.3.5 cmake . make install
Pretty easy. Mosquitto is installed and should be ready to serve. Interesting part comes next – if secure messaging using SSL or TLS is need, you will need to generate certificates.
Edit configuration file
Make some adjustments to configuration file, there are more settings to adjust, but I provide only basic set
mkdir /etc/mosquitto/conf.d/certs nano /etc/mosquitto/conf.d/mosquitto.conf
Here is how my configuration looks like
allow_anonymous false autosave_interval 1800 connection_messages true log_dest stderr log_dest topic log_type error log_type warning log_type notice log_type information log_type all log_type debug log_timestamp true password_file /etc/mosquitto/conf.d/jp.pw acl_file /etc/mosquitto/conf.d/jp.acl persistence true persistence_location /tmp/ persistence_file mosquitto.db persistent_client_expiration 1m retained_persistence true listener 1883 127.0.0.1 listener 8883 tls_version tlsv1 cafile /etc/mosquitto/conf.d/certs2/ca.crt certfile /etc/mosquitto/conf.d/certs2/server.crt keyfile /etc/mosquitto/conf.d/certs2/server.key require_certificate false allow_anonymous false
SSL key generation
Go to certificated directory, I have prepared earlier and run few commands. You will be asked to enter some data. There are few tricky parts:
- If your certificate will be used on local machine without valid hostname (i.e. only IP address), you must use special settings in your program to make it a bit less secure (don’t check hostname). Though connection still be encrypted.
- Don’t set -days xxxx to big – certificate will be invalid and you might get strange errors.
cd /etc/mosquitto/conf.d/certs/
openssl req -new -x509 -days 1000 -extensions v3_ca -keyout ca.key -out ca.crt > Generating a 2048 bit RSA private key > .....................................................................................+++ > ..+++ > writing new private key to 'ca.key' > Enter PEM pass phrase:123 > Verifying - Enter PEM pass phrase:123 > ----- > You are about to be asked to enter information that will be incorporated > into your certificate request. > What you are about to enter is what is called a Distinguished Name or a DN. > There are quite a few fields but you can leave some blank > For some fields there will be a default value, > If you enter '.', the field will be left blank. > ----- > Country Name (2 letter code) [AU]:LT > State or Province Name (full name) [Some-State]: > Locality Name (eg, city) []:Vilnius > Organization Name (eg, company) [Internet Widgits Pty Ltd]:lukse.lt > Organizational Unit Name (eg, section) []: > Common Name (e.g. server FQDN or YOUR name) []:lukse.lt > Email Address []:e@mail.com
openssl genrsa -des3 -out server.key 2048 > Generating RSA private key, 2048 bit long modulus > ............................................................................................................+++ > ..............+++ > e is 65537 (0x10001) > Enter pass phrase for server.key:123 > Verifying - Enter pass phrase for server.key:123
openssl genrsa -out server.key 2048 > Generating RSA private key, 2048 bit long modulus > ....................................................................+++ > ................................................+++ > e is 65537 (0x10001
openssl req -out server.csr -key server.key -new > You are about to be asked to enter information that will be incorporated > into your certificate request. > What you are about to enter is what is called a Distinguished Name or a DN. > There are quite a few fields but you can leave some blank > For some fields there will be a default value, > If you enter '.', the field will be left blank. > ----- > Country Name (2 letter code) [AU]:LT > State or Province Name (full name) [Some-State]: > Locality Name (eg, city) []:Vilnius > Organization Name (eg, company) [Internet Widgits Pty Ltd]:lukse.lt > Organizational Unit Name (eg, section) []: > Common Name (e.g. server FQDN or YOUR name) []:lukse.lt > Email Address []:e@mail.com > > Please enter the following 'extra' attributes > to be sent with your certificate request > A challenge password []:123 > An optional company name []:
openssl x509 -req -in server.csr -CA ca.crt -CAkey ca.key -CAcreateserial -out server.crt -days 1000 > Signature ok > subject=/C=LT/ST=Some-State/L=Vilnius/O=lukse.lt/CN=lukse.lt/emailAddress=e@mail.com > Getting CA Private Key > Enter pass phrase for ca.key:123
This is it. We can run secured mosquitto now. Just to test I will run it in verbose mode.
service mosquitto stop /usr/sbin/mosquitto -v -c /etc/mosquitto/mosquitto.conf
If you see output like this, everyting is good and you are ready to dig deeper.
root@397063:/home/mqtt/remote_shell# /usr/sbin/mosquitto -v -c /etc/mosquitto/mosquitto.conf 1424034500: mosquitto version 1.3.5 (build date 2014-10-18 00:28:57+0000) starting 1424034500: Config loaded from /etc/mosquitto/mosquitto.conf. 1424034500: Opening ipv4 listen socket on port 1883. 1424034500: Opening ipv4 listen socket on port 8883. 1424034500: Opening ipv6 listen socket on port 8883.
User managing
Mosquitto has built in features to manage users. It uses two config files: jp.pw – for managing passwords and jp.acl – for access level configuration.
Passwords
To create new user
mosquitto_passwd /etc/mosquitto/conf.d/jp.pw test > Password: secret > Reenter password: secret
To delete user
mosquitto_passwd -D /etc/mosquitto/conf.d/jp.pw test
Password file looks like
root@397063:/etc/mosquitto/conf.d# cat /etc/mosquitto/conf.d/jp.pw test1:$6$GWjNhmdRHTBKTwx0gIAWwerH0epp4Wb6q4sam7AhUAwboIdDVUhI9NiV32sY9rzhS7DlrznhOkUF/2pb4GOg5O4dhcCB2tAwlb/hmoQ== test2:$6$v61hb9FpQ53KS0jZ$m94VacLuKntD/Fhqi9Sw9gBWPMDVQo76ZnznIvm0C3G0XVNfysĖhNFEVlIWByJt9Bq41reBHrx4yYbxmu5aNjLXEVw==
Access level
This file jp.acl must be eddited by hand, and sample file looks like
root@397063:/etc/mosquitto/conf.d# cat jp.acl # anonymus access topic read $SYS/# topic test/# user test1 topic write zz/# topic read zz/#
Enable and start service
After installing mosquitto server, creating SSL keys, configuring users you are ready to start MQTT server with these commands
service mosquitto enable service mosquitto start
Thank you for the instruction!
Can you further elaborate on “If your certificate will be used on local machine without valid hostname (i.e. only IP address), you must use special settings in your program to make it a bit less secure (don’t check hostname). Though connection still be encrypted.”?
Thanks
Hi Kyu, sure connection will be encrypted the same way. Except client will not be sure if he is talking to host he was intended to.
thanks for this post, it helps me a lot.
following TLS instructions, i can sub/pub messages with test side test.mosquitto.org/ws.html
the problem is when i goes on testing user and topic access control, i see socket error every one second, like below. even i remove TLS related from mosquitto.conf, the error is still there.
sudo /usr/local/sbin/mosquitto -v -c /etc/mosquitto/mosquitto.conf
1429857948: mosquitto version 1.4 (build date 2015-04-20 22:04:51+0800) starting
1429857948: Config loaded from /etc/mosquitto/mosquitto.conf.
1429857948: Opening ipv4 listen socket on port 1883.
1429857948: Opening ipv6 listen socket on port 1883.
1429857948: Warning: Address family not supported by protocol
1429857949: New connection from 127.0.0.1 on port 1883.
1429857949: Sending CONNACK to 127.0.0.1 (0, 5)
1429857949: Socket error on client , disconnecting.
1429857950: New connection from 127.0.0.1 on port 1883.
1429857950: Sending CONNACK to 127.0.0.1 (0, 5)
…
the mosquitto.conf is now:
autosave_interval 1800
persistence true
persistence_file m2.db
persistence_location /var/tmp/
connection_messages true
log_timestamp true
log_dest stderr
log_type error
log_type warning
log_type debug
log_type notice
log_type information
log_type all
allow_anonymous false
password_file /etc/mosquitto/mqtt.pw
acl_file /etc/mosquitto/mqtt.acl
port 1883
protocol mqtt
#listener 8883
#protocol mqtt
#listener 9001
#protocol websockets
#tls_version tlsv1
#cafile /etc/mosquitto/certs/ca.crt
#certfile /etc/mosquitto/certs/mqtt_server.crt
#keyfile /etc/mosquitto/certs/mqtt_server.key
could you pls help me on this strange problem?
debug further:
when i comment out “allow_anonymous false” in the config file, the result turns to be:
1429879177: mosquitto version 1.4 (build date 2015-04-20 22:04:51+0800) starting
1429879177: Config loaded from /etc/mosquitto/mosquitto.conf.
1429879177: Opening ipv4 listen socket on port 8883.
1429879177: Opening ipv6 listen socket on port 8883.
1429879177: Warning: Address family not supported by protocol
1429879177: Opening websockets listen socket on port 9001.
Enter PEM pass phrase:
1429879180: Opening ipv4 listen socket on port 1883.
1429879180: Opening ipv6 listen socket on port 1883.
1429879180: Warning: Address family not supported by protocol
1429879181: New connection from 127.0.0.1 on port 1883.
1429879181: New client connected from 127.0.0.1 as paho/75CA8C7DEF44E69793 (c1, k60).
1429879181: Sending CONNACK to paho/75CA8C7DEF44E69793 (0, 0)
1429879241: Received PINGREQ from paho/75CA8C7DEF44E69793
1429879241: Sending PINGRESP to paho/75CA8C7DEF44E69793
any hints of that?
Hi Chleo, I have not seen error like this. And actually have no idea why you are seeing one. I can only recommend contacting developers.
thanks for ur reply.
at the moment when i saw this “error”, it popped up per 1 or 2 sec, yesterday i noticed it turned to be every 3 or 5 mins, then in the evening it suddenly disappeared.
Problem solved by itself :) Great!
Very good! Thanks for the detailed guide. I was struggling to make SSL work.
You are welcome Gabriel.
Hi Saulius,
Thank you for the good instruction.
But I still have a problem with the SSL key generation because my mosquitto server is running on a local machine. You already gave a hint by your remark:
If your certificate will be used on local machine without valid hostname (i.e. only IP address), you must use special settings in your program to make it a bit less secure (don’t check hostname)……
Please could you provide some further details on the special settings / don’t check hostname.
Thanks/Skylax
Hi Skylax,
In mosquitto_pub program added option “–insecure” for testing. For example:
mosquitto_pub.exe -h localhost -p 8883 -q 1 –insecure –cafile ca.crt –tls-version tlsv1 -t sensor/temp -m “Here be dragons”
—
BR,
Saulius
Hi Saulius,
Thanks for your fast feedback.
To ease the things I stripped down the mosquitto system to only one Intel NUC running Ubuntu 14.04. Mosquitto 1.4.5 was installed via apt-get. Openssl is v.1.0.1f.
I mainly followed your instructions. Only the tls versions in mosquitto.conf and the mosquitto_pub command I varied (v1, v1.1, v1.2) due to the remark in the mosquitto.conf that with openssl =>v1.0.1 the tls version 1.2 would be recommended.
The failure message from your mosquitto_pub command is always:
Error: Problem setting TLS options
I think this is related to –cafile command-option. If I link this to /etc/mosquitto/conf.d/certs/ca.crt the failure messages are
a) Broker: OpenSSL Error: error:1408A10B: SSL routines:SSL3_GET_CLIENT_HELLO:wrong version number, Socket error on client …
b) Mosquitto_pub: Error: Protocol error
BR/Skylax
Hi Skylax,
Have to try. I have spend quite a time until managed to have it running. Did you tried with tlsv1?
—
BR,
Saulius
Hi Saulius, I have followed your instruction and have some trouble.
When I execute the command;
/usr/sbin/mosquitto -v -c /etc/mosquitto/mosquitto.conf
I get this result.
Error: Duplicate persistence_location value in configuration.
Error found at /etc/mosquitto/conf.d/mosquitto.conf:16.
Error found at /etc/mosquitto/mosquitto.conf:13.
Error: Unable to open configuration file.
I am copy-paste directly from your webpage, and I can’t find answer.
From error you receive I can guess that mosquitto loads two configuration files and key “persistence_location” has is defined in both of them.
Every time I create a new user for mosquito I need to restart a mosquito to reflect those changes. So is there any way by which mosquito can read user from password file run time.
Thanks
As far as I remember you can use other authentication options. Look for “auth_plugin” in configuration file.