티스토리 뷰
개요
이전 글 : Private Subnet에 있는 AWS RDS에 접근하기 1. Bastion + SSH with. DBeaver
bastion 점프 서버와 SSH만을 이용해서 상용 DB에 접근하게 된다면, 팀원들이 각각 로컬에 pem key를 갖고 있어야 한다는 너무나 큰 문제가 있다. 이 문제의 가장 보편적인 대안인 AWS SSM을 이용한 방식을 사용해보려고 한다.
AWS SSM은 SSH만 쓰는 것 보다 어떤 측면에서는 더 쉽고 간단하며, 더 많은 관리자로서의 기능을 제공한다.
하나씩 알아보자.
1. AWS SSM 이란?
https://docs.aws.amazon.com/ko_kr/systems-manager/latest/userguide/session-manager.html
Session Manager는 완전 관리형 AWS Systems Manager 도구입니다. Session Manager를 사용하여 Amazon Elastic Compute Cloud(Amazon EC2) 인스턴스, 엣지 디바이스, 온프레미스 서버 및 가상 머신을 관리할 수 있습니다. 대화형 원클릭 브라우저 기반 쉘 또는 AWS Command Line Interface(AWS CLI)을 사용할 수 있습니다. Session Manager는 인바운드 포트를 열고 배스천 호스트를 유지 관리하거나 SSH 키를 관리할 필요 없이 안전한 노드 관리 기능을 제공합니다.
위에서 잘 설명해줬다. ssh 키 관리가 필요 없이 bastion에 접근이 가능하며, 누가 세션을 사용 중인지 그리고 로깅, 접속 관리까지 다 할 수 있다고 설명되어 있었다. 나한텐 로깅 기능이 너무 필요해서 이거면 되겠다 하고 작업을 시작했다.
그리고 결론부터 이야기하면 내 요구사항에는 맞지 않았다. 그래도 한번 시도해본 결과를 공유해보려고 했다.
2. EC2 bastion Host + SSM을 이용한 점프 서버로 RDS와 연결하기
SSH pem key 대신해 AWS CLI의 SSM을 이용해 EC2에 접속하고, 포트포워딩을 통해 RDS에 접속하는 방식이다. 쉽게 생각하면 pem key 대신 IAM을 쓴다는 개념이다. 공식 문서에 따르면 기존 인스턴스에도 AmazonSSMManagedInstanceCore 역할이 있는 IAM Role을 붙이고 재시작하면 바로 SSM이 붙어야 한다. 하지만 내 경우엔 SSM 연결이 안되거나, Managed Instances 목록에 노출되지 않음 등의 문제가 있었고, 결국 새로 인스턴스를 띄웠더니 정상적으로 연결되었다.
3. Terraform 코드
####################################
# 1. 최신 Amazon Linux 2 AMI
####################################
data "aws_ami" "amazon_linux" {
most_recent = true
owners = ["amazon"]
filter {
name = "name"
values = ["amzn2-ami-hvm-*-x86_64-gp2"]
}
filter {
name = "virtualization-type"
values = ["hvm"]
}
}
####################################
# 2. SSM용 IAM Role 생성
####################################
resource "aws_iam_role" "ssm_instance_role" {
name = "ssm-role-for-ec2"
assume_role_policy = jsonencode({
Version = "2012-10-17",
Statement = [
{
Effect = "Allow",
Principal = {
Service = "ec2.amazonaws.com"
},
Action = "sts:AssumeRole"
}
]
})
}
####################################
# 3. SSM 정책 attach
####################################
resource "aws_iam_role_policy_attachment" "ssm_core_attach" {
role = aws_iam_role.ssm_instance_role.name
policy_arn = "arn:aws:iam::aws:policy/AmazonSSMManagedInstanceCore"
}
resource "aws_iam_role_policy_attachment" "cloudwatch_logs_attach" {
role = aws_iam_role.ssm_instance_role.name
policy_arn = "arn:aws:iam::aws:policy/CloudWatchAgentServerPolicy"
}
####################################
# 4. IAM Instance Profile
####################################
resource "aws_iam_instance_profile" "ssm_profile" {
name = "ssm-instance-profile"
role = aws_iam_role.ssm_instance_role.name
}
####################################
# 5. SSM 접속 가능한 EC2 인스턴스
####################################
resource "aws_instance" "bastion" {
ami = data.aws_ami.amazon_linux.id
instance_type = "t3.micro"
subnet_id = data.terraform_remote_state.vpc.outputs.public_subnets[0]
vpc_security_group_ids = [data.terraform_remote_state.security_group.outputs.bastion_sg_id]
associate_public_ip_address = true
iam_instance_profile = aws_iam_instance_profile.ssm_profile.name
tags = {
Name = "bastion-ssm-enabled"
Environment = terraform.workspace
}
}
####################################
# 6. CloudWatch 로그 그룹 (SSM 세션용)
####################################
resource "aws_cloudwatch_log_group" "ssm_session_logs" {
name = "/aws/ssm/session-logs"
retention_in_days = 1
}
별다른 설명이 필요없다. cloud watch 로그 그룹까지 만들어졌으면 추가적인 설정을 해야한다.
4. AWS CLI와 로깅 활성화
cmd에서 아래와 같이 입력하면 접속이 된다.
aws ssm start-session \
--target i-0123456789abcdef0 \
--document-name "AWS-StartPortForwardingSessionToRemoteHost" \
--parameters '{\"host\":[\"your-db.cluster-xxxxxxxxxxxx.region.rds.amazonaws.com\"],\"portNumber\":[\"5432\"],\"localPortNumber\":[\"15433\"]}'
DBeaver를 사용한다면 ssh 터널링을 끄고, 그냥 localhost와 포트를 매칭시켜서 접속하면 된다.
AWS Systems Manager > 세션 관리자 > 기본 설정 탭에서 위에서 만든 session-logs 로그 그룹을 등록해준다. 그러면 로그가 잘 나온다고 한다.
문제는 여기서 발생하는데.....
5. 문제점
https://docs.aws.amazon.com/ko_kr/systems-manager/latest/userguide/session-manager-logging.html
포트 전달 또는 SSH를 통해 연결하는 Session Manager 세션에는 로깅을 사용할 수 없습니다. SSH는 모든 세션 데이터를 암호화하고 Session Manager는 SSH 연결을 위한 터널 역할만 하기 때문입니다.
내 요구 사항 중 가장 중요한 것이 로그였는데, 아무리 만져봐도 로그가 안남길래 너무 이상해서 알아봤더니 공식 문서에 딱 적혀 있었다. 그래서 결국 다른 접근제어 어플리케이션을 찾아보게 됐는데.... 일단 첫 번째로 고른게 teleport였다.
마치며
AWS의 공식문서들은 다른 벤더에 비하면 진짜 잘 정리되어있다. 그러나 잘 정리되어있는건 좋은데 내용들이 너무 많아서 내가 필요한 것들과 가이드대로 적용했을 때 어떤 결과가 나오는지까지는 잘 분류되어 있지 않다. 설정 방법이 쭉 나열되어 있고, 결과는 또 따로 나열되어 있어서 찾기가 너무 어렵다... 그래서 다하고 나서 문제가 있다는 것을 파악해버렸다.
이제 진짜 어려운 방식인 접근제어 오픈소스를 사용하는 방법만 남아버렸다. 접근제어 오픈소스를 사용한다면 다양한 오픈소스와의 비교도 필요하고 옵션을 선택함에 있어서 많은 편의성들이 희생되기 때문에 잘할 수 있을지 모르겠다....
'개발 > AWS' 카테고리의 다른 글
Private Subnet에 있는 AWS RDS에 접근하기 1. Bastion + SSH with. DBeaver (0) | 2025.04.16 |
---|---|
AWS ECS 기초부터 파악해보기 (0) | 2025.01.31 |
Terraform으로 AWS Parameter Store 사용하기 + 하기 쉬운 실수 (0) | 2025.01.31 |
CloudFront 403 에러 원인을 찾아가는 여정 feat. WAF (1) | 2024.11.02 |
Spot 인스턴스로 운영 되던 서버 문제 해결하기 (0) | 2024.08.26 |
- Total
- Today
- Yesterday
- AWS
- ChatGPT
- OpenAI
- springboot
- JWT
- MySQL
- CloudFront
- AWS EC2
- 스프링부트
- Log
- 티스토리챌린지
- Spring
- serverless
- cache
- Elastic cloud
- 오블완
- openAI API
- S3
- 후쿠오카
- lambda
- java
- terraform
- EKS
- object
- Kotlin
- 람다
- AOP
- docker
- elasticsearch
- GIT
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | ||
6 | 7 | 8 | 9 | 10 | 11 | 12 |
13 | 14 | 15 | 16 | 17 | 18 | 19 |
20 | 21 | 22 | 23 | 24 | 25 | 26 |
27 | 28 | 29 | 30 |