概要
ではConsulのACLの基本的な設定方法を説明しました。その時は
"default_policy": "deny"のようにデフォルトで全リソースのアクセス禁止にしてwhitelist形式で扱っていきます。
と言いましたが、そもそもACL未設定なConsulを稼働中で、急にdefault denyにしたらサービスに影響が出てしまうというケースももちろんあります。
今回はACLを後から有効化(ACLのマイグレーション?)する方法を説明します。
環境
- Consul 1.4.0
ハンズオン
こちらのリポジトリで検証できます。
手順
大まかな手順としては
- サーバの
default_policy
をallow
にし、ACLをenable
に - サーバを再起動
- Agent Policy用意してconfigの
acl.tokens.agent
にtokenをセット - Consulを利用するサービス毎に適切なポリシーを用意してconfigの
acl.tokens.default
にtokenをセット - 全agentを再起動
- Anonymous TokenのPolicyを更新
- サーバの
default_policy
をdeny
に変更 - サーバを再起動
です。
結構手間ですが各ACLを最低限必要なものにする場合はこれを守らないとどこかしらでERRが出てきます。
1. サーバのdefault_policy
をallow
にし、ACLをenable
に
リポジトリのものはすでにallow
にしていますが、稼働中のConsulの設定を
{ "primary_datacenter": "dc1", "acl": { "enabled": true, "default_policy": "allow", "down_policy": "extend-cache", "tokens": { "master": "b1gs33cr3t" } } }
の状態にしてください。
今回も簡単のためmaster token
を明示的に書いてますが、本番では書かずにbootstrapで生成してください。
2. サーバを再起動
再起動順ですが、リーダーの再選出が行われるとその間一時的にConsulが使えないので
- リーダー以外を再起動
- 最後にリーダーを再起動
の順で行ってください。
リーダーが再起動されるまではACLは有効化されませんし、各client agentも通常通りクエリを叩けますが、再起動後のサーバはリーダーが再起動されるまではどのコマンドも
/ # consul members Error retrieving members: Unexpected response code: 403 (ACL not found)
とうエラーが発生するので注意してください。
ただログを見る感じだとコマンドにコケるだけで、内部通信等は問題ないようです。
この時
ですが、クライアント側ではコマンドは問題なく通ります。未設定のまま再起動しても通ります。
例
$ docker restart acl-migration_consul-server-1_1
3. Agent Policy用意してconfigのacl.tokens.agent
にtokenをセット
ConsulのACLでアクセス制御 - Carpe Diem
の通りに作って設定します。
Policy
/ # consul acl policy create \ -name "agent-policy" \ -description "Agent Token Policy" \ -rules @/consul/policies/agent.hcl
Token
/ # consul acl token create \ -description "Agent Token" \ -policy-name "agent-policy"
生成したらサーバ・クライアント(agent)側の両方のacl.tokens.agent
にtokenをセットします。
サーバ側の例
{ "primary_datacenter": "dc1", "acl": { "enabled": true, "default_policy": "allow", "down_policy": "extend-cache", "tokens": { "master": "b1gs33cr3t", "agent": "a2b385df-4355-a37e-d465-b5430ea8b671" } } }
後ほどまとめて再起動するので今はconfigの更新のみで大丈夫です。
4. Consulを利用するサービス毎に適切なポリシーを用意してconfigのacl.tokens.default
にtokenをセット
例えばUI用のポリシーを個別に設定するとして、
ConsulのACLでアクセス制御 - Carpe Diem
のようにtokenを作ります。
Policy
/ # consul acl policy create \ -name "ui-policy" \ -description "UI Token Policy" \ -rules @/consul/policies/ui.hcl
Token
/ # consul acl token create \ -description "UI Token" \ -policy-name "ui-policy"
UIの場合はWebからも登録できますが、以下のようにconfigでacl.tokens.default
にセットすれば登録できます。
{ "primary_datacenter": "dc1", "acl": { "enabled": true, "down_policy": "extend-cache", "tokens": { "agent": "a2b385df-4355-a37e-d465-b5430ea8b671", "default": "a2b385df-4355-a37e-d465-b5430ea8b671" } } }
5. 全agentを再起動
サーバ含め各agentを再起動してください。
例
$ docker restart acl-migration_consul-agent-1_1
6. Anonymous TokenのPolicyを更新
ConsulのACLでアクセス制御 - Carpe Diem
の通りに更新します。
Policy
/ # consul acl policy create \ -name "anonymous-policy" \ -description "Anonymous Token Policy" \ -rules @/consul/policies/anonymous.hcl
Anonymous Tokenにアタッチ
/ # consul acl token update \ -id 00000000-0000-0000-0000-000000000002 \ -policy-name "anonymous-policy" \ -description "Anonymous Token"
7. サーバのdefault_policy
をdeny
に変更
一通り設定できたら最後にdefault_policy
をdeny
に変更します。
{ "primary_datacenter": "dc1", "acl": { "enabled": true, "default_policy": "deny", "down_policy": "extend-cache", "tokens": { "master": "b1gs33cr3t", "agent": "a2b385df-4355-a37e-d465-b5430ea8b671" } } }
8. サーバを再起動
再起動順は先程と同じく
- リーダー以外を再起動
- 最後にリーダーを再起動
の順で行ってください。
リーダーが再選出されない限りdefault_policy: deny
の設定は反映されません。
例
$ docker restart acl-migration_consul-server-1_1
まとめ
ConsulのACLを後から有効化する方法を紹介しました。
手っ取り早いのはAnonymous Tokenにゴリゴリ権限を追加する方法ですが、それだとサービス毎に設定できる柔軟性・セキュリティの担保ができなくなるのでドキュメント通りの最低限の権限を付与していくのが良いです。