「[[マイクロソフト系技術情報 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]]