🤖

본 콘텐츠의 이미지 및 내용은 AI로 생성되었습니다.

⚠️

본 콘텐츠의 이미지 및 내용을 무단으로 복제, 배포, 수정하여 사용할 경우 저작권법에 의해 법적 제재를 받을 수 있습니다.

이미지 로딩 중...

AWS 보안과 접근 제어 완벽 가이드 - 슬라이드 1/7
A

AI Generated

2025. 12. 18. · 10 Views

AWS 보안과 접근 제어 완벽 가이드

AWS 환경에서 안전하게 시스템을 운영하기 위한 보안 필수 개념을 실무 중심으로 배워봅니다. IAM 정책부터 VPC 엔드포인트, 데이터 암호화까지 체계적으로 알아봅니다.


목차

  1. IAM_정책_설계
  2. 최소_권한_원칙
  3. VPC_엔드포인트_설정
  4. 데이터_암호화
  5. API_키_관리
  6. 보안_베스트_프랙티스

1. IAM 정책 설계

신입 개발자 김개발 씨가 AWS 콘솔에 처음 로그인했을 때의 일입니다. "왜 저는 EC2는 볼 수 있는데 RDS는 접근이 안 되죠?" 팀장님은 미소를 지으며 말했습니다.

"그건 바로 IAM 정책 때문이에요."

IAM 정책은 AWS 리소스에 대한 접근 권한을 정의하는 규칙입니다. 마치 회사의 출입 카드처럼, 누가 어떤 자원에 어떤 작업을 할 수 있는지를 명확하게 지정합니다.

JSON 형식으로 작성되며, 사용자나 역할에 부여됩니다.

다음 코드를 살펴봅시다.

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": [
        "s3:GetObject",
        "s3:PutObject"
      ],
      "Resource": "arn:aws:s3:::my-bucket/*",
      // 특정 버킷의 객체만 읽고 쓸 수 있습니다
      "Condition": {
        "IpAddress": {
          "aws:SourceIp": "203.0.113.0/24"
          // 특정 IP 대역에서만 접근 가능
        }
      }
    }
  ]
}

김개발 씨는 입사 첫날, AWS 콘솔 접속 계정을 받았습니다. 설레는 마음으로 로그인했지만 이상한 점을 발견했습니다.

EC2 인스턴스는 잘 보이는데, RDS 데이터베이스 메뉴에 들어가니 "권한이 없습니다"라는 메시지가 떴습니다. 팀장 박시니어 씨에게 물어보니, "그건 IAM 정책 때문이에요"라는 답변이 돌아왔습니다.

IAM 정책이란 정확히 무엇일까요? 쉽게 비유하자면, IAM 정책은 마치 회사의 출입 카드와 같습니다.

건물에 들어갈 때 카드를 찍으면, 그 카드에 설정된 권한에 따라 어떤 층은 갈 수 있고 어떤 층은 갈 수 없죠. IAM 정책도 똑같습니다.

AWS 리소스라는 건물에서, 누가 어느 층의 어떤 방에 들어가 무엇을 할 수 있는지를 정의하는 것입니다. IAM 정책이 없던 시절에는 어땠을까요?

초창기 클라우드 환경에서는 모든 사용자가 관리자 권한을 가지고 있었습니다. 편리하긴 했지만, 실수로 중요한 데이터베이스를 삭제하거나 비용이 많이 드는 리소스를 무분별하게 생성하는 일이 빈번했습니다.

더 큰 문제는 보안이었습니다. 한 명의 계정이 탈취되면 전체 시스템이 위험에 빠졌습니다.

바로 이런 문제를 해결하기 위해 IAM 정책이 등장했습니다. IAM 정책을 사용하면 역할별로 정확한 권한 분리가 가능해집니다.

개발자는 개발 환경에만, 운영팀은 운영 환경에만 접근할 수 있습니다. 또한 감사 추적도 명확해집니다.

누가 언제 무엇을 했는지 CloudTrail을 통해 모두 기록됩니다. 무엇보다 보안 사고 발생 시 피해를 최소화할 수 있다는 큰 이점이 있습니다.

위의 코드를 한 줄씩 살펴보겠습니다. 먼저 Version 필드는 정책 언어의 버전을 나타냅니다.

거의 항상 "2012-10-17"을 사용합니다. Statement 배열에는 실제 권한 규칙들이 들어갑니다.

Effect는 "Allow" 또는 "Deny"로 허용 여부를 결정합니다. Action에는 허용할 작업들을 나열합니다.

여기서는 S3 객체를 읽고 쓰는 작업이죠. Resource는 어떤 리소스에 대한 권한인지 ARN으로 명시합니다.

Condition은 추가 조건으로, 특정 IP 대역에서만 접근을 허용하도록 설정했습니다. 실제 현업에서는 어떻게 활용할까요?

예를 들어 쇼핑몰 서비스를 개발한다고 가정해봅시다. 프론트엔드 개발자는 S3 버킷에 이미지를 업로드할 권한만 필요합니다.

백엔드 개발자는 EC2와 RDS에 접근해야 하고, DevOps 엔지니어는 전체 인프라를 관리해야 합니다. IAM 정책을 활용하면 각 역할에 딱 맞는 권한만 부여할 수 있습니다.

쿠팡, 배달의민족 같은 대형 서비스들도 이런 패턴을 적극적으로 사용하고 있습니다. 하지만 주의할 점도 있습니다.

초보 개발자들이 흔히 하는 실수 중 하나는 와일드카드를 남용하는 것입니다. "Action": ["*"]처럼 모든 작업을 허용하면 IAM 정책을 만든 의미가 없습니다.

이렇게 하면 최소 권한 원칙을 위반하게 되고, 보안 취약점이 생깁니다. 따라서 필요한 작업만 명시적으로 나열하는 방법으로 사용해야 합니다.

다시 김개발 씨의 이야기로 돌아가 봅시다. 박시니어 씨가 김개발 씨에게 개발자용 IAM 정책을 추가로 부여했습니다.

"이제 RDS도 볼 수 있을 거예요." 김개발 씨는 고개를 끄덕였습니다. "아, 그래서 권한 관리가 이렇게 중요하군요!" IAM 정책을 제대로 이해하면 더 안전하고 체계적인 AWS 환경을 구축할 수 있습니다.

여러분도 오늘 배운 내용을 실제 프로젝트에 적용해 보세요.

실전 팁

💡 - IAM 정책 시뮬레이터를 활용하면 정책이 실제로 어떻게 동작하는지 테스트할 수 있습니다

  • 정책은 명시적 Deny가 항상 우선순위가 높습니다. Deny가 하나라도 있으면 접근이 차단됩니다

2. 최소 권한 원칙

어느 날 보안 감사에서 지적 사항이 나왔습니다. "개발자 계정에 Admin 권한이 부여되어 있습니다.

이건 심각한 보안 위험입니다." 김개발 씨는 당황했습니다. "하지만 편하잖아요?" 보안팀 이보안 씨가 심각한 표정으로 말했습니다.

"편리함과 보안은 항상 트레이드오프 관계입니다."

최소 권한 원칙은 사용자나 시스템에게 작업 수행에 필요한 최소한의 권한만 부여하는 보안 원칙입니다. 마치 은행 직원에게 모든 금고 열쇠를 주는 대신 자기 업무에 필요한 열쇠만 주는 것과 같습니다.

AWS에서는 IAM 정책을 통해 이를 구현합니다.

다음 코드를 살펴봅시다.

import boto3
import json

def create_minimal_policy():
    # 최소 권한 정책 생성 예제
    policy = {
        "Version": "2012-10-17",
        "Statement": [
            {
                "Effect": "Allow",
                "Action": [
                    "s3:GetObject"  # 읽기 전용
                ],
                "Resource": "arn:aws:s3:::prod-data/reports/*",
                # 특정 경로만 접근 가능
                "Condition": {
                    "StringEquals": {
                        "s3:ExistingObjectTag/Department": "Sales"
                        # 부서별 태그 기반 접근 제어
                    }
                }
            }
        ]
    }
    return json.dumps(policy, indent=2)

김개발 씨는 개발이 편하다는 이유로 AWS 관리자 권한을 요청했습니다. "이것저것 테스트하려면 권한이 많아야 편하잖아요." 하지만 보안 감사 결과, 이것이 큰 문제로 지적되었습니다.

보안팀 이보안 씨가 설명했습니다. "만약 당신 계정이 해킹당하면 어떻게 되죠?

공격자가 전체 시스템을 장악할 수 있습니다." 최소 권한 원칙이란 정확히 무엇일까요? 쉽게 비유하자면, 최소 권한 원칙은 마치 은행의 권한 관리와 같습니다.

은행에서 창구 직원에게 모든 금고의 열쇠를 주지 않습니다. 각자 업무에 필요한 금고만 열 수 있는 열쇠를 줍니다.

지점장은 더 많은 금고에 접근할 수 있지만, 그것도 업무상 필요한 범위 내에서만입니다. 이처럼 최소 권한 원칙도 업무 수행에 꼭 필요한 권한만 부여하는 것입니다.

최소 권한 원칙이 없던 시절에는 어땠을까요? 많은 회사에서 "일단 Admin 권한 주고 시작하자"는 식으로 운영했습니다.

빠르고 편리했지만, 문제가 터지면 속수무책이었습니다. 한 개발자의 AWS 키가 GitHub에 실수로 올라가면서 해커가 전체 인프라를 암호화하고 몸값을 요구한 사례도 있었습니다.

더 큰 문제는 내부자 위협이었습니다. 퇴사 예정인 직원이 악의적으로 데이터를 삭제하거나 유출하는 일도 발생했습니다.

바로 이런 문제를 해결하기 위해 최소 권한 원칙이 보안의 기본으로 자리 잡았습니다. 최소 권한 원칙을 적용하면 보안 사고의 영향 범위를 최소화할 수 있습니다.

한 계정이 탈취되어도 피해가 제한적입니다. 또한 컴플라이언스 요구사항을 충족할 수 있습니다.

GDPR, ISO 27001 같은 보안 인증에서 최소 권한 원칙은 필수 요구사항입니다. 무엇보다 의도치 않은 실수를 방지할 수 있다는 큰 이점이 있습니다.

위의 코드를 한 줄씩 살펴보겠습니다. 먼저 정책 객체를 생성하는데, Action에서 "s3:GetObject"만 허용했습니다.

쓰기, 삭제 권한은 없습니다. Resource는 특정 버킷의 특정 경로만 지정했습니다.

전체 버킷이 아닙니다. Condition에서 태그 기반 접근 제어를 추가했습니다.

"Department" 태그가 "Sales"인 객체만 접근할 수 있습니다. 이렇게 여러 레이어로 권한을 제한하는 것이 핵심입니다.

실제 현업에서는 어떻게 활용할까요? 예를 들어 데이터 분석 팀이 S3의 로그 데이터를 분석한다고 가정해봅시다.

이들에게 필요한 권한은 읽기뿐입니다. 원본 데이터를 수정하거나 삭제할 필요가 없습니다.

따라서 s3:GetObject만 부여하고, 특정 로그 버킷의 특정 경로만 접근하도록 제한합니다. 또한 분석 결과를 저장할 별도 버킷에는 쓰기 권한을 줍니다.

Netflix, Airbnb 같은 기업들은 이런 방식으로 수천 명의 직원 권한을 관리합니다. 하지만 주의할 점도 있습니다.

초보 개발자들이 흔히 하는 실수 중 하나는 너무 제한적으로 설정해서 업무가 마비되는 것입니다. 최소 권한 원칙을 지나치게 엄격하게 적용하면 개발자들이 매번 권한 요청을 해야 하고, 생산성이 떨어집니다.

이렇게 하면 오히려 개발자들이 권한 관리를 우회하려 들 수 있습니다. 따라서 업무 효율성과 보안의 균형을 잘 맞춰야 합니다.

다시 김개발 씨의 이야기로 돌아가 봅시다. 이보안 씨는 김개발 씨에게 개발 환경에서만 사용할 수 있는 제한된 권한을 새로 발급했습니다.

"이 권한이면 개발하는 데 충분할 거예요. 운영 환경은 별도 승인이 필요합니다." 김개발 씨는 고개를 끄덕였습니다.

"처음엔 불편할 것 같았는데, 생각해보니 더 안전하네요." 최소 권한 원칙을 제대로 이해하면 더 안전한 시스템을 구축할 수 있습니다. 여러분도 오늘 배운 내용을 실제 프로젝트에 적용해 보세요.

실전 팁

💡 - IAM Access Analyzer를 사용하면 과도한 권한을 자동으로 탐지할 수 있습니다

  • 정기적으로 사용하지 않는 권한을 검토하고 제거하는 것이 중요합니다

3. VPC 엔드포인트 설정

김개발 씨가 S3에 저장된 민감한 고객 데이터를 처리하는 서비스를 개발하고 있었습니다. 코드 리뷰에서 박시니어 씨가 물었습니다.

"이 트래픽이 인터넷을 거쳐서 S3로 가는 거 알고 있어요?" 김개발 씨는 깜짝 놀랐습니다. "VPC 안에서 통신하는 거 아니었나요?"

VPC 엔드포인트는 VPC 내부에서 AWS 서비스에 비공개로 접근할 수 있게 해주는 게이트웨이입니다. 마치 회사 내부 전용선처럼, 인터넷을 거치지 않고 AWS 서비스를 안전하게 사용할 수 있습니다.

데이터가 외부에 노출될 위험을 원천 차단합니다.

다음 코드를 살펴봅시다.

import boto3

def create_vpc_endpoint():
    ec2 = boto3.client('ec2', region_name='ap-northeast-2')

    # S3용 VPC 엔드포인트 생성
    response = ec2.create_vpc_endpoint(
        VpcId='vpc-0abcd1234efgh5678',
        ServiceName='com.amazonaws.ap-northeast-2.s3',
        # 게이트웨이 엔드포인트 (S3, DynamoDB 지원)
        VpcEndpointType='Gateway',
        RouteTableIds=[
            'rtb-12345678',  # 라우트 테이블 연결
        ],
        PolicyDocument='''{
            "Statement": [{
                "Effect": "Allow",
                "Principal": "*",
                "Action": "s3:*",
                "Resource": "arn:aws:s3:::secure-bucket/*"
            }]
        }'''  # 엔드포인트 정책으로 접근 제어
    )
    return response['VpcEndpoint']['VpcEndpointId']

김개발 씨는 EC2 인스턴스에서 S3 버킷의 고객 데이터를 처리하는 배치 작업을 작성했습니다. VPC 내부에 있으니 안전하다고 생각했습니다.

하지만 박시니어 씨의 지적에 놀랐습니다. "이 데이터가 실제로는 인터넷 게이트웨이를 통해 나갔다가 다시 들어옵니다." 김개발 씨는 혼란스러웠습니다.

"같은 AWS 안인데 왜 그런 거죠?" VPC 엔드포인트란 정확히 무엇일까요? 쉽게 비유하자면, VPC 엔드포인트는 마치 회사 건물 내부에 설치된 은행 ATM과 같습니다.

은행 업무를 보려고 건물 밖으로 나가지 않아도 됩니다. 내부에 있는 ATM을 사용하면 안전하고 빠르게 업무를 처리할 수 있습니다.

VPC 엔드포인트도 똑같습니다. VPC 외부로 나가지 않고 AWS 서비스에 직접 연결되는 비공개 통로를 만들어주는 것입니다.

VPC 엔드포인트가 없던 시절에는 어땠을까요? VPC 안에서 S3나 DynamoDB를 사용하려면 인터넷 게이트웨이나 NAT 게이트웨이를 거쳐야 했습니다.

데이터가 일단 퍼블릭 인터넷으로 나갔다가 다시 AWS로 들어오는 구조였습니다. 이 과정에서 중간자 공격의 위험이 있었고, 네트워크 비용도 발생했습니다.

더 큰 문제는 컴플라이언스였습니다. 금융, 의료 데이터는 인터넷에 노출되면 안 되는데, 기술적으로 완전히 차단하기 어려웠습니다.

바로 이런 문제를 해결하기 위해 VPC 엔드포인트가 등장했습니다. VPC 엔드포인트를 사용하면 데이터가 절대 인터넷에 노출되지 않습니다.

완전히 AWS 백본 네트워크 내부에서만 통신합니다. 또한 NAT 게이트웨이 비용을 절감할 수 있습니다.

데이터 전송 비용도 줄어듭니다. 무엇보다 네트워크 성능이 향상된다는 큰 이점이 있습니다.

지연시간이 줄어들고 대역폭도 안정적입니다. 위의 코드를 한 줄씩 살펴보겠습니다.

먼저 EC2 클라이언트를 생성합니다. create_vpc_endpoint 메서드를 호출하는데, VpcId에 엔드포인트를 생성할 VPC를 지정합니다.

ServiceName은 접근할 AWS 서비스를 나타냅니다. S3의 경우 리전별로 다릅니다.

VpcEndpointType을 "Gateway"로 설정했습니다. S3와 DynamoDB는 게이트웨이 타입을 지원합니다.

RouteTableIds에 라우트 테이블을 연결하면 자동으로 라우팅 규칙이 추가됩니다. PolicyDocument로 어떤 버킷에 접근할 수 있는지 제어합니다.

실제 현업에서는 어떻게 활용할까요? 예를 들어 병원 시스템에서 환자 의료 기록을 S3에 저장한다고 가정해봅시다.

개인정보보호법에 따라 의료 데이터는 암호화되어야 하고, 인터넷에 노출되면 안 됩니다. VPC 엔드포인트를 사용하면 EC2에서 S3로 가는 모든 트래픽이 AWS 내부망을 통해서만 이동합니다.

외부 공격자가 중간에서 가로챌 수 없습니다. 삼성병원, 서울아산병원 같은 대형 의료기관들이 이런 방식을 사용합니다.

하지만 주의할 점도 있습니다. 초보 개발자들이 흔히 하는 실수 중 하나는 모든 서비스에 게이트웨이 엔드포인트를 쓰려는 것입니다.

게이트웨이 타입은 S3와 DynamoDB만 지원합니다. EC2, Lambda 같은 서비스는 인터페이스 엔드포인트를 사용해야 합니다.

이렇게 하면 엔드포인트 생성이 실패합니다. 따라서 서비스별로 올바른 엔드포인트 타입을 선택해야 합니다.

다시 김개발 씨의 이야기로 돌아가 봅시다. 박시니어 씨가 VPC 엔드포인트를 설정하는 법을 알려줬습니다.

"이제 데이터가 절대 밖으로 나가지 않습니다. 보안팀도 만족할 거예요." 김개발 씨는 고개를 끄덕였습니다.

"보이지 않는 보안 위험이 이렇게 많았네요!" VPC 엔드포인트를 제대로 이해하면 더 안전한 네트워크 아키텍처를 설계할 수 있습니다. 여러분도 오늘 배운 내용을 실제 프로젝트에 적용해 보세요.

실전 팁

💡 - 인터페이스 엔드포인트는 시간당 비용이 청구되니 필요한 서비스만 생성하세요

  • VPC 엔드포인트 정책을 활용하면 더욱 세밀한 접근 제어가 가능합니다

4. 데이터 암호화

어느 날 김개발 씨의 노트북이 분실되었습니다. 그 안에는 개발 중인 서비스의 데이터베이스 덤프 파일이 있었습니다.

보안팀 이보안 씨가 급히 달려왔습니다. "암호화는 되어 있죠?" 김개발 씨는 식은땀을 흘리며 대답했습니다.

"그게..."

데이터 암호화는 데이터를 읽을 수 없는 형태로 변환하여 보호하는 기술입니다. 마치 소중한 문서를 금고에 넣고 자물쇠를 채우는 것과 같습니다.

AWS에서는 저장 시 암호화와 전송 중 암호화 모두 지원하며, KMS를 통해 키를 안전하게 관리합니다.

다음 코드를 살펴봅시다.

import boto3
import json

def encrypt_data_with_kms():
    kms = boto3.client('kms', region_name='ap-northeast-2')

    # 고객 데이터 (민감 정보)
    sensitive_data = json.dumps({
        "customer_id": "C12345",
        "ssn": "123-45-6789",
        "credit_card": "1234-5678-9012-3456"
    })

    # KMS로 데이터 암호화
    response = kms.encrypt(
        KeyId='arn:aws:kms:ap-northeast-2:123456789012:key/abc-def',
        # 마스터 키 ARN
        Plaintext=sensitive_data.encode('utf-8')
    )

    encrypted_blob = response['CiphertextBlob']
    # 이 암호화된 데이터를 저장

    # 복호화 (필요시)
    decrypt_response = kms.decrypt(
        CiphertextBlob=encrypted_blob
    )
    decrypted_data = decrypt_response['Plaintext'].decode('utf-8')
    return json.loads(decrypted_data)

김개발 씨는 개발을 위해 운영 데이터베이스의 일부 데이터를 로컬로 복사해서 작업하고 있었습니다. 테스트하기 편리했습니다.

하지만 노트북을 지하철에 두고 내렸습니다. 순간 머릿속이 하얘졌습니다.

보안팀 이보안 씨가 긴급 회의를 소집했습니다. "데이터가 암호화되어 있으면 다행인데, 아니면 전체 고객에게 개인정보 유출 통보를 해야 합니다." 데이터 암호화란 정확히 무엇일까요?

쉽게 비유하자면, 데이터 암호화는 마치 편지를 암호문으로 쓰는 것과 같습니다. 제2차 세계대전 때 군대가 사용한 에니그마 암호기를 떠올려보세요.

평문 메시지를 암호기에 넣으면 무작위처럼 보이는 문자열로 변환됩니다. 정확한 키가 없으면 아무도 원본 메시지를 읽을 수 없습니다.

데이터 암호화도 똑같습니다. 평문 데이터를 암호화 알고리즘으로 변환하여 권한이 없는 사람이 읽을 수 없게 만드는 것입니다.

데이터 암호화가 없던 시절에는 어땠을까요? 초창기 웹 서비스들은 데이터를 평문으로 저장했습니다.

비밀번호도 그냥 텍스트로 데이터베이스에 들어 있었습니다. 해커가 데이터베이스에 침입하면 모든 정보가 그대로 노출되었습니다.

2011년 소니 플레이스테이션 네트워크 해킹 사건에서 7천7백만 명의 개인정보가 유출되었는데, 신용카드 정보 일부가 암호화되지 않았습니다. 더 큰 문제는 법적 책임이었습니다.

GDPR 같은 개인정보 보호법을 위반하면 수천억 원의 벌금이 부과됩니다. 바로 이런 문제를 해결하기 위해 데이터 암호화가 필수가 되었습니다.

데이터 암호화를 사용하면 데이터 유출 시에도 피해를 최소화할 수 있습니다. 암호화된 데이터는 키 없이는 무용지물입니다.

또한 컴플라이언스 요구사항을 충족할 수 있습니다. PCI-DSS, HIPAA 같은 산업 표준은 암호화를 필수로 요구합니다.

무엇보다 고객 신뢰를 확보할 수 있다는 큰 이점이 있습니다. 위의 코드를 한 줄씩 살펴보겠습니다.

먼저 KMS 클라이언트를 생성합니다. 민감한 고객 데이터를 JSON으로 만듭니다.

kms.encrypt 메서드로 데이터를 암호화하는데, KeyId에는 KMS에서 생성한 마스터 키의 ARN을 지정합니다. Plaintext에는 암호화할 원본 데이터를 바이트 형태로 전달합니다.

암호화된 결과는 CiphertextBlob으로 반환됩니다. 이것을 데이터베이스나 S3에 저장합니다.

복호화할 때는 kms.decrypt를 사용하는데, 키를 명시하지 않아도 KMS가 자동으로 올바른 키를 찾아줍니다. 실제 현업에서는 어떻게 활용할까요?

예를 들어 핀테크 스타트업에서 사용자의 계좌 정보를 저장한다고 가정해봅시다. 금융 데이터는 법적으로 암호화가 필수입니다.

RDS 데이터베이스 생성 시 "저장 시 암호화" 옵션을 활성화하면 모든 데이터가 자동으로 암호화됩니다. API 통신은 TLS 1.2 이상으로 암호화합니다.

S3에 저장하는 파일은 SSE-KMS로 암호화합니다. 토스, 카카오페이 같은 서비스들은 다층 암호화 전략을 사용합니다.

하지만 주의할 점도 있습니다. 초보 개발자들이 흔히 하는 실수 중 하나는 암호화 키를 코드에 하드코딩하는 것입니다.

아무리 강력한 암호화를 써도 키가 코드에 그대로 노출되면 의미가 없습니다. 이렇게 하면 GitHub에 코드를 올리는 순간 키가 유출됩니다.

따라서 AWS KMS나 Secrets Manager를 사용해서 키를 관리해야 합니다. 다시 김개발 씨의 이야기로 돌아가 봅시다.

다행히 김개발 씨는 로컬 디스크 암호화를 해놨고, 데이터베이스 덤프 파일도 암호화했습니다. 노트북을 찾은 사람이 데이터를 읽을 수 없었습니다.

이보안 씨가 안도의 한숨을 쉬었습니다. "이번엔 운이 좋았어요.

앞으로도 항상 암호화를 습관화하세요." 김개발 씨는 고개를 끄덕였습니다. "암호화가 정말 생명줄이네요!" 데이터 암호화를 제대로 이해하면 더 안전한 애플리케이션을 만들 수 있습니다.

여러분도 오늘 배운 내용을 실제 프로젝트에 적용해 보세요.

실전 팁

💡 - S3 기본 암호화를 활성화하면 업로드되는 모든 파일이 자동으로 암호화됩니다

  • 전송 중 암호화를 위해서는 HTTPS(TLS) 사용을 강제하세요

5. API 키 관리

새벽 3시, 김개발 씨의 전화가 울렸습니다. 보안팀 이보안 씨의 급박한 목소리가 들렸습니다.

"당신이 어제 푸시한 코드, GitHub에 API 키가 그대로 노출되어 있습니다. 벌써 50건의 무단 접근이 감지되었어요!" 김개발 씨는 잠이 확 깼습니다.

API 키 관리는 애플리케이션이 AWS 서비스에 접근하기 위한 인증 정보를 안전하게 보관하고 운영하는 프로세스입니다. 마치 은행 비밀번호를 안전하게 보관하는 것처럼, 코드에 직접 쓰지 않고 별도의 안전한 저장소에 보관해야 합니다.

AWS Secrets Manager나 Parameter Store를 활용합니다.

다음 코드를 살펴봅시다.

import boto3
import json

def get_secret_from_secrets_manager():
    # Secrets Manager 클라이언트 생성
    client = boto3.client('secretsmanager', region_name='ap-northeast-2')

    try:
        # 시크릿 가져오기
        response = client.get_secret_value(
            SecretId='prod/database/credentials'
            # 절대 코드에 직접 쓰지 않습니다
        )

        # JSON 형태의 시크릿 파싱
        secret = json.loads(response['SecretString'])

        # 안전하게 사용
        db_config = {
            'host': secret['host'],
            'username': secret['username'],
            'password': secret['password'],  # 코드에 노출 안 됨
            'database': secret['dbname']
        }
        return db_config

    except Exception as e:
        # 에러 처리
        print(f"시크릿 가져오기 실패: {str(e)}")
        raise

김개발 씨는 개발 속도를 높이려고 데이터베이스 비밀번호를 코드에 직접 입력했습니다. "로컬에서만 쓸 건데 뭐..." 하지만 습관적으로 git add .

명령을 실행했고, 프라이빗 레포지토리라고 생각하고 푸시했습니다. 문제는 레포지토리가 실수로 퍼블릭으로 설정되어 있었다는 것입니다.

보안팀의 자동화 도구가 GitHub를 스캔하다가 API 키 노출을 발견했습니다. 이미 봇들이 자동으로 크롤링해서 무단 접근을 시도하고 있었습니다.

API 키 관리란 정확히 무엇일까요? 쉽게 비유하자면, API 키 관리는 마치 집 열쇠를 관리하는 것과 같습니다.

집 열쇠를 현관문 앞 화분 밑에 숨겨두면 편리하지만 위험합니다. 마찬가지로 API 키를 코드에 직접 쓰면 편하지만 매우 위험합니다.

열쇠는 안전한 곳에 보관하고, 필요할 때만 꺼내 쓰는 것이 원칙입니다. API 키도 똑같습니다.

안전한 저장소에 보관하고, 런타임에만 불러와 사용하는 것입니다. API 키 관리가 제대로 안 되던 시절에는 어땠을까요?

많은 개발자들이 설정 파일이나 환경변수 파일을 Git에 그대로 커밋했습니다. .env 파일을 .gitignore에 추가하지 않고 올리는 경우가 부지기수였습니다.

2014년 Uber에서 개발자의 GitHub 계정이 해킹되면서 5만 명의 운전자 정보가 유출된 사건이 있었습니다. 하드코딩된 데이터베이스 키가 원인이었습니다.

더 큰 문제는 키 교체였습니다. 키가 노출되면 코드를 전부 수정해야 했습니다.

바로 이런 문제를 해결하기 위해 체계적인 API 키 관리가 필수가 되었습니다. API 키를 제대로 관리하면 키 노출 위험을 원천 차단할 수 있습니다.

코드에는 절대 키가 들어가지 않습니다. 또한 키 교체가 간편해집니다.

Secrets Manager에서 키만 업데이트하면 애플리케이션을 다시 배포할 필요 없습니다. 무엇보다 접근 로그를 추적할 수 있다는 큰 이점이 있습니다.

누가 언제 어떤 키를 사용했는지 모두 기록됩니다. 위의 코드를 한 줄씩 살펴보겠습니다.

먼저 Secrets Manager 클라이언트를 생성합니다. get_secret_value 메서드로 시크릿을 가져오는데, SecretId에는 미리 등록한 시크릿의 이름을 지정합니다.

여기서 중요한 점은 실제 비밀번호는 코드 어디에도 없다는 것입니다. 응답의 SecretString을 JSON으로 파싱하면 실제 값들을 얻을 수 있습니다.

이 값들을 데이터베이스 연결에 사용하지만, 코드를 읽어도 비밀번호를 알 수 없습니다. 에러 처리도 중요합니다.

시크릿을 가져오지 못하면 안전하게 실패해야 합니다. 실제 현업에서는 어떻게 활용할까요?

예를 들어 전자상거래 플랫폼에서 결제 API를 연동한다고 가정해봅시다. 토스페이먼츠나 네이버페이 같은 서비스의 API 키와 시크릿이 필요합니다.

이런 키를 Secrets Manager에 저장하고, 애플리케이션 시작 시 한 번만 불러와 메모리에 캐싱합니다. 키가 변경되어도 Secrets Manager에서만 업데이트하면 됩니다.

쿠팡, 11번가 같은 대형 커머스 플랫폼들은 수백 개의 외부 API 키를 이런 방식으로 관리합니다. 하지만 주의할 점도 있습니다.

초보 개발자들이 흔히 하는 실수 중 하나는 환경변수에 키를 저장하고 안심하는 것입니다. 환경변수도 시스템에 접근하면 볼 수 있습니다.

컨테이너 설정이나 EC2 인스턴스 메타데이터에 키가 노출될 수 있습니다. 이렇게 하면 내부자 위협에 취약합니다.

따라서 민감한 키는 반드시 Secrets Manager나 Parameter Store를 사용해야 합니다. 다시 김개발 씨의 이야기로 돌아가 봅시다.

이보안 씨와 함께 긴급하게 모든 API 키를 교체했습니다. 그리고 코드를 수정해서 Secrets Manager를 사용하도록 바꿨습니다.

"이제 GitHub에 아무리 올려도 키는 안전합니다." 김개발 씨는 고개를 끄덕였습니다. "정말 아찔한 순간이었어요.

앞으로는 절대 키를 코드에 쓰지 않겠습니다!" API 키 관리를 제대로 이해하면 더 안전한 애플리케이션을 만들 수 있습니다. 여러분도 오늘 배운 내용을 실제 프로젝트에 적용해 보세요.

실전 팁

💡 - Git에 키를 커밋했다면 히스토리를 완전히 삭제해도 이미 노출된 것입니다. 반드시 키를 교체하세요

  • AWS IAM 역할을 사용하면 EC2나 Lambda에서 키 없이도 AWS 서비스에 접근할 수 있습니다

6. 보안 베스트 프랙티스

1년 차가 된 김개발 씨에게 후배 최주니어 씨가 입사했습니다. "선배님, AWS 보안 설정이 너무 복잡해요.

어디서부터 시작해야 할까요?" 김개발 씨는 1년 전 자신의 모습이 떠올랐습니다. "제가 경험으로 배운 것들을 알려줄게요."

보안 베스트 프랙티스는 AWS 환경을 안전하게 운영하기 위한 검증된 방법론과 원칙들의 집합입니다. 마치 운전할 때 안전벨트를 매고 신호를 지키는 것처럼, 기본적이지만 반드시 지켜야 할 보안 규칙들입니다.

한 번 제대로 설정해두면 대부분의 보안 위협을 예방할 수 있습니다.

다음 코드를 살펴봅시다.

import boto3
from datetime import datetime, timedelta

def implement_security_best_practices():
    # 1. MFA 활성화 확인
    iam = boto3.client('iam')

    # 루트 사용자 MFA 상태 확인
    account_summary = iam.get_account_summary()
    if account_summary['SummaryMap']['AccountMFAEnabled'] == 0:
        print("경고: 루트 계정 MFA가 비활성화되어 있습니다!")

    # 2. 오래된 액세스 키 탐지
    users = iam.list_users()
    for user in users['Users']:
        access_keys = iam.list_access_keys(UserName=user['UserName'])
        for key in access_keys['AccessKeyMetadata']:
            created_date = key['CreateDate'].replace(tzinfo=None)
            age = (datetime.now() - created_date).days
            # 90일 이상 된 키는 교체 권장
            if age > 90:
                print(f"경고: {user['UserName']}의 키가 {age}일 경과")

    # 3. CloudTrail 활성화 확인
    cloudtrail = boto3.client('cloudtrail')
    trails = cloudtrail.describe_trails()
    if not trails['trailList']:
        print("경고: CloudTrail이 활성화되지 않았습니다!")

    # 4. S3 버킷 공개 접근 차단 확인
    s3 = boto3.client('s3')
    buckets = s3.list_buckets()
    for bucket in buckets['Buckets']:
        try:
            acl = s3.get_bucket_acl(Bucket=bucket['Name'])
            # 퍼블릭 읽기 권한 확인
            for grant in acl['Grants']:
                if grant['Grantee'].get('URI') == 'http://acs.amazonaws.com/groups/global/AllUsers':
                    print(f"경고: {bucket['Name']} 버킷이 공개되어 있습니다!")
        except:
            pass

김개발 씨는 1년간 여러 보안 사고를 겪으며 많은 것을 배웠습니다. API 키 노출 사건, 권한 설정 실수, 암호화 누락 등 작은 실수들이 큰 문제로 이어지는 것을 직접 경험했습니다.

이제 후배에게 이 경험을 전수할 차례입니다. 최주니어 씨가 물었습니다.

"보안 설정이 너무 많은데, 우선순위가 뭔가요?" 보안 베스트 프랙티스란 정확히 무엇일까요? 쉽게 비유하자면, 보안 베스트 프랙티스는 마치 건강 검진 체크리스트와 같습니다.

혈압 측정, 혈액 검사, 시력 검사 등 기본적인 항목들이 있습니다. 이것들을 정기적으로 확인하면 큰 병을 미리 예방할 수 있습니다.

AWS 보안도 똑같습니다. MFA 활성화, 로그 모니터링, 권한 최소화 같은 기본 항목들을 체크하면 대부분의 보안 사고를 막을 수 있습니다.

보안 베스트 프랙티스가 없던 시절에는 어땠을까요? 각 회사마다 제멋대로 보안을 설정했습니다.

어떤 곳은 루트 계정으로 모든 작업을 했고, 어떤 곳은 로그도 남기지 않았습니다. 문제가 생기면 원인을 찾을 수도 없었습니다.

2019년 Capital One 해킹 사건에서는 잘못 설정된 방화벽 때문에 1억 명의 고객 정보가 유출되었습니다. 더 큰 문제는 일관성 부족이었습니다.

팀마다 보안 수준이 달라서 가장 약한 고리가 전체를 위험하게 만들었습니다. 바로 이런 문제를 해결하기 위해 표준화된 보안 베스트 프랙티스가 확립되었습니다.

보안 베스트 프랙티스를 따르면 보안 수준을 일정하게 유지할 수 있습니다. 모든 팀이 같은 기준을 따릅니다.

또한 컴플라이언스 감사를 통과하기 쉬워집니다. ISO 27001, SOC 2 같은 인증을 받을 때 필수 요구사항들입니다.

무엇보다 자동화가 가능하다는 큰 이점이 있습니다. 체크리스트를 코드로 만들어서 자동으로 점검할 수 있습니다.

위의 코드를 한 줄씩 살펴보겠습니다. 먼저 루트 계정의 MFA 활성화 여부를 확인합니다.

루트 계정은 모든 권한을 가지므로 반드시 MFA로 보호해야 합니다. 다음으로 오래된 액세스 키를 탐지합니다.

90일 이상 사용한 키는 보안상 위험하므로 교체를 권장합니다. CloudTrail 활성화 여부도 확인합니다.

CloudTrail이 없으면 누가 무엇을 했는지 추적할 수 없습니다. 마지막으로 S3 버킷의 공개 접근 권한을 점검합니다.

의도치 않게 민감한 데이터가 인터넷에 노출될 수 있습니다. 실제 현업에서는 어떻게 활용할까요?

예를 들어 스타트업이 MVP를 런칭한다고 가정해봅시다. 빠르게 개발하느라 보안은 뒷전이 되기 쉽습니다.

하지만 처음부터 베스트 프랙티스를 적용하면 나중에 보안 사고를 예방할 수 있습니다. 루트 계정 MFA 활성화, IAM 역할 사용, 모든 데이터 암호화, CloudTrail 로깅, AWS Config로 설정 모니터링 등을 자동화합니다.

당근마켓, 토스 같은 유니콘 기업들도 초기부터 이런 원칙을 지켰습니다. 하지만 주의할 점도 있습니다.

초보 개발자들이 흔히 하는 실수 중 하나는 체크리스트만 따르고 이해하지 않는 것입니다. 왜 MFA가 필요한지, 왜 로그를 남겨야 하는지 이해하지 못하면 예외 상황에 대처할 수 없습니다.

이렇게 하면 형식적인 보안에 그치고 실제 위협에는 취약할 수 있습니다. 따라서 각 원칙의 목적과 배경을 이해하는 것이 중요합니다.

다시 김개발 씨의 이야기로 돌아가 봅시다. 최주니어 씨에게 체크리스트를 하나씩 설명해줬습니다.

"이 항목들만 지켜도 80%의 보안 사고를 막을 수 있어요. 저도 처음엔 어렵게 느껴졌지만, 익숙해지면 자동으로 하게 됩니다." 최주니어 씨는 고개를 끄덕였습니다.

"선배님 경험을 바탕으로 배우니까 훨씬 이해가 잘 돼요!" 보안 베스트 프랙티스를 제대로 이해하면 더 안전한 시스템을 만들 수 있습니다. 여러분도 오늘 배운 내용을 실제 프로젝트에 적용해 보세요.

실전 팁

💡 - AWS Well-Architected Framework의 보안 원칙을 정기적으로 검토하세요

  • AWS Security Hub를 활성화하면 베스트 프랙티스 준수 여부를 자동으로 점검할 수 있습니다

이상으로 학습을 마칩니다. 위 내용을 직접 코드로 작성해보면서 익혀보세요!

#AWS#IAM#VPC#Encryption#Security

댓글 (0)

댓글을 작성하려면 로그인이 필요합니다.