AnsibleVaultを使用して機密性の高いPlaybookデータを保護する方法
序章
Ansible Vaultは、ユーザーがAnsibleプロジェクト内の値とデータ構造を暗号化できるようにする機能です。 これにより、Ansibleプレイを正常に実行するために必要であるが、パスワードや秘密鍵などの公開されるべきではない機密データを保護する機能が提供されます。 Ansibleは、キーが提供されると、実行時にボールトで暗号化されたコンテンツを自動的に復号化します。
このガイドでは、Ansible Vaultの使用方法を示し、その使用を簡素化するためのいくつかの推奨プラクティスを探ります。 AnsibleコントロールマシンにはUbuntu20.04サーバーを使用します。 リモートホストは必要ありません。
前提条件
フォローするには、root以外のユーザーがいるUbuntu20.04サーバーが必要です。 sudo
特権。 Ubuntu 20.04初期サーバーセットアップガイドに従って、適切な権限を持つユーザーを作成できます。
サーバー上で、Ansibleをインストールして構成する必要があります。 Ubuntu 20.04 へのAnsibleのインストールに関するチュートリアルに従って、適切なパッケージをインストールできます。
サーバーが上記の要件で構成されている場合は、このガイドを続けてください。
Ansible Vaultとは何ですか?
Ansible Vaultは、暗号化されたコンテンツをAnsibleワークフローに透過的に組み込むことができるメカニズムです。 と呼ばれるユーティリティ ansible-vault
ディスク上で暗号化することにより、secretsと呼ばれる機密データを保護します。 これらの秘密を通常のAnsibleデータと統合するには、両方とも ansible
と ansible-playbook
アドホックタスクと構造化プレイブックをそれぞれ実行するためのコマンドは、実行時にボールトで暗号化されたコンテンツを復号化することをサポートしています。
Vaultはファイルレベルの粒度で実装されます。つまり、個々のファイルは暗号化されているか、暗号化されていないかのどちらかです。 それは使用します AES256
ユーザー指定のパスワードにキー設定された対称暗号化を提供するアルゴリズム。 これは、コンテンツの暗号化と復号化に同じパスワードが使用されることを意味します。これは、使いやすさの観点から役立ちます。 Ansibleは、プレイブックまたはタスクの実行中に見つかったボールト暗号化ファイルを識別して復号化できます。
Vaultとは何かについて少し理解できたので、Ansibleが提供するツールと既存のワークフローでVaultを使用する方法について説明します。
AnsibleVaultエディターの設定
使用する前に ansible-vault
コマンドの場合は、好みのテキストエディタを指定することをお勧めします。 Vaultのコマンドのいくつかは、暗号化されたファイルの内容を操作するためにエディターを開くことを含みます。 Ansibleは EDITOR
好みのエディタを見つけるための環境変数。 これが設定されていない場合、デフォルトで vi
.
で編集したくない場合 vi
エディター、あなたは設定する必要があります EDITOR
環境内の変数。
注: vi
誤ってセッションを終了するには、Escキーを押して次のように入力します。 :q!
、次にEnterを押します。 あなたが精通していない場合 vi
エディターでは、行った変更は意図しないものである可能性が高いため、このコマンドは保存せずに終了します。
個々のコマンドのエディターを設定するには、次のように、コマンドの前に環境変数の割り当てを追加します。
- EDITOR=nano ansible-vault . . .
これを永続的にするには、 ~/.bashrc
ファイル:
- nano ~/.bashrc
を追加して、好みのエディタを指定します EDITOR
ファイルの終わりへの割り当て:
export EDITOR=nano
終了したら、ファイルを保存して閉じます。
ファイルを再度ソースして、変更を現在のセッションに読み込みます。
- . ~/.bashrc
を表示します EDITOR
設定が適用されたことを確認する変数:
- echo $EDITOR
Outputnano
好みのエディターを確立したので、利用可能な操作について話し合うことができます。 ansible-vault
指図。
ansible-vaultで機密ファイルを管理する方法
The ansible-vault
コマンドは、Ansible内で暗号化されたコンテンツを管理するためのメインインターフェイスです。 このコマンドは、最初にファイルを暗号化するために使用され、その後、データを表示、編集、または復号化するために使用されます。
新しい暗号化ファイルの作成
Vaultで暗号化された新しいファイルを作成するには、 ansible-vault create
指図。 作成するファイルの名前を渡します。 たとえば、次のような暗号化されたYAMLファイルを作成するには vault.yml
機密変数を保存するには、次のように入力します。
- ansible-vault create vault.yml
パスワードを入力して確認するように求められます。
OutputNew Vault password:
Confirm New Vault password:
パスワードを確認すると、Ansibleはすぐに編集ウィンドウを開き、目的のコンテンツを入力できます。
暗号化機能をテストするには、次のテストテキストを入力します。
Secret information
Ansibleは、ファイルを閉じるときにコンテンツを暗号化します。 ファイルをチェックすると、入力した単語が表示される代わりに、暗号化されたブロックが表示されます。
- cat vault.yml
Output$ANSIBLE_VAULT;1.1;AES256
65316332393532313030636134643235316439336133363531303838376235376635373430336333
3963353630373161356638376361646338353763363434360a363138376163666265336433633664
30336233323664306434626363643731626536643833336638356661396364313666366231616261
3764656365313263620a383666383233626665376364323062393462373266663066366536306163
31643731343666353761633563633634326139396230313734333034653238303166
Ansibleがファイルの処理方法を知るために使用するいくつかのヘッダー情報と、それに続く数字として表示される暗号化されたコンテンツを見ることができます。
既存のファイルの暗号化
Vaultで暗号化するファイルがすでにある場合は、 ansible-vault encrypt
代わりにコマンド。
テストのために、次のように入力してサンプルファイルを作成できます。
- echo 'unencrypted stuff' > encrypt_me.txt
これで、次のように入力して既存のファイルを暗号化できます。
- ansible-vault encrypt encrypt_me.txt
ここでも、パスワードを入力して確認するように求められます。 その後、暗号化を確認するメッセージが表示されます。
OutputNew Vault password:
Confirm New Vault password:
Encryption successful
編集ウィンドウを開く代わりに、 ansible-vault
ファイルの内容を暗号化してディスクに書き戻し、暗号化されていないバージョンを置き換えます。
ファイルを確認すると、同様の暗号化されたパターンが表示されます。
- cat encrypt_me.txt
Output$ANSIBLE_VAULT;1.1;AES256
66633936653834616130346436353865303665396430383430353366616263323161393639393136
3737316539353434666438373035653132383434303338640a396635313062386464306132313834
34313336313338623537333332356231386438666565616537616538653465333431306638643961
3636663633363562320a613661313966376361396336383864656632376134353039663662666437
39393639343966363565636161316339643033393132626639303332373339376664
ご覧のとおり、Ansibleは、新しいファイルを暗号化するのとほぼ同じ方法で既存のコンテンツを暗号化します。
暗号化されたファイルの表示
場合によっては、ボールトで暗号化されたファイルを編集したり、暗号化されていないファイルシステムに書き込んだりせずに、ファイルの内容を参照する必要があります。 The ansible-vault view
コマンドは、ファイルの内容を標準出力に送ります。 デフォルトでは、これはコンテンツが端末に表示されることを意味します。
ボールト暗号化ファイルを次のコマンドに渡します。
- ansible-vault view vault.yml
ファイルのパスワードの入力を求められます。 入力に成功すると、内容が表示されます。
OutputVault password:
Secret information
ご覧のとおり、ファイルの内容の出力にはパスワードプロンプトが混在しています。 使用するときはこれを覚えておいてください ansible-vault view
自動化されたプロセスで。
暗号化されたファイルの編集
暗号化されたファイルを編集する必要がある場合は、 ansible-vault edit
指図:
- ansible-vault edit vault.yml
ファイルのパスワードの入力を求められます。 入力後、Ansibleはファイルを編集ウィンドウで開き、必要な変更を加えることができます。
保存すると、新しいコンテンツはファイルの暗号化パスワードを使用して再度暗号化され、ディスクに書き込まれます。
暗号化されたファイルを手動で復号化する
ボールト暗号化ファイルを復号化するには、 ansible-vault decrypt
指図。
注:機密データをプロジェクトリポジトリに誤ってコミットする可能性が高くなるため、 ansible-vault decrypt
コマンドは、ファイルから暗号化を完全に削除する場合にのみ推奨されます。 ボールトで暗号化されたファイルを表示または編集する必要がある場合は、通常、 ansible-vault view
また ansible-vault edit
それぞれコマンド。
暗号化されたファイルの名前を渡します。
- ansible-vault decrypt vault.yml
ファイルの暗号化パスワードの入力を求められます。 正しいパスワードを入力すると、ファイルは復号化されます。
OutputVault password:
Decryption successful
ボールト暗号化の代わりにファイルを再度表示すると、ファイルの実際の内容が表示されます。
- cat vault.yml
OutputSecret information
これで、ファイルはディスク上で暗号化されなくなりました。 終了したら、機密情報を削除するか、ファイルを再暗号化してください。
暗号化されたファイルのパスワードの変更
暗号化されたファイルのパスワードを変更する必要がある場合は、 ansible-vault rekey
指図:
- ansible-vault rekey encrypt_me.txt
コマンドを入力すると、最初にファイルの現在のパスワードの入力を求められます。
OutputVault password:
入力後、新しいボールトパスワードを選択して確認するように求められます。
OutputVault password:
New Vault password:
Confirm New Vault password:
新しいパスワードを正常に確認すると、再暗号化プロセスが成功したことを示すメッセージが表示されます。
OutputRekey successful
これで、新しいパスワードを使用してファイルにアクセスできるようになります。 古いパスワードは機能しなくなります。
Vaultで暗号化されたファイルでAnsibleを実行する
Vaultで機密情報を暗号化した後、Ansibleの従来のツールでファイルの使用を開始できます。 The ansible
と ansible-playbook
どちらのコマンドも、正しいパスワードを指定してボールトで保護されたファイルを復号化する方法を知っています。 必要に応じて、これらのコマンドにパスワードを提供する方法はいくつかあります。
従うには、ボールトで暗号化されたファイルが必要になります。 次のように入力して作成できます。
- ansible-vault create secret_key
パスワードを選択して確認します。 必要なダミーコンテンツを入力します。
confidential data
ファイルを保存して閉じます。
一時的なものを作成することもできます hosts
インベントリとしてのファイル:
- nano hosts
Ansibleローカルホストだけを追加します。 後のステップに備えるために、 [database]
グループ:
[database]
localhost ansible_connection=local
終了したら、ファイルを保存して閉じます。
次に、を作成します ansible.cfg
まだ存在しない場合は、現在のディレクトリにあるファイル:
- nano ansible.cfg
今のところ、追加するだけです [defaults]
セクションとポイント作成したばかりのインベントリにAnsible:
[defaults]
inventory = ./hosts
準備ができたら、続行します。
インタラクティブプロンプトの使用
実行時にコンテンツを復号化する最も簡単な方法は、Ansibleに適切なクレデンシャルの入力を求めるプロンプトを表示させることです。 これを行うには、 --ask-vault-pass
に ansible
また ansible-playbook
指図。 Ansibleは、ボールトで保護されたコンテンツを見つけた場合に復号化するために使用するパスワードの入力を求めます。
たとえば、ボールトで暗号化されたファイルの内容をホストにコピーする必要がある場合は、 copy
モジュールと --ask-vault-pass
国旗。 ファイルに実際に機密データが含まれている場合は、アクセス許可と所有権の制限を使用して、リモートホストへのアクセスをロックダウンすることをお勧めします。
注:使用しています localhost
この例では、必要なサーバーの数を最小限に抑えるためのターゲットホストとして使用しますが、結果は、ホストが本当にリモートである場合と同じになるはずです。
- ansible --ask-vault-pass -bK -m copy -a 'src=secret_key dest=/tmp/secret_key mode=0600 owner=root group=root' localhost
このタスクでは、ファイルの所有権を次のように変更する必要があることを指定しています root
、したがって、管理者権限が必要です。 The -bK
フラグはAnsibleにプロンプトを表示するように指示します sudo
ターゲットホストのパスワード。 sudo
パスワード。 次に、Vaultのパスワードの入力を求められます。
OutputBECOME password:
Vault password:
パスワードが提供されると、Ansibleは、検出した暗号化ファイルにVaultパスワードを使用して、タスクの実行を試みます。 実行中に参照されるすべてのファイルは同じパスワードを使用する必要があることに注意してください。
Outputlocalhost | SUCCESS => {
"changed": true,
"checksum": "7a2eb5528c44877da9b0250710cba321bc6dac2d",
"dest": "/tmp/secret_key",
"gid": 0,
"group": "root",
"md5sum": "270ac7da333dd1db7d5f7d8307bd6b41",
"mode": "0600",
"owner": "root",
"size": 18,
"src": "/home/sammy/.ansible/tmp/ansible-tmp-1480978964.81-196645606972905/source",
"state": "file",
"uid": 0
}
パスワードの入力を求めることは安全ですが、特に繰り返し実行する場合は面倒であり、自動化の妨げにもなります。 ありがたいことに、これらの状況にはいくつかの選択肢があります。
パスワードファイルでのAnsibleVaultの使用
タスクを実行するたびにVaultパスワードを入力したくない場合は、Vaultパスワードをファイルに追加して、実行中にファイルを参照できます。
たとえば、パスワードを .vault_pass
このようなファイル:
- echo 'my_vault_password' > .vault_pass
バージョン管理を使用している場合は、誤ってコミットしないように、バージョン管理ソフトウェアの無視ファイルにパスワードファイルを追加してください。
- echo '.vault_pass' >> .gitignore
これで、代わりにファイルを参照できます。 The --vault-password-file
フラグはコマンドラインで使用できます。 次のように入力することで、前のセクションと同じタスクを完了することができます。
- ansible --vault-password-file=.vault_pass -bK -m copy -a 'src=secret_key dest=/tmp/secret_key mode=0600 owner=root group=root' localhost
今回は、Vaultパスワードの入力を求められることはありません。
Outputlocalhost | SUCCESS => {
"changed": false,
"checksum": "52d7a243aea83e6b0e478db55a2554a8530358b0",
"dest": "/tmp/secret_key",
"gid": 80,
"group": "root",
"mode": "0600",
"owner": "root",
"path": "/tmp/secret_key",
"size": 8,
"state": "file",
"uid": 0
}
パスワードファイルの自動読み取り
フラグをまったく提供する必要がないように、次のように設定できます。 ANSIBLE_VAULT_PASSWORD_FILE
パスワードファイルへのパスを持つ環境変数:
- export ANSIBLE_VAULT_PASSWORD_FILE=./.vault_pass
これで、コマンドを実行しなくてもコマンドを実行できるようになります。 --vault-password-file
現在のセッションのフラグ:
- ansible -bK -m copy -a 'src=secret_key dest=/tmp/secret_key mode=0600 owner=root group=root' localhost
Ansibleにセッション間でのパスワードファイルの場所を認識させるために、 ansible.cfg
ファイル。
ローカルを開く ansible.cfg
以前に作成したファイル:
- nano ansible.cfg
の中に [defaults]
セクション、を設定します vault_password_file
設定。 パスワードファイルの場所をポイントします。 これは、どちらが最も役立つかに応じて、相対パスまたは絶対パスにすることができます。
[defaults]
. . .
vault_password_file = ./.vault_pass
これで、復号化が必要なコマンドを実行するときに、ボールトパスワードの入力を求められなくなりました。 ボーナスとして、 ansible-vault
ファイル内のパスワードを使用してファイルを復号化するだけでなく、で新しいファイルを作成するときにパスワードを適用します ansible-vault create
と ansible-vault encrypt
.
環境変数からのパスワードの読み取り
パスワードファイルを誤ってリポジトリにコミットすることを心配するかもしれません。 Ansibleにはパスワードファイルの場所を指す環境変数がありますが、パスワード自体を設定するための環境変数はありません。
ただし、パスワードファイルが実行可能である場合、Ansibleはそれをスクリプトとして実行し、結果の出力をパスワードとして使用します。 GitHubの問題で、 Brian Schwind は、次のスクリプトを使用して環境変数からパスワードを取得できることを示唆しています。
あなたの .vault_pass
エディター内のファイル:
- nano .vault_pass
内容を次のスクリプトに置き換えます。
#!/usr/bin/env python3
import os
print os.environ['VAULT_PASSWORD']
次のように入力して、ファイルを実行可能にします。
- chmod +x .vault_pass
その後、設定してエクスポートできます VAULT_PASSWORD
現在のセッションで使用できる環境変数:
export VAULT_PASSWORD=my_vault_password
これは、各Ansibleセッションの開始時に行う必要があり、不便に聞こえるかもしれません。 ただし、これにより、Vault暗号化パスワードを誤ってコミットすることを効果的に防ぐことができます。これは重大な欠点をもたらす可能性があります。
Vaultで暗号化された変数を通常の変数で使用する
Ansible Vaultは任意のファイルで使用できますが、機密性の高い変数を保護するために最も頻繁に使用されます。 例を使用して、通常の変数ファイルをセキュリティと使いやすさのバランスが取れた構成に変換する方法を示します。
例の設定
この例では、前提条件としてデータベースを実際にインストールする必要なしに、データベースサーバーを構成しているように見せかけます。
作成したとき hosts
以前にファイルを配置しました localhost
と呼ばれるグループのエントリ database
このステップの準備をします。 データベースには通常、機密性の高い変数と機密性の低い変数が混在している必要があります。 これらはで割り当てることができます group_vars
グループにちなんで名付けられたファイル内のディレクトリ:
- mkdir -p group_vars
- nano group_vars/database
内部 group_vars/database
ファイル、いくつかの典型的な変数を追加します。 MySQLポート番号などの一部の変数は秘密ではなく、自由に共有できます。 データベースパスワードなどの他の変数は機密扱いになります。
---
# nonsensitive data
mysql_port: 3306
mysql_host: 10.0.0.3
mysql_user: fred
# sensitive data
mysql_password: supersecretpassword
Ansibleを使用して、すべての変数がホストで利用可能であることをテストできます。 debug
モジュールと hostvars
変数:
- ansible -m debug -a 'var=hostvars[inventory_hostname]' database
Outputlocalhost | SUCCESS => {
"hostvars[inventory_hostname]": {
"ansible_check_mode": false,
"ansible_version": {
"full": "2.2.0.0",
"major": 2,
"minor": 2,
"revision": 0,
"string": "2.2.0.0"
},
"group_names": [
"database"
],
"groups": {
"all": [
"localhost"
],
"database": [
"localhost"
],
"ungrouped": []
},
"inventory_dir": "/home/sammy",
"inventory_file": "hosts",
"inventory_hostname": "localhost",
"inventory_hostname_short": "localhost",
"mysql_host": "10.0.0.3",
"mysql_password": "supersecretpassword",
"mysql_port": 3306,
"mysql_user": "fred",
"omit": "__omit_place_holder__1c934a5a224ca1d235ff05eb9bda22044a6fb400",
"playbook_dir": "."
}
}
出力は、設定したすべての変数がホストに適用されていることを確認します。 しかし、私たちの group_vars/database
ファイルは現在、すべての変数を保持しています。 これは、データベースのパスワード変数のためにセキュリティ上の懸念がある暗号化されないままにするか、すべての変数を暗号化することで、使いやすさとコラボレーションの問題を引き起こす可能性があることを意味します。
機密変数をAnsibleVaultに移動する
この問題を解決するには、機密変数と非機密変数を区別する必要があります。 機密値を暗号化すると同時に、機密性の低い変数を簡単に共有できる必要があります。 そのために、変数を2つのファイルに分割します。
複数のファイルから変数を適用するために、Ansible変数fileの代わりに変数directoryを使用することができます。 その機能を利用するために、構成をリファクタリングできます。 まず、既存のファイルの名前を database
に vars
. これは、暗号化されていない変数ファイルになります。
- mv group_vars/database group_vars/vars
次に、古い変数ファイルと同じ名前のディレクトリを作成します。 移動します vars
内部のファイル:
- mkdir group_vars/database
- mv group_vars/vars group_vars/database/
これで、 database
単一のファイルの代わりにグループを作成すると、暗号化されていない変数ファイルが1つあります。 機密変数を暗号化するので、暗号化されていないファイルからそれらを削除する必要があります。 編集します group_vars/database/vars
機密データを削除するファイル:
- nano group_vars/database/vars
この場合、削除したい mysql_password
変数。 ファイルは次のようになります。
---
# nonsensitive data
mysql_port: 3306
mysql_host: 10.0.0.3
mysql_user: fred
次に、暗号化されていないファイルと一緒に存在するディレクトリ内にボールト暗号化されたファイルを作成します vars
ファイル:
- ansible-vault create group_vars/database/vault
このファイルで、以前は vars
ファイル。 同じ変数名を使用しますが、文字列を先頭に追加します vault_
これらの変数がボールトで保護されたファイルで定義されていることを示すには、次のようにします。
---
vault_mysql_password: supersecretpassword
終了したら、ファイルを保存して閉じます。
結果のディレクトリ構造は次のようになります。
.
├── . . .
├── group_vars/
│ └── database/
│ ├── vars
│ └── vault
└── . . .
この時点で、変数は分離され、機密データのみが暗号化されます。 これは安全ですが、私たちの実装は私たちの使いやすさに影響を与えました。 私たちの目標は機密性の高い値を保護することでしたが、実際の変数名の可視性も意図せずに低下させました。 複数のファイルを参照せずにどの変数が割り当てられるかは明確ではありません。共同作業中に機密データへのアクセスを制限したい場合でも、変数名を共有したい場合があります。
これに対処するために、Ansibleプロジェクトは通常、わずかに異なるアプローチを推奨しています。
暗号化されていない変数からのVault変数の参照
機密データをボールトで保護されたファイルに移動するとき、変数名の前に vault_
(mysql_password
なりました vault_mysql_password
). 元の変数名を追加できます(mysql_password
)暗号化されていないファイルに戻ります。 これらを機密値に直接設定する代わりに、Jinja2テンプレートステートメントを使用して、暗号化されていない変数ファイル内から暗号化された変数名を参照できます。 このように、単一のファイルを参照することで定義されたすべての変数を確認できますが、機密値は暗号化されたファイルに残ります。
実例を示すために、暗号化されていない変数ファイルをもう一度開きます。
- nano group_vars/database/vars
追加します mysql_password
再び変数。 今回は、Jinja2テンプレートを使用して、ボールトで保護されたファイルで定義された変数を参照します。
---
# nonsensitive data
mysql_port: 3306
mysql_host: 10.0.0.3
mysql_user: fred
# sensitive data
mysql_password: "{{ vault_mysql_password }}"
The mysql_password
変数はの値に設定されます vault_mysql_password
ボールトファイルで定義されている変数。
この方法を使用すると、ホストに適用されるすべての変数を理解できます。 database
グループを表示して group_vars/database/vars
ファイル。 敏感な部分は、Jinja2のテンプレートによって隠されます。 The group_vars/database/vault
値自体を表示または変更する必要がある場合にのみ開く必要があります。
あなたはすべてが mysql_*
変数は、前回と同じ方法を使用して正しく適用されます。
注: Vaultのパスワードがパスワードファイルに自動的に適用されない場合は、 --ask-vault-pass
以下のコマンドにフラグを立てます。
- ansible -m debug -a 'var=hostvars[inventory_hostname]' database
Outputlocalhost | SUCCESS => {
"hostvars[inventory_hostname]": {
"ansible_check_mode": false,
"ansible_version": {
"full": "2.2.0.0",
"major": 2,
"minor": 2,
"revision": 0,
"string": "2.2.0.0"
},
"group_names": [
"database"
],
"groups": {
"all": [
"localhost"
],
"database": [
"localhost"
],
"ungrouped": []
},
"inventory_dir": "/home/sammy/vault",
"inventory_file": "./hosts",
"inventory_hostname": "localhost",
"inventory_hostname_short": "localhost",
"mysql_host": "10.0.0.3",
"mysql_password": "supersecretpassword",
"mysql_port": 3306,
"mysql_user": "fred",
"omit": "__omit_place_holder__6dd15dda7eddafe98b6226226c7298934f666fc8",
"playbook_dir": ".",
"vault_mysql_password": "supersecretpassword"
}
}
両方 vault_mysql_password
そしてその mysql_password
アクセス可能です。 この複製は無害であり、このシステムの使用に影響を与えることはありません。
結論
プロジェクトには、複雑なシステムを正常にインストールおよび構成するために必要なすべての情報が含まれている必要があります。 ただし、一部の構成データは定義上機密性が高く、公開すべきではありません。 このガイドでは、セキュリティを損なうことなくすべての構成データを1つの場所に保持できるように、AnsibleVaultが機密情報を暗号化する方法を示しました。