MQTTブローカMosquitto

MQTTブローカであるMosquittoのインストール

$ sudo apt install mosquitto

設定ファイルを /etc/mosquitto/conf.d フォルダに作成します。

雛形は /usr/share/doc/mosquitto/examples 内に格納されています。

SSL/TLS認証設定を含んだ主な設定内容は以下の通りです。

    # Config file for mosquitto
    #
    # See mosquitto.conf(5) for more information.
    #
    # Default values are shown, uncomment to change.
    #
    # Use the # character to indicate a comment, but only if it is the 
    # very first character on the line.

    # =================================================================
    # General configuration
    # =================================================================


    # =================================================================
    # Default listener
    # =================================================================

    # IP address/hostname to bind the default listener to. If not
    # given, the default listener will not be bound to a specific 
    # address and so will be accessible to all network interfaces.
    # bind_address ip-address/host name
    #bind_address

    # Port to use for the default listener.

    port 1883

    # =================================================================
    # Extra listeners
    # =================================================================

    # Listen on a port/ip address combination. By using this variable 
    # multiple times, mosquitto can listen on more than one port. If 
    # this variable is used and neither bind_address nor port given, 
    # then the default listener will not be started.
    # The port number to listen on must be given. Optionally, an ip 
    # address or host name may be supplied as a second argument. In 
    # this case, mosquitto will attempt to bind the listener to that 
    # address and so restrict access to the associated network and 
    # interface. By default, mosquitto will listen on all interfaces.
    # listener port-number [ip address/host name]

    listener 8883

    # -----------------------------------------------------------------
    # Certificate based SSL/TLS support
    # -----------------------------------------------------------------
    # The following options can be used to enable certificate based SSL/TLS support
    # for this listener. Note that the recommended port for MQTT over TLS is 8883,
    # but this must be set manually.
    #
    # See also the mosquitto-tls man page and the "Pre-shared-key based SSL/TLS
    # support" section. Only one of certificate or PSK encryption support can be
    # enabled for any listener.

    # At least one of cafile or capath must be defined to enable certificate based
    # TLS encryption. They both define methods of accessing the PEM encoded
    # Certificate Authority certificates that have signed your server certificate
    # and that you wish to trust.
    # cafile defines the path to a file containing the CA certificates.
    # capath defines a directory that will be searched for files
    # containing the CA certificates. For capath to work correctly, the
    # certificate files must have ".crt" as the file ending and you must run
    # "c_rehash <path to capath>" each time you add/remove a certificate.

    cafile /etc/mosquitto/ca_certificates/mqtt_ca.crt

    #capath

    # Path to the PEM encoded server certificate.

    certfile /etc/mosquitto/certs/mqtt_srv.crt

    # Path to the PEM encoded keyfile.

    keyfile /etc/mosquitto/certs/mqtt_srv.key

    # By default an TLS enabled listener will operate in a similar fashion to a
    # https enabled web server, in that the server has a certificate signed by a CA
    # and the client will verify that it is a trusted certificate. The overall aim
    # is encryption of the network traffic. By setting require_certificate to true,
    # the client must provide a valid certificate in order for the network
    # connection to proceed. This allows access to the broker to be controlled
    # outside of the mechanisms provided by MQTT.

    require_certificate false

    # =================================================================
    # Security
    # =================================================================

    # If set, only clients that have a matching prefix on their 
    # clientid will be allowed to connect to the broker. By default, 
    # all clients may connect.
    # For example, setting "secure-" here would mean a client "secure-
    # client" could connect but another with clientid "mqtt" couldn't.
    #clientid_prefixes

    # Boolean value that determines whether clients that connect 
    # without providing a username are allowed to connect. If set to 
    # false then a password file should be created (see the 
    # password_file option) to control authenticated client access. 
    # Defaults to true.

    allow_anonymous false

    # In addition to the clientid_prefixes, allow_anonymous and TLS 
    # authentication options, username based authentication is also 
    # possible. The default support is described in "Default 
    # authentication and topic access control" below. The auth_plugin 
    # allows another authentication method to be used.
    # Specify the path to the loadable plugin and see the 
    # "Authentication and topic access plugin options" section below.
    #auth_plugin

    # -----------------------------------------------------------------
    # Default authentication and topic access control
    # -----------------------------------------------------------------

    # Control access to the broker using a password file. This file can be
    # generated using the mosquitto_passwd utility. If TLS support is not compiled
    # into mosquitto (it is recommended that TLS support should be included) then
    # plain text passwords are used, in which case the file should be a text file
    # with lines in the format:
    # username:password
    # The password (and colon) may be omitted if desired, although this 
    # offers very little in the way of security.
    # 
    # See the TLS client require_certificate and use_identity_as_username options
    # for alternative authentication options.

    password_file /etc/mosquitto/mqttpass

動作確認

ユーザとパスワードを指定してデータのパブリッシュ、サブスクライブをmosquittoがインストールされた端末から確認する場合。

1.トピックをサブスクライブ

$ mosquitto_sub -u 'user' -P 'password' -t 'test/topic' -v

2.トピックをパブリッシュ

$ mosquitto_pub -u 'user' -P 'password' -t 'test/topic' -m 'hello world'

3.他の端末からmosquittoサーバ192.168.xx.xxを指定してデータをパプリッシュ

$ mosquitto_pub -h 192.168.xx.xx -u 'user' -P 'password' -t 'test/topic' -m 'hello world'

2,3の結果が1に表示されます。

パスワード認証

パスワードファイルの作成

mosquitto_passwdコマンドで、Mosquittoへのアクセスユーザと暗号化パスワードのセットが記述されたファイルを作成します。

new_userという名称のユーザパスワードファイルを作成

$ sudo mosquitto_passwd -c /etc/mosquitto/mqttpass new_user

パスワードを入力求められるので入力して下さい。

    SYNOPSIS
           mosquitto_passwd [-c | -D] passwordfile username

           mosquitto_passwd -b passwordfile username password

           mosquitto_passwd -U passwordfile

    DESCRIPTION
           mosquitto_passwd is a tool for managing password files the mosquitto MQTT broker.

           Usernames must not contain ":". Passwords are stored in a similar format to crypt(3).

    OPTIONS
           -b
               Run in batch mode. This allows the password to be provided at the command line which
               can be convenient but should be used with care because the password will be visible on
               the command line and in command history.

           -c
               Create a new password file. If the file already exists, it will be overwritten.

           -D
               Delete the specified user from the password file.

           -U
               This option can be used to upgrade/convert a password file with plain text passwords
               into one using hashed passwords. It will modify the specified file. It does not detect
               whether passwords are already hashed, so using it on a password file that already
               contains hashed passwords will generate new hashes based on the old hashes and render
               the password file unusable.

起動しない場合、ターミナルからコンフィグファイルを指定して起動

$ mosquitto -c /etc/mosquitto/mosquitto.conf

/var/log/mosquittoフォルダの所有権を修正します。

$ sudo chown -R root:mosquitto /var/log/mosquitto

または /etc/mosquitto/mosquitto.conf 内で log取得を無効(コメントアウト) にします。

# log_dest file /var/log/mosquitto/mosquitto.log

Mosquitto Docker

Docker Hub

Docker Compose ファイル例 (OpenSSLがインストールされたイメージを指定)

version: '3.5'

services:
  mosquitto:
    container_name: mosquitto
    image: eclipse-mosquitto:2-openssl
    tty: true
    restart: unless-stopped
    privileged: true
    volumes:
      - ./mosquitto/config:/mosquitto/config
      - ./mosquitto/data:/mosquitto/data
      - ./mosquitto/log:/mosquitto/log
      - ./letsencrypt:/mosquitto/certs
    network_mode: host

Dockerイメージで使用される設定ファイル・ログファイル・データファイルの各ディレクトリパスはパッケージ版とは異なるため、設定ファイルのパス設定に注意。

コンテナ内でのユーザ:グループ名 mosquitto のユーザIDとグループID:1883

Dockerfile は以下参照。

事前に下記設定ファイルを作成

  • 設定ファイル
    /mosquitto/config/mosquitto.conf
listener 1883 localhost
listener 1883 hostname.local

persistence true
persistence_location /mosquitto/data
log_dest file /mosquitto/log/mosquitto.log

password_file /mosquitto/data/mosquitto.password_file
acl_file /mosquitto/data/mosquitto.aclfile

listener 8883
certfile /mosquitto/certs/live/www.example.com/fullchain.pem
keyfile /mosquitto/certs/live/www.example.com/privkey.key

# include_dir /mosquitto/config/conf.d

LAN内からのアクセスにはポート1883、外部からのアクセスにはTLSポート8883を指定

注) hostname.localavahi により作成されるドメイン名で、このドメインとIPアドレスをセットにして /etc/hosts に登録すること。

パスワード作成

ACLファイル例


Let’s Encrypt(Certbot)によるTLS認証

Dockerがインストールされているため、TLS認証にもCertbotのDockerイメージを使用します。スタンドアローンモードでドメインを指定、Arm32ビット版 のRaspberry PiやOrangepiを使用している場合には arm32v6-xx を指定します。

$ docker run -it --rm --name certbot -v "$PWD/letsencrypt:/etc/letsencrypt" -p 80:80  certbot/certbot:arm32v6-latest certonly --standalone -d www.example.com

letsencrypt フォルダにTLS認証に必要な証明書・認証キー一式が保存されるので、ここから mosquitto のサーバ証明書とサーバキーを設定ファイルで指定します。

参考

listener 8883
cafile /etc/ssl/certs/DST_Root_CA_X3.pem
certfile /etc/letsencrypt/live/example.com/fullchain.pem
keyfile /etc/letsencrypt/live/example.com/privkey.pem

TLS接続に必要な証明書は下記設定ファイル内の条件により異なります。クライアントがCAファイルをサーバに提示しなければならない条件は require_certificate, use_identity_as_username を共に true にした場合です。

mosquitto_tls_chart