[보안]Lambda 환경변수 전송중 암호화 가이드
목적
- AWS Lambda에서 ‘환경변수’ 전송 중 암호화 기능을 활성화한다.
- Lambda 함수의 환경변수는 함수 코드를 변경할 필요 없이 구성 설정을 저장하는 데 사용되는 키-값 쌍이다.
- 암호, 토큰 및 액세스 키와 같은 중요한 정보를 저장하는 Lambda 함수 환경변수가 전송 중 암호화 기능을 활성화되지 않은 경우 전송 중에 데이터가 노출될 위협이 생기게 되며, 이는 통신을 가로챌 수 있는 모든 사람이 잠재적으로 데이터를 읽거나 수정하거나 오용할 수 있으므로 보안 위협이 될 수 있다.
- 민감하고 중요한 데이터를 저장하는 Lambda 함수 환경 변수를 처리할 때 함수에 동적으로 전달하는 데이터를 악의적인 사용자의 무단 액세스로부터 보호하기 위해 암호화한다.
가이드
KMS 키 생성
- [KMS] > [고객관리형키] > 생성
- 기본 설정 대칭키로 생성
KMS 권한 추가
- Lambda 역할에 KMS 접근 정책을 만들어 추가한다.
- KMSLambdaExecution
{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": [ "kms:Decrypt", "kms:DescribeKey" ], "Resource": "arn:aws:kms:ap-northeast-2:{AWS_ACCOUNT_ID}:key/{KMS-KEY-UUID}" } ] }
암호화
-
함수 진입 > [구성] > [환경변수] > 전송중 암호화 체크 및 암호화
복호화
- 환경변수는 복호화하여 전역변수로 사용함
python
import os
import boto3
from base64 import b64decode
from botocore.exceptions import ClientError
def decrypt_env(var_name: str) -> str:
ENCRYPTED = os.environ[var_name]
DECRYPTED = boto3.client('kms').decrypt(
CiphertextBlob=b64decode(ENCRYPTED),
EncryptionContext={'LambdaFunctionName': os.environ['AWS_LAMBDA_FUNCTION_NAME']})['Plaintext'].decode('utf-8')
return DECRYPTED
# ===== 환경 변수 설정 =====
DB_HOST = decrypt_env('DB_HOST')
DB_PORT = decrypt_env('DB_PORT')
DB_USER = decrypt_env('DB_USER')
DB_PASSWORD = decrypt_env('DB_PASSWORD')
DB_NAME = decrypt_env('DB_NAME')
BUCKET_NAME = decrypt_env('BUCKET_NAME')
node.js
import { KMSClient, DecryptCommand } from "@aws-sdk/client-kms"
const client = new KMSClient({ region: process.env.AWS_REGION || "ap-northeast-2", });
async function decryptEnvVar(name) {
try{
const encrypted = process.env[name];
if(!encrypted){
throw new Error(`Missing encrypted env var: ${name}`);
}
const req = {
CiphertextBlob: Buffer.from(encrypted, 'base64'),
EncryptionContext: {
LambdaFunctionName: process.env['AWS_LAMBDA_FUNCTION_NAME'],
},
};
const command = new DecryptCommand(req);
const response = await client.send(command);
const decrypted = new TextDecoder().decode(response.Plaintext);
process.env[name] = decrypted;
return decrypted;
}catch (err){
console.log(`Error decrypting env var: ${name}`, err);
throw err;
}
}
async function decryptAll(names){
return await Promise.all(names.map(decryptEnvVar));
}
await decryptAll([
"WAS_PORT",
"DB_HOST",
"DB_DATABASE",
"DB_USER",
"DB_PASSWORD",
"DB_PORT",
]);