how-to-use-vault-to-protect-sensitive-ansible-data-on-ubuntu-16-04
前書き
Ansible Vaultは、ユーザーがAnsibleプロジェクト内の値とデータ構造を暗号化できる機能です。 これにより、Ansibleプレイを正常に実行するために必要な機密データを保護することができますが、パスワードや秘密キーなど、一般に公開されるべきではありません。 Ansibleは、キーが提供されると、実行時にボールト暗号化コンテンツを自動的に復号化します。
このガイドでは、Ansible Vaultの使用方法を示し、その使用を簡素化するためのいくつかの推奨プラクティスを検討します。 AnsibleコントロールマシンにはUbuntu 16.04サーバーを使用します。 リモートホストは必要ありません。
前提条件
これに従うには、 `+ sudo +`特権を持つ非rootユーザーのUbuntu 16.04サーバーが必要です。 Ubuntu 16.04初期サーバーセットアップガイドに従って、適切な権限を持つユーザーを作成できます。
サーバーに、Ansibleをインストールして構成する必要があります。 Ubuntu 16.04へのAnsibleのインストールのチュートリアルに従って、適切なものをインストールできます。パッケージ。
サーバーが上記の要件で構成されている場合は、このガイドを続けてください。
Ansible Vaultとは何ですか?
Vaultは、暗号化されたコンテンツを透過的にAnsibleワークフローに組み込むことができるメカニズムです。 「+ ansible-vault 」と呼ばれるユーティリティは、ディスク上で暗号化することで機密データを保護します。 これらのシークレットを通常のAnsibleデータと統合するために、アドホックタスクと構造化されたプレイブックをそれぞれ実行するための ` ansible `と ` ansible-playbook +`コマンドの両方が、実行時にボールト暗号化コンテンツの復号化をサポートします。
Vaultはファイルレベルの粒度で実装されています。つまり、ファイルは完全に暗号化されているか、暗号化されていません。 「+ AES256 +」アルゴリズムを使用して、ユーザーが指定したパスワードにキーイングされた対称暗号化を提供します。 これは、コンテンツの暗号化と復号化に同じパスワードが使用されることを意味し、使いやすさの観点から役立ちます。 Ansibleは、プレイブックまたはタスクの実行中に見つけたボールト暗号化されたファイルを識別および復号化できます。
https://github.com/ansible/ansible/issues/13243 [これを変更する提案があります]が、この記事の執筆時点では、ユーザーは単一のパスワードのみをAnsibleに渡すことができます。 つまり、関連する暗号化された各ファイルはパスワードを共有する必要があります。
Vaultについて少し理解したので、Ansibleが提供するツールと、既存のワークフローでVaultを使用する方法について説明します。
Ansible Vault Editorの設定
`+ ansible-vault `コマンドを使用する前に、好みのテキストエディターを指定することをお勧めします。 Vaultのコマンドには、エディターを開いて暗号化されたファイルの内容を操作するコマンドが含まれます。 Ansibleは、 ` EDITOR `環境変数を見て、好みのエディターを見つけます。 これが設定されていない場合、デフォルトで ` vi +`になります。
+ vi`エディターで編集したくない場合、環境で
+ EDITOR of`変数を設定する必要があります。
個々のコマンドにエディターを設定するには、次のようにコマンドに環境変数の割り当てを追加します。
EDITOR= ansible-vault
これを永続化するには、 `+〜/ .bashrc +`ファイルを開きます:
nano ~/.bashrc
ファイルの末尾に `+ EDITOR +`割り当てを追加して、好みのエディターを指定します。
〜/ .bashrc
export EDITOR=
完了したら、ファイルを保存して閉じます。
ファイルを再度ソースして、変更を現在のセッションに読み込みます。
. ~/.bashrc
`+ EDITOR +`変数を表示して、設定が適用されたことを確認します。
echo $EDITOR
Output
好みのエディターを確立したので、 `+ ansible-vault +`コマンドで利用可能な操作について議論できます。
ansible-vaultで機密ファイルを管理する方法
`+ ansible-vault +`コマンドは、Ansible内で暗号化されたコンテンツを管理するためのメインインターフェイスです。 このコマンドは、最初にファイルを暗号化するために使用され、その後データを表示、編集、または復号化するために使用されます。
新しい暗号化ファイルの作成
Vaultで暗号化された新しいファイルを作成するには、 `+ ansible-vault create `コマンドを使用します。 作成するファイルの名前を渡します。 たとえば、機密変数を保存するために ` vault.yml +`という名前の暗号化されたYAMLファイルを作成するには、次のように入力できます。
ansible-vault create
パスワードの入力と確認を求められます。
OutputNew Vault password:
Confirm New Vault password:
パスワードを確認すると、Ansibleはすぐに編集ウィンドウを開き、希望する内容を入力できます。
暗号化機能をテストするには、テストテキストを入力します。
vault.yml
Secret information
Ansibleは、ファイルを閉じるときにコンテンツを暗号化します。 ファイルをチェックすると、入力した単語が表示される代わりに、暗号化されたブロックが表示されます。
cat
Output$ANSIBLE_VAULT;1.1;AES256
65316332393532313030636134643235316439336133363531303838376235376635373430336333
3963353630373161356638376361646338353763363434360a363138376163666265336433633664
30336233323664306434626363643731626536643833336638356661396364313666366231616261
3764656365313263620a383666383233626665376364323062393462373266663066366536306163
31643731343666353761633563633634326139396230313734333034653238303166
Ansibleがファイルの処理方法を知るために使用するヘッダー情報と、それに続く数字で表示される暗号化されたコンテンツを見ることができます。
既存のファイルの暗号化
Vaultで暗号化するファイルが既にある場合は、代わりに `+ ansible-vault encrypt +`コマンドを使用します。
テストのために、次のように入力してサンプルファイルを作成できます。
echo 'unencrypted stuff' >
これで、次のように入力して既存のファイルを暗号化できます。
ansible-vault encrypt
繰り返しますが、パスワードの入力と確認を求められます。 その後、暗号化を確認するメッセージが表示されます。
OutputNew Vault password:
Confirm New Vault password:
Encryption successful
編集ウィンドウを開く代わりに、 `+ ansible-vault +`はファイルの内容を暗号化し、ディスクに書き戻し、暗号化されていないバージョンを置き換えます。
ファイルをチェックすると、同様の暗号化されたパターンが表示されるはずです。
cat
Output$ANSIBLE_VAULT;1.1;AES256
66633936653834616130346436353865303665396430383430353366616263323161393639393136
3737316539353434666438373035653132383434303338640a396635313062386464306132313834
34313336313338623537333332356231386438666565616537616538653465333431306638643961
3636663633363562320a613661313966376361396336383864656632376134353039663662666437
39393639343966363565636161316339643033393132626639303332373339376664
ご覧のとおり、Ansibleは新しいファイルを暗号化するのとほぼ同じ方法で既存のコンテンツを暗号化します。
暗号化されたファイルの表示
場合によっては、vaultで暗号化されたファイルの内容を、編集したり暗号化されていないファイルシステムに書き込んだりせずに参照する必要がある場合があります。 `+ ansible-vault view +`コマンドは、ファイルの内容を標準出力に送ります。 デフォルトでは、これはコンテンツが端末に表示されることを意味します。
ボールト暗号化ファイルをコマンドに渡します。
ansible-vault view
ファイルのパスワードを求められます。 正常に入力すると、内容が表示されます:
OutputVault password:
Secret information
ご覧のとおり、パスワードプロンプトはファイルの内容の出力に混在しています。 自動化されたプロセスで「+ ansible-vault view +」を使用する場合は、このことに留意してください。
暗号化されたファイルの編集
暗号化されたファイルを編集する必要がある場合、 `+ ansible-vault edit +`コマンドを使用します:
ansible-vault edit
ファイルのパスワードの入力を求められます。 入力後、Ansibleはファイルを編集ウィンドウで開き、必要な変更を加えることができます。
保存すると、新しいコンテンツはファイルの暗号化パスワードを使用して再度暗号化され、ディスクに書き込まれます。
暗号化されたファイルを手動で復号化する
ボールト暗号化ファイルを復号化するには、 `+ ansible-vault decrypt +`コマンドを使用します。
暗号化されたファイルの名前を渡します。
ansible-vault decrypt
ファイルの暗号化パスワードの入力を求められます。 正しいパスワードを入力すると、ファイルが復号化されます。
OutputVault password:
Decryption successful
ボールト暗号化の代わりにファイルを再度表示すると、ファイルの実際の内容が表示されます。
cat
OutputSecret information
ファイルはディスク上で暗号化されなくなりました。 終了したら、必ず機密情報を削除するか、ファイルを再暗号化します。
暗号化されたファイルのパスワードを変更する
暗号化されたファイルのパスワードを変更する必要がある場合は、 `+ ansible-vault rekey +`コマンドを使用します:
ansible-vault rekey
コマンドを入力すると、最初にファイルの現在のパスワードの入力を求められます。
OutputVault password:
入力後、新しいボールトパスワードを選択して確認するように求められます。
OutputVault password:
新しいパスワードを正常に確認すると、再暗号化プロセスの成功を示すメッセージが表示されます。
OutputRekey successful
これで、新しいパスワードを使用してファイルにアクセスできるようになります。 古いパスワードは機能しなくなります。
Vaultで暗号化されたファイルでAnsibleを実行する
Vaultで機密情報を暗号化したら、Ansibleの従来のツールでファイルの使用を開始できます。 `+ ansible `コマンドと ` ansible-playbook +`コマンドはどちらも、正しいパスワードを指定してボールト保護されたファイルを復号化する方法を知っています。 これらのコマンドにパスワードを提供するには、ニーズに応じていくつかの異なる方法があります。
これに従うには、ボールトで暗号化されたファイルが必要です。 次のように入力して作成できます。
ansible-vault create secret_key
パスワードを選択して確認します。 必要なダミーコンテンツを入力します。
secret_key
ファイルを保存して閉じます。
一時的な `+ hosts +`ファイルをインベントリとして作成することもできます:
nano hosts
Ansible localhostのみを追加します。 後のステップの準備として、それを `+ [database] +`グループに配置します:
ホスト
[database]
localhost ansible_connection=local
完了したら、ファイルを保存して閉じます。
次に、現在のディレクトリに `+ ansible.cfg +`ファイルが存在しない場合は作成します:
nano ansible.cfg
今のところ、 `+ [defaults] +`セクションを追加して、作成したインベントリにAnsibleをポイントするだけです。
ansible.cfg
[defaults]
inventory = ./hosts
準備ができたら、続けてください。
対話型プロンプトを使用する
実行時にコンテンツを復号化する最も簡単な方法は、Ansibleに適切な資格情報の入力を求めることです。 これを行うには、「-ask-vault-pass +」を「 ansible 」または「 ansible-playbook +」コマンドに追加します。 Ansibleは、パスワードを入力するよう要求します。パスワードは、検出されたボールト保護されたコンテンツを復号化するために使用されます。
たとえば、vaultで暗号化されたファイルの内容をホストにコピーする必要がある場合、 `+ copy `モジュールと `-ask-vault-pass +`フラグを使用してコピーできます。 ファイルに実際に機密データが含まれている場合、ほとんどの場合、許可と所有権の制限があるリモートホストへのアクセスをロックダウンします。
ansible -bK -m copy -a 'src= dest=/tmp/ mode=0600 owner=root group=root'
このタスクでは、ファイルの所有権を「+ root 」に変更する必要があるため、管理者権限が必要です。 ` -bK `フラグは、ターゲットホストの ` sudo `パスワードの入力を求めるようAnsibleに指示するため、 ` sudo +`パスワードの入力を求められます。 その後、Vaultパスワードの入力を求められます。
OutputSUDO 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
}
パスワードの入力は安全ですが、特に繰り返し実行する場合は面倒であり、自動化の妨げにもなります。 ありがたいことに、これらの状況にはいくつかの選択肢があります。
パスワードファイルでのAnsible Vaultの使用
タスクを実行するたびにVaultパスワードを入力したくない場合は、Vaultパスワードをファイルに追加して、実行中にファイルを参照できます。
たとえば、次のようにパスワードを `+ .vault_pass +`ファイルに入れることができます。
echo '' > .vault_pass
バージョン管理を使用している場合は、バージョン管理ソフトウェアの無視ファイルにパスワードファイルを追加して、誤ってコミットしないようにしてください。
echo '.vault_pass' >> .gitignore
これで、代わりにファイルを参照できます。 `+-vault-password-file`フラグはコマンドラインで利用可能です。 次のように入力して、前のセクションから同じタスクを完了できます。
ansible -bK -m copy -a 'src= dest=/tmp/ mode=0600 owner=root group=root'
今回はVaultパスワードの入力を求められません。
パスワードファイルを自動的に読み取る
フラグをまったく指定しなくても済むように、パスワードファイルへのパスを使用して `+ ANSIBLE_VAULT_PASSWORD_FILE`環境変数を設定できます。
export ANSIBLE_VAULT_PASSWORD_FILE=./.vault_pass
これで、現在のセッションで `+-vault-password-file`フラグなしでコマンドを実行できるはずです。
ansible -bK -m copy -a 'src= dest=/tmp/ mode=0600 owner=root group=root'
セッション間でパスワードファイルの場所をAnsibleに認識させるには、 `+ ansible.cfg +`ファイルを編集できます。
前に作成したローカルの `+ ansible.cfg +`ファイルを開きます。
nano ansible.cfg
`+ [defaults] `セクションで、 ` vault_password_file +`設定を設定します。 パスワードファイルの場所をポイントします。 これは、どちらが最も役立つかによって、相対パスまたは絶対パスになります。
ansible.cfg
[defaults]
. . .
vault_password_file = ./.vault_pass
これで、復号化を必要とするコマンドを実行するときに、ボールトパスワードの入力を求められなくなりました。 おまけとして、 `+ ansible-vault `はファイル内のパスワードを使用してファイルを復号化するだけでなく、 ` ansible-vault create `および ` ansible-vault encrypt +`で新しいファイルを作成するときにパスワードを適用します。
環境変数からパスワードを読み取る
パスワードファイルを誤ってリポジトリにコミットしてしまうことが心配になる場合があります。 残念ながら、Ansibleにはパスワードファイルの場所を指す環境変数がありますが、パスワード自体を設定するための環境変数はありません。
ただし、パスワードファイルが実行可能な場合、Ansibleはそれをスクリプトとして実行し、結果の出力をパスワードとして使用します。 GitHub issue、https://github.com/bschwind [Brian Schwind]では、次のスクリプトを使用してパスワードを取得できることが示唆されています環境変数から。
エディターで `+ .vault_pass +`ファイルを開きます:
nano .vault_pass
内容を次のスクリプトに置き換えます。
#!/usr/bin/env python
import os
print os.environ['VAULT_PASSWORD']
次のように入力して、ファイルを実行可能にします。
chmod +x .vault_pass
次に、現在のセッションで使用できる環境変数 `+ VAULT_PASSWORD +`を設定してエクスポートできます。
export VAULT_PASSWORD=
各Ansibleセッションの開始時にこれを行う必要がありますが、これは不便に聞こえるかもしれません。 ただし、これにより、Vault暗号化パスワードを誤ってコミットすることを防ぐことができ、重大な欠点が生じる可能性があります。
Vaultで暗号化された変数と通常の変数の使用
Ansible Vaultは任意のファイルで使用できますが、機密変数を保護するために最も頻繁に使用されます。 例を通して、通常の変数ファイルを、セキュリティと使いやすさのバランスをとる構成に変換する方法を示します。
サンプルのセットアップ
データベースサーバーを構成しているふりをします。 先に `+ hosts `ファイルを作成したとき、このステップの準備として ` database `というグループに ` localhost +`エントリを配置しました。
データベースには通常、機密変数と非機密変数の混合が必要です。 これらは、グループにちなんで名付けられたファイルの `+ group_vars +`ディレクトリで割り当てることができます:
mkdir -p group_vars
nano group_vars/database
`+ group_vars / database +`ファイル内で、いくつかの変数を設定します。 MySQLポート番号などの一部の変数は秘密ではなく、自由に共有できます。 データベースパスワードなどの他の変数は機密情報です。
group_vars / database
---
# nonsensitive data
mysql_port: 3306
mysql_host: 10.0.0.3
mysql_user: fred
# sensitive data
mysql_password:
Ansibleの + debug`モジュールと
+ hostvars`変数を使用して、すべての変数がホストで使用できることをテストできます。
ansible -m debug -a 'var=hostvars[inventory_hostname]'
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",
"omit": "__omit_place_holder__1c934a5a224ca1d235ff05eb9bda22044a6fb400",
"playbook_dir": "."
}
}
出力により、設定したすべての変数がホストに適用されていることが確認されます。 ただし、現在、 `+ group_vars / database +`ファイルにはすべての変数が保持されています。 これは、データベースパスワード変数のためにセキュリティ上の懸念事項である暗号化されていないままにするか、すべての変数を暗号化してユーザビリティとコラボレーションの問題を引き起こすことを意味します。
機密変数をAnsible Vaultに移動する
この問題を解決するには、機密変数と非機密変数を区別する必要があります。 機密値を暗号化すると同時に、機密でない変数を簡単に共有できる必要があります。 そのためには、変数を2つのファイルに分割します。
Ansible変数fileの代わりに変数ディレクトリを使用して、複数のファイルから変数を適用することができます。 その能力を活用するためにリファクタリングできます。 まず、既存のファイルの名前を「+ database in」から「+ var」に変更します。 これは暗号化されていない変数ファイルになります。
mv group_vars/database group_vars/vars
次に、古い変数ファイルと同じ名前のディレクトリを作成します。 `+ vars +`ファイルを内部に移動します:
mkdir group_vars/database
mv group_vars/vars group_vars/database/
単一のファイルではなく、 `+ database in`グループの変数ディレクトリがあり、暗号化されていない変数ファイルが1つあります。 機密変数を暗号化するため、暗号化されていないファイルからそれらを削除する必要があります。 `+ group_vars / database / vars +`ファイルを編集して、機密データを削除します。
nano group_vars/database/vars
この場合、 `+ mysql_password +`変数を削除します。 ファイルは次のようになります。
group_vars / database / vars
---
# nonsensitive data
mysql_port: 3306
mysql_host: 10.0.0.3
mysql_user: fred
次に、ディレクトリ内に、暗号化されていない `+ vars +`ファイルと共存するボールト暗号化ファイルを作成します。
ansible-vault create group_vars/database/vault
このファイルでは、かつて `+ vars `ファイルにあった機密変数を定義します。 同じ変数名を使用しますが、文字列 ` vault_ +`を追加して、これらの変数がボールト保護ファイルで定義されていることを示します。
group_vars / database / vault
---
mysql_password:
完了したら、ファイルを保存して閉じます。
結果のディレクトリ構造は次のようになります。
.
├── . . .
├── group_vars/
│ └── database/
│ ├── vars
│ └── vault
└── . . .
この時点で、変数は分離され、機密データのみが暗号化されます。 これは安全ですが、実装がユーザビリティに影響を与えています。 私たちの目標は機密の_values_を保護することでしたが、実際の変数名の可視性を意図せずに低下させました。 複数のファイルを参照せずにどの変数が割り当てられるかは明確ではありません。共同作業中に機密データへのアクセスを制限したい場合でも、おそらく変数名を共有したいでしょう。
これに対処するために、Ansibleプロジェクトでは通常、わずかに異なるアプローチを推奨しています。
暗号化されていない変数からVault変数を参照する
機密データをvaultで保護されたファイルに移動したとき、変数名の前に + vault_ +`を付けました( `+ mysql_password +`は `+ vault_mysql_password +`になりました)。 元の変数名( `+ mysql_password +
)を暗号化されていないファイルに追加できます。 これらを機密値に直接設定する代わりに、Jinja2テンプレートステートメントを使用して、暗号化されていない変数ファイル内から暗号化された変数名を参照できます。 この方法では、単一のファイルを参照することで定義済みの変数をすべて表示できますが、機密値は暗号化されたファイルに残ります。
実証するために、暗号化されていない変数ファイルを再度開きます。
nano group_vars/database/vars
`+ mysql_password +`変数を再度追加します。 今回は、Jinja2テンプレートを使用して、vaultで保護されたファイルで定義された変数を参照します。
group_vars / database / vars
---
# nonsensitive data
mysql_port: 3306
mysql_host: 10.0.0.3
mysql_user: fred
# sensitive data
mysql_password:
`+ mysql_password `変数は、vaultファイルで定義されている ` vault_mysql_password +`変数の値に設定されます。
この方法では、 `+ group_vars / database / vars `ファイルを表示することで、 ` database `グループのホストに適用されるすべての変数を理解できます。 敏感な部分は、Jinja2のテンプレートによって隠されます。 ` group_vars / database / vault +`は、値自体を表示または変更する必要がある場合にのみ開く必要があります。
前回と同じ方法を使用して、すべての `+ mysql _ * +`変数がまだ正しく適用されていることを確認できます。
ansible -m debug -a 'var=hostvars[inventory_hostname]'
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",
"omit": "__omit_place_holder__6dd15dda7eddafe98b6226226c7298934f666fc8",
"playbook_dir": ".",
}
}
`+ vault_mysql_password `と ` mysql_password +`の両方にアクセスできます。 この複製は無害であり、このシステムの使用には影響しません。
結論
プロジェクトには、複雑なシステムを正常にインストールおよび構成するために必要なすべての情報が含まれている必要があります。 ただし、一部の構成データは定義上機密であり、一般に公開されるべきではありません。 このガイドでは、Ansible Vaultが機密情報を暗号化して、セキュリティを損なうことなくすべての設定データを1か所に保持できるようにする方法を示しました。