Ansible Vault로 콘텐츠 암호화하기
Ansible Vault로 콘텐츠 암호화하기 (Encrypting content with Ansible Vault)
vault 비밀번호를 관리·저장하는 전략을 세웠다면 이제 본격적으로 콘텐츠를 암호화할 차례예요. Ansible Vault는 **변수(variables)**와 파일(files) 두 종류의 콘텐츠를 암호화할 수 있어요.
암호화된 콘텐츠에는 항상 !vault 태그가 붙어요. 이 태그는 Ansible과 YAML에게 해당 콘텐츠를 복호화해야 한다는 것을 알려주고, | 문자는 여러 줄 문자열을 허용하게 해 줘요. --vault-id로 만든 암호화 콘텐츠에는 vault ID 라벨도 함께 포함돼요.
출처: 문서
본문
암호화된 변수와 암호화된 파일의 주요 차이를 다음 표로 정리할게요.
| 암호화된 변수 (Encrypted variables) | 암호화된 파일 (Encrypted files) | |
|---|---|---|
| 얼마나 암호화되나요? | 평문 파일 안의 변수 | 파일 전체 |
| 언제 복호화되나요? | 요청 시, 필요할 때만 | 로드되거나 참조될 때마다 [1] |
| 무엇을 암호화할 수 있나요? | 변수만 | 모든 구조화된 데이터 파일 |
[1] Ansible은 암호화된 파일에서 어떤 콘텐츠가 필요한지 파일을 복호화하기 전에는 알 수 없어요. 그래서 플레이북과 롤에서 참조되는 암호화된 파일은 전부 복호화해요.
Ansible Vault로 개별 변수 암호화하기
YAML 파일 안의 단일 값을 ansible-vault encrypt_string 명령으로 암호화할 수 있어요. vault 처리된 변수를 안전하게 보이게 유지하는 방법 하나는 "Keep vaulted variables safely visible"을 참고하세요.
변수 암호화의 장단점
변수 단위 암호화를 쓰면 파일이 여전히 쉽게 읽혀요. 플레이나 롤 안에서 인라인으로 평문 변수와 암호화 변수를 섞어 쓸 수 있죠. 하지만 비밀번호 교체(rotation)가 파일 단위 암호화만큼 간단하지 않아요. 암호화된 변수는 rekey할 수 없어요. 또한 변수 단위 암호화는 변수에만 동작해요. 작업(task)이나 다른 콘텐츠를 암호화하려면 파일 전체를 암호화해야 해요.
암호화된 변수 만들기
ansible-vault encrypt_string 명령은 여러분이 입력(또는 복사·생성)한 어떤 문자열이든 플레이북·롤·변수 파일에 넣을 수 있는 형식으로 암호화하고 포맷해 줘요. 기본 암호화 변수를 만들려면 encrypt_string 명령에 세 가지 옵션을 전달해요:
- vault 비밀번호의 소스 (vault ID 유무와 상관없이 prompt, file, script)
- 암호화할 문자열
- 문자열 이름 (변수의 이름)
패턴은 이렇게 생겼어요:
ansible-vault encrypt_string <password_source> '<string_to_encrypt>' --name '<string_name_of_variable>'
예를 들어 a_password_file에 저장된 유일한 비밀번호로 문자열 foobar를 암호화하고 변수 이름을 the_secret으로 지정하려면:
ansible-vault encrypt_string --vault-password-file a_password_file 'foobar' --name 'the_secret'
위 명령은 다음 콘텐츠를 만들어요:
the_secret: !vault |
$ANSIBLE_VAULT;1.1;AES256
62313365396662343061393464336163383764373764613633653634306231386433626436623361
6134333665353966363534333632666535333761666131620a663537646436643839616531643561
63396265333966386166373632626539326166353965363262633030333630313338646335303630
3438626666666137650a353638643435666633633964366338633066623234616432373231333331
6564
dev vault ID 라벨과 함께 a_password_file의 dev 비밀번호로 문자열 foooodev를 암호화하고, 암호화된 변수 이름을 the_dev_secret으로 지정하려면:
ansible-vault encrypt_string --vault-id dev@a_password_file 'foooodev' --name 'the_dev_secret'
위 명령은 다음 콘텐츠를 만들어요:
the_dev_secret: !vault |
$ANSIBLE_VAULT;1.2;AES256;dev
30613233633461343837653833666333643061636561303338373661313838333565653635353162
3263363434623733343538653462613064333634333464660a663633623939393439316636633863
61636237636537333938306331383339353265363239643939666639386530626330633337633833
6664656334373166630a363736393262666465663432613932613036303963343263623137386239
6330
stdin에서 읽은 문자열 letmein을 암호화하고, a_password_file의 dev 비밀번호로 vault ID dev를 추가한 뒤 변수 이름을 db_password로 지정하려면:
echo -n 'letmein' | ansible-vault encrypt_string --vault-id dev@a_password_file --stdin-name 'db_password'
경고: 프롬프트 없이 시크릿 콘텐츠를 커맨드 라인에 직접 입력하면 그 시크릿 문자열이 쉘 히스토리에 남아요. 테스트 환경 밖에서는 이렇게 하지 마세요.
위 명령은 다음 출력을 만들어요:
Reading plaintext input from stdin. (ctrl-d to end input, twice if your content does not already have a new line)
db_password: !vault |
$ANSIBLE_VAULT;1.2;AES256;dev
61323931353866666336306139373937316366366138656131323863373866376666353364373761
3539633234313836346435323766306164626134376564330a373530313635343535343133316133
36643666306434616266376434363239346433643238336464643566386135356334303736353136
6565633133366366360a326566323363363936613664616364623437336130623133343530333739
3039
암호화할 문자열을 프롬프트로 입력받으려면 a_password_file의 dev 비밀번호로 암호화하고, 변수 이름을 new_user_password로, vault ID 라벨을 dev로 지정하면 돼요:
ansible-vault encrypt_string --vault-id dev@a_password_file --stdin-name 'new_user_password'
위 명령은 다음 프롬프트를 띄워요:
Reading plaintext input from stdin. (ctrl-d to end input, twice if your content does not already have a new line)
암호화할 문자열(예: hunter2)을 입력하고 ctrl-d를 누르면 돼요.
경고: 문자열을 입력한 뒤 Enter를 누르지 마세요. 그러면 암호화된 값에 줄바꿈이 추가돼요.
위 과정은 다음 출력을 만들어요:
new_user_password: !vault |
$ANSIBLE_VAULT;1.2;AES256;dev
37636561366636643464376336303466613062633537323632306566653533383833366462366662
6565353063303065303831323539656138653863353230620a653638643639333133306331336365
62373737623337616130386137373461306535383538373162316263386165376131623631323434
3866363862363335620a376466656164383032633338306162326639643635663936623939666238
3161
위 예제들의 출력은 앞으로 재사용할 수 있게 어떤 플레이북·변수 파일·롤에든 추가할 수 있어요. 암호화된 변수는 평문 변수보다 크지만, 민감 콘텐츠를 보호하면서도 플레이북·변수 파일·롤의 나머지 부분은 평문으로 남겨 쉽게 읽을 수 있게 해 줘요.
암호화된 변수 보기
debug 모듈을 사용해 암호화된 변수의 원래 값을 볼 수 있어요. 변수를 암호화할 때 사용한 비밀번호를 반드시 전달해야 해요. 예를 들어 마지막 예제에서 만든 변수를 vars.yml이라는 파일에 저장했다면, 이렇게 복호화된 값을 볼 수 있어요:
ansible localhost -m ansible.builtin.debug -a var="new_user_password" -e "@vars.yml" --vault-id dev@a_password_file
localhost | SUCCESS => {
"new_user_password": "hunter2"
}
Ansible Vault로 파일 암호화하기
Ansible Vault는 Ansible이 사용하는 모든 구조화된 데이터 파일을 암호화할 수 있어요. 다음을 포함하죠:
- 인벤토리의 그룹 변수 파일
- 인벤토리의 호스트 변수 파일
-e @file.yml또는-e @file.json으로ansible-playbook에 전달하는 변수 파일include_vars나vars_files로 로드하는 변수 파일- 롤 안의 변수 파일
- 롤 안의 defaults 파일
- 작업(tasks) 파일
- 핸들러(handlers) 파일
- 바이너리 파일이나 그 외 임의의 파일
이 경우 파일 전체가 vault에 암호화돼요.
참고: Ansible Vault는 암호화된 파일을 만들거나 수정할 때 편집기를 사용해요. 편집기 보안에 대한 안내는 "Steps to secure your editor"를 참고하세요.
파일 암호화의 장단점
파일 단위 암호화는 사용하기 쉬워요. 암호화된 파일의 비밀번호 교체는 rekey 명령으로 간단하게 할 수 있어요. 파일 암호화는 민감한 값뿐 아니라 사용하는 변수의 이름까지 숨길 수 있어요. 하지만 파일 단위 암호화를 하면 파일의 내용을 쉽게 접근하고 읽을 수 없게 돼요. 특히 암호화된 작업 파일에서 문제가 될 수 있어요. 변수 파일을 암호화할 때는 "Keep vaulted variables safely visible"을 참고해 변수에 대한 참조를 암호화되지 않은 파일에 남겨 두는 방법을 쓸 수 있어요. Ansible은 로드되거나 참조될 때 암호화된 파일 전체를 항상 복호화해요. 왜냐하면 콘텐츠가 필요한지 알려면 복호화해야 하기 때문이에요.
암호화된 파일 만들기
multi_password_file의 test 비밀번호로 foo.yml이라는 새 암호화 데이터 파일을 만들려면:
ansible-vault create --vault-id test@multi_password_file foo.yml
도구는 편집기($EDITOR로 정의된 편집기, 기본은 vi)를 실행해요. 콘텐츠를 추가하고 편집기 세션을 닫으면 파일이 암호화된 데이터로 저장돼요. 파일 헤더는 만드는 데 사용한 vault ID를 반영해요:
$ANSIBLE_VAULT;1.2;AES256;test
vault ID my_new_password를 할당하고 비밀번호를 프롬프트로 입력받아 새 암호화 데이터 파일을 만들려면:
ansible-vault create --vault-id my_new_password@prompt foo.yml
역시 편집기에서 파일에 콘텐츠를 추가하고 저장해요. 나중에 그 파일을 복호화하고 싶을 때 찾을 수 있도록, 프롬프트에서 만든 새 비밀번호를 꼭 저장해 두세요.
기존 파일 암호화하기
기존 파일을 암호화하려면 ansible-vault encrypt 명령을 사용해요. 이 명령은 여러 파일을 한 번에 처리할 수 있어요. 예를 들어:
ansible-vault encrypt foo.yml bar.yml baz.yml
project ID로 기존 파일을 암호화하고 비밀번호를 프롬프트로 받으려면:
ansible-vault encrypt --vault-id project@prompt foo.yml bar.yml baz.yml
암호화된 파일 보기
편집하지 않고 암호화된 파일의 내용을 보려면 ansible-vault view 명령을 사용해요:
ansible-vault view foo.yml bar.yml baz.yml
암호화된 파일 편집하기
암호화된 파일을 제자리에서 편집하려면 ansible-vault edit 명령을 사용해요. 이 명령은 파일을 임시 파일로 복호화하고, 편집을 허용한 뒤, 내용을 저장·재암호화하고 편집기를 닫을 때 임시 파일을 제거해요. 예를 들어:
ansible-vault edit foo.yml
vault2 비밀번호 파일로 암호화되고 pass2 vault ID가 할당된 파일을 편집하려면:
ansible-vault edit --vault-id pass2@vault2 foo.yml
암호화된 파일의 비밀번호 및/또는 vault ID 변경하기
암호화된 파일의 비밀번호를 변경하려면 rekey 명령을 사용해요:
ansible-vault rekey foo.yml bar.yml baz.yml
이 명령은 여러 데이터 파일을 한 번에 rekey할 수 있고, 원래 비밀번호와 새 비밀번호를 묻습니다. rekey된 파일에 다른 ID를 설정하려면 새 ID를 --new-vault-id로 전달해요. 예를 들어 ppold 파일의 preprod1 vault ID로 암호화된 파일 목록을 preprod2 vault ID로 rekey하고 새 비밀번호를 프롬프트로 받으려면:
ansible-vault rekey --vault-id preprod1@ppold --new-vault-id preprod2@prompt foo.yml bar.yml baz.yml
암호화된 파일 복호화하기
더 이상 암호화 상태로 유지하고 싶지 않은 암호화 파일이 있다면, ansible-vault decrypt 명령으로 영구히 복호화할 수 있어요. 이 명령은 파일을 암호화되지 않은 상태로 디스크에 저장하므로, 편집을 원하는 것인지 먼저 확인하세요.
ansible-vault decrypt foo.yml bar.yml baz.yml
암호화된 문자열 복호화하기
암호화된 문자열의 내용을 확인하고 싶다면 stdin으로 전달해 볼 수도 있어요:
echo -e '$ANSIBLE_VAULT;1.1;V2\neyJrZX...MTVx\nSU1JVDlJZlRrSXBkVThmLXhKS00xZGl6X3F3YXZmWWUteGJWaHNZZXZNWl9hMWZvLVRYM3ZUZDRvaHRR\nWkhIdkJmZEZWNlBwVjhNVjJFT05QbDFwandaazAiLCAiY2lwaGVydGV4dCI6ICJnQUFBQUFCblRjOU9u\nWmM2dDh2VEN5c3NTQVlyV0hMclNEOFZfSGd2eEVHdERCdkJfakFpcUpaWWNTV19sR2hPY0VsWEVweS0z\nQ0NBcmJfdUdsUEt0NzJuSmFxVVVmRFIzdz09In0=' | ansible-vault decrypt
대안으로 다음 명령을 쓰면 encrypt_string을 쓸 때처럼 Ansible이 입력을 요구하게 할 수 있어요(입력을 끝내려면 Ctrl+D를 두 번):
ansible-vault decrypt
Reading ciphertext input from stdin
편집기 보안 확보하기 (Steps to secure your editor)
Ansible Vault는 설정된 편집기에 의존하는데, 이 편집기가 비밀 노출의 원인이 될 수 있어요. 대부분의 편집기는 데이터 손실을 방지하는 방법이 있지만, 보통 시크릿의 평문 복사본을 담을 수 있는 추가 평문 파일에 의존해요. 편집기 문서를 참고해 보안 데이터를 노출하지 않도록 설정하세요. 다음 섹션은 흔한 편집기에 대한 몇 가지 안내이며, 완전한 편집기 보안 가이드로 받아들이면 안 돼요.
vim
명령 모드에서 다음 vim 옵션을 설정해 노출 사례를 피할 수 있어요. 특히 플러그인을 쓸 때 보안을 위해 수정해야 할 설정이 더 있을 수 있으니 vim 문서를 참고하세요.
- 크래시나 중단 시 자동 저장처럼 동작하는 swapfile을 비활성화:
set noswapfile
- 백업 파일 생성 비활성화:
set nobackup
set nowritebackup
- viminfo 파일이 현재 세션에서 데이터를 복사하지 않도록 비활성화:
set viminfo=
- 시스템 클립보드로의 복사 비활성화:
set clipboard=
이 설정들은 .vimrc에 둬서 모든 파일에 적용하거나, 특정 경로·확장자에만 적용할 수도 있어요. 상세 내용은 vim 매뉴얼을 참고하세요.
Emacs
다음 Emacs 옵션을 설정해 노출 사례를 피할 수 있어요. 특히 플러그인을 쓸 때 보안을 위해 수정해야 할 설정이 더 있을 수 있으니 Emacs 문서를 참고하세요.
- 시스템 클립보드로 데이터를 복사하지 않기:
(setq x-select-enable-clipboard nil)
- 백업 파일 생성 비활성화:
(setq make-backup-files nil)
- 자동 저장 파일 비활성화:
(setq auto-save-default nil)
더 알아보기 (Learn more)
- 변수 단위 암호화는 파일을 평문으로 유지하면서 민감 값만 보호하고 싶을 때, 파일 단위 암호화는 변수 이름까지 숨겨야 할 때 유용해요.
rekey명령은 파일의 비밀번호·vault ID를 바꿀 때 써요. 암호화된 변수는 rekey할 수 없어요.- 편집기가 시크릿을 평문 파일로 남기지 않도록 설정해서 노출을 막으세요.