MQTTプロトコルの仲介役であるMosquittoブローカは、デフォルトではユーザ認証・送受信データの暗号化が無効になっています。ブローカにアクセスできるユーザ指定とTLS(SSL)による暗号化を有効化することでセキュリティを確保します。以下設定のポイントです。
(1)パスワードによるユーザ認証には、ユーザとパスワードがセットになったパスワードファイルを作成
(2)TLS認証にはMosquittoのブローカ側とクライアント側双方に必要なファイル(キーファイル、証明書)を作成
(3)上記設定を有効にするため、Mosquittoの設定ファイルでファイルパス、ファイル名などの指定をします。
対象ハードとOS
OrangePi PC : ARMBIAN 5.36 user-built Ubuntu 16.04.3 LTS 3.4.113-sun8i
(1)パスワード認証
Mosquittoのパスワード作成コマンドとそのオプションについてはmosquitto_passコマンドマニュアルを参照願います。
まずユーザ名userを指定してパスワードファイルmqttpassを作成します。
$ sudo mosquitto_passwd -c /etc/mosquitto/mqttpass user1
パスワードを入力すると確認のため再度パスワードの入力を求められます。
mqttpassの中身は以下のようにコロン:を挟んで、ユーザ名(user1):暗号化されたパスワードとなります。
$ cat /etc/mosquitto/mqttpass
user1:$6$SVen8AFp/cFwOzRw$a2TEcduNff+6xZPxEzDDmC5Hr1N8SFw9Vhg78P8Zxtunm/+tWV6FeCGcgaX9dY09yD6gUfmLsEcsn7A5X1AH1g==
ここでユーザカスタム用設定ファイルを作成します。設定ファイルの雛形は/usr/share/doc/mosquitto/examplesに格納されています。この雛形の内容をそのまま既存の設定ファイル/etc/mosquitto/mosquitto.confに追加するか、または/etc/mosquitto/conf.d/xxxxx.confとして新規作成して中身をコピーするかは任意です。設定ファイルの以下2項目をコメントアウト・内容追加して有効にします。
allow_anonymousを無効化
# 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
password_fileの指定
# -----------------------------------------------------------------
# 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
Mosquittonoの再起動で特定ユーザによるパスワード認証が有効になります。
(2)TLS/SSL認証
(1)のパスワード認証のみでは、ユーザ名、パスワードなどのデータがそのままやり取りされるため、TLSにより送受信データを暗号化してセキュリティをより高めます。TLSとSSLは同義として捉えて構いません。
TLS/SSL認証の仕組みはやや複雑で、概念をイメージ化して理解する必要があります。認証局(CA)、サーバ、クライアントと公開キーと秘密キー(キーファイル)、証明書というキーワードがポイントです。
認証局、サーバ、クライアントとキーファイルと証明書の関係図
TLS/SSL認証に必要なファイル(公開キーと秘密キーを関連付けるキーファイルや証明書ファイル)はOpenSSLにより作成します。
公開キーと秘密キーは数学的に相互に関連付けられており、その実態はランダムな数列です。この関連付けを一つのファイルに纏めたものがキーファイル(拡張子.key)です。証明書(拡張子.crt)はこのキーファイルに基づいて作成されます。
キーファイルは認証局(CA)とサーバ側とで別々に作成・保管します。
CAのキーファイルはCAが発行するCA自身の証明書作成の際やこの証明書によりサーバの公開キーを認証(署名)する際に使用されます。
サーバ側のキーファイルは、公開キーをCA認証(署名)するためのリクエストファイル(拡張子.csr)作成の際に使用されます。
このリクエストファイルにより、サーバ側の公開キーをCA認証(署名)した証明書ファイル(拡張子.crt)が作成され、これがクライアントに配布されます。
クライアントは、サーバ側から配布された証明書とCA自身の証明書を照合することで公開キーを取り出しデータを暗号化します。
サーバ側は秘密キーによりクライアントから暗号化されたデータを元に戻します。
本来ならば公認CAの証明書を使用するべきですが、ここではサーバ側にCAの役割も担わせます(CAの秘密キーをサーバが保有することになりセキュリティ上の欠点となりますが、サーバ側とクライアント側の負荷軽減のため自己署名認証とします)。
MosquittoによるTLS/SSL認証マニュアルも参照願います。
OpenSSLのインストール
TLS/SSL認証に必要なファイルを作成するため、OpenSSLを導入します。作成されたファイル内容の確認もOpenSSLによって行うことができます。
$ sudo apt install openssl
以下OpenSSLにより作成するファイルの概要です。
- CAのキーファイルの作成 mqtt_ca.key
- CAキーファイルによるCA署名入り証明書の作成 mqtt_ca.crt
- サーバキーファイルの作成 mqtt_srv.key
- サーバキーファイルをCA認証してもらうためのリクエストファイルの作成 mqtt_srv.csr
- 上記リクエストファイルによりサーバキーファイルがCA署名入り証明書で認証されたことを証明する証明書の作成 mqtt_srv.crt
CAのキーファイルmqtt_ca.keyの作成
$ openssl genrsa -des3 -out mqtt_ca.key 2048
オプションはマニュアルページ参照 (https://wiki.openssl.org/index.php/Manual:Genrsa(1)):
- genrsa: Generate an RSA private key
- -des3: Using DES3 cipher for the key generation
- -out: Specifies the output file name (.key)
- 2048: Number of bits for the private key
-des3により秘密キーの利用にはパスワード入力が必要となります。内容の確認は、
$ openssl rsa -noout -text -in mqtt_ca.key
CAキーファイルによるCA署名入り証明書mqtt_ca.crtの作成
$ openssl req -new -x509 -days 3650 -key mqtt_ca.key -out mqtt_ca.crt
オプションはマニュアルページ参照 (https://wiki.openssl.org/index.php/Manual:Req(1)):
- req: Certificate request and certification utility.
- -new: Generate a new certificate. It will prompt the user for several input fields.
- -x509: Create a self-signed certificate.
- -days: Specify the number of days the certificate is valid.
- -key: Key file with the private key to be used for signing.
- -out: Specifies the file name for the certificate (.crt).
以下のパラメータを入力する必要があります。
サーバはCAも兼ねるため、Common Nameにはサーバのドメインを入力します。Avahiを導入している場合にはUser-PC.localとなります。
Country Name (2 letter code) [AU]:JP
State or Province Name (full name) [Some-State]:Tokyo
Locality Name (eg, city) []:Tokyo
Organization Name (eg, company) [Internet Widgits Pty Ltd]:FicusOnline
Organizational Unit Name (eg, section) []:Development
Common Name (e.g. server FQDN or YOUR name) []:User-PC.local
Email Address []:[email protected]
内容の確認は、
$ openssl x509 -text -fingerprint -noout -in mqtt_ca.crt
以下のように表示されます。
Certificate:
Data:
Version: 3 (0x2)
Serial Number: 14689342117405525537 (0xcbdb06d40c240621)
Signature Algorithm: sha256WithRSAEncryption
Issuer: C=JP, ST=tokyo, L=tokyo, O=FicusOnline, OU=dev, CN=User-PC.local/emailAddress=[email protected]
Validity
Not Before: Jan 22 04:55:18 2018 GMT
Not After : Jan 20 04:55:18 2028 GMT
Subject: C=JP, ST=tokyo, L=tokyo, O=FicusOnline, OU=dev, CN=User-PC.local/emailAddress=[email protected]
Subject Public Key Info:
Public Key Algorithm: rsaEncryption
Public-Key: (2048 bit)
Modulus:
00:c1:04:8f:39:c5:ed:0e:99:a5:d6:07:24:2b:d4:
96:81:e7:cf:e4:84:06:1b:d8:9e:c0:58:cc:95:9b:
c0:27:62:3a:c5:c2:30:af:08:e5:d4:f4:b1:52:a1:
b5:67:7e:e5:c3:2e:ce:56:f0:e8:06:88:27:ea:60:
cc:ce:53:12:54:3e:79:55:8b:ea:2f:40:61:b1:54:
05:b6:b9:7c:ce:21:28:17:0f:5e:da:24:f7:19:0b:
95:c3:d1:70:2f:b3:de:16:34:26:6a:04:bd:ce:37:
9a:43:57:96:90:d6:1a:46:57:c9:17:d4:b6:85:bb:
88:5c:2c:73:82:f1:8e:09:b2:20:92:8d:55:4e:ce:
3e:6b:21:aa:35:bd:57:e5:6d:95:f9:ae:db:b3:3d:
fa:56:78:c6:c9:c6:2a:13:55:41:17:3f:0e:87:72:
f3:cb:50:a2:1f:ca:77:32:e3:7f:3f:0b:02:e9:5d:
2c:ee:1d:e0:97:53:e2:44:3b:bc:89:4e:9e:c6:d8:
18:a5:44:18:fa:35:99:20:30:5c:f2:d2:bf:5c:3d:
7d:66:8b:9c:36:aa:98:1d:f9:14:92:41:1e:75:27:
32:f5:a6:36:45:21:e0:44:76:ac:14:cf:88:12:57:
63:f3:b0:ee:e5:3e:56:0d:b2:a3:71:98:5a:b8:40:
35:af
Exponent: 65537 (0x10001)
X509v3 extensions:
X509v3 Subject Key Identifier:
CC:E7:48:D4:E0:F2:57:14:A6:D3:43:59:6C:77:BB:98:7F:22:B0:59
X509v3 Authority Key Identifier:
keyid:CC:E7:48:D4:E0:F2:57:14:A6:D3:43:59:6C:77:BB:98:7F:22:B0:59
X509v3 Basic Constraints:
CA:TRUE
Signature Algorithm: sha256WithRSAEncryption
89:78:7c:63:9f:81:b5:3c:e0:d3:68:df:67:e3:96:a2:ff:be:
84:77:06:95:2c:8e:2e:ec:1c:2b:37:1a:23:10:55:63:e1:33:
94:6c:ad:b9:86:06:d2:f5:f4:50:58:53:d1:7e:15:a2:2d:7c:
f1:e7:72:1b:85:43:33:96:61:bb:9b:3d:ce:61:d0:03:95:d6:
9e:62:13:3a:76:61:d0:a3:a6:f9:64:dc:43:e5:8e:2e:d3:e1:
19:48:79:57:0d:4a:06:27:71:83:aa:e4:2e:79:74:e1:90:be:
fe:aa:ca:91:ab:f9:c7:17:80:38:3c:29:bc:f0:14:3e:79:d8:
e3:5c:9b:05:01:cb:9d:66:4d:0a:58:3c:de:86:cc:43:dd:cb:
64:3a:71:f1:4b:6b:f4:30:14:29:da:e7:e9:dd:22:46:26:4c:
21:8e:2c:09:36:13:97:82:8f:32:b8:52:83:83:28:40:4b:47:
e5:3e:60:83:7e:3a:44:bc:4e:41:d8:29:8c:d1:ce:92:f1:ea:
67:39:c6:94:1f:db:2a:39:2b:31:29:ed:5f:c6:63:57:c5:ba:
95:4d:f7:69:a7:76:25:06:94:ea:45:cc:8c:64:8c:67:2e:50:
e4:ba:79:eb:b7:9b:2f:ec:11:22:7e:0d:fc:a7:d7:40:94:00:
2d:46:82:8a
SHA1 Fingerprint=D2:E4:D2:08:62:BD:9D:88:72:97:F8:EA:47:B9:75:CC:9E:B8:BA:96
サーバキーファイルmqtt_srv.keyの作成
$ openssl genrsa -out mqtt_srv.key 2048
オプションはマニュアルページ参照 (https://wiki.openssl.org/index.php/Manual:Genrsa(1)):
- genrsa: Generate an RSA private key.
- -out: Specifies the output file name (.key).
- 2048: Number of bits for the private key.
ブローカー起動毎にパスワード入力が求められるため、ここでは-des3オプションは利用しません。内容の確認は、
$ openssl rsa -noout -text -in mqtt_srv.key
サーバキーファイルをCA認証してもらうためのリクエストファイルmqtt_srv.csrの作成
$ openssl req -new -out mqtt_srv.csr -key mqtt_srv.key
オプションはマニュアルページ参照 (https://wiki.openssl.org/index.php/Manual:Req(1)):
- req: Certificate request and certification utility.
- -new: Create new request file.
- -out: File name for the certificate signing request (.csr).
- -key: File name of the key to be certified.
以下のパラメータを入力する必要があります。
サーバはCAも兼ねるため、Common Nameにはサーバのドメインを入力します。Avahiを導入している場合にはUser-PC.localとなります。
Country Name (2 letter code) [AU]:JP
State or Province Name (full name) [Some-State]:Tokyo
Locality Name (eg, city) []:Tokyo
Organization Name (eg, company) [Internet Widgits Pty Ltd]:FicusOnline
Organizational Unit Name (eg, section) []:Development
Common Name (e.g. server FQDN or YOUR name) []:User-PC.local
Email Address []:[email protected]
Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []:
An optional company name []:
このリクエストファイルはTLS/SSL認証には必要ありません。
上記リクエストファイルによりサーバキーファイルがCA署名入り証明書で認証されたことを証明する証明書mqtt_srv.crtの作成
$ openssl x509 -req -in mqtt_srv.csr -CA mqtt_ca.crt -CAkey mqtt_ca.key -CAcreateserial -out mqtt_srv.crt -days 3650
オプションはマニュアルページ参照 (https://wiki.openssl.org/index.php/Manual:X509(1)):
- x509: Certificate display and signing utility.
- -req: A certificate request is expected as the input.
- -in: Input file for the certificate.
- -CA: Specifies the file to be signed.
- -CAkey: CA private key to sign the certificate with.
- -Cacreateserial: The serial number file gets created if it does not exist. このファイルは認証に必要ありません。
- -out: Output file name.
- -days: How long the certificate shall be valid.
CAの秘密キーのパスワードはここで必要です。
内容の確認は、
$ openssl x509 -text -fingerprint -noout -in mqtt_srv.crt
以下のように表示されます。
Certificate:
Data:
Version: 1 (0x0)
Serial Number: 18017377005282721129 (0xfa0a94ed182afd69)
Signature Algorithm: sha256WithRSAEncryption
Issuer: C=JP, ST=tokyo, L=tokyo, O=FicusOnline, OU=dev, CN=User-PC.local/emailAddress=[email protected]
Validity
Not Before: Jan 22 05:03:44 2018 GMT
Not After : Jan 20 05:03:44 2028 GMT
Subject: C=JP, ST=tokyo, L=tokyo, O=FicusOnline, OU=dev, CN=User-PC.local/emailAddress=[email protected]
Subject Public Key Info:
Public Key Algorithm: rsaEncryption
Public-Key: (2048 bit)
Modulus:
00:c6:25:6f:6c:19:9d:f2:f3:49:85:f4:01:5e:09:
69:12:06:81:47:01:99:de:68:d6:78:c9:d6:6f:ac:
5f:e7:39:32:d2:74:0d:5b:70:37:c1:3f:ca:47:8d:
76:90:e3:0f:54:ed:f1:b0:7e:24:b9:ef:e4:1f:43:
29:cf:a0:1c:41:ed:5b:41:63:44:d2:0f:0a:4a:44:
91:0e:3a:91:c8:29:c2:e6:fc:19:99:1e:e1:7d:7d:
6c:58:c0:57:e1:12:19:fa:07:9a:06:2e:1d:31:04:
e8:83:46:03:c1:2b:ef:6c:94:23:26:91:ab:75:55:
b3:81:ae:3d:36:cb:fd:ed:aa:3c:a8:a1:94:2b:01:
22:ac:5a:9f:39:0e:67:45:86:fa:bb:42:88:b0:12:
b3:4d:23:87:a1:9a:06:18:d1:48:3a:4c:8a:a6:00:
2e:ac:3b:af:58:83:14:7c:16:df:5c:83:19:94:db:
ea:a1:d6:a8:2e:9f:0f:cc:77:5a:fc:70:40:0f:24:
dc:cd:a1:83:dd:7f:5b:e5:c5:84:ec:2c:30:c7:7a:
a7:7e:aa:31:65:88:f2:6b:21:7d:a0:2b:31:f7:8e:
d1:6c:68:b4:0d:54:5c:b4:07:68:a7:26:5d:5c:38:
6b:dc:94:cf:3f:f9:72:60:c6:2c:7e:b1:d7:d7:ff:
5d:59
Exponent: 65537 (0x10001)
Signature Algorithm: sha256WithRSAEncryption
0e:55:27:be:b3:f5:f5:61:28:f5:4d:04:04:2c:c5:0b:3a:90:
2c:23:e4:07:50:fb:b4:41:b7:a3:56:79:ac:e4:a3:45:52:f3:
34:7f:8c:44:f1:7e:f3:bf:e9:1e:cb:eb:4e:d2:d1:02:9e:99:
07:7f:61:ed:5f:68:aa:53:39:0f:07:fa:2f:d2:3b:32:04:40:
88:29:94:96:ff:d3:fe:5c:e6:87:26:b2:e0:53:b7:48:d3:7b:
fc:2b:fb:f8:41:32:ce:d6:8a:c0:ce:ef:60:73:b9:1f:44:ed:
1d:5a:22:2f:b4:be:cc:c6:46:ad:b7:27:c1:d8:0f:07:f0:41:
e3:fc:0d:51:d7:fb:7c:5b:de:ac:a8:96:32:c0:1a:f6:36:3a:
96:15:ba:c6:23:4e:3f:9c:63:9c:54:d9:22:bc:f4:01:39:86:
16:70:fa:51:01:db:ad:a8:df:86:24:52:ba:1c:ca:26:0e:8c:
03:ec:19:c9:14:f6:ac:7c:85:71:d2:0f:d0:f9:af:88:6d:08:
c1:af:c0:6c:f5:0b:5b:89:6f:fd:d7:72:06:72:a3:02:44:ee:
59:4c:8e:f2:d0:e1:f3:d7:61:7f:ee:8f:77:4a:83:25:38:db:
5b:95:26:ce:4b:6e:c3:6a:21:a2:7b:4d:55:e7:6f:82:ae:b2:
98:9f:11:fc
SHA1 Fingerprint=8E:33:0F:C1:2A:A8:F7:DC:85:9B:FB:9C:83:65:ED:35:30:93:C1:BF
以上の作業で以下の6ファイルが作成されますが、TLS/SSL認証に必要なのは--->印の3ファイルです。
---> mqtt_ca.crt : CA Certificate
mqtt_ca.key : CA key pair (private, public)
mqtt_ca.srl : CA serial number file
---> mqtt_srv.crt : server certificate
mqtt_srv.csr : certificate sign request, not needed any more
---> mqtt_srv.key : server key pair
上記3ファイルをサーバの/etc/mosquitto/certsフォルダにコピーします。
Mosquitto設定ファイルの編集
TLS/SSL用ポートの設定をします。
# =================================================================
# 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 8883
CA証明書ファイルmqtt_ca.crtとCAによるサーバキー証明書ファイルmqtt_srv.crt、サーバキーファイルmqtt_srv.keyのパスとTLSバージョンを指定します。
# -----------------------------------------------------------------
# Certificate based SSL/TLS support
# -----------------------------------------------------------------
# The following options can be used to enable 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.
# At least one of cafile or capath must be defined. 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_cetificates/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
# This option defines the version of the TLS protocol to use for this listener.
# The default value allows v1.2, v1.1 and v1.0, if they are all supported by
# the version of openssl that the broker was compiled against. For openssl >=
# 1.0.1 the valid values are tlsv1.2 tlsv1.1 and tlsv1. For openssl < 1.0.1 the
# valid values are tlsv1.
tls_version tlsv1
Mosquittoの再起動で設定が有効になります。
クライアント側に必要なファイルはCA証明書ファイルmqtt_ca.crtのみです。
クライアント側から接続する際には、MQTTクライアントアプリでTLS/SSL接続、ポートの指定、mqtt_ca.crtのパス指定が必要になります。
内容の補足説明は同名タイトルのフォーラム記事を参照願います。