コーヒー飲みながら仕事したい

仕事で使う技術的なことの備忘録とか

mosquitto で CommonName が異なっていても無理やり TLS 接続できるようにする

追記(修正)

mosquitto Ver1.4.15 にて修正されているようです。
ですので、最新の mosquitto を使用すると、 CommonName が異なっていても、 --insecure オプションをつければ、無理やり TLS 接続できます。

mosquitto クライアントアプリの TLS 接続における CommonName に関する仕様

mosquitto のクライアントアプリである「mosquitto_sub」および「mosquitto_pub」の仕様で、TLS接続する際、サーバーの証明書1に含まれるコモンネーム(CommonName)とサーバー(ブローカー)の接続先名称が異なる場合は接続に失敗する。

例えば、サーバーの証明書に含まれる CommonName が i_love_coffee だった場合、クライアント側の接続は以下のようになる。

# 接続失敗
$ mosquitto_sub -t abc -h 192.168.0.1 -p 8883 -d  --cafile <CAの証明書> 
Error: A TLS error occurred.

# 接続成功
$ mosquitto_sub -t abc -h i_love_coffee -p 8883 -d  --cafile <CAの証明書> 
Client mosqsub/1900-i_love_coffee sending CONNECT
Client mosqsub/1900-i_love_coffee received CONNACK
Client mosqsub/1900-i_love_coffee sending SUBSCRIBE (Mid: 1, Topic: abc, QoS: 0)
Client mosqsub/1900-i_love_coffee received SUBACK
Subscribed (mid: 1): 0

接続しようとするサーバーと CommonName が異なれば TLS 接続失敗するというのは、セキュリティ上至極まっとうである。
しかし、オレオレ認証したりデバッグする環境では、 CommonName なんて気にしたくないし、実行環境がころころ変わる場合もあり、かなり不便。

--insecure オプション・・・

一応、 --insecure オプションをつけると、ホスト名等を気にせずサーバー認証できると、 マニュアルに書いてあるが、実際にそのオプション付けても、 CommonName が異なるとはじかれる。
(これバグなの?仕様?)

mosquitto の改造

ということで、今回、ソースコードを変更して無理やり CommonName が異なっていても TLS 接続できるようにしてみた。

変更仕様としては以下である。

  • --insecure オプションを付加した場合のみ、サーバーの証明書に含まれる CommonName と接続先サーバー(ブローカー)名が異なっていても、 TLS 接続可能とする
  • 対象は mosquitto.dll
    • mosquitto_sub と mosquitto_sub は mosquitto.dll をロードして動作するため、この DLL を変更してデプロイすれば、変更される

で、ソースの変更内容は以下である。

github.com

とりあえずこれで、目的を達成することができた。


  1. サーバーの証明書(*.crt)については、前回の記事を参照