# ACLファイルの使用

EMQXは、ACLファイルに格納された事前定義済みのルールに基づく認可チェックをサポートしています。ファイル内に複数の認可チェックルールを設定できます。クライアントからの操作リクエストを受け取ると、EMQXはACLファイル内の認可ルールを上から順に照合します。ルールにマッチした場合、その設定に従って現在のリクエストを許可または拒否し、以降のルールの照合を停止します。

ファイルベースのACLはシンプルで軽量なため、一般的なルールの設定に適しています。クライアントごとに数百以上のルールが必要な場合は、他の認可ソースの利用を推奨します。ファイルベースのACLは認可チェーンの最後の安全装置として利用できます。

::: tip 前提条件
バージョン5.0以降、ファイルベースのACLルールはEMQXダッシュボードUIから編集およびリロードが可能です。

[認可](./authz.md)の基本概念に慣れておいてください。

:::

## ACLファイル形式

ACLファイルに基づく認可チェックを行う前に、認可ルールを[Erlangタプル](https://www.erlang.org/doc/reference_manual/data_types.html#tuple)のデータリスト形式でファイルに保存する必要があります。

ACL設定ファイルは、ピリオドで終わるErlangタプルのリストです。_タプル_はカンマ区切りの式のリストで、全体は中括弧で囲まれています。

`%%`で始まる行はコメントとして認識され、パース時に無視されます。

例：

```erlang
%% ユーザー名 "dashboard" のMQTTクライアントに "$SYS/#" トピックのサブスクライブを許可
{allow, {user, "dashboard"}, subscribe, ["$SYS/#"]}.

%% IPアドレス "127.0.0.1" のユーザーに "$SYS/#", "#" トピックのパブリッシュ/サブスクライブを許可
{allow, {ipaddr, "127.0.0.1"}, all, ["$SYS/#", "#"]}.

%% "全ユーザー" に `$SYS/#`, `#`, `+/#` のサブスクライブを拒否
{deny, all, subscribe, ["$SYS/#", {eq, "#"}, {eq, "+/#"}]}.

%% その他のパブリッシュ/サブスクライブ操作を許可
%% 注意: 本番環境では最後のルールを `{deny, all}` に変更し、設定 `authorization.no_match = deny` を推奨
{allow, all}.
```

ルールは上から順に照合され、マッチしたルールの権限が適用され、以降のルールは無視されます。

- タプルの第1要素は、ルールがマッチした場合に適用される権限を示します。可能な値は以下の通りです：
  * `allow`
  * `deny`

- 第2要素は、そのルールが適用されるクライアントを表します。以下の用語や組み合わせでクライアントを指定できます：
  * `{username, "dashboard"}`：ユーザー名が `dashboard` のクライアント；`{user, "dashboard"}` も可
  * `{username, {re, "^dash"}}`：ユーザー名が正規表現 `^dash` にマッチするクライアント
  * `{clientid, "dashboard"}`：クライアントIDが `dashboard` のクライアント；`{client, "dashboard"}` も可
  * `{clientid, {re, "^dash"}}`：クライアントIDが正規表現 `^dash` にマッチするクライアント
  * `{client_attr, "name", "dashboard"}`：クライアント属性 `name` が `dashboard` のクライアント
  * `{client_attr, "name", {re, "^dash"}}`：クライアント属性 `name` が正規表現 `^dash` にマッチするクライアント
  * `{ipaddr, "127.0.0.1"}`：IPアドレス `127.0.0.1` から接続するクライアント。ネットマスクも利用可能。EMQXがロードバランサーの背後にある場合、クライアントのMQTTリスナーで `proxy_protocol` を有効にする必要があります。
  * `{ipaddrs, ["127.0.0.1", ..., ]}`：指定された複数のIPアドレスのいずれかから接続するクライアント。ネットマスクも利用可能。
  * `all`：すべてのクライアント
  * `{'and', [Spec1, Spec2, ...]}`：リスト内のすべての仕様を満たすクライアント
  * `{'or', [Spec1, Spec2, ...]}`：リスト内のいずれかの仕様を満たすクライアント

- 第3要素は、ルールが適用される操作を示します：
  * `publish`：パブリッシュ操作に適用
  * `subscribe`：サブスクライブ操作に適用
  * `all`：パブリッシュおよびサブスクライブの両方に適用
  * EMQX v5.1.1以降では、パブリッシュおよびサブスクライブ操作におけるQoSや保持メッセージフラグのチェックが可能です。第3要素に `qos` や `retain` を追加して指定できます。例：
    * `{publish, [{qos, 1}, {retain, false}]}`：QoSが1で保持メッセージでないパブリッシュを拒否
    * `{publish, {retain, true}}`：保持メッセージのパブリッシュを拒否
    * `{subscribe, {qos, 2}}`：QoS2のトピックへのサブスクライブを拒否

- 第4要素は、ルールが適用されるトピックを指定します。トピックはパターンのリストで指定し、[トピックプレースホルダー](./authz.md#topic-placeholders)を使用可能です。利用可能なパターンは以下の通りです：
  * `"t/${clientid}"` のような文字列値：トピックプレースホルダーを使用。クライアントIDが `emqx_c` の場合、トピック `t/emqx_c` に正確にマッチします。
  * `"$SYS/#"` のような文字列値：ワイルドカードを含む標準的なトピックフィルター。トピックフィルターは[MQTT仕様](http://docs.oasis-open.org/mqtt/mqtt/v3.1.1/errata01/os/mqtt-v3.1.1-errata01-os-complete.html#_Toc442180920)に従ってマッチします。例：`$SYS/#` はパブリッシュで `$SYS/foo`、`$SYS/foo/bar` にマッチし、サブスクライブで `$SYS/foo`、`$SYS/foo/#`、`$SYS/#` にマッチします。トピックプレースホルダーも利用可能です。
  * `{eq, "foo/#"}` のようなeqタプル：トピック文字列の完全一致を示します。このパターンはすべての操作において正確に `foo/#` トピックにマッチします。ワイルドカードやプレースホルダーは考慮されません。つまり、トピック `foo/bar` はマッチしません。

さらに、設定の最後に通常デフォルトとして使われる2つの特別なルールがあります。
- `{allow, all}`：すべての操作を許可
- `{deny, all}`：すべての操作を拒否

## ダッシュボードでの設定

EMQXはデフォルトでファイルベースのオーソライザーを設定しています。**Actions**列の**Settings**をクリックすると設定を表示・編集できます。別のファイルベースのオーソライザーを作成するには、**Create**をクリックし、**Backend**で**File**を選択して**Next**をクリックします。以下は**Configuration**ステップの画面例です。

<img src="./assets/dashboard-edit-ACL-file_ee.png" alt="ダッシュボードでのACLファイル編集画面" style="zoom:67%;" />

**Configuration**ステップでは：

- **Precondition**：任意のVariform式を入力します。EMQXはこの式が`true`の場合のみオーソライザーを呼び出します。詳細は[オーソライザープリコンディション](./authz.md#authorizer-preconditions)を参照してください。
- **ACL File**：認可ルールを入力します。ファイル形式やフィールドの詳細は[ACLファイル形式](#acl-file-format)を参照してください。

## 設定ファイルでの設定

ファイルベースのオーソライザーは`file`タイプで識別されます。

設定例：

```bash
authorization {
  deny_action = ignore
  no_match = deny
  sources = [
    {
      type = file
      enable = true
      path = "etc/acl.conf"
    }
  ]
}
```

各項目の説明：

- `type`：オーソライザーのデータソースタイプ。ここでは`file`。
- `enable`：オーソライザーを有効にするかどうか。オプション値は`true`または`false`。
- `precondition`：任意のVariform式。EMQXはこの式が`true`の場合のみオーソライザーを呼び出します。省略または空の場合はプリコンディションなし。詳細は[オーソライザープリコンディション](./authz.md#authorizer-preconditions)を参照してください。
- `path`：設定ファイルのパス。デフォルトは`etc/acl.conf`。ダッシュボードやREST APIからファイルベースのオーソライザーを編集した場合、EMQXは新しいファイルを`data/authz/acl.conf`に保存し、元のファイルからの読み込みを停止します。

<!--詳細なパラメータ一覧は[authz-file](../../configuration/configuration-manual.html#authz-file)を参照してください。リンクは後で更新予定-->

::: tip

`path`設定で指定された初期ファイルはEMQXによって変更されません。  
ダッシュボードUIや管理APIからルールが更新されると、新しいルールは`data/authz/acl.conf`に保存され、元の設定ファイルは読み込まれなくなります。

:::
