Fire Engine

化学の修士号→消防士→ITエンジニア(2016年11月〜)

ConsulのACL Bootstrapをリセットしてもう一度やり直す方法

こんにちは、つるべーです!
先日、Consul ACLの記事を書きましたが、今回もACLのちょっとした小ネタについて書きます。
内容としては、ACLをBootstrapしたあとにMater TokenのSecret IDをなくしてしまい、Consul関連の操作が何もできなって、発狂しそうになったときの対応方法です。

前回の記事

blog.tsurubee.tech

環境

DockerでConsul ACLの検証環境を用意しています。使い方はREADMEをご覧ください。

github.com

Consulのバージョンは1.4.0です。

/ # consul version
Consul v1.4.0
Protocol 2 spoken by default, understands 2 to 3 (agent will automatically use protocol >2 when speaking to compatible agents)

ACLのBootstrap

ACLを使い始めるには、最初にBootstrap、いわゆる初期化をしてやる必要があります。
公式ドキュメントではこのあたりに説明があります。

Consulの設定ファイルでACLを有効にしたのち、serverモードのサーバでBootstrapをすると、下のようにBootstrap Token(Master Token)が払い出されます。

/ # consul acl bootstrap
AccessorID:   3cff8208-af8e-feb9-9ebb-fc75a5ddb76e
SecretID:     91118e17-445b-942d-f090-f3b34defa4bf
Description:  Bootstrap Token (Global Management)
Local:        false
Create Time:  2018-12-21 14:26:58.574906326 +0000 UTC
Policies:
   00000000-0000-0000-0000-000000000001 - global-management

ACLのBootstrapは一度しかできない

上記のACLのBootstrapは一度しかできず、二回目を叩くと下のようにエラーが出ます。

/ # consul acl bootstrap -token=91118e17-445b-942d-f090-f3b34defa4bf
Failed ACL bootstrapping: Unexpected response code: 403 (Permission denied: ACL bootstrap no longer allowed (reset index: 18))

通常は、Bootstrapをし直す必要などないのですが、例えば、Bootstrapしたあとに、Bootstrap時に出力されるMater TokenのSecret IDをなくしてしまったらどうなるでしょう?
そうです、Bootstrapした直後の時点ではMaster TokenなしではConsulコマンドが何も実行できません。(Bootstrap時にAnonymous Tokenには何もPolicyがアタッチしていないため)
したがって、Bootstrap後にMater TokenのSecret IDがわからなくなるとConsul関連の操作が何もできなくなり、にっちもさっちもいかなくなります。

Bootstrapをリセットしてやり直す方法

Consulの公式ドキュメントを探しても、Bootstrapをもう一回やり直す方法が見当たりませんでした。(2018年12月22日現在)
しかし、同じくhashicorpが開発しているNomadのドキュメントにResetting ACL Bootstrapの説明がありました。このNomadのドキュメントと同じ手順でConsul ACLのBootstrapをリセットすることができました。

実際に手順を示します。まず二回目のBootstrapを叩いた時に出力されるエラーメッセージのreset index: 18の部分に着目してください。

ACL bootstrap no longer allowed (reset index: 18)

このindexの値は固定値でなく、個々で異なる値です。(クラスタ内では共有の値)
この値を埋め込んだファイルを、acl-bootstrap-resetという名前で、Leaderノードのデータディレクトリ配下に作成します。データディレクトリとは設定ファイルのdata_dirの部分です。(ここでは仮に/tmp/dataとする)

$ echo 18 >> /tmp/data/acl-bootstrap-reset

このようにreset indexを埋め込んだacl-bootstrap-resetファイルを作成すると、Bootstrapコマンドを再度実行できるようになります。

/ # consul acl bootstrap
AccessorID:   180d0d38-424f-69be-1897-d98b41abed7e
SecretID:     32ff58d9-df47-05d0-1279-f63ae28af609
Description:  Bootstrap Token (Global Management)
Local:        false
Create Time:  2018-12-22 07:09:03.8573353 +0000 UTC
Policies:
   00000000-0000-0000-0000-000000000001 - global-management

ここで全ての権限が与えられたTokenができるため、このSecretIDでConsulの操作ができるようになります。
ちなみに作成したacl-bootstrap-resetファイルは勝手に削除されています。

/ # cat /tmp/data/acl-bootstrap-reset
cat: can't open '/tmp/data/acl-bootstrap-reset': No such file or directory

また、実は再Bootstrapをしたからといって、完全に初期化されたのでなく、1回目のBootstrap時に作成されたMater TokenとAnonymous Tokenは残ったまま、新しいMaster Tokenが作られた形になります。

/ # consul acl token list -token=32ff58d9-df47-05d0-1279-f63ae28af609
AccessorID:   180d0d38-424f-69be-1897-d98b41abed7e
Description:  Bootstrap Token (Global Management)
Local:        false
Create Time:  2018-12-22 07:09:03.8573353 +0000 UTC
Legacy:       false
Policies:
   00000000-0000-0000-0000-000000000001 - global-management

AccessorID:   3cff8208-af8e-feb9-9ebb-fc75a5ddb76e
Description:  Bootstrap Token (Global Management)
Local:        false
Create Time:  2018-12-21 14:26:58.574906326 +0000 UTC
Legacy:       false
Policies:
   00000000-0000-0000-0000-000000000001 - global-management

AccessorID:   00000000-0000-0000-0000-000000000002
Description:  Anonymous Token
Local:        false
Create Time:  2018-12-21 14:18:38.848568562 +0000 UTC
Legacy:       false
Policies:

そのため、古いMaster Tokenは消しておいてもいいですし、新しいMaster Tokenが発行された今であれば、古いMaster TokenのSecretIDを確認することもできます。

/ # consul acl token read -id=3cff8208-af8e-feb9-9ebb-fc75a5ddb76e -token=32ff58d9-df47-05d0-1279-f63ae28af609
AccessorID:   3cff8208-af8e-feb9-9ebb-fc75a5ddb76e
SecretID:     91118e17-445b-942d-f090-f3b34defa4bf
Description:  Bootstrap Token (Global Management)
Local:        false
Create Time:  2018-12-21 14:26:58.574906326 +0000 UTC
Policies:
   00000000-0000-0000-0000-000000000001 - global-management

さいごに

最初Bootstrapをもう一回やりたいとなった時、bootstrapコマンドに--forceみたいなオプションないかなぁーと思ったのですが、ありませんでした。
今回見たように再Bootstrapできたとしても、古いTokenが消えるわけではないためすぐには事故に繋がらなさそうですが、Consulでは一意なreset indexを指定のファイル名・パスに埋め込むというオペミスが起こり得ない安全な設計になっており、自分で何かしらツールを作る時にもこういった設計は参考になりそうだなぁと思いました。

consul image