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

トップ   編集 差分 バックアップ 添付 複製 名前変更 リロード   新規 一覧 単語検索 最終更新   ヘルプ   最終更新のRSS