Ansible vault
변수 , 파일등을 암호화하여 비밀번호,키와 민감한 콘텐츠들을 보호 할 수 있다.
[개 요]
종 류 : 엔지니어링 / 프로그램 운영 기술
난이도 :
내용요약 : Ansible-vault 를 통한 이중 암호화
테스트 환경 : Rocky 8 제어노드 1대 , 관리노드 1대 / root ssh-copy-id 가 된 상태
관련직무 : 시스템&클라우드 엔지니어, 프로그래머
이번 글에서는 Ansible-vault 를 통한 이중 암호화 방법에 대해 작성해보겠습니다.
먼저 인벤토리에 작성할 ansible 통신을 할 유저명과 패스워드를 작성해야 하는데 , 작성하기전에 먼저 패스워드를 암호화 해줍니다.
패스워드를 암호화하는 방법은 다양합니다.
먼저 파일을 생성하여 파일의 내용을 작성 후에 암호화하는 방식과, 파일을 생성함과 동시에 암호화를 하는 방식이 있습니다.
파일 생성 후 Ansible-vault로 암호화 하기
# vi .password // 파일명은 상관없습니다.
12345
# ansible-vault encrypt .password // 실행 시 해당 파일의 암호를 입력하도록 합니다.
New Vault password:
Confirm New Vault password:
위에 생성한 파일의 암호는 추후 플레이북 실행 시 필요하니 꼭 기억해두시기 바랍니다.
# cat .password
암호화되어 표시됩니다.
Ansible-vault를 통해 파일을 생성함과 동시에 암호화를 하기
# ansible-vault create .password // 명령어 실행 시 파일을 생성할 때 파일의 암호를 입력하도록 합니다. New Vault password: Confirm New Vault password:
.password파일의 암호 생성
12345
# cat .password // 명령어 실행 시 암호화된 내용이 출력됩니다.
위 두가지 방식은 모두 동일하게 암호화되며, 암호화된 내용의 실제 패스워드를 확인하기 위해서는 ansible-vault decrypt 명령어를 통해 복호화를 진행할 수 있지만 , 복호화 진행 시 암호화 할 당시 파일의 암호를 입력해야지만 복호화가 가능합니다.
이제 위와같이 암호화된 내용을 인벤토리에 작성해줍니다.
# vi inventory.yaml
all: vars: ansible_user: root ansible_ssh_pass: !vault | $ANSIBLE_VAULT;1.1;AES256 35336635353363333665326139653132396463353865363332643161353262373935613161376465 6334383431396333383261613936333337313230623162300a633833656236376439336236636636 36623362353165633463303632663161656434643637626236303264336230616130323266333962 6164616165643734630a663465623863326139306561316664643466363363316564363730346665 3464 webservers: hosts: 10.101.0.4:
위 인벤토리에서는 ansible_user와 ansible_ssh_pass를 변수로 지정하여 모든 hosts에 대해 해당 정보로 적용하는 설정입니다.
위에서 .password 를 암호화하여 출력된 내용을 ansible_ssh_pass에 작성이 가능합니다.
암호화된 인벤토리와 함께 실행할 ping test 플레이북을 생성해줍니다.
# vi ping.yaml
--- - name: ping test hosts: webservers tasks: - name: connection test ping:
# ansible-playbook -i inventory.yaml ping.yaml [DEPRECATION WARNING]: Ansible will require Python 3.8 or newer on the controller starting with Ansible 2.12. Current version: 3.6.8 (default, Jan 10 2024, 18:22:50) [GCC 8.5.0 20210514 (Red Hat 8.5.0-20)]. This feature will be removed from ansible-core in version 2.12. Deprecation warnings can be disabled by setting deprecation_warnings=False in ansible.cfg. PLAY [ping test] ***************************************************************************************************************************************************************************************************************************** TASK [Gathering Facts] *********************************************************************************************************************************************************************************************************************** fatal: [10.101.0.40]: FAILED! => {"msg": "Attempting to decrypt but no vault secrets found"} PLAY RECAP *********************************************************************************************************************************************************************************************************************************** 10.101.0.40 : ok=0 changed=0 unreachable=0 failed=1 skipped=0 rescued=0 ignored=0
위와 같이 암호화된 패스워드가 포함된 인벤토리를 통해 ping 플레이북을 실행 시 암호화된 비밀번호를 복호화해주지 않아 실행이 실패됩니다.
vault를 통해 암호화를 한 경우 –ask-vault-pass 명령어를 추가하여 실행을 해줍니다.
# ansible-playbook --ask-vault-pass -i inventory.yaml ping.yaml [DEPRECATION WARNING]: Ansible will require Python 3.8 or newer on the controller starting with Ansible 2.12. Current version: 3.6.8 (default, Jan 10 2024, 18:22:50) [GCC 8.5.0 20210514 (Red Hat 8.5.0-20)]. This feature will be removed from ansible-core in version 2.12. Deprecation warnings can be disabled by setting deprecation_warnings=False in ansible.cfg. Vault password:
그러면 위와 같이 패스워드 입력을 하도록 대화창이 생기며 , 앞서 생성했던 패스워드인 12345를 입력해줍니다.
PLAY [ping test] ***************************************************************************************************************************************************************************************************************************** TASK [Gathering Facts] *********************************************************************************************************************************************************************************************************************** ok: [10.101.0.40] TASK [connection test] *********************************************************************************************************************************************************************************************************************** ok: [10.101.0.40] PLAY RECAP *********************************************************************************************************************************************************************************************************************************** 10.101.0.40 : ok=2 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
그러면 정상적으로 ok 가 떨어지는 점 확인됩니다.
vault-keyring-client 를 이용한 이중 암호화
지금까지는 단일 암호화를 진행해보았으며, 이중암호화를 위한 vault-id 를 포함해봅니다.
우선 vault-id 를 사용하기 위해서는 github 를 통해 python 기반의 vault-keyring-client 스크립트를 다운받은 후 필요한 모듈들을 설치해주어야 합니다.
curl -o vault-keyring-client https://raw.githubusercontent.com/ansible-community/contrib-scripts/main/vault/vault-keyring-client.py chmod 700 vault-keyring-client dnf install -y python3-pip ln -s /usr/bin/python3.6 /usr/bin/python ln -s /usr/bin/pip3.6 /usr/bin/pip pip install keyring pip install cryptography pip install --upgrade keyring pip install ansible pip install poetry pip install keyrings.alt python -m pip install --upgrade pip pip install --upgrade keyring // 위에 이미 --upgrade keyring 과 poetry 설치를 진행했으나, 한번 더 진행하지 않으면 오류가 나서 실행이 안되는데 아직까지는 정확한 이유는 확인하지 못했고 작성된 순서대로 설치를 진행하면 정상적으로 생성이 가능 pip install poetry
필요한 모듈이 설치가 다되어 준비가 되었으면 이제 vault-id 를 생성해줍니다. // *이중 암호화를 진행하기 위함이니 인벤토리의 암호와 다르게 설정하시는것을 권장드립니다.
# ./vault-keyring-client --set --vault-id test // --set 옵션을 통해 id 생성 및 패스워드 설정 Storing password in "root" user keyring using key name: test Password: Confirm password: # ./vault-keyring-client --vault-id test // 생성된 id의 패스워드 확인 1234
위에서는 ping 테스트를 진행했던 플레이북을 암호화하지 않은 상태로 인벤토리의 패스워드만 암호화 하였지만, 이제는 이중 암호화를 진행하기 위해 ping 플레이북도 암호화를 진행합니다.
이번에는 암호화 할때에도 vault-id 를 통해 암호화를 진행해봅니다.
# ansible-vault encrypt ping.yaml --vault-id test@vault-keyring-client // 위에서 생성한 test vault-id 를 통해 ping.yaml 플레이북 암호화 [DEPRECATION WARNING]: Ansible will require Python 3.8 or newer on the controller starting with Ansible 2.12. Current version: 3.6.8 (default, Jan 10 2024, 18:22:50) [GCC 8.5.0 20210514 (Red Hat 8.5.0-20)]. This feature will be removed from ansible-core in version 2.12. Deprecation warnings can be disabled by setting deprecation_warnings=False in ansible.cfg. Encryption successful
별다른 대화형식없이 바로 암호화에 성공하게 됩니다.
# cat ping.yaml
플레이북도 이렇게 암호화가 된것을 확인할 수 있습니다.
그러면 암호화된 인벤토리패스워드와 암호화된 ping 플레이북을 기존처럼 실행하게 되면 아래와 같은 결과가 출력됩니다.
# ansible-playbook --ask-vault-pass -i inventory.yaml ping.yaml [DEPRECATION WARNING]: Ansible will require Python 3.8 or newer on the controller starting with Ansible 2.12. Current version: 3.6.8 (default, Jan 10 2024, 18:22:50) [GCC 8.5.0 20210514 (Red Hat 8.5.0-20)]. This feature will be removed from ansible-core in version 2.12. Deprecation warnings can be disabled by setting deprecation_warnings=False in ansible.cfg. Vault password: ERROR! Decryption failed (no vault secrets were found that could decrypt) on /root/ping.yaml
왜냐하면 이러한 경우에는 –ask-vault-pass 를 통해 inventory.yaml 의 패스워드를 물어보면서 ansible_ssh_pass 의 패스워드를 입력했지만 암호화된 ping.yaml 의 패스워드 암호는 입력이 안되었기 때문에 위와같은 에러가 발생합니다.
이럴때는 마지막에 vault-id 명령어를 더 추가하여 실행을 해줍니다.
# ansible-playbook --ask-vault-pass -i inventory.yaml ping.yaml --vault-id test@vault-keyring-client [DEPRECATION WARNING]: Ansible will require Python 3.8 or newer on the controller starting with Ansible 2.12. Current version: 3.6.8 (default, Jan 10 2024, 18:22:50) [GCC 8.5.0 20210514 (Red Hat 8.5.0-20)]. This feature will be removed from ansible-core in version 2.12. Deprecation warnings can be disabled by setting deprecation_warnings=False in ansible.cfg. Vault password: PLAY [ping test] ***************************************************************************************************************************************************************************************************************************** TASK [Gathering Facts] *********************************************************************************************************************************************************************************************************************** [DEPRECATION WARNING]: Distribution centos 8.9 on host 10.101.0.4 should use /usr/libexec/platform-python, but is using /usr/bin/python for backward compatibility with prior Ansible releases. A future Ansible release will default to using the discovered platform python for this host. See https://docs.ansible.com/ansible-core/2.11/reference_appendices/interpreter_discovery.html for more information. This feature will be removed in version 2.12. Deprecation warnings can be disabled by setting deprecation_warnings=False in ansible.cfg. ok: [10.101.0.4] TASK [connection test] *********************************************************************************************************************************************************************************************************************** ok: [10.101.0.4] PLAY RECAP *********************************************************************************************************************************************************************************************************************************** 10.101.0.4 : ok=2 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
정상적으로 ping 체크가 되는것을 확인할 수 있습니다.
마무리하며,
ansible 이용 시 혹시모를 상황에 대비하여 가급적이면 단일패스워드보단 다중패스워드를 통해 보안에 신경쓰는것이 좋을것 같습니다.
참고 문서 : https://docs.ansible.com/ansible/latest/vault_guide/vault_managing_passwords.html