1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Mosquittoでクライアント認証をやろうとして詰まったところ

Last updated at Posted at 2025-04-06

要約

  • Mosquittoライブラリを使ってローカルにあるMQTTブローカに接続したい
  • 以下の記事を参考にルートCA証明書とサーバ証明書・鍵を作った

  • また以下の記事を参考にクライアント認証をしようとしたが、うまくいかなかった

  • 最終的にuse_identity_as_username trueをmosquitto.confに追加する必要があることがわかった

証明書の作成

CA証明書

テスト目的なので自己署名
生成するときにいろいろ聞かれるが、CNはクライアント証明書と違う値にする必要がある

  • 今回は空白にした
$ openssl req -new -x509 -days 365 -extensions v3_ca -keyout ca.key -out ca.crt

サーバ証明書

$ openssl genrsa -out server.key 2048
$ openssl req -out server.csr -key server.key -new
$ openssl x509 -req -in server.csr -CA ca.crt -CAkey ca.key -CAcreateserial -out server.crt -days 365

クライアント証明書

前述のとおりCNはCA証明書と違う値にする必要がある

  • 今回はocalhostにした
$ openssl genrsa -out client.key 2048
$ openssl req -out client.csr -key client.key -new
$ openssl x509 -req -in client.csr -CA ca.crt -CAkey ca.key -CAcreateserial -out client.crt -days 365

証明書の配置

CA証明書を/etc/mosquitto/ca_certificatesにコピー

$ ls -l
total 12
-rw-r--r-- 1 root root 1245 Apr  6 08:41 ca.crt
-rw------- 1 root root 1854 Apr  6 08:41 ca.key
-rw-r--r-- 1 root root   73 Oct  1  2023 README

サーバ証明書と鍵を/etc/mosquitto/certsにコピー
その際オーナーをchownでmosquittoに変更

$ ls -l
total 12
-rw-r--r-- 1 root      root       130 Oct  1  2023 README
-rw-r--r-- 1 mosquitto mosquitto 1151 Apr  6 08:42 server.crt
-rw------- 1 mosquitto mosquitto 1704 Apr  6 08:42 server.key

クライアント証明書はクライアントアプリケーションと同じディレクトリに配置

mosquitto.confの設定

TLSを使う場合ポートは8883に設定
cafile, certfile, keyfileにそれぞれCA証明書、サーバ証明書、サーバ鍵のパスを設定
require_certificateをtrueにすることでクラインと認証を有効にする

listener 8883
cafile   /etc/mosquitto/ca_certificates/ca.crt
certfile /etc/mosquitto/certs/server.crt
keyfile  /etc/mosquitto/certs/server.key
require_certificate true

クライアントアプリケーションの実装

mosquitto_connect()の前にmosquitto_tls_set()を呼ぶ

  • CA証明書のパスを指定していればcapathはNULLでもいい
  • certfileとkeyfileにクライアント証明書を指定
  • 今回クライアント鍵にパスワードを設定していないのでpw_callbackはNULLにした

mosquitto_tls_insecure_setをtrueにするとサーバ証明書のホストを確認する

  • 自己署名CAなのでtrueにしておかないとcertificate verify failedになる
//省略しているが、各関数呼び出しのあとにエラーチェックしている
mosquitto_lib_init();
m_mosq = mosquitto_new("iot_device_hub", true, NULL);
mosquitto_tls_set(
    m_mosq, 
    "/etc/mosquitto/ca_certificates/ca.crt", 
    NULL, 
    "client.crt",  
    "client.key",
    NULL);

mosquitto_tls_insecure_set(m_mosq,true);
mosquitto_connect(m_mosq, "127.0.0.1", 8883, 60);
mosquitto_loop_start(m_mosq);
//この後にpublishなどを実行している

テスト結果

各関数を呼び出したときにエラーは返ってきていなかったが、すぐにDisconnectされてしまう
/var/log/mosquitto/mosquitto.logを見ると以下のような出力が出ていた

1743898855: New connection from 127.0.0.1:46826 on port 8883.
1743898855: Sending CONNACK to 127.0.0.1 (0, 5)
1743898855: Client <unknown> disconnected, not authorised.

ログを見るとunknownユーザが接続しようとして認証に失敗しているように見える

解決方法

mosquitto.confにuse_identity_as_usernameを設定したら接続後Publishまですることができた

1743900176: New connection from 127.0.0.1:55378 on port 8883.
1743900176: New client connected from 127.0.0.1:55378 as iot_device_hub (p2, c1, k60, u'localhost').
1743900176: No will message specified.
1743900176: Sending CONNACK to iot_device_hub (0, 0)
1743900177: Received PUBLISH from iot_device_hub (d0, q0, r0, m0, 'iot_device_hub/sensor_data/bed_room/temperature', ... (18 bytes))
  • copilotにこのログを見せたらuse_identity_as_usernameを設定するといいよと教えてくれて、確かにmanページにもそんなことが書いてあった

If require_certificate is true, the client must provide a valid certificate in order to connect successfully. In this case, the second and third options, use_identity_as_username and use_subject_as_username, become relevant. If set to true, use_identity_as_username causes the Common Name (CN) from the client certificate to be used instead of the MQTT username for access control purposes.

最終的なmosquitto.confの設定は以下の通り

listener 8883
allow_anonymous false
use_identity_as_username true
cafile   /etc/mosquitto/ca_certificates/ca.crt
certfile /etc/mosquitto/certs/server.crt
keyfile  /etc/mosquitto/certs/server.key
require_certificate true
1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?