MySQLとの統合
EMQXはパスワード認証のためにMySQLとの統合をサポートしています。
TIP
EMQX認証の基本概念についての知識
データスキーマとクエリ文
MySQL認証機能はほぼすべてのMySQLストレージスキーマをサポートしています。認証情報の保存方法やアクセス方法は、ビジネスのニーズに応じて、単一または複数のテーブルやビューなどを使用して自由に決定できます。
ユーザーはクエリ文のテンプレートを提供し、以下のフィールドが含まれていることを確認する必要があります。
password_hash:必須。データベースに保存されているパスワード(プレーンテキストまたはハッシュ化済み)。salt:任意。salt = ""またはこのフィールドを削除すると、ソルト値が追加されないことを示します。is_superuser:任意。現在のクライアントがスーパーユーザーかどうかを示すフラグ。デフォルトはfalse。
認証情報を保存するためのテーブル構造の例:
CREATE TABLE `mqtt_user` (
`id` int(11) unsigned NOT NULL AUTO_INCREMENT,
`username` varchar(100) DEFAULT NULL,
`password_hash` varchar(100) DEFAULT NULL,
`salt` varchar(35) DEFAULT NULL,
`is_superuser` tinyint(1) DEFAULT 0,
`created` datetime DEFAULT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `mqtt_username` (`username`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;TIP
上記の例では、クエリに役立つ暗黙の UNIQUE インデックスフィールド(username)が作成されています。 システム内のユーザー数が多い場合は、クエリの応答時間を短縮し、EMQXの負荷を軽減するために、事前にテーブルの最適化とインデックス付けを行ってください。
このテーブルでは、MQTTユーザーは username で識別されます。
例えば、スーパーユーザー(is_superuser: true)として、ユーザー名 emqx_u、パスワード public、サフィックスのソルト slat_foo123、パスワードハッシュは sha256 で追加したい場合、クエリ文は以下のようになります。
mysql> INSERT INTO mqtt_user(username, password_hash, salt, is_superuser) VALUES ('emqx_u', SHA2(concat('public', 'slat_foo123'), 256), 'slat_foo123', 1);
Query OK, 1 row affected (0,01 sec)対応する設定パラメータは以下の通りです。
password_hash_algorithm {
name = sha256
salt_position = suffix
}
query = "SELECT password_hash, salt, is_superuser FROM mqtt_user WHERE username = ${username} LIMIT 1"ダッシュボードでの設定
EMQXダッシュボードを使って、MySQLをパスワード認証に利用する設定が可能です。
- EMQXダッシュボードの左側ナビゲーションメニューから アクセス制御 -> 認証 をクリックします。
- 認証 ページの右上にある 作成 をクリックします。
- メカニズム に パスワードベース を、バックエンド に MySQL を選択して、以下の 設定 タブに進みます。

以下の指示に従って認証バックエンドを設定してください。
接続:MySQL接続情報を入力します。
サーバー:EMQXが接続するサーバーアドレス(
host:port)を指定します。データベース:MySQLのデータベース名。
ユーザー名:ユーザー名を指定します。
パスワード:ユーザーパスワードを指定します。
認証設定:認証に関連する設定を行います。
- パスワードハッシュ:プレーンテキストのパスワードに適用され、データベースに保存される前のハッシュアルゴリズムを選択します。利用可能なオプションは
plain、md5、sha、sha256、sha512、bcrypt、pbkdf2です。選択したアルゴリズムに応じて追加設定があります。md5、sha、sha256、sha512の場合:- ソルトの位置:ソルト(ランダムデータ)をパスワードにどのように混ぜるかを指定します。
suffix、prefix、disableのいずれかを選択します。外部ストレージからEMQX組み込みデータベースにユーザー認証情報を移行する場合を除き、デフォルト値のままで問題ありません。 - ハッシュ結果は16進数文字列として表現され、大文字小文字を区別せずに保存された認証情報と比較されます。
- ソルトの位置:ソルト(ランダムデータ)をパスワードにどのように混ぜるかを指定します。
plainの場合:- ソルトの位置 は
disableにしてください。
- ソルトの位置 は
bcryptの場合:- ソルトラウンド数:ハッシュ関数が適用される回数を定義します。これは 2ソルトラウンド数 として表され、「コストファクター」とも呼ばれます。デフォルトは
10で、許容範囲は5から10です。セキュリティ強化のために値を大きくすることが推奨されます。注意:コストファクターを1増やすと認証にかかる時間が2倍になります。
- ソルトラウンド数:ハッシュ関数が適用される回数を定義します。これは 2ソルトラウンド数 として表され、「コストファクター」とも呼ばれます。デフォルトは
pbkdf2の場合:- 疑似乱数関数:キーを生成するためのハッシュ関数を選択します(例:
sha256)。 - 反復回数:ハッシュ関数が実行される回数を設定します。デフォルトは
4096です。 - 生成キー長(任意):生成されるキーのバイト長を指定します。空欄の場合は選択した疑似乱数関数のデフォルト長になります。
- ハッシュ結果は16進数文字列として表現され、大文字小文字を区別せずに保存された認証情報と比較されます。
- 疑似乱数関数:キーを生成するためのハッシュ関数を選択します(例:
- パスワードハッシュ:プレーンテキストのパスワードに適用され、データベースに保存される前のハッシュアルゴリズムを選択します。利用可能なオプションは
前提条件:Variform式で記述し、このMySQL認証機能をクライアント接続に適用するか制御します。式はクライアントの属性(
username、clientid、listenerなど)に対して評価され、結果が文字列"true"の場合のみ認証機能が呼び出されます。そうでなければスキップされます。詳細は認証機能の前提条件をご覧ください。TLSを有効化:TLSを有効にする場合はトグルスイッチをオンにします。TLS有効化の詳細はネットワークとTLSをご参照ください。
SQL:データスキーマに従ってクエリ文を入力します。詳細はSQLデータスキーマとクエリ文をご覧ください。
詳細設定:接続プール、タイムアウト、プリペアドステートメントの動作を設定します。
- 接続プールサイズ(任意):EMQXノードからMySQLへの同時接続数を整数で指定します。デフォルトは
8。 - クエリタイムアウト(任意):EMQXがクエリのタイムアウトと判断するまでの待機時間を指定します。単位はミリ秒、秒、分、時間が利用可能です。デフォルトは
5秒。 - 接続タイムアウト(任意):EMQXが接続試行のタイムアウトと判断するまでの待機時間を指定します。単位はミリ秒、秒、分、時間が利用可能です。デフォルトは
15秒。 - プリペアドステートメントを無効化(任意):データベースクエリでプリペアドステートメントの使用を無効にします。MySQLプロキシやミドルウェア(例:PGBouncerやTransactionモードのSupabase)がセッションレベルの機能(プリペアドステートメントなど)をサポートしていない場合に有効にしてください。デフォルトは無効です。
- 接続プールサイズ(任意):EMQXノードからMySQLへの同時接続数を整数で指定します。デフォルトは
設定が完了したら、作成 をクリックします。
設定項目による設定
EMQXの設定項目を使ってMySQL認証機能を設定することも可能です。設定パラメータの完全な一覧はEMQX Enterprise設定マニュアルをご参照ください。
MySQL認証は mechanism = password_based と backend = mysql で識別されます。
設定例:
{
backend = "mysql"
mechanism = "password_based"
server = "127.0.0.1:3306"
username = "root"
database = "mqtt_user"
password = ""
pool_size = 8
password_hash_algorithm {name = "sha256", salt_position = "suffix"}
query = "SELECT password_hash, salt FROM mqtt_user where username = ${username} LIMIT 1"
query_timeout = "5s"
connect_timeout = "15s"
disable_prepared_statements = false
}