ファイナンス、情報通信技術のスキル・アグリゲーション・サイト
PHP で MQTT クライアントを作成します。ブローカーには、Mosquitto を使用していますので、Mosquitto-PHP ライブラリを利用しました。
Mosquitto については、Mosquitto(MQTT Broker)を Windows と Ubuntu にインストール も参照してください。
GitHub - mgdm/Mosquitto-PHP: A wrapper for the Eclipse Mosquitto™ MQTT client library for PHP. のドキュメントを参照して、インストールと SSL/TLS の対応などを進めていきます。
MQTT クライアントについては、これまで Paho(MQTT Client Library)サンプルプログラム(Python、JavaScript) 、Node.js で MQTT クライアント(MQTT.js) で取り扱っています。今回は PHP で、ということになります。なお、OS は Ubuntu 18.04 LTS 、そして、PHP バージョン 7.3 を使用しました。
Mosquitto-PHP ライブラリをインストールするには、libmosquitto が必要です。Ubuntu にインストールする場合です。
$ sudo apt install libmosquitto-dev
次は、PHP 拡張のコンパイルに必要です。Ubuntu で、PHP 7.3 の場合です。
$ sudo apt install php7.3-dev
Mosquitto-PHP ライブラリをインストールします。
$ sudo pecl install Mosquitto-alpha
『WARNING: channel "pecl.php.net" has updated its protocols, use "pecl channel-update pecl.php.net" to update』のような場合は、メッセージにあるコマンドを実行します。
$ sudo pecl install channel-update pecl.php.net
インストールが成功したら、php.ini に extension=mosquitto.so を追記します。PHP 7.3 の場合です。
$ sudo vim /etc/php/7.3/cli/php.ini
続いて、mosquitto.conf の設定例です。
# Default listener
listener 1883
# Certificate based SSL/TLS support
listener 8883
cafile /etc/mosquitto/ca_certificates/ca.crt
certfile /etc/mosquitto/certs/server.crt
keyfile /etc/mosquitto/certs/server.key
tls_version tlsv1.2
require_certificate true
password_file /etc/mosquitto/passwd
上記の SSL/TLS 証明書の設定では、サーバ証明書を記載しています。今回作成する MQTT クライアントは、クライアント証明書も使用することとしました。 tls_version tlsv1.2 は、TLS バージョンを明示して設定しています。 require_certificate true は、接続するすべてのクライアントがクライアント証明書を必要とします。なお、クライアント証明書のないクライアントも接続する場合、false に設定します。
さらに、パスワードファイルも使用します。バスワードファイルは、 mosquitto_passwd の手順で管理します。作成コマンド例です。
$ mosquitto_passwd -c /etc/mosquitto/passwd ral
さて、今回使用したサーバ証明書やクライアント証明書は、プライベート認証局(CA)を作成して、プライベート SSL/TLS 証明書を発行したものです。この手順については、プライベート認証局でプライベート SSL/TLS 証明書を発行する も参考にしてください。
今回作成した MQTT クライアントのコード例です。クライアント証明書を使用する例です。
<?php
$c = new Mosquitto\Client;
$topic = "/test/php";
$qos = 0;
$host = "host.jp";
$port = 8883;
$c->onConnect(function($code, $message) use ($c) {
echo $code ." - ".$message . "\n";
global $topic, $qos;
$arr = array();
$c->subscribe($topic, $qos);
$arr = array("msg" => "Hello", "name" =>"Joe");
$msg = json_encode($arr);
$c->publish($topic, $msg, $qos);
});
$c->onMessage(function($message) {
$decarr = json_decode($message->payload, true);
echo $message->topic . "\n" . $decarr["msg"] . "\n";
});
// setCredentials($username, $password)
$c->setCredentials("ral", "ralpasswd");
$ca_path = "/etc/mosquitto/ca_certificates/";
//$ca_certs = "/etc/mosquitto/ca_certificates/ca.crt";
$certfile = "/etc/mosquitto/certs/client.crt";
$keyfile = "/etc/mosquitto/certs/client.key";
// setTlsCertificates($caPath[, $certFile, $keyFile, $password])
$c->setTlsCertificates($ca_path, $certfile, $keyfile, null);
// setTlsOptions($certReqs, $tlsVersion, $ciphers)
$c->setTlsOptions(Mosquitto\Client::SSL_VERIFY_NONE, "tlsv1.2", null);
// setTlsInsecure($value)
//$c->setTlsInsecure(true);
// connect($host[, $port = 1883, $keepalive = 60, $interface = null])
$c->connect($host, $port, 60, null);
$c->loopForever();
?>
setTlsOptions() の SSL_VERIFY_NONE は、プライベート認証局の CA 証明書を使用していることによります。'tlsv1.2' は、ブローカーの TLS バージョンの設定にあわせたものです。
setTlsInsecure(true) は、証明書のホスト名の照合を行わないという設定です。今回は、サーバ証明書による接続てはありませんので影響はありません。
テストに使用した Mosuitto クライアントコマンドの Subscribe コマンド例です。
mosquitto_sub --cafile /etc/mosquitto/ca_certificates/ca.crt --cert /etc/mosquitto/certs/client.crt --key /etc/mosquitto/certs/client.key -t /test/php -p 8883 -h host.jp -u ral -P ralpasswd --tls-version tlsv1.2 --insecure
テストに使用した Mosuitto クライアントコマンドの Publish コマンド例です。
mosquitto_pub --cafile /etc/mosquitto/ca_certificates/ca.crt --cert /etc/mosquitto/certs/client.crt --key /etc/mosquitto/certs/client.key -t test -p 8883 -m Message -h host.jp -u ral -P ralpasswd --tls-version tlsv1.2 --insecure