MosquittoでTLS通信
はじめに
昨日作ったMQTTのお試し環境をTLS通信できるようにする。
DockerとEclipse MosquittoでMQTT - ブログに書くつもりじゃなかった
証明書の作成
この辺はググればいくらでも出てくる情報だが、俺自信が覚えるために。
認証局の秘密鍵を作成
$ openssl genrsa -des3 -out ca.key 2048 Generating RSA private key, 2048 bit long modulus .......+++ ....+++ e is 65537 (0x10001) Enter pass phrase for ca.key: Verifying - Enter pass phrase for ca.key:
自己署名証明書を作成
$ openssl req -new -x509 -days 1826 -key ca.key -out ca.crt Enter pass phrase for ca.key: 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) []: State or Province Name (full name) []: Locality Name (eg, city) []: Organization Name (eg, company) []: Organizational Unit Name (eg, section) []: Common Name (eg, fully qualified host name) []:root-ca Email Address []:
サーバーの秘密鍵を作成
$ openssl genrsa -out server.key 2048 Generating RSA private key, 2048 bit long modulus ...............................+++ ...............+++ e is 65537 (0x10001)
サーバーの証明書要求を作成
$ openssl req -new -out server.csr -key server.key 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) []:JP State or Province Name (full name) []:Miyagi Locality Name (eg, city) []:Sendai Organization Name (eg, company) []: Organizational Unit Name (eg, section) []: Common Name (eg, fully qualified host name) []:mosquitto-broker Email Address []: Please enter the following 'extra' attributes to be sent with your certificate request A challenge password []:
Common Nameはホスト名に合わせる。
証明書要求に署名する
$ openssl x509 -req -in server.csr -CA ca.crt -CAkey ca.key -CAcreateserial -out server.crt -days 360 -sha256 Signature ok subject=/C=JP/ST=Miyagi/L=Sendai/CN=mosquitto-broker Getting CA Private Key Enter pass phrase for ca.key:
後述するけど、自分の環境では-sha256
オプションが必要だった。
環境構築
mosquitto.conf
リッスンするポート番号を8883に変更。証明書と秘密鍵のパスを指定。
allow_anonymous true listener 8883 cafile /mosquitto/certs/ca.crt keyfile /mosquitto/certs/server.key certfile /mosquitto/certs/server.crt
docker-compose.yml
証明書と秘密鍵のファイルをバインドする。
version: '3' services: mosquitto-publisher: build: . container_name: mosquitto-publisher tty: true volumes: - ./ca.crt:/ca.crt mosquitto-subscriber: build: . container_name: mosquitto-subscriber tty: true volumes: - ./ca.crt:/ca.crt mosquitto-broker: image: eclipse-mosquitto container_name: mosquitto-broker volumes: - ./mosquitto.conf:/mosquitto/config/mosquitto.conf - ./ca.crt:/mosquitto/certs/ca.crt - ./server.key:/mosquitto/certs/server.key - ./server.crt:/mosquitto/certs/server.crt
実践
Subscriber側。--cafile
オプションでCA証明書を指定する。
$ mosquitto_sub -h mosquitto-broker -t mytopic --cafile /ca.crt
Publisher側。同じく--cafile
オプションでCA証明書を指定する。
$ mosquitto_pub -h mosquitto-broker -t mytopic -m "This is a test." --cafile /ca.crt
つまずいた箇所
当初mosquitto_sub
、mosquitto_pub
を実行したときにTLSエラーが出た。
Error: A TLS error occurred.
証明書を作り直す、dockerコンテナの設定を変えるなどして何度も試したが、なかなか解決せず。結構な時間を使った後で、証明書の中身を覗くと、署名アルゴリズムがまさかのSHA1になってたのを発見。
$ openssl x509 -text -noout -in server.crt
どうやらこれが原因で、サーバー証明書の危険が危ない的なエラーになっていたようだ。証明書要求を認証する際に-sha256
オプションを付けることで、無事解消。やれやれ。