LabHub
배우기 러닝패스 코스

Ansible実戦

ansible-vault — リポジトリに入れてよいシークレット

LabHub 에서 이어서 보기

한국어 원문으로 표시합니다.

한 줄 요약

Vault 는 시크릿을 저장소 밖으로 빼는 도구가 아니라, 저장소 안에 암호문으로 두고 실행 시점에만 푸는 도구다.

概念マップ: 밖으로・안에 암호문으로・시크릿이 새었을 때 몇 분 안에 그 키를 폐기하고 교체할 수 있는가?・어디에 몇 개가 있는지 셀 수 있고

왜 이게 필요했나

.env.gitignore 에 넣었다고 안전해지지 않는다. 환경변수는 같은 호스트에서 /proc/PID/environ 으로 그대로 읽히고, 크래시 리포트와 CI 로그와 컨테이너 이미지 레이어에 실려 나간다. 그리고 더 중요한 질문이 남는다 — 시크릿이 새었을 때 몇 분 안에 그 키를 폐기하고 교체할 수 있는가? 대부분의 팀에서 답은 "모른다"이다. 어디에 몇 벌이 복사돼 있는지 모르기 때문이다.

Vault 는 이 문제의 절반을 푼다. 시크릿이 코드와 같은 저장소에 있으므로 어디에 몇 개가 있는지 셀 수 있고, 리뷰를 거치며, 히스토리가 남는다. 나머지 절반(자동 로테이션, 짧은 수명 자격증명)은 외부 시크릿 매니저의 영역이다.

어떻게 동작하나

Vault 는 AES256 대칭키 암호화다. 열쇠는 비밀번호 하나이고, 그 비밀번호는 파일이나 프롬프트로 전달한다.

명령 하는 일
ansible-vault create 새 암호화 파일 생성
ansible-vault encrypt 기존 평문 파일을 암호화
ansible-vault view 복호화해서 보여 주기만
ansible-vault edit 복호화 → 편집 → 재암호화
ansible-vault rekey 새 비밀번호로 다시 암호화
ansible-vault encrypt_string 값 하나만 암호화해 YAML 에 인라인으로

암호화된 파일의 첫 줄은 $ANSIBLE_VAULT;1.1;AES256 형태의 헤더다. 이 줄이 없으면 그 파일은 평문이다. 감사할 때 가장 먼저 보는 것이 이 헤더다.

encrypt_string 은 파일 전체가 아니라 값 하나만 암호화한다. 그러면 변수 파일의 나머지는 평문이라 diff 를 읽을 수 있고, 시크릿만 암호문으로 남는다. 실무에서는 이쪽이 더 자주 쓰인다.

--vault-id 는 여러 키를 라벨로 구분한다. prod@파일 처럼 쓰면 헤더에 라벨이 박히므로, 운영 키와 개발 키를 섞어 쓰다 사고 나는 것을 막는다.

시크릿을 다루는 태스크에는 반드시 no_log: true 를 붙인다. 그러지 않으면 애써 암호화한 값이 실행 로그에 평문으로 찍힌다. 로그 수집 시스템은 대개 애플리케이션보다 접근 권한이 넓다.

현장에서 만나는 모습

첫째, 비밀번호 파일의 위치. .vault_pass 를 저장소 안에 두면 자물쇠 옆에 열쇠를 붙여 놓은 것과 같다. 반드시 .gitignore 에 넣고 권한을 600 으로 둔다.

둘째, 폐기가 먼저다. 시크릿이 평문으로 커밋된 것을 발견했다면 순서는 폐기 → 영향 조사 → 히스토리 정리다. 히스토리 재작성부터 하는 것은 순서가 틀렸다 — 공개된 값은 이미 자동 스캐너가 수집했을 수 있고, 포크와 클론과 CI 캐시에 남는다. 히스토리 정리는 유출을 되돌리는 조치가 아니라 재발을 줄이는 위생 작업이다.

셋째, rekey 는 옛 키를 무효화한다. rekey 후에는 옛 비밀번호로 그 파일을 열 수 없다. 여러 사람이 쓰는 키라면 교체 시점을 조율해야 한다.

시크릿이 새는 다른 통로들

파일을 암호화하고 no_log 를 붙여도, 값이 흘러나가는 통로가 몇 개 더 남는다. 점검 목록으로 적어 두면 좋다.

명령줄 인자. 값을 명령의 인자로 넘기면 같은 호스트의 다른 사용자가 프로세스 목록으로 그대로 볼 수 있다. 파일이나 표준 입력으로 넘기는 방식이 있으면 그쪽을 쓴다.

셸 히스토리. 사람이 손으로 친 명령에 값이 들어가면 그대로 파일에 남는다. 이 파일은 대개 백업에도 포함된다.

오류 메시지와 예외. 실패한 요청을 통째로 로그에 남기는 코드가 흔한데, 그 안에 인증 헤더가 들어 있다. 로그에 요청을 남길 때는 무엇을 지울지 미리 정해 두어야 하고, 그 목록은 새 헤더가 생길 때마다 갱신되어야 한다.

중간 파일. 템플릿으로 설정 파일을 만드는 과정에서 임시 파일이 기본 권한으로 잠시 놓였다가 지워지는 경우가 있다. 짧은 순간이라도 그 시점에 다른 프로세스가 읽을 수 있으므로, 처음부터 좁은 권한으로 만들어야 한다.

백업과 스냅샷. 암호화된 파일은 그대로 백업되어도 괜찮지만, 복호화된 결과물이 서버에 남아 있으면 그것이 백업에 실린다. 그래서 배포 결과물의 권한과 위치를 정해 두는 것이 시크릿 관리의 일부다.

여기서 한 걸음 더 나가면 탐지다. 저장소에 시크릿이 평문으로 들어오는 것을 커밋 단계나 CI 에서 잡아내는 도구가 있고, 이것을 걸어 두면 앞에서 말한 "폐기 → 조사 → 정리" 를 아예 겪지 않아도 된다. 사람의 주의력에 기대는 규칙은 언젠가 실패하지만, 커밋을 막는 검사는 매번 동작합니다.

다음 실습에서 할 것

비밀번호 파일을 안전하게 만들고, 변수 파일을 통째로 암호화하고, 값 하나만 인라인으로 암호화한다. 플레이북에서 복호화된 값을 써서 권한 600 파일을 만들고, no_log 로 로그 유출을 막는다. rekey 와 vault-id 를 거쳐 마지막에는 저장소 전체를 감사한다.