Windows 10 환경에서 Terraform을 이용한 AWS 자원 배포 - 9. 민감정보 보안
Terraform의 민감정보 보안이란?
Terraform을 사용할 때 크게 2종류로 민감정보(계정 정보, API 키 등)가 저장될 수 있다.
- Terraform 코드 안에 적혀진 민감정보
- AWS Access 키 정보, DB계정 정보 등 - Terraform 상태 파일(terraform.tfstate) 안에 적혀진 민감정보
- Tag에 적혀진 이메일이나 AWS 계정 정보, IP 정보 등
Terraform 코드가 github 저장소에 올라가거나, S3에 상태 파일이 업로드 되면서
허가되지 않은 사용자에게 공유될 경우 치명적인 보안 사고로 이어질 수 있다.
따라서 이런 민감정보는 저장될 경우 기본적으로 암호화해서 저장해야 한다.
(DO NOT STORE SECRETS IN PLAIN TEXT)
Terraform에서 민감정보를 보완하기 방안
1. 환경변수를 활용한 방법
- Terraform 코드에 민감정보를 작성하지 않고, 실행 시에 환경변수를 통해 별도 입력받는 방식이다.
- 아래 예시와 같이 환경변수를 사용하면 코드에 민감정보가 입력되지 않고, 메모리에만 저장된다.
- 다만 이런 경우 민감정보를 외우고 있거나, 별도로 관리하고 있어서 매번 환경변수를 설정해줘야 하는 단점이 있다.
(전역 환경변수를 영구적으로 설정할 경우에는, 환경변수에 민감정보를 저장하기 때문에 또다른 취약점이 되고 만다.)
// Terraform에서 DB생성 예시
...
...
...
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" "test_rds" {
identifier_prefix = "t101"
engine = "mysql"
allocated_storage = 10
instance_class = "db.t2.micro"
db_subnet_group_name = aws_db_subnet_group.mydbsubnet.name
vpc_security_group_ids = [aws_security_group.mysg2.id]
skip_final_snapshot = true
db_name = var.db_name
username = var.db_username
password = var.db_password
}
...
...
...
// Command 창에서 환경변수 설정 후 수행
set TF_VAR_db_username=dbuser
set TF_VAR_db_password=dbpassword!!
terraform apply
2. 암호 관리자 프로그램을 활용한 방법
- 1Password, LassPass와 같은 프로그램을 활용해서, 별도의 인증절차를 거치고 민감정보를 획득해 사용하는 방법
- 아래는 무료인 AWS Vault를 사용해 Access Key를 획득하는 테스트 내용이다.
#### 윈도우 Command에서 테스트 했기 때문에
#### Linux 명령어와 다소 차이가 있을 수 있음
// 윈도우용 AWS Vault 다운로드 및 파일이름 변경
c:\terraform_study>move aws-vault-windows-386.exe aws-vault.exe
1개 파일을 이동했습니다.
// AWS Vault 버전 확인
c:\terraform_study>aws-vault.exe --version
v6.6.0
// AWS Vault에 Access Key 설정
c:\terraform_study>aws-vault.exe add ersia
Enter Access Key ID: ******************** // 보안상 * 처리
Enter Secret Access Key: // Access Key는 입력해도 표시되지 않음
Added credentials to profile "ersia" in vault
// 설정한 Access Key 확인
c:\terraform_study>aws-vault.exe list
Profile Credentials Sessions
======= =========== ========
default - -
ersia ersia sts.GetSessionToken:55m55s
// Access Key 사용하기
c:\terraform_study\git_repository\ersia_t101\week5\iam>aws-vault.exe exec --no-session ersia -- terraform plan
data.aws_iam_policy.ersia_devel_access: Reading...
data.aws_iam_policy.ersia_guest_access: Reading...
data.aws_iam_policy.ersia_guest_access: Read complete after 9s [id=arn:aws:iam::aws:policy/IAMReadOnlyAccess]
data.aws_iam_policy.ersia_devel_access: Read complete after 9s [id=arn:aws:iam::aws:policy/ReadOnlyAccess]
Terraform used the selected providers to generate the following execution plan. Resource actions are indicated with the
following symbols:
+ create
...
...
...
// 이전에 사용하던 AWS Configure 파일 중 키 정보가 포함된 credentials 파일은 삭제
c:\terraform_study>cd C:\Users\%username%\.aws\
C:\Users\user\.aws>dir
Directory of C:\Users\user\.aws
2022-10-16 오후 08:52 <DIR> .
2022-10-16 오후 08:52 <DIR> ..
2022-11-26 오후 10:55 55 config
2022-10-22 오후 05:40 119 credentials
2 File(s) 174 bytes
2 Dir(s) 45,430,738,944 bytes free
C:\Users\user\.aws>del credentials
--> 만약 config 파일까지 삭제할 경우
--> default region을 찾지못해서 aws cli 실행에 문제가 생기는 것을 확인함
// AWS Vault Profile 삭제
c:\terraform_study\git_repository\ersia_t101\week5\iam>aws-vault.exe remove ersia
Delete credentials for profile "ersia"? (y|N) y
Deleted credentials.
c:\terraform_study\git_repository\ersia_t101\week5\iam>aws-vault.exe clear ersia
Cleared 1 sessions.
- Mac OS에서는 KeyChain을 통해 자동으로 암호를 설정하게 되어있다고 한다. (Mac이 없어 테스트 해보진 못함)
- 윈도우에서는 자격증명 관리자를 통해서 관리가 되고 있었다.
- aws-vault.exe login <profile name> 명령어로 AWS Console에 바로 로그인 할 수도 있다.
(명령어 수행 시 바로 기본 브라우저로 AWS Console 화면에 연결 및 로그인되어 실행해준다.)
추가사항1 - exec 명령어 수행 시 기본으로 GetSessionToken을 사용해 sts 임시자격증명을 발급해서 사용하는 것으로 확인된다.
따라서 이런 요청에 MFA인증 정보가 없을 경우 IAM API 작업 호출이 실패 한다.
(상단의 테스트에서는 --no-session 옵션을 사용해 수행했기 때문에 문제가 발생하지 않았다.)
GetSessionToken 사용 시 IAM API 호출에 대한 제약사항을 아래에서 확인할 수 있다.
추가사항2 - AWS Vault 사용 시 Region관련 테스트 이슈
- region의 경우 AWS config 파일에 저장되어있는 내용을 읽거나 환경변수를 읽어서 사용하는 것으로 확인된다.
-> 만약 config 파일에 region 정보가 없고, region에 대한 환경변수가 없을 경우 아래와 같은 에러가 발생하며 실행되지 않았다.
c:\terraform_study>aws-vault.exe exec ersia -- aws s3 ls
aws-vault: error: exec: Failed to get credentials for ersia: operation error STS: GetSessionToken, failed to resolve service endpoint, an AWS region is required, but was not found
-> AWS Vault는 AWS CLI를 대체하기 위해 만들어진 것이 아닌, 보완하기 위해 설계되어서 발생하는 이슈로 보인다.
(aws-vault is designed to compliment the AWS cli configuration, not replace it.)
3. 임시 보안자격증명을 사용하는 방법
- 민감정보에 대해 환경변수를 사용하거나 암호화를 하는 방법의 경우 한번 주어지면 반영구적으로 사용이 가능하다는 취약점이 존재한다.
- 또한 서비스 환경(Github 등)이나 타인의 PC나 서버에서 이런 민감정보를 사용할 때는 환경변수, 암호화 방법이 의미 없거나 어려울 수 있다.
- 이런 상황에도 대응하기 위해 사용할 때마다 임시적으로 자격증명을 발급받아서 사용하는 방법이다.
AWS 공식 문서를 참고해보면, 임의의 EC2에 IAM Role을 할당해 해당 EC2에서 별다른 Access Key를 설정하지 않고 S3에 접근하는 권한을 부여하는 방법을 볼 수 있다.
- IAM Role은 영구적인 자격증명이 아니며, 일정 기간 동안 특정 권한을 부여하는데 사용된다.
위의 그림의 동작을 순서대로 나열하면
- AWS 관리자는 photos라는 S3 버킷에 대한 admin Role인 Get-pics를 생성한다.
- AWS 관리자는 EC2 인스턴스를 생성하고 Get-pics Role을 할당한다.
- 개발자는 photos S3에 접근이 필요한 application 서비스를 해당 EC2에서 동작시킨다.
- EC2는 photos S3 접근에 대한 임시 보안자격증명을 발급받는다.
- EC2에서 발급받은 임시 보안자격증명으로 photos S3 접근이 수행된다.
- 수행이 끝나고 제한된 시간이 지나면 임시 보안자격증명(일종의 token)은 삭제된다.
이런식으로 민감한 Access Key 정보를 EC2에 저장하지 않고, 임시 보안자격증명을 통해서 수행이 가능하다.
DB 계정 정보 같은 경우에도 AWS에서는 Role을 통해서 로그인 권한을 부여할 수 있다.
- 참고 : https://aws.amazon.com/ko/premiumsupport/knowledge-center/users-connect-rds-iam/
위의 그림과 비슷하게 EC2에 대해 EC2 Role을 부여하고 테스트 해보면 아래와 같다.
부여된 Role에 대한 Token정보와 Expiration 정보를 확인할 수 있다.
참고자료
- 테라폼 공식 홈페이지 : https://developer.hashicorp.com/terraform/intro
- 악분 님의 테라폼 민감정보 보안 영상 : https://youtu.be/-ysCr2BsC1I
- AWS Vault의 github : https://github.com/99designs/aws-vault
- AWS Vault의 region 관련 이슈 논의 내용 : https://github.com/99designs/aws-vault/issues/156
- AWS Vault 사용법(지원하는 환경변수 등) : https://github.com/99designs/aws-vault/blob/master/USAGE.md
- AWS GetSessionToken 문서 : https://docs.aws.amazon.com/STS/latest/APIReference/API_GetSessionToken.html
- 윈도우 환경에서 SSH Key Pair 만들기 : https://thekoguryo.github.io/oci/chapter03/3/