MQTTブローカー MosquittoをUbuntu 18.04にインストール

Ubuntu18.04で立てたサーバーにMQTTブローカーを作ってみたので作業メモ。
※同じ作業をUbuntu20.04で行うとうまいこと動きませんでした。

## 準備

本記事の作業をするにあたり、以下のことを前提としています。

- Ubuntu18.04サーバーがすでにインストールされていること。
- ルートユーザー以外で且つsudo権限が与えられたユーザーで作業を行う。
- Ubuntu18.04サーバーにSSHで接続が可能である。
- Ubunbu18.04サーバーにサブドメインが割り当てられている。本記事では`mqtt.example.com`と仮定して進める。
- 80番ポートが使用可能であること。他のプログラムが80番ポートを使用していないこと。

## いざ、作業へ

### Step 1 - ソフトウェアをインストール

まずはじめに、作業に必要なプログラムをインストールしていきます。

```bash
$ sudo add-apt-repository ppa:certbot/certbot
$ sudo apt install certbot mosquitto mosquitto-clients
```

### Step 2 - SSL証明書をダウンロード

ファイアウォールに80番を許可します。

```bash
$ sudo ufw allow 80
```

次に、Certbotを使ってSSL証明書を発行します。

```bash
sudo certbot certonly --standalone --preferred-challenges http -d mqtt.example.com
```

`mqtt.example.com`はあくまでサンプルなので、あなたがサーバーに割り当てたドメインを使用して下さい。

このコマンドを実行すると、メールアドレスの入力と利用規約への同意が求められます。手順に従って作業を行って下さい。
プロセスが成功すると、証明書が保存されている場所を示すメッセージが表示されます。

ここで発行した証明書を使って、次からMosquittoの設定を行って行きます。

### Step 3 - Mosquittoの設定

Mosquittoに接続する際のセキュリティにはユーザー名とパスワードの認証を使います。

最初に、パスワード設定用のファイルを作りましょう。`mosquitto_passwd`コマンドを使えば作成が可能です。`your-username`は接続認証に使いますので、好きな名前を設定して下さい。

パスワードは二回入力を求められますので、間違えないように入力して下さい。

```bash
$ sudo mosquitto_passwd -c /etc/mosquitto/passwd your-username
```

次に、Mosquittoの設定ファイルを作ります。

```bash
$ sudo nano /etc/mosquitto/conf.d/default.conf
```

そして、以下のテキストを入力します。例によって、`mqtt.example.com`はご自身のドメインに置き換えて下さい。

```conf
allow_anonymous false
password_file /etc/mosquitto/passwd

listener 8883
certfile /etc/letsencrypt/live/mqtt.example.com/cert.pem
cafile /etc/letsencrypt/live/mqtt.example.com/chain.pem
keyfile /etc/letsencrypt/live/mqtt.example.com/privkey.pem

listener 8083
protocol websockets
certfile /etc/letsencrypt/live/mqtt.example.com/cert.pem
cafile /etc/letsencrypt/live/mqtt.example.com/chain.pem
keyfile /etc/letsencrypt/live/mqtt.example.com/privkey.pem
```

入力が完了するとファイルを保存し、閉じて下さい。

このファイルでは、以下の設定を記述しました。

- 匿名ログインを無効化
- 接続認証にパスワードを使用
- `8883`番ポートをSSLを使用したTCP接続に設定
- `8083`番ポートをSSLを使用したWebSocket接続に設定

以下のコマンドでMosquittoを再起動し、設定を反映します。

```bash
$ sudo systemctl restart mosquitto
```

以下のコマンドで正常に起動ができていることを確認してください。

```bash
$ sudo systemctl status mosquitto
● mosquitto.service - LSB: mosquitto MQTT v3.1 message broker
   Loaded: loaded (/etc/init.d/mosquitto; generated)
   Active: active (running) since Mon 2018-07-16 15:03:42 UTC; 2min 39s ago
     Docs: man:systemd-sysv-generator(8)
  Process: 6683 ExecStop=/etc/init.d/mosquitto stop (code=exited, status=0/SUCCESS)
  Process: 6699 ExecStart=/etc/init.d/mosquitto start (code=exited, status=0/SUCCESS)
    Tasks: 1 (limit: 1152)
   CGroup: /system.slice/mosquitto.service
           └─6705 /usr/sbin/mosquitto -c /etc/mosquitto/mosquitto.conf
```

次に、ファイアフォールの設定を行います。

```bash
$ sudo ufw allow 8883
$ sudo ufw allow 8083
```

### Step 4 - Certbotの自動更新

基本的にはここまでの作業でMosquittoの設定は終わり、接続できるようになっているはずです。

しかし、Let's Encryptには有効期限があり、自動で更新できるようにしておいた方が便利です。自動更新の設定を行っておきます。

以下のコマンドでCertbotの設定ファイルを開きます。

```bash
$ sudo nano /etc/letsencrypt/renewal/mqtt.example.com.conf
```

そして、以下の行を追加して下さい。

```conf
renew_hook = systemctl restart mosquitto
```

入力が完了すると、ファイルを保存して閉じます。

そして、以下のコマンドでシンタックスエラーが出ないか確認します。

```bash
$ sudo certbot renew --dry-run
```

### Step5 - 動作確認

ここまできたら、動作確認を行います。

`mqtt.example.com`や`your-username`、`your-password`は先程設定した値を入力してください。
以下のコマンドでは`test`というトピックをサブスクライブします。

```bash
$ mosquitto_sub -h mqtt.example.com -t test -p 8883 --capath /etc/ssl/certs/ -u "your-username" -P "your-password"
```

別ウィンドウを立ち上げる等し、以下のコマンドから`test`トピックに対してメッセージを送ってみましょう。

```bash
$ mosquitto_pub -h mqtt.example.com -t test -m "hello world" -p 8883 --capath /etc/ssl/certs/ -u "your-username" -P "your-password"
```

無事にメッセージが受信できていればちゃんと動いています。

作業は以上となります。
お疲れさまでした。