Secret Management Basics
배포 과정에서 민감 정보 (DB암호, API 키, TLS인증서, SSH키, GPG 키 등)를 안전하게 관리가 필요하며 절대 민감 정보를 평문으로 저장해서는 안됩니다.
테라폼에서 민감 정보가 노출되는 부분과 이를 어떻게 보완해야하는지 확인해봅니다.
민감 정보의 종류
•
Personal secrets : 개인 소유의 암호, 예) 방문하는 웹 사이트 사용자 이름과 암호, SSH 키
•
Customer secrets : 고객 소유의 암호, 예) 사이트를 운영하는데 고객의 사용자 이름과 암호, 고객의 개인정보 등 → 해싱 알고리즘 사용
•
Infrastructure secrets : 인프라 관련 암호, 예) DB암호, API 키 등 → 암복호화 알고리즘 사용
민감 정보의 저장 방법
•
File-based secret stores : 민감 정보를 암호화 후 저장 → 암호화 관련 키 관리는 AWS KMS, GCP KMS 혹은 PGP Key
•
Centralized secret stores : 데이터베이스(MySQL, Psql, DynamoDB 등)에 비밀번호를 암호화하여 저장, 암호화 키는 서비스 자체 혹은 클라우드 KMS를 사용
테라폼에서의 위험 요소
Provider Block에 인증 정보가 하드코딩 된 경우
•
예시
provider "aws" {
region = "ap-northeast-2"
access_key = "AKIA***** ~ "
secret_key = "3TaHkQ***** ~ "
Bash
•
해결 방법
⇒ 환경 변수를 사용한다.
export AWS_ACCESS_KEY_ID="AKIA***** ~ "
export AWS_SECRET_ACCESS_KEY="3TaHkQ***** ~ "
Bash
⇒ 설정 파일을 사용한다. (+ aws-vault 툴 사용 - 링크)
$ aws configure list
Name Value Type Location
---- ----- ---- --------
profile <not set> None None
access_key AKIA***** ~ shared-credentials-file None
secret_key 3TaHkQ***** ~ shared-credentials-file None
region ap-northeast-2 config-file ~/.aws/config
Bash
⇒ 임시 보안자격증명을 사용한다.
AWS가 주체가 되어 임시 보안자격증명 발급
https://dev.classmethod.jp/articles/what-is-aws-iam-kr/
외부 서비스(Github OIDC)가 주체가 되어 임시 보안자격증명 발급
https://github.blog/2021-11-23-secure-deployments-openid-connect-github-actions-generally-available/
•
실습 1 - EC2 Instance running Jenkins as a CI server, with IAM roles
Role(EC2FullAccess) Switch 를 통해, EC2를 사용할 수 있습니다.
code
결과
•
실습 2 - GitHub Actions as a CI server, with OIDC
github actions에서 S3 접근을 위한 OIDC 사용 실습으로 대체
code
결과
Resource 또는 Data Source block에 민감 정보가 하드코딩 된 경우(Database 암호 등)
•
예시
resource "aws_db_instance" "staging-rds" {
identifier = "staging-rds"
...
db_name = var.db_name
username = admin
password = password123!
}
Bash
⇒ 환경 변수를 사용한다.
$ export TF_VAR_db_username=(DB_USERNAME)
$ export TF_VAR_db_password=(DB_PASSWORD)
Bash
⇒ 입력 변수를 사용한다.
variable "db_username" {
description = "The username for the database"
type = string
sensitive = true
}
variable "db_password" {
description = "The password for the database"
type = string
sensitive = true
}
resource "aws_db_instance" "staging-rds" {
identifier = "staging-rds"
...
db_name = var.db_name
username = var.db_username
password = var.db_password
}
Bash
•
장점 : 모든 언어에서 환경 변수를 설정 및 쉽게 사용할 수 있으며 추가 비용이 들지 않음
•
단점 : 변수의 수동 관리가 필요하며 여러 환경에서 사용할 경우 표준화 및 에러 발생 가능성이 존재
⇒ 민감정보를 암호화한 키를 클라우드 공급자 KMS를 통해 사용한다.
AWS KMS
AWS Key Management Service(AWS KMS)는 데이터를 보호하는 데 사용하는 암호화 키를 쉽게 생성하고 제어할 수 있게 해주는 관리형 서비스입니다
•
실습 1 - Encrypted files with AWS KMS
AWS KMS 서비스를 통해 암호화 키를 생성하고 RDS 생성 시 활용 실습
AWS KMS 실습
RDS 생성 및 Key 활용 실습
결과
•
실습 2 - Secret Stores with AWS Secret Manager
3주차 ‘Terraform에서 민감 정보를 다루는 방법’에서 중앙 집중식 비밀저장소(AWS Secret Manager)를 이용한 민감 정보 관리 방법에 대해 실습하였습니다. - 링크
State files 또는 Plan files에 민감 정보 노출
•
State files : 3주차 ‘Terraform에서 민감 정보를 다루는 방법’에서 언급한 것 처럼, 테라폼 리소스와 데이터 소스에 전달되는 모든 민감정보는 테라폼 상태 파일에 평문으로 저장되므로 아래와 같이 Backend에 대한 접근제어가 필요합니다.
◦
백엔드 저장소에 저장 시 암호화 Store Terraform state in a backend that supports encryption
◦
백엔드 액세스에 대한 접근 통제 Strictly control who can access your Terraform backend
•
Plan files : 암호화 및 파일 통제 필요
# plan 출력 내용을 파일로 저장
terraform plan -out=t101.plan
#(참고) plan 출력 파일로 apply
## terraform apply t101.plan
# plan 출력 내용을 파일 확인
cat t101.plan
# 평문
terraform show t101.plan > t101.ansi
less t101.ansi
Bash
참고 사항
A comparison of methods for machine users (e.g., a CI server) to pass secrets to Terraform providers
Stored credentials | IAM roles | OIDC | |
Example | CircleCI | Jenkins on an EC2 Instance | GitHub Actions |
Avoid manually managing credentials | X | O | O |
Avoid using permanent credentials | X | O | O |
Works inside of cloud provider | X | O | X |
Works outside of cloud provider | O | X | O |
Widely supported as of 2022 | O | O | X |
A comparison of methods for passing secrets to Terraform resources and data sources
Environment variables | Encrypted files | Centralized secret stores | |
Keeps plain-text secrets out of code | O | O | O |
All secrets management defined as code | X | O | O |
Audit log for access to encryption keys | X | O | O |
Audit log for access to individual secrets | X | X | O |
Rotating or revoking secrets is easy | X | X | O |
Standardizing secrets management is easy | X | X | O |
Secrets are versioned with the code | X | O | X |
Storing secrets is easy | O | X | O |
Retrieving secrets is easy | O | O | X |
Integrating with automated testing is easy | O | X | X |
Cost | 0 | $ | $$$ |
참고
•
가시다님 스터디 자료
•
악분님 Youtube - 링크