LDAPとの統合
Lightweight Directory Access Protocol (LDAP) は、ディレクトリ情報にアクセスおよび管理するためのプロトコルです。EMQXはパスワード認証のためにLDAPサーバーとの統合をサポートしています。この統合により、ユーザーはEMQXの認証にLDAPの資格情報を使用できます。
前提条件
EMQXの基本的な認証概念の知識が必要です。
パスワード認証方式
EMQXのLDAP統合には、以下の2つの異なる認証方式があります。
LDAPバインド認証
EMQXはLDAPバインドを直接使用してユーザー名とパスワードを認証します。クライアントが接続すると、EMQXは提供されたユーザー名とパスワードを受け取り、設定された
base_dnとfilterを使って識別名(DN)を構築します。その後、これらの資格情報を用いてクライアントとしてLDAPサーバーにバインド(ログイン)を試みます。バインド操作が成功すれば認証が承認され、失敗すれば接続は拒否されます。この方式は既存のLDAPユーザーエントリのみに依存し、EMQXがパスワードハッシュなどの機密データを取得・処理する必要がありません。設定が簡単でLDAPスキーマの変更も不要です。
この方式は以下のような場合に適しています。
- ユーザーアカウントが既にLDAPサーバーに存在している。
- LDAPスキーマを変更・拡張できない。
- 最小限の設定でLDAPサーバーが直接認証を処理することを望む。
ローカルパスワード比較
EMQXは
usernameおよびpassword設定オプションで指定されたバインドアカウント(バインドDN)を使ってLDAPサーバーに接続します。次にクライアントのLDAPエントリを検索し、特定の属性から保存されているパスワード(通常はハッシュ形式)を取得します。クライアントが提供したパスワードはEMQX内で取得したハッシュとローカルに比較されます。この方式は認証プロセスに対してより柔軟かつ詳細な制御を提供します。より複雑な検証ロジックやセキュリティ戦略をサポートし、追加のユーザー属性も扱えます。例えば、EMQXはユーザーの
isSuperUserフラグをパスワード照会時に取得できるため、認証時にユーザーがスーパーユーザーかどうかを判別し、権限レベルに応じて異なるアクセスや操作を提供できます。この方式は以下のような場合に適しています。
- カスタム認証属性(例:
isSuperuser、ACLルール)を保存または処理する必要がある。 - LDAPサーバーのスキーマやデータを設定する権限がある。
- 単純なLDAPバインドを超えた高度なセキュリティや検証ロジックが必要。
- カスタム認証属性(例:
LDAPデータスキーマとクエリ
TIP
このセクションは「ローカルパスワード比較」認証方式に適用されます。「LDAPバインド認証」方式を使用している場合はこのセクションをスキップできます。
このセクションでは、LDAPスキーマの設定、LDAP資格情報の作成、およびパスワード認証用の資格情報の保存方法について説明します。
LDAPスキーマは、LDAPディレクトリ内で認証データを整理・保存するための構造とルールを定義します。LDAP認証機能はほぼすべてのLDAPスキーマをサポートしています。以下はOpenLDAPのスキーマ例です。
attributetype ( 1.3.6.1.4.1.11.2.53.2.2.3.1.2.3.1.4 NAME 'isSuperuser'
EQUALITY booleanMatch
SYNTAX 1.3.6.1.4.1.1466.115.121.1.7
SINGLE-VALUE
USAGE userApplications )
objectclass ( 1.3.6.1.4.1.11.2.53.2.2.3.1.2.3.4 NAME 'mqttUser'
SUP top
STRUCTURAL
MAY ( isSuperuser )
MUST ( uid $ userPassword ) )このスキーマ例では、ユーザーがスーパーユーザーかどうかを示すisSuperuser属性を定義しています。また、ユーザーを表すmqttUserオブジェクトクラスが定義されており、このオブジェクトクラスはuserPassword属性を必須としています。
LDAP資格情報を作成するには、必要な属性名、ベースオブジェクトの識別名(dn)、およびLDAPクエリのフィルターを定義する必要があります。
以下は、OpenLDAP用のスキーマに基づくLDAPデータ交換フォーマット(LDIF)で指定されたLDAP資格情報の例です。
## create organization: emqx.io
dn:dc=emqx,dc=io
objectclass: top
objectclass: dcobject
objectclass: organization
dc:emqx
o:emqx,Inc.
## create organization unit: testdevice.emqx.io
dn:ou=testdevice,dc=emqx,dc=io
objectClass: top
objectclass:organizationalUnit
ou:testdevice
## create user=mqttuser0001,
# password=mqttuser0001,
# passhash={SHA}mlb3fat40MKBTXUVZwCKmL73R/0=
# base64passhash=e1NIQX1tbGIzZmF0NDBNS0JUWFVWWndDS21MNzNSLzA9
dn:uid=mqttuser0001,ou=testdevice,dc=emqx,dc=io
objectClass: top
objectClass: mqttUser
uid: mqttuser0001
userPassword:: e1NIQX1tbGIzZmF0NDBNS0JUWFVWWndDS21MNzNSLzA9
## create user=mqttuser0002
# password=mqttuser0002,
# passhash={SSHA}n9XdtoG4Q/TQ3TQF4Y+khJbMBH4qXj4M
# base64passhash=e1NTSEF9bjlYZHRvRzRRL1RRM1RRRjRZK2toSmJNQkg0cVhqNE0=
dn:uid=mqttuser0002,ou=testdevice,dc=emqx,dc=io
objectClass: top
objectClass: mqttUser
uid: mqttuser0002
userPassword:: e1NTSEF9bjlYZHRvRzRRL1RRM1RRRjRZK2toSmJNQkg0cVhqNE0=
## create a superuser mqttuser0003
# password=mqttuser0003,
# passhash={MD5}ybsPGoaK3nDyiQvveiCOIw==
# base64passhash=e01ENX15YnNQR29hSzNuRHlpUXZ2ZWlDT0l3PT0=
dn:uid=mqttuser0003,ou=testdevice,dc=emqx,dc=io
objectClass: top
objectClass: mqttUser
uid: mqttuser0003
isSuperuser: TRUE
userPassword:: e01ENX15YnNQR29hSzNuRHlpUXZ2ZWlDT0l3PT0=LDAPサーバー起動時にスキーマおよびLDIFファイルを読み込むよう、LDAP設定ファイルslapd.confを編集します。以下はslapd.confの例です。
TIP
LDAP資格情報の保存方法やアクセス方法は、ビジネス要件に応じて決定してください。
include /usr/local/etc/openldap/schema/core.schema
include /usr/local/etc/openldap/schema/cosine.schema
include /usr/local/etc/openldap/schema/inetorgperson.schema
include /usr/local/etc/openldap/schema/emqx.schema
TLSCACertificateFile /usr/local/etc/openldap/cacert.pem
TLSCertificateFile /usr/local/etc/openldap/cert.pem
TLSCertificateKeyFile /usr/local/etc/openldap/key.pem
database mdb
suffix "dc=emqx,dc=io"
rootdn "cn=root,dc=emqx,dc=io"
rootpw {SSHA}eoF7NhNrejVYYyGHqnt+MdKNBh4r1w3W
directory /usr/local/etc/openldap/dataダッシュボードでLDAP認証を設定する
EMQXダッシュボードでパスワード認証にLDAPを使用する設定が可能です。
EMQXダッシュボードの左ナビゲーションメニューから アクセス制御 -> 認証 をクリックします。
認証 ページの右上にある 作成 をクリックします。
メカニズムに パスワードベース を、バックエンドに LDAP を選択し、設定タブに移動します。以下のように表示されます。

以下の手順に従って設定してください。
LDAPサーバーに接続するための情報を入力します。
サーバー: EMQXが接続するサーバーアドレス(
host:port)を指定します。ユーザー名: EMQXがLDAPサーバーにバインドするために使用するアカウント名(バインドDN)を指定します。例:
cn=root,dc=emqx,dc=io。このアカウントはユーザーエントリの読み取り権限を持ち、通常はLDAP設定ファイル(例:slapd.conf)で定義されたrootdnと同じです。パスワード: 上記ユーザー名に対応する平文パスワードで、バインド操作を完了するために使用します。この値はLDAP設定の
rootpwの実際のパスワードと一致する必要があります。
認証設定: 認証に関する設定を入力します。
パスワード認証方式: 認証方式を選択します。
LDAPバインド認証(デフォルト)またはローカルパスワード比較から選択します。バインドパスワード: EMQXがLDAPサーバーに対して操作やクエリを行う前に自身を認証するために使用するパスワードを指定します。
${password}というプレースホルダーで参照され、実行時に設定のパスワードで定義された実際のパスワードに解決されます。ベースDN: LDAP検索操作の開始点(ベースDN)を指定します。EMQXはこのDNから設定されたフィルターに一致するユーザーエントリの検索を開始します。
${username}などのプレースホルダーを使ってクライアントIDを動的に構築できます。詳細はRFC 4511 Search Requestを参照してください。TIP
DNは識別名(Distinguished Name)を指します。これは各オブジェクトエントリの一意の識別子であり、情報ツリー内のエントリの位置も示します。
パスワードハッシュ属性: 認証方式に
ローカルパスワード比較を選択した場合に適用される、ユーザーのパスワードを表す属性を指定します。この属性の値はRFC 3112に準拠し、サポートされるアルゴリズムはmd5、sha、sha256、sha384、sha512、sshaです。スーパーユーザー属性: 認証方式に
ローカルパスワード比較を選択した場合に適用される、ユーザーがスーパーユーザーかどうかを示す属性を指定します。この属性の値はブール値であり、存在しない場合はfalseとみなされます。クライアントID上書き属性: 接続時にクライアントが提供したクライアントIDを上書きするために使用されるLDAP属性名を指定します。これにより認証データに基づいて一意のクライアントIDを割り当てられ、マルチテナントなどのセッション競合を防止できます。
前提条件: Variform式で、LDAP認証機能をクライアント接続に適用するかどうかを制御します。この式はクライアントの属性(例:
username、clientid、listenerなど)に対して評価され、結果が文字列"true"の場合のみ認証機能が呼び出されます。そうでなければスキップされます。詳細は認証機能の前提条件を参照してください。
TLSを有効化: TLSを有効にする場合はトグルスイッチをオンにします。TLS有効化の詳細はネットワークとTLSを参照してください。
フィルター: LDAPクエリの条件を定義します。フィルターはエントリが一致とみなされる条件を設定します。フィルターの構文はRFC 4515に準拠し、プレースホルダーもサポートします。
詳細設定: 同時接続数や接続タイムアウトまでの待機時間を設定します。
- 接続プールサイズ(任意): EMQXノードからLDAPへの同時接続数を整数値で指定します。デフォルトは
8です。 - クエリタイムアウト(任意): EMQXがクエリのタイムアウトとみなすまでの待機時間を秒単位で指定します。デフォルトは
5秒です。
- 接続プールサイズ(任意): EMQXノードからLDAPへの同時接続数を整数値で指定します。デフォルトは
設定が完了したら、作成をクリックします。
設定項目によるLDAP認証の設定
EMQXの設定項目でLDAP認証機能を設定できます。
LDAP認証はmechanism = password_basedかつbackend = ldapで識別されます。
以下はローカルパスワード比較方式の設定例です。
{
backend = "ldap"
mechanism = "password_based"
method {
type = hash
password_attribute = "userPassword"
is_superuser_attribute = "isSuperuser"
}
server = "127.0.0.1:389"
query_timeout = "5s"
username = "root"
password = "root password"
pool_size = 8
base_dn = "uid=${username},ou=testdevice,dc=emqx,dc=io"
filter = "(objectClass=mqttUser)"
}以下はLDAPバインド認証方式の設定例です。
{
backend = "ldap"
mechanism = "password_based"
method {
type = bind
bind_password = "${password}"
}
server = "127.0.0.1:389"
query_timeout = "5s"
username = "root"
password = "root password"
pool_size = 8
base_dn = "uid=${username},ou=testdevice,dc=emqx,dc=io"
filter = "(objectClass=mqttUser)"
}LDAPからACLルールを取得する
クライアントの認証に加えて、EMQXは認証時に使用した同じLDAPエントリからユーザーごとのACL(アクセス制御リスト)ルールを取得できます。これにより、認証と認可をLDAPで一元管理できます。
認証処理中に、EMQXは設定されたbase_dnとfilterを使ってユーザーのLDAPエントリを検索します。ACL関連の属性が見つかれば、それらを取得してクライアントのセッションにキャッシュします。これらのルールは認可チェック(パブリッシュやサブスクライブの権限など)に使用され、繰り返しLDAPクエリを行う必要がなくなります。
サポートされるACL属性
LDAPからACLルールを取得する機能を有効にするには、LDAPスキーマに以下のいずれかの属性を定義する必要があります。
mqttPublishTopic: クライアントがパブリッシュを許可されているトピックのホワイトリスト。mqttSubscriptionTopic: クライアントがサブスクライブを許可されているトピックのホワイトリスト。mqttPubSubTopic: クライアントがパブリッシュおよびサブスクライブの両方を許可されているトピック。mqttAclRule: JSON形式で定義された詳細なACLルール。アクション(パブリッシュやサブスクライブ)、許可(許可または拒否)、トピックフィルターなどを細かく制御可能。mqttAclTtl: クライアントセッション内でACLルールが有効な期間(TTL)を指定する任意の属性。
上記の属性名はあくまで例です。LDAP認証機能の設定で適切なフィールドを使ってカスタマイズできます。
これらの属性の動作や意味はLDAPオーソライザーで定義されたものと同じですが、mqttAclTtlはLDAP認証機能固有の属性です。この属性により、取得したACLルールをクライアントセッション内でどのくらいの期間キャッシュするかを制御できます。値は秒単位の数値文字列(例:60)か、1s、15m、1h、1dなどの時間単位付きの期間を指定できます。
指定されたTTLが切れると、EMQXはキャッシュされたルールを使用しなくなり、新たな認証やセッションで新しいルールが取得されない限り、デフォルトの認可設定に戻ります。
ACLルール用LDAPスキーマ例
以下はACLルール用の属性を定義したスキーマ例です。
attributetype ( 1.3.6.1.4.1.11.2.53.2.2.3.1.2.3.1.4 NAME 'isSuperuser'
EQUALITY booleanMatch
SYNTAX 1.3.6.1.4.1.1466.115.121.1.7
SINGLE-VALUE
USAGE userApplications )
attributetype ( 1.3.6.1.4.1.11.2.53.2.2.3.1.2.3.4.1 NAME ( 'mqttPublishTopic' 'mpt' )
EQUALITY caseExactMatch
SUBSTR caseExactSubstringsMatch
SYNTAX 1.3.6.1.4.1.1466.115.121.1.15
USAGE userApplications )
attributetype ( 1.3.6.1.4.1.11.2.53.2.2.3.1.2.3.4.2 NAME ( 'mqttSubscriptionTopic' 'mst' )
EQUALITY caseExactMatch
SUBSTR caseExactSubstringsMatch
SYNTAX 1.3.6.1.4.1.1466.115.121.1.15
USAGE userApplications )
attributetype ( 1.3.6.1.4.1.11.2.53.2.2.3.1.2.3.4.3 NAME ( 'mqttPubSubTopic' 'mpst' )
EQUALITY caseExactMatch
SUBSTR caseExactSubstringsMatch
SYNTAX 1.3.6.1.4.1.1466.115.121.1.15
USAGE userApplications )
attributetype ( 1.3.6.1.4.1.11.2.53.2.2.3.1.2.3.4.4 NAME ( 'mqttAclRule' 'mar' )
EQUALITY caseExactMatch
SUBSTR caseExactSubstringsMatch
SYNTAX 1.3.6.1.4.1.1466.115.121.1.15
USAGE userApplications )
attributetype ( 1.3.6.1.4.1.11.2.53.2.2.3.1.2.3.4.5 NAME ( 'mqttAclTtl' 'mat' )
EQUALITY caseExactMatch
SUBSTR caseExactSubstringsMatch
SYNTAX 1.3.6.1.4.1.1466.115.121.1.15
USAGE userApplications )
objectclass ( 1.3.6.1.4.1.11.2.53.2.2.3.1.2.3.4 NAME 'mqttUser'
SUP top
STRUCTURAL
MAY ( isSuperuser $ mqttPublishTopic $ mqttSubscriptionTopic $ mqttPubSubTopic $ mqttAclRule $ mqttAclTtl )
MUST ( uid $ userPassword ))ACL属性を含むLDIFエントリの例
以下は、OpenLDAP用スキーマに基づくACL属性を含むLDAP認証データのLDAPデータ交換フォーマット(LDIF)の例です。
dn:dc=emqx,dc=io
objectclass: top
objectclass: dcobject
objectclass: organization
dc:emqx
o:emqx,Inc.
# create testdevice.emqx.io
dn:ou=testdevice,dc=emqx,dc=io
objectClass: top
objectclass:organizationalUnit
ou:testdevice
## create user=mqttuser0002
# password=mqttuser0002,
# passhash={SSHA}n9XdtoG4Q/TQ3TQF4Y+khJbMBH4qXj4M
# base64passhash=e1NTSEF9bjlYZHRvRzRRL1RRM1RRRjRZK2toSmJNQkg0cVhqNE0=
dn:uid=mqttuser0002,ou=testdevice,dc=emqx,dc=io
objectClass: top
objectClass: mqttUser
objectClass: mqttDevice
objectClass: mqttSecurity
uid: mqttuser0002
isEnabled: TRUE
mqttAccountName: user2
mqttPublishTopic: mqttuser0002/pub/1
mqttPublishTopic: mqttuser0002/pub/+
mqttPublishTopic: mqttuser0002/pub/#
mqttSubscriptionTopic: mqttuser0002/sub/1
mqttSubscriptionTopic: mqttuser0002/sub/+
mqttSubscriptionTopic: mqttuser0002/sub/#
mqttPubSubTopic: mqttuser0002/pubsub/1
mqttPubSubTopic: mqttuser0002/pubsub/+
mqttPubSubTopic: mqttuser0002/pubsub/#
mqttAclRule: [{"permission": "allow", "action": "pub", "topic": "mqttuser0002/complexrule1/1"}]
mqttAclRule: {"permission": "allow", "action": "pub", "topic": "mqttuser0002/complexrule2/#"}
mqttAclTtl: 1s
userPassword:: e1NTSEF9bjlYZHRvRzRRL1RRM1RRRjRZK2toSmJNQkg0cVhqNE0=LDAP認証機能の設定例
ACLルールの取得とキャッシュを有効にするには、LDAP認証機能の設定で属性名を明示的に指定する必要があります。
{
backend = "ldap"
mechanism = "password_based"
method {
type = hash
password_attribute = "userPassword"
is_superuser_attribute = "isSuperuser"
}
server = "127.0.0.1:389"
query_timeout = "5s"
username = "root"
password = "root password"
pool_size = 8
base_dn = "uid=${username},ou=testdevice,dc=emqx,dc=io"
filter = "(objectClass=mqttUser)"
publish_attribute = "mqttPublishTopic"
subscribe_attribute = "mqttSubscriptionTopic"
all_attribute = "mqttPubSubTopic"
acl_attribute = "mqttAclRule"
acl_ttl_attribute = "mqttAclTtl"
}