Ansible - パスワード隠蔽化

前回の記事「Ansible - 自動化の手始め」で簡単なAnsible Playbookを作成しましたが、インベントリファイルにSSH接続パスワード、sudoパスワードを平文で書いていました。
パスワードを平文で記載しているのは、セキュリティ的によろしくないので隠蔽化します。
また、Ansibleが操作対象サーバに接続する際に、パスワードではなくSSH公開鍵認証で接続できるように変更します。

sudoパスワードの暗号化

ではまず、sudoパスワードの方を暗号化します。前回作成したインベントリの「ansible_become_password」の値です。

[user01@ansible-ctl01 ~]$ cat ansible/hosts.ini
ansible-client01 ansible_host=10.0.220.10 ansible_user=user01 ansible_password=userpass ansible_become_password=userpass

変数を記載したファイルを用意

暗号化したいパスワードを記載したファイルを用意します。Ansible関連のファイルをまとめておいてあるディレクトリとは別の場所、ホームディレクトリ等に作成します。

[user01@ansible-ctl01 ~]$ cat ansible/vault.yml
ansible_become_password: userpass

Vaultを使用して暗号化

Ansibleのコマンドを使用して暗号化します。暗号化用のパスワードを入力する必要があります。

[user01@ansible-ctl01 ~]$ ansible-vault encrypt ansible/vault.yml
New Vault password:
Confirm New Vault password:
Encryption successful

コマンドを実行すると、先ほど作成したファイルが暗号化されます。

[user01@ansible-ctl01 ~]$ cat ansible/vault.yml
$ANSIBLE_VAULT;1.1;AES256
35313337643462663066343463613930667256693863313561356537396566636262343736393364
3766356366326361386631383835623762336138363738370a636433335363316138353933636165
35616636383663623163396435616336623333346266626335306666333163353139623034626366
6630393562356335380a306635613730343165366534336333663665666133623213661936316631
32633165333064363764616537663437363263623965623637326366623237363438633837353936
623264376438353229716235366133353530323063303835343

インベントリファイル修正

インベントリファイルからsudoパスワード部分を削除しておきます。

[user01@ansible-ctl01 ~]$ cat ansible/hosts.ini
ansible-client01 ansible_host=10.0.220.10 ansible_user=user01 ansible_password=userpass

パスワードファイル読み込み設定

前回作成したPlaybookに暗号化したパスワードファイルを読み込む設定を追加します。「vars_files:」で読み込む変数ファイルを指定します。vars_filesのパスは、Playbookファイルからの相対パス、または絶対パスで記述します。

[user01@ansible-ctl01 ~]$ cat ansible/chrony_setting.yml
---
- name: Configure NTP servers in chrony.conf
  hosts: all
  become: true

  vars_files:
    - vault.yml

~ 省略 ~

実行

実行してみます。ansible-playbookコマンドに「--ask-vault-pass」オプションをつけて、暗号化したファイルのパスワードを標準入力から入力するようにします。

[user01@ansible-ctl01 ~]$ ansible-playbook -i ansible/hosts.ini ansible/chrony_setting.yml --ask-vault-pass
Vault password:

PLAY [Configure NTP servers in chrony.conf] *******************************************************************************

TASK [Gathering Facts] ****************************************************************************************************
ok: [ansible-client01]

TASK [Replace chrony.conf] ************************************************************************************************
ok: [ansible-client01]

PLAY RECAP ****************************************************************************************************************
ansible-client01           : ok=2    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0

正常に実行されました。暗号化したファイルの内容やファイルパスが間違っている場合はエラーメッセージが表示されて実行されません。

パスワード入力を行わない方式

上記のansible-playbookコマンドでは、「--ask-vault-pass」オプションをつけていることにより、パスワード入力待ちになっています。処理を自動化する上で、ユーザの入力待ちがあるのはよろしくありません。そこでパスワード入力待ちを行わず、処理が進むように変更します。

暗号化ファイルのパスワードを記載したファイルを作成し、ansible-playbookにオプションで渡します。

[user01@ansible-ctl01 ~]$ cat ~/.vault_pass.txt
vaultpass

[user01@ansible-ctl01 ~]$ chmod 600 ~/.vault_pass.txt

[user01@ansible-ctl01 ~]$ ansible-playbook -i ansible/hosts.ini ansible/chrony_setting.yml --vault-password-file=~/.vault_pass.txt

PLAY [Configure NTP servers in chrony.conf] *******************************************************************************

TASK [Gathering Facts] ****************************************************************************************************
ok: [ansible-client01]

TASK [Replace chrony.conf] ************************************************************************************************
ok: [ansible-client01]

PLAY RECAP ****************************************************************************************************************
ansible-client01           : ok=2    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0

これで、パスワードを平文で記載せず、入力待ちにならずにPlaybookを実行可能になりました。
平文ファイルを暗号化して、ファイル暗号化ファイルのパスワードを平文で保存しているので、暗号化の意味は半減していますが、
Ansibleの使用方法としてよくある、Gitや共有ディスクにAnsibe関連ファイルを置いて共同管理する場合には、共有領域に平文パスワードを置かないというメリットがあります。

SSHログイン公開鍵認証化

続いて、SSHログインをパスワードから公開鍵認証に変更します。
「ansible_password=userpass」の部分を記載せずに、対象サーバへSSH接続できるようにします。

[user01@ansible-ctl01 ~]$ cat ansible/hosts.ini
ansible-client01 ansible_host=10.0.220.10 ansible_user=user01 ansible_password=userpass

SSH秘密鍵・公開鍵の作成

SSH公開鍵・秘密鍵は通常のSSHログインで使用するものと作成方法は同じです。パスフレーズは未設定で作成します。
作成した鍵ファイルはパーミッションを変更しておきます。

[user01@ansible-ctl01 ~]$ ssh-keygen -t ed25519 -f ~/.ssh/ansible_ssh_key
Generating public/private ed25519 key pair.
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in /home/user01/.ssh/ansible_ssh_key
Your public key has been saved in /home/user01/.ssh/ansible_ssh_key.pub
The key fingerprint is:
SHA256:9o5VhYoXUo8pi/RGTNS7Tbd49bd3mKdaX5cvUTzZzyc user01@ansible-ctl01
The key's randomart image is:
+--[ED25519 256]--+
|        .+..     |
|        o..      |
|       .  . . .  |
|        . .+ o . |
|       oS.S++   o|
|      ..=.++.  o+|
|     . + .+o ++o*|
|      . +=. *.E=B|
|       o+o. .+.+*|
+----[SHA256]-----+

[user01@ansible-ctl01 ~]$ chmod 600 ~/.ssh/ansible_ssh_key*
[user01@ansible-ctl01 ~]$ ll ~/.ssh/ansible_ssh_key*
-rw-------. 1 user01 user01 411  9月  2 15:05 /home/user01/.ssh/ansible_ssh_key
-rw-------. 1 user01 user01 102  9月  2 15:05 /home/user01/.ssh/ansible_ssh_key.pub

対象サーバへ公開鍵を登録

公開鍵の中身を対象サーバの~/.ssh/authorized_keysに追記します。

[user01@ansible-ctl01 ~]$ ssh-copy-id -i ~/.ssh/ansible_ssh_key.pub user01@10.0.220.10
/usr/bin/ssh-copy-id: INFO: Source of key(s) to be installed: "/home/user01/.ssh/ansible_ssh_key.pub"
/usr/bin/ssh-copy-id: INFO: attempting to log in with the new key(s), to filter out any that are already installed
/usr/bin/ssh-copy-id: INFO: 1 key(s) remain to be installed -- if you are prompted now it is to install the new keys
user01@10.0.220.10's password:

Number of key(s) added: 1

Now try logging into the machine, with:   "ssh 'user01@10.0.220.10'"
and check to make sure that only the key(s) you wanted were added.

対象サーバ側で公開鍵が登録されたことを確認します。

[user01@ansible-client01 ~]$ cat .ssh/authorized_keys
ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIBRFaZfnVG/JWjGlLD2UaO0pRctsl6s6CN2abDfS9ZBA user01@ansible-ctl01

インベントリファイル修正

インベントリファイルからSSH接続パスワード部分を削除し、SSH秘密鍵ファイルへのパスを指定します。

[user01@ansible-ctl01 ~]$ cat ansible/hosts.ini
ansible-client01 ansible_host=10.0.220.10 ansible_user=user01 ansible_ssh_private_key_file=~/.ssh/ansible_ssh_key

実行

実行してみます。実行コマンドは先のコマンドと同じです。

[user01@ansible-ctl01 ~]$ ansible-playbook -i ansible/hosts.ini ansible/chrony_setting.yml --vault-password-file=~/.vault_pass.txt

PLAY [Configure NTP servers in chrony.conf] *******************************************************************************

TASK [Gathering Facts] ****************************************************************************************************
ok: [ansible-client01]

TASK [Replace chrony.conf] ************************************************************************************************
ok: [ansible-client01]

PLAY RECAP ****************************************************************************************************************
ansible-client01           : ok=2    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0

正常に実行されました。

まとめ

これで、パスワードを平文で書かなくてもansible-playbookを実行できるようになりました。公開鍵を対象サーバに配布するPlaybookを作っておくと、対象サーバが追加された時や、鍵ファイルの変更があった場合に作業が楽になります。

参考

お問い合わせ

弊社では様々なサービスを取り扱っております。
詳細はサービス一覧からご覧ください。

お気軽にお問い合わせください。応対時間 9:30-17:30 [ 土・日・祝日除く ]

お問い合わせ