MySQLとの統合
EMQXはパスワード認証のためにMySQLとの統合をサポートしています。
TIP
基本的なEMQX認証の概念についての知識
データスキーマとクエリ文
MySQL認証機能はほぼすべてのMySQLストレージスキーマをサポートしています。ビジネスニーズに応じて、資格情報の保存方法やアクセス方法を決定できます。例えば、1つまたは複数のテーブルやビューを使用することが可能です。
ユーザーはクエリ文のテンプレートを提供し、以下のフィールドが含まれていることを確認する必要があります:
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、ソルトがsalt_foo123(サフィックス)、パスワードハッシュがsha256の場合、クエリ文は以下のようになります:
mysql> INSERT INTO mqtt_user(username, password_hash, salt, is_superuser) VALUES ('emqx_u', SHA2(concat('public', 'salt_foo123'), 256), 'salt_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のソルトラウンド数乗 として表され、「コストファクター」とも呼ばれます。デフォルトは
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やトランザクションモードの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
}