16장. EC2 접속과 권한 — 키 페어 · Session Manager · IAM Role
이 장에서 말하고자 하는 것
EC2를 띄웠다면 다음 질문이 생긴다.
“이 서버에 어떻게 접속해서 들어가지?” “이 서버 안의 코드는 어떻게 AWS API를 호출하지?”
이 둘은 다른 문제다.
- 사람 → 서버 접속 — SSH · Session Manager
- 서버 코드 → AWS API — IAM Role (Instance Profile)
이 장은 이 두 가지를 각각 정리한다.
1. 전통 방식 — SSH + 키 페어
키 페어 생성
EC2를 만들 때 키 페어를 선택한다.
공개 키 → AWS가 EC2 안에 자동 설치
비공개 키(.pem) → 사용자가 보관
접속
ssh -i my-key.pem ec2-user@<public-ip>
ec2-user(Amazon Linux),ubuntu(Ubuntu) 등 OS별 기본 사용자- 22번 포트가 열려 있어야 함
키 페어 운영의 어려움
.pem파일을 누가 가졌는지 추적이 어렵다- 키 회전이 번거롭다
- 22 포트를 인터넷에 노출 → 공격 표면
- 누가 언제 접속했는지 감사 로그가 약하다
운영 환경에서 SSH 키는 점점 안 쓰는 방향이다
2. 더 나은 방식 — AWS Systems Manager Session Manager
[운영자] → AWS 콘솔 / CLI → IAM 검증 → Session Manager → EC2
- SSH 키 불필요
- 22 포트 열 필요 없음 (그래서 인터넷에서도 차단 가능)
- IAM 권한으로 누가 접속할 수 있는지 통제
- CloudTrail에 모든 세션 기록 (선택적으로 명령까지 기록)
- 프라이빗 서브넷의 EC2도 직접 접속 가능 (VPC Endpoint 필요)
운영 환경의 기본은 Session Manager 다
3. Session Manager의 동작
1. EC2에 SSM Agent 설치 (Amazon Linux 2023 · Ubuntu 최근 버전은 기본 설치)
2. EC2에 IAM Role 부여 → AmazonSSMManagedInstanceCore
3. EC2가 시작 시 SSM 서비스에 연결 (아웃바운드 443)
4. 운영자가 콘솔/CLI에서 세션 시작
22 포트도, 키 페어도, 인터넷 노출도 필요 없다.
4. EC2가 AWS API를 호출하려면 — IAM Role + Instance Profile
EC2 안의 코드가 S3를 읽거나 DynamoDB에 쓰려면 권한이 필요하다.
[EC2]
↑ 받음
[Instance Profile]
↑ 담음
[IAM Role]
├─ Trust Policy: ec2.amazonaws.com이 받을 수 있음
└─ Permission Policy: S3 GetObject 등
EC2 안에서
aws s3 ls
를 그냥 호출하면 자동으로 임시 자격증명이 사용된다.
EC2 안에 액세스 키를 절대 박지 않는다
Instance Profile + Role이 그 자리를 대신한다
5. Instance Metadata Service (IMDS)
EC2 안에서 자기 정보를 조회하는 API.
http://169.254.169.254/latest/meta-data/
여기서
- 자기 인스턴스 ID
- 자기 IAM Role의 임시 자격증명
- 자기 보안 그룹 ID
- 자기 사용자 데이터
등을 받을 수 있다.
IMDSv1 vs IMDSv2
IMDSv1은 보안 취약점이 있어 SSRF 공격으로 악용될 수 있었다.
신규 인스턴스는 무조건 IMDSv2 only 로
HttpTokens = required
HttpPutResponseHopLimit = 1
6. Bastion vs Session Manager
옛날 패턴 — 외부 노출된 작은 EC2 (Bastion) 를 거쳐 내부 EC2로 SSH.
운영자 → Bastion (퍼블릭) → 내부 EC2
문제:
- Bastion 자체가 공격 표면
- 키 관리 · 패치 운영 부담
- 감사 로그 약함
Session Manager를 쓰면 Bastion 자체가 불필요해진다
정말 SSH가 필요한 환경에서만 Bastion 운영
7. 우리 서비스에서
이 책의 척추는 ECS Fargate라 사람이 컨테이너에 접속할 일이 거의 없다.
사람 → 운영용 일회성 컨테이너 (ECS Exec)
↑ SSM 동일 메커니즘
- ECS Exec — 컨테이너 안에 셸 접속하는 ECS 기능
- 권한 모델은 SSM과 같다 (IAM)
EC2 직접 운영이 필요한 경우 (예: 일부 워커, GPU 노드):
[운영자] → Session Manager → EC2 (프라이빗 서브넷)
↑
VPC Endpoint (com.amazonaws.region.ssm)
8. 직접 확인해보기 — CLI
Session Manager 접속
aws ssm start-session --target i-1234567890abcdef0
브라우저 없이 터미널에서 바로 셸이 열린다.
EC2 안에서 자기 자격증명 보기 (IMDSv2)
TOKEN=$(curl -s -X PUT "http://169.254.169.254/latest/api/token" \
-H "X-aws-ec2-metadata-token-ttl-seconds: 21600")
curl -s -H "X-aws-ec2-metadata-token: $TOKEN" \
http://169.254.169.254/latest/meta-data/iam/security-credentials/
ECS Exec — 컨테이너 셸 접속
aws ecs execute-command \
--cluster msa \
--task <task-id> \
--container app \
--interactive \
--command "/bin/sh"
9. 코드로는 이렇게 생겼다 — Terraform
# IAM Role (Session Manager + 애플리케이션 권한)
resource "aws_iam_role" "web" {
name = "web-role"
assume_role_policy = jsonencode({
Version = "2012-10-17"
Statement = [{
Effect = "Allow"
Principal = { Service = "ec2.amazonaws.com" }
Action = "sts:AssumeRole"
}]
})
}
resource "aws_iam_role_policy_attachment" "ssm" {
role = aws_iam_role.web.name
policy_arn = "arn:aws:iam::aws:policy/AmazonSSMManagedInstanceCore"
}
resource "aws_iam_instance_profile" "web" {
name = "web-instance-profile"
role = aws_iam_role.web.name
}
resource "aws_instance" "web" {
ami = data.aws_ami.web.id
instance_type = "t3.small"
subnet_id = aws_subnet.private_a.id # 프라이빗
iam_instance_profile = aws_iam_instance_profile.web.name
# IMDSv2 강제
metadata_options {
http_tokens = "required"
http_put_response_hop_limit = 1
}
# SSH 안 열어도 됨 (Session Manager 사용)
vpc_security_group_ids = [aws_security_group.web.id]
}
AmazonSSMManagedInstanceCore 한 줄이 Session Manager의 핵심.
10. 이렇게 쓰면 망한다 — 안티패턴
안티패턴 1. 22번 포트를 0.0.0.0/0 에 연다
“잠깐 디버깅” 으로 연 포트가 영영 열려 있다.
Session Manager로 가서 22를 닫는다
안티패턴 2. .pem 키를 Slack/이메일로 공유
누가 가졌는지 추적 안 됨, 퇴사자 회수 어려움.
안티패턴 3. EC2 안에 AWS 액세스 키를 박는다
가장 흔한 보안 사고. 코드 저장소에 박히기까지 한다.
Instance Profile + Role 외 다른 길은 없다
안티패턴 4. IMDSv1을 그대로 두는 옛 인스턴스
신규는 IMDSv2 only. 옛 인스턴스도 점진 전환.
11. 한 줄로 정리
사람 접속은 Session Manager, 코드의 AWS 호출은 Instance Profile + Role.
22 포트와 키 페어는 점점 자리를 비운다.
12. 이 장의 핵심 정리
- 사람 → EC2 접속은 Session Manager가 표준이다.
- EC2 안 코드의 AWS 호출은 Instance Profile + IAM Role 로.
- EC2 안에 액세스 키 박지 않는다.
- IMDSv2 only가 신규 인스턴스의 기본값.
- Bastion은 거의 불필요 — Session Manager + 프라이빗 서브넷.
- ECS Exec은 같은 메커니즘으로 컨테이너 셸을 연다.