이 문서를 통해 아래 질문들에 답할 수 있게 됩니다.
- VPC, Subnet, Security Group은 요청 경로에서 각각 무엇을 결정하는가?
- 보안 그룹 변경 후 특정 API만 실패할 때 무엇을 확인해야 하는가?
- 백엔드 개발자는 네트워크 장애 분석에 어떤 정보를 제공해야 하는가?
개요
VPC는 클라우드 안의 논리적 네트워크 경계다.
Subnet은 그 VPC 안에서 public 또는 private 자원을 배치하는 구역이다.
Security Group은 어떤 source가 어떤 port로 어떤 resource에 접근할 수 있는지 정하는 방화벽 규칙이다.
백엔드 개발자는 네트워크를 직접 설계하지 않더라도 애플리케이션이 어떤 경로로 요청을 받고 어떤 외부 시스템으로 나가는지 설명해야 한다.
네트워크 문제는 애플리케이션 오류처럼 보이지만 로그만 봐서는 원인을 찾기 어렵다.
요청 경로
일반적인 백엔드 요청 경로는 다음과 같다.
internet
public subnet: Load Balancer
private subnet: application VM
private subnet: managed DB
internet egress: external payment API각 단계에는 다른 네트워크 규칙이 있다.
- Load Balancer는 인터넷에서 80/443을 받는다.
- 애플리케이션 VM은 Load Balancer에서 오는 8080만 받는다.
- DB는 애플리케이션 보안 그룹에서 오는 5432만 받는다.
- 외부 API 호출은 NAT나 egress rule을 통해 나간다.
이 경로 중 하나가 막히면 Spring 애플리케이션에서는 timeout, connection refused, name resolution error로 보일 수 있다.
Public과 Private Subnet
Public subnet은 인터넷 gateway로 직접 나갈 수 있는 경로를 가진다.
Private subnet은 보통 인터넷에서 직접 접근할 수 없고 Load Balancer나 NAT를 통해 통신한다.
운영에서는 다음 원칙을 많이 쓴다.
- Load Balancer는 public subnet에 둔다.
- 애플리케이션 VM은 private subnet에 둔다.
- DB는 private subnet에 둔다.
- SSH는 bastion 또는 session manager 같은 통제 경로를 쓴다.
- 외부 API 호출은 NAT와 egress 정책을 통해 관리한다.
모든 자원을 public subnet에 두면 처음에는 편하지만 장애와 보안 사고의 범위가 커진다.
Security Group 예시
보안 그룹은 source와 target을 명확히 표현해야 한다.
resource "aws_security_group_rule" "alb_to_app" {
type = "ingress"
security_group_id = aws_security_group.app.id
source_security_group_id = aws_security_group.alb.id
protocol = "tcp"
from_port = 8080
to_port = 8080
description = "ALB to Spring API"
}
resource "aws_security_group_rule" "app_to_db" {
type = "ingress"
security_group_id = aws_security_group.db.id
source_security_group_id = aws_security_group.app.id
protocol = "tcp"
from_port = 5432
to_port = 5432
description = "Spring API to PostgreSQL"
}CIDR을 넓게 여는 것보다 보안 그룹 간 참조를 쓰면 의도를 더 분명하게 남길 수 있다.
장애 분석
네트워크 장애는 “애플리케이션이 느리다”로 접수되는 경우가 많다.
먼저 통신 방향을 나눈다.
- 사용자가 Load Balancer까지 도달하는가?
- Load Balancer가 application target에 도달하는가?
- application이 DB에 도달하는가?
- application이 외부 API에 나갈 수 있는가?
- DNS resolve가 되는가?
- TLS handshake가 성공하는가?
각 질문은 다른 팀과 다른 로그를 필요로 한다.
백엔드 로그에는 Connect timed out, Connection refused, UnknownHostException처럼 다른 단서가 남을 수 있다.
관찰 명령
aws ec2 describe-security-groups --group-ids "$APP_SG_ID"
aws ec2 describe-route-tables --filters "Name=vpc-id,Values=$VPC_ID"
aws ec2 describe-subnets --filters "Name=vpc-id,Values=$VPC_ID"VM에서 읽기 테스트를 할 수 있다면 다음처럼 확인한다.
nc -vz db.internal.example.com 5432
curl -v https://payment.example.com/status
dig db.internal.example.com명령은 어디에서 실행했는지가 중요하다.
개인 노트북에서 성공한 통신이 private subnet의 애플리케이션 VM에서도 성공한다는 뜻은 아니다.
장애 신호
- 보안 그룹 변경 후 DB 연결만 timeout 된다.
- 외부 결제 API 호출만 실패하고 내부 API는 정상이다.
- 특정 subnet에 있는 VM만 Load Balancer target에서 제외된다.
- DNS 이름은 맞지만 private IP 대역이 기대와 다르다.
- 새로 만든 VM은 DB에 접속하지 못하지만 기존 VM은 접속한다.
- egress 제한 후 메일, 문자, 결제 연동이 실패한다.
이 신호는 애플리케이션 코드보다 네트워크 경로와 보안 규칙을 먼저 확인해야 한다는 뜻이다.
안전한 완화 조치
- 막힌 방향을 먼저 확인하고 필요한 port만 임시로 연다.
- 0.0.0.0/0 대신 특정 보안 그룹이나 CIDR로 범위를 제한한다.
- 임시 rule에는 만료 시각과 제거 담당자를 기록한다.
- 외부 API egress 문제는 NAT, route, DNS, TLS를 분리해 확인한다.
- DB 접근 rule 변경은 애플리케이션 보안 그룹 기준으로 제한한다.
- 변경 전후 규칙을 export해 비교할 수 있게 남긴다.
네트워크 완화는 빠르지만 과하게 열면 보안 사고로 이어진다.
하지 말아야 할 대응
- 원인을 모른 채 모든 inbound port를 열지 않는다.
- 임시로 연 0.0.0.0/0 rule을 기록 없이 방치하지 않는다.
- DB를 public subnet으로 옮겨 문제를 해결하려 하지 않는다.
- 노트북에서 통신된다는 이유로 서버 네트워크가 정상이라고 판단하지 않는다.
- Security Group, route table, DNS를 동시에 바꿔 효과를 알 수 없게 만들지 않는다.
인프라 담당자와 공유할 자료
- 요청 방향: user to LB, LB to app, app to DB, app to external API
- source와 target의 resource id, private IP, port
- 실패한 endpoint와 exception 메시지
- 최근 보안 그룹, route, DNS 변경 시각
- 어느 위치에서 실행한 연결 테스트인지
- 임시로 열어도 되는 최소 port와 source 범위
공유 자료는 “네트워크가 안 된다”가 아니라 “이 source에서 이 target의 이 port가 실패한다”로 정리해야 한다.
운영 체크리스트
- public/private subnet 배치 기준이 문서화되어 있는가?
- 보안 그룹 rule마다 목적과 owner가 있는가?
- 애플리케이션 outbound 의존성이 목록화되어 있는가?
- DB 접근 source가 애플리케이션 보안 그룹으로 제한되어 있는가?
- 임시 rule 제거 절차가 있는가?
- 장애 중 연결 테스트 위치를 기록하는가?
확인 질문
확인 질문
- Security Group 장애 분석에서 가장 중요한 세 요소는 무엇인가?
- source, target, port/protocol이다.
- 노트북에서 DB 접속이 된다고 애플리케이션 VM에서도 된다고 말할 수 없는 이유는 무엇인가?
- 실행 위치가 다르면 subnet, route, 보안 그룹, DNS 경로가 다를 수 있기 때문이다.
- 임시 방화벽 완화에서 반드시 남겨야 할 것은 무엇인가?
- 열린 범위, 이유, 만료 시각, 제거 담당자다.
리뷰 체크포인트
- 요청 경로가 public/private subnet 기준으로 설명되는가?
- source와 target을 보안 그룹 기준으로 표현하는가?
- inbound와 outbound 장애를 구분하는가?
- 임시 rule의 제거 기준이 있는가?
- 백엔드 exception과 네트워크 경로가 연결되는가?