「[[マイクロソフト系技術情報 Wiki>http://techinfoofmicrosofttech.osscons.jp/]]」は、「[[Open棟梁Project>https://github.com/OpenTouryoProject/]]」,「[[OSSコンソーシアム .NET開発基盤部会>https://www.osscons.jp/dotNetDevelopmentInfrastructure/]]」によって運営されています。 -[[戻る>IoT関連の通信プロトコル]] --Mosquitto --[[RabbitMQ]] * 目次 [#teddd724] #contents *概要 [#o54ba824] MQTTブローカーのOSS *詳細 [#y65792e6] **ブローカーモデル [#k458ca97] ***Producer [#i3c098c9] 送信する人 ***Consumer [#jd0a2113] 受信する人 ***Message [#i266318d] 送受信対象のメッセージ ***Queue [#h2c8afa3] キュー ***Topic [#c09052e5] -トピック --/ から始まる Unicode UTF-8 文字列 --全長 65535 バイト以下 --ヌル文字を含まない -ワイルドカード --#:マルチレベル・ワイルドカード(その階層以下の全トピック文字列と一致) --+:シングルレベル・ワイルドカード(当該階層以下の全トピック文字列と一致) **[[Windows]] [#s7585203] ***インストール [#o836ef9f] http://mosquitto.org/download/ ***ブローカー起動 [#z05d3807] >cd C:\Program Files\Mosquitto >mosquitto -v ***送受信 [#t7dc79c4] -受信~ 全トピックを受信 >cd C:\Program Files\Mosquitto >mosquitto_sub -h 127.0.0.1 -t "#" -v -送信~ testトピックに送信 >cd C:\Program Files\Mosquitto >mosquitto_pub -h 127.0.0.1 -t test -m "hoge" **その他の環境 [#s0a3ddd0] ***Linux [#j24edc22] -インストール --リポジトリを追加 $ sudo add-apt-repository ppa:mosquitto-dev/mosquitto-ppa --サーバー&クライアント $ sudo apt-get install mosquitto mosquitto-clients -ブローカー起動~ 不要 -送受信~ [[Windows>#t7dc79c4]]と同じ。 -参考 --Mosquitto(MQTT Broker)のインストール - Qiita~ https://qiita.com/n-yamanaka/items/73e4d3022186732b4e88 ***Raspberry Pi [#n19c21c7] -インストール --サーバー $ sudo apt-get install mosquitto --クライアント $ sudo apt-get install mosquitto-clients -ブローカー起動~ 不要 -送受信~ [[Windows>#t7dc79c4]]と同じ。 -参考 --Raspberry PiでIoT(MQTTで遠隔操作編 その1)MQTTでの通信 – 株式会社インデペンデンスシステムズ横浜~ http://independence-sys.net/main/?p=4054 ***Docker on Windows [#ee39ea11] ミドルウェアなので、[[コチラ>https://dotnetdevelopmentinfrastructure.osscons.jp/index.php?Docker#b8f4ba04]]の作法で動かせるっぽい。~ (ただし、コンフィグ・ファイルの準備は必要) >https://github.com/OpenTouryoProject/DxCommon/tree/develop/Edge/Mosquitto/IaC -参考 --MQTTを使ってみよう - Crieit~ https://crieit.net/posts/MQTT --DockerでMQTT通信|竹のしんのテック日記 | 竹のしんのテック日記~ https://take6shin-tech-diary.com/mqtt-docker/ --mosquitto(MQTT broker)の構築手順 | SINETStream~ https://www.sinetstream.net/server/brokers/mosquitto%E6%A7%8B%E7%AF%89%E6%89%8B%E9%A0%86.html --Qiita ---DockerでMosquittoを動かしてMQTTとWebSocket通信してみる~ https://qiita.com/danishi/items/bac267e85bc01523f385 ---mosquittoをdocker-composeで動かす~ https://qiita.com/github0013@github/items/7c410216b74f29919da8 ***Docker on Raspberry Pi [#f618948b] ... ***SaaS / PaaS [#f95e183c] -Azure:[[Azure IoT Hub]] -Azure:AWS IoT Core(ブリッジ機能) -GCP:Cloud Pub/Sub? **認証 [#y998af5a] ***パスワード [#ld4024b8] -Linux --Mosquitto で Username と Password を使う - Qiita~ https://qiita.com/ekzemplaro/items/77bfa6274cbddd4b5624 --Mosquitto(MQTT Broker)のインストール - Qiita > パスワード認証~ https://qiita.com/n-yamanaka/items/73e4d3022186732b4e88#%E3%83%91%E3%82%B9%E3%83%AF%E3%83%BC%E3%83%89%E8%AA%8D%E8%A8%BC -Windows --mosquitto でパスワード認証の設定をする | コーヒー飲みながら仕事したい~ https://coffee-nominagara.com/2018-09-25-141304 ***証明書 [#cf414c77] -サーバー認証とクライアント認証の両方が可能。 -Linux --Mosquitto(MQTT Broker)のインストール - Qiita > Mosquitto-TLS~ https://qiita.com/n-yamanaka/items/73e4d3022186732b4e88#mosquitto-tls -Windows --mosquitto で OpenSSL を 用いて TLS 接続する | コーヒー飲みながら仕事したい~ https://coffee-nominagara.com/2018-03-07-185728 **送受信(C#) [#mf0ea2bd] ***Paho M2Mqtt [#h3eed3dc] 最近、更新頻度が落ちてきている。 -認証フル実装は、[[チュートリアル>#td988178]]側を参照。 --受信 using System; using System.Text; using uPLibrary.Networking.M2Mqtt; using uPLibrary.Networking.M2Mqtt.Messages; namespace M2MqttSub { class Program { static void Main(string[] args) { var client = new MqttClient("127.0.0.1"); client.MqttMsgPublishReceived += (sender, eventArgs) => { var msg = Encoding.UTF8.GetString(eventArgs.Message); var topic = eventArgs.Topic; Console.WriteLine(topic + ", " + msg); }; var ret = client.Connect(Guid.NewGuid().ToString()); Console.WriteLine("Connected with result code {0}", ret); client.Subscribe(new[] { "test" }, new[] { MqttMsgBase.QOS_LEVEL_EXACTLY_ONCE }); while (client.IsConnected) { } } } } --送信 using System; using System.Text; using uPLibrary.Networking.M2Mqtt; namespace M2MqttPub { class Program { static void Main(string[] args) { var client = new MqttClient("127.0.0.1"); var ret = client.Connect(Guid.NewGuid().ToString()); Console.WriteLine("Connected with result code {0}", ret); while (client.IsConnected) { var msg = "Test message from Publisher " + DateTime.Now; client.Publish("test", Encoding.UTF8.GetBytes(msg), 0, true); Console.WriteLine("Message published."); System.Threading.Thread.Sleep(1500); } } } } -参考 --NuGet ---https://www.nuget.org/packages/M2Mqtt/ ---https://www.nuget.org/packages/M2MqttDotnetCore/ ***MQTTnet [#v3002e17] 更新が頻繁で、トータル・ダウンロードが[[Paho M2Mqtt>#h3eed3dc]]の4倍以上 -以下は認証フル実装だが、証明書検証を無効化している。~ CertificateValidationHandlerで原因を見ると、~ SslPolicyErrors.RemoteCertificateChainErrorsが出ている。 --受信 using System; using System.Text; using System.Collections.Generic; using System.Threading.Tasks; using MQTTnet; using MQTTnet.Client; using MQTTnet.Client.Options; using MQTTnet.Client.Connecting; using MQTTnet.Client.Receiving; using System.Security.Cryptography.X509Certificates; namespace msqt_sub { class Program { private static IMqttClient mqttClient = null; static async Task Main(string[] args) { X509Certificate2 ca = new X509Certificate2("ca.crt"); X509Certificate2 cli = new X509Certificate2("client.pfx", "xxxxx"); var factory = new MqttFactory(); Program.mqttClient = factory.CreateMqttClient(); var options = new MqttClientOptionsBuilder() .WithClientId("ef3614fca42b32d3") .WithTcpServer("localhost", 8883) .WithCredentials("guest", "guest") .WithTls(new MqttClientOptionsBuilderTlsParameters(){ UseTls = true, SslProtocol = System.Security.Authentication.SslProtocols.Tls12, AllowUntrustedCertificates = true, //CertificateValidationCallback = (a, b, c, d) => true, CertificateValidationHandler = (o) => { Console.WriteLine(o.ToString()); return true; }, Certificates = new List<X509Certificate>() { ca, cli } }) .Build(); // 接続後のイベントハンドラの設定 Program.mqttClient.ApplicationMessageReceivedHandler = new MqttApplicationMessageReceivedHandlerDelegate(OnAppMessage); Program.mqttClient.ConnectedHandler = new MqttClientConnectedHandlerDelegate(OnConnected); // 接続 await Program.mqttClient.ConnectAsync(options); // 待機 Console.ReadLine(); } static private async void OnConnected(MqttClientConnectedEventArgs e) { await Program.mqttClient.SubscribeAsync( new TopicFilterBuilder() .WithTopic("test").Build()); } static private void OnAppMessage(MqttApplicationMessageReceivedEventArgs e) { string payload = Encoding.UTF8.GetString(e.ApplicationMessage.Payload); Console.WriteLine(payload); } } } --送信 using System; using System.Text; using System.Collections.Generic; using System.Threading.Tasks; using MQTTnet; using MQTTnet.Client; using MQTTnet.Client.Options; using System.Security.Cryptography.X509Certificates; namespace msqt_pub { class Program { private static IMqttClient mqttClient = null; static async Task Main(string[] args) { X509Certificate2 ca = new X509Certificate2("ca.crt"); X509Certificate2 cli = new X509Certificate2("client.pfx", "xxxxx"); var factory = new MqttFactory(); Program.mqttClient = factory.CreateMqttClient(); var options = new MqttClientOptionsBuilder() .WithClientId("ef3614fca42b32d3") .WithTcpServer("localhost", 8883) .WithCredentials("guest", "guest") .WithTls(new MqttClientOptionsBuilderTlsParameters(){ UseTls = true, SslProtocol = System.Security.Authentication.SslProtocols.Tls12, AllowUntrustedCertificates = true, //CertificateValidationCallback = (a, b, c, d) => true, CertificateValidationHandler = (o) => { Console.WriteLine(o.ToString()); return true; }, Certificates = new List<X509Certificate>() { ca, cli } }) .Build(); // 接続 await Program.mqttClient.ConnectAsync(options); // メッセージの送信するための設定 var message = new MqttApplicationMessageBuilder() .WithTopic("test") .WithPayload("hoge") .WithExactlyOnceQoS() .Build(); // メッセージの送信 publish await Program.mqttClient.PublishAsync(message); } } } -参考 --NuGet~ https://www.nuget.org/packages/MQTTnet/ --より洗練された実装~ https://github.com/OpenTouryoProject/DxCommon/tree/develop/Edge/Mosquitto/Client/CS *チュートリアル [#td988178] [[証明書認証>#cf414c77]](サーバー認証とクライアント認証)+[[パスワード認証>#ld4024b8]]を構成し、[[Paho M2Mqtt>#h3eed3dc]]、[[MQTTnet>#v3002e17]]からアクセスする。 **[[Windows>#s7585203]] [#p4f5a191] ***サーバー認証 [#r2882624] [[コチラ>#cf414c77]]と[[コチラ>OpenSSL#q1310f25]]が参考になる。 -認証局の証明書を作成する。 >openssl req -new -x509 -days 365 -extensions v3_ca -keyout ca.key -out ca.crt Generating a RSA private key ................................................+++++ ............+++++ writing new private key to 'ca.key' Enter PEM pass phrase: Verifying - Enter PEM pass phrase: ----- 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) [AU]:JP State or Province Name (full name) [Some-State]: Locality Name (eg, city) []: Organization Name (eg, company) [Internet Widgits Pty Ltd]: Organizational Unit Name (eg, section) []: Common Name (e.g. server FQDN or YOUR name) []:hogeca Email Address []: -サーバー証明書 --RSA鍵の作成 >openssl genrsa -out server.key 2048 Generating RSA private key, 2048 bit long modulus (2 primes) ..............+++++ e is 65537 (0x010001) --証明書要求の作成 >openssl req -out server.csr -key server.key -new 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) [AU]:JP State or Province Name (full name) [Some-State]: Locality Name (eg, city) []: Organization Name (eg, company) [Internet Widgits Pty Ltd]: Organizational Unit Name (eg, section) []: Common Name (e.g. server FQDN or YOUR name) []:localhost Email Address []: Please enter the following 'extra' attributes to be sent with your certificate request A challenge password []: An optional company name []: --サーバー証明書の発行 >openssl x509 -req -in server.csr -CA ca.crt -CAkey ca.key -CAcreateserial -out server.crt -days 365 Signature ok subject=C = JP, ST = Some-State, O = Internet Widgits Pty Ltd, CN = localhost Getting CA Private Key Enter pass phrase for ca.key: --証明書ファイルの配置~ 証明書ファイルをインストール・ディレクトリ直下のcertsディレクトリに配置 --サーバー証明書の設定~ mosquitto.confの先頭に以下を追加 listener 8883 cafile ./certs/ca.crt certfile ./certs/server.crt keyfile ./certs/server.key allow_anonymous true -動作確認を行う。 --confを指定してブローカー起動 >cd C:\Program Files\Mosquitto >mosquitto -v -c mosquitto.conf --送受信 ---受信 >cd C:\Program Files\Mosquitto >mosquitto_sub -h localhost -t "#" -v -d -p 8883 --cafile <ca.crtのパス> ---送信 >cd C:\Program Files\Mosquitto >mosquitto_pub -h localhost -t test -m "hoge" -d -p 8883 --cafile <ca.crtのパス> -ハマりどころ --認証局のCNとサーバーのCNが同じ場合、以下のエラーが表示される。 ---SSL routines:tls_process_server_certificate:certificate verify failed~ ---SSL routines:ssl3_read_bytes:tlsv1 alert unknown ca --Connection error: Connection Refused: not authorised.が出る。~ 「allow_anonymous true」を設定ファイルに追加する。 ***クライアント認証 [#k649a644] [[コチラ>#cf414c77]]と[[コチラ>OpenSSL#q1310f25]]が参考になる。 -クライアント認証 --RSA鍵の作成 >openssl genrsa -out client.key 2048 Generating RSA private key, 2048 bit long modulus (2 primes) ......+++++ e is 65537 (0x010001) --証明書要求の作成 >openssl req -out client.csr -key client.key -new 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) [AU]: State or Province Name (full name) [Some-State]: Locality Name (eg, city) []: Organization Name (eg, company) [Internet Widgits Pty Ltd]: Organizational Unit Name (eg, section) []: Common Name (e.g. server FQDN or YOUR name) []:hogecli Email Address []: Please enter the following 'extra' attributes to be sent with your certificate request A challenge password []: An optional company name []: --クライアント認証の発行 >openssl x509 -req -in client.csr -CA ca.crt -CAkey ca.key -CAcreateserial -out client.crt -days 365 Signature ok subject=C = AU, ST = Some-State, O = Internet Widgits Pty Ltd, CN = hogecli Getting CA Private Key Enter pass phrase for ca.key: --証明書ファイルの配置~ 証明書ファイルをインストール・ディレクトリ直下のcertsディレクトリに配置 --クライアント証明書の設定~ mosquitto.confに以下を追加 require_certificate true -動作確認を行う。 --confを指定してブローカー起動 >cd C:\Program Files\Mosquitto >mosquitto -v -c mosquitto.conf --送受信~ 前述の送受信コマンドに以下を追加して実行する。 [[前述の送受信コマンド>#r2882624]]に以下を追加して実行する。 --cert <client.crtのパス> --key <client.keyのパス> -ハマりどころ~ ... ***パスワード認証 [#k61808fb] -パスワードファイルを生成 >cd C:\Program Files\Mosquitto >mosquitto_passwd -c pwfile guest Password: Reenter password: -パスワード認証の有効化~ mosquitto.confのallow_anonymous周辺に修正・追記 allow_anonymous false password_file /etc/mosquitto/pwfile -動作確認を行う。 --confを指定してブローカー起動 >cd C:\Program Files\Mosquitto >mosquitto -v -c mosquitto.conf --送受信~ 前述の送受信コマンドに以下を追加して実行する。 [[前述の送受信コマンド>#k649a644]]に以下を追加して実行する。 -u guest -P guest -ハマりどころ~ パスワードは「-p」ではなく「-P」で指定する。 ***Paho M2Mqtt からアクセス [#ef375921] -クライアント証明書を、[[*.pfxに変換する>OpenSSL#wd296f49]]必要がありそう。 -pkcs12 クライアント証明書(*.pfx)を合成 >openssl pkcs12 -export -out client.pfx -inkey client.key -in client.crt Enter Export Password: Verifying - Enter Export Password: -認証局の証明書(ca.crt)は、[[証明書ストア>証明書#dccdb7e5]]の~ 信頼されたルート証明機関に入れておく必要がある。 -証明書やパスワードの追加実装を行う。 X509Certificate2 ca = new X509Certificate2("ca.crt"); X509Certificate2 cli = new X509Certificate2("client.pfx", "xxxxx"); var client = new MqttClient("localhost", 8883, true, ca, cli, MqttSslProtocols.TLSv1_2); client.ProtocolVersion = MqttProtocolVersion.Version_3_1_1; var ret = client.Connect(Guid.NewGuid().ToString(), "guest", "guest"); -デバッグ実行で動作確認~ WindowsはPublisherだけ動作確認済み。 -参考 --Stack Overflow ---A call to SSPI failed, see inner exception paho m2mqtt Dot.Net(c#) client SSL/TLS connection~ https://stackoverflow.com/questions/43993106/a-call-to-sspi-failed-see-inner-exception-paho-m2mqtt-dot-netc-client-ssl-tl ---self signed x509 certificate issue in MQTT mosquitto using c#~ https://stackoverflow.com/questions/31653754/self-signed-x509-certificate-issue-in-mqtt-mosquitto-using-c-sharp ***MQTTnetからアクセス [#g6b4e364] [[コチラ>#v3002e17]]の実装で動作すると思う。 -[[Linuxで動作確認済み>#sf45c565]]。 -WindowsはPublisherだけ動作確認済み。 **[[Linux>#j24edc22]] [#o4c0072a] ***サーバー認証 [#h791597d] -基本的に、[[Windows>#r2882624]]と同じ。 -以下のように表示される場合、sudoを付ける。 req: Can't open "ファイル名" for writing, Permission denied -keyファイルに権限付与~ mosquittoに読み取り権限が無いらしい。 sudo chmod 644 server.key -ファイル設定~ パスの指定方法が異なる。 listener 8883 cafile /etc/mosquitto/certs/ca.crt certfile /etc/mosquitto/certs/server.crt keyfile /etc/mosquitto/certs/server.key allow_anonymous true -後は、以下で再起動。 $ sudo systemctl restart mosquitto -テストを行う。 ※ ca_certificatesフォルダがあったので、~ CAのファイルはそちらに配置した方が良いカモ。 --ca.key --ca.crt ***クライアント認証 [#bbb909e3] -基本的に、[[Windows>#k649a644]]と同じ。 -以下のように表示される場合、sudoを付ける。 req: Can't open "ファイル名" for writing, Permission denied -keyファイルに権限付与~ mosquittoに読み取り権限が無いらしい。 sudo chmod 644 client.key -ファイル設定~ 以下を追記 require_certificate true -後は、以下で再起動。 $ sudo systemctl restart mosquitto -テストを行う。 ***パスワード認証 [#c5200539] -基本的に、[[Windows>#k61808fb]]と同じ。 -以下のように表示される場合、sudoを付ける。 Error: Unable to open file pwfile for writing. Permission denied. -ファイル設定~ mosquitto.confのallow_anonymous周辺に修正・追記 allow_anonymous false password_file ./pwfile -後は、以下で再起動。 $ sudo systemctl restart mosquitto -テストを行う。 ***Paho M2Mqtt からアクセス [#yac8b1d5] -基本的に、[[Windows>#ef375921]]と同じ。 -以下のように表示される場合、sudoを付ける。 Error: Unable to open file pwfile for writing. Permission denied. -/dev/msqt_pubとか言うフォルダを作成 -プロジェクトを作成し $ dotnet new console -VS Codeでmsqt_pubフォルダを開く~ -必要に応じてエクステンションをインストール --[[CSharp for Visual Studio Code]]をインストール --NuGet Package Managerをインストール --NuGetでM2MqttDotnetCoreをインストール -Program.csに[[コチラの送信処理>#h3eed3dc]]を実装 -認証局の証明書(ca.crt)は、[[証明書ストア>証明書#dccdb7e5]]の~ 信頼されたルート証明機関に入れておく必要がある。 -証明書やパスワードの追加実装を行う。 -デバッグ実行で動作確認~ --[[Windows>#ef375921]]と同じで動作するハズ --[[証明書ストアの位置>証明書#xf1c5354]]に注意が必要かと思う。 ***MQTTnetからアクセス [#sf45c565] [[コチラ>#v3002e17]]の実装で動作した。 **正規の証明書 [#s1e985c5] 正規のCN、場合によっては、~ [[証明書ストアへの登録>証明書#xf1c5354]]が必要なのかもしれない。 *参考 [#y75f60b4] -eclipse/mosquitto: Eclipse Mosquitto - An open source MQTT broker~ https://github.com/eclipse/mosquitto -MQTTで始めるIoTデバイスの作り方~ 第1回:「MQTT」を知り「Mosquitto」を導入する:~ MQTTで始めるIoTデバイスづくり(1/3 ページ) - MONOist~ https://monoist.atmarkit.co.jp/mn/articles/1605/23/news017.html **Qiita [#g2b54cac] -Raspberry Pi で mosquitto を使う~ https://qiita.com/ekzemplaro/items/ab90dd630c3ad8e819ab -RaspberryPiにDockerでMosquittoを立てて、MQTTとWebsockets~ https://qiita.com/hilucky/items/42492e7ef5706b718bbb **.NETライブラリ [#yd956d63] -M2Mqttを使用したMQTTのクライアントサンプル | OPC Diary~ https://opcdiary.net/?p=28785 -C# (.net) で使える MQTT クライアント (Paho M2Mqtt)-スケ郎のお話~ https://www.sukerou.com/2018/08/c-net-mqtt-paho-m2mqtt.html -【MQTTnet】C#でMQTTを扱う - 地底人newbieの気まぐれ~ https://www.rect29.com/entry/2021/01/17/234306 ---- Tags: [[:通信技術]], [[:.NET開発]], [[:IoT]]