AWS 개발/운영, 운영/운영 시스템 간 접근 통제 점검하기(VPC 기준)
클라우드 점검 시 접근통제 확인해야하는데.. 도대체 어디를 봐야하는지 모르겠어서 정리.
1. 점검 내용
개발/운영, 운영/운영 시스템 간 접근 통제를 잘하고 있는지 확인하는 내용이다.
🔐 왜 ?
만약 개발 서버(dev1)가 해킹당하면,
→ 운영 서버(ops1)로 접근해서 피해를 더 키울 수 있어.
그래서 기본적으로 어쩔 수 없는 개발 상의 이유로 개발/개발 시스템 간의 접근을 제외하고는 모두 통제하는게 보안상 좋다.
1.1 개발 VPC, 운영 VPC 이해
서브넷 단위로 개발, 운영을 나누는 것도 이론 상 가능하지만, 보통 공공기관, 대기업은 VPC 단위로 나누어진다.
네트워크 구성도를 먼저 보면 좋다. 어떤 VPC가 개발 VPC인지 운영 VPC인지 사전에 파악해야 확인을 하기 때문..
VPC로 나누지 않고, Subnet 단위로 나누거나, 그냥 EC2 단위로 나눌 경우에는 2단계, 3단계만 확인해주자.
2. 점검 방법
2.1 [1단계] VPC 간의 연결 확인(Peering, Tramsit Gateway)
VPC 간 연결하려면, 일단 Peering 혹은 Transit Gateway 연결이 필요하다.
Peering 이란 ?
단일 VPC 들을 1:1 연결 (직접 연결) 해주는 서비스. 집과 집 사이에 직접 놓는 사다리라고 비유할 수 있다
Transit Gateway 란?
여러 VPC나 온프레미스 네트워크를 연결해주는 중앙 허브 역할을 하는 AWS 서비스. 단톡방이라고 비유할 수 있다. 여기에 연결하면 연결한 애들끼리 라우팅을 해주면 서로 연결됨!
🎯 언제 무엇을 써야 할까?
VPC 2~ 3개 만 연결 👉 피어링 연결
VPC가 여러 개 (5개 이상) / 온프레미스도 연결해야 함 / 중앙통제 원함 👉 Transit Gateway
1) peering 연결 확인
📍 확인 위치:
- AWS Console > VPC > 피어링 연결
🚀 체크할 것
- 활성화됨(Active)이면 두 VPC 간 통신 가능한 상태일 수 있음
- 요청자/수락자 VPC ID 확인해서 개발/운영 VPC인지 파악
2) Transit Gateway 연결 확인(VPC 연결)
📍 확인 위치:
1. Transit Gateway Attachments (물리적 연결)
- AWS 콘솔 > VPC > Transit Gateway > 연결 (Attachments)
2. Transit Gateway 라우팅 테이블 (논리적 연결)
- AWS 콘솔 > VPC > Transit Gateway > Transit Gateway 라우팅 테이블
🚀 체크할 것
1. Transit Gateway Attachments (물리적 연결)
- 연결되어있는 VPC 확인(불필요하게 운영VPC가 연결되어있는지)
- 운영VPC와 개발VPC가 모두 연결되어있으면 서로 연결되어있을 가능성이 있으므로 확인
- ResourceID 란에서 확인 가능
2. Transit Gateway 라우팅 테이블 (논리적 연결)
- 물리적 연결에서 연결되어있는 것들이 논리적으로 연결되어있는지 확인.
둘다 그냥 연결한다고 서로 통신할 수 있는건 아니고, 라우팅 테이블에 등록해줘야한다. 근데 이걸 안하면 아예 연결이 안되니 이걸 먼저해야하나보다. 그래서 연결이 되어있더라도, 실제로 연결이 되었는지 보려면 라우팅테이블이랑 보안그룹들도 확인해줘야한다.
연결은 파이프 설치, 라우팅은 "어디로 물 흘릴지" 방향표를 다는 작업이에요. ~ 둘 다 있어야 물이 흘러요 🚰
2.2 [2단계] 라우팅 테이블 확인
라우팅 테이블에서도 어떻게 설정했는지 확인해보자. Peering과 TGW의 방식이 다르기때문에 각자 알아보자.
📍 확인 위치:
- AWS 콘솔 > VPC > 라우팅테이블
1)1단계에서 Peering으로 연결되어있을 경우
🚀 체크할 것
- 아까 Peering 으로 연결되어있던 VPC의 라우팅 테이블 확인
- 실제로 라우팅 테이블에서도 서로의 대역대가 허용되어있는지 확인
- 피어링 연결에서 DNS 설정 확인
🧭 예시
- 아래 와같이 vpc-dev1과 vpc-op가 서로 peering으로 연결되어있다고 가정해보자
- 라우팅 테이블설정은 아래와 같이 각각 서로의 CIDR을 향하도록 설정해준다.
- 해당 Peering 연결 DNS 설정에서 아래와 같이 설정되어있어야 실제로 Peering이 된다.
2)1단계에서 TGW(VPC)로 연결되어있을 경우
🚀 체크할 것
- 아까 TGW에 연결되어있던 VPC들의 라우팅 테이블 확인
- 실제로 라우팅 테이블에도 TGW로 연결되어있는지 확인
- 아래와 같이 tgw- 로 시작하는 target이 연결되어있으면 연결되어있는것.
대역대를 직접 확인하면 좋은데, 아래 예시를 들어 설명해보겠다
🔧 예시
1. 3개의 VPC가 아래와 같이 CIDR을 갖고 있다고 가정하고, 세개 모두 TGW에 연결했다고 하자.
VPC A | 10.1.0.0/16 |
VPC B | 10.2.0.0/16 |
VPC C | 10.3.0.0/16 |
2. 각각의 VPC 라우팅 테이블에 아래와 같이 10.0.0.0/8 로 설정하면 3개의 VPC가 모두 통신할 수 있다.
⁉️ VPC에 여러개의 라우팅 테이블이 있으면 그 중 어떤 라우팅 테이블을 따라가지..?
- 실제로 VPC - VPC 에서 연결되는게아니라 인스턴스 - 인스턴스로 연결되게 된다.
- 인스턴스는 특정 서브넷에 연결되고, 특정 서브넷은 반드시 하나의 라우팅 테이블에 연결된다. 그래서 그 때 연결되는 라우팅테이블을 따라가게 된다.
- 서브넷끼리 다른 라우팅 테이블을 사용해서 관리하는게 운영상 필요한 경우도 있어서 VPC내에 여러 라우팅 테이블을 만들어두고 사용한다고 보면 된다.
[인스턴스는 길을 가고, 라우팅 테이블은 지도 역할을 한다..!!]
- VPC 안에는 여러 개의 서브넷(방)과 라우팅테이블(지도)이 있고, 각 서브넷엔 컴퓨터(사람)가 있다.
- 서브넷(방)마다 연결된(부착된) 라우팅 테이블(지도)이 다를 수 있다.
- 컴퓨터(사람)는 자기 서브넷(방)에 연결된(부착된)라우팅 테이블(지도)을 따라 네트워크(길)를 이동한다.
⁉️ 라우팅 테이블 보는 법
Destination Target ✅ IP 갯수 ✅ 서비스
-------------------------------------------------------------------------------------------------------------------------
10.0.0.0/16 local 약 65,000개 내부 통신. (같은 VPC 안의 인스턴스들끼리 통신)
10.0.0.0/8 tgw-123123123123 약 16,777,216개 TGW(외부 VPC)
0.0.0.0/0 igw-123123123123 전세계 인터넷 전체 외부 사이트,퍼블릭 주소 등에 접근할 때 사용
해당 라우팅테이블이 연결된 서브넷 안에 있는 모든 인스턴스가 특정 IP를 요청할때 라우팅 테이블을 참조해서 그 IP가 어떤 목적지(Destination)에 해당하는지 확인하고 그에 맞는 Target(목적지로 가는 경로)으로 트래픽을 보낸다.
✅ 10.0.5.10 요청
- 10.0.5.10은 10.0.0.0/16에 정확히 포함됨. 그래서 local로 보냄. (같은 VPC 내부로 통신)
>> VPC 내부로 바로 통신
✅ 10.20.30.40 요청
10.20.30.40은 10.0.0.0/16에는 안 들어감 하지만 10.0.0.0/8에는 들어감! 그래서 Transit Gateway(tgw-123...)로 보냄
>> 다른 VPC나 외부 네트워크로 연결
✅ 8.8.8.8 요청 (구글 DNS)
10.0.0.0/16, 10.0.0.0/8 다 안 맞음 그래서 0.0.0.0/0에 해당됨 (모든 IP 포함하는 기본 경로) 인터넷 게이트웨이(igw-123...)로 보냄
>> 인터넷으로 나감
당연한 말이지만 라우팅 테이블들이 서브넷에 연결되어있고, 인스턴스에 연결되어있어야 작동한다. 따라서 연결된 라우터들이 어디에 붙어있는지, 실제로 사용하는 라우터테이블인지 확인은 필수. 다 설정되어있더라도 실제로 라우팅 테이블을 사용하고 있지않으면 서로 소통안하고 있다고 보면 된다.
이렇게 라우팅 테이블을 설정해뒀더라도, SG와 NACL에서 서로 허용안해주면 말짱도루묵이므로 서로 허용해주어야한다.
2.3 [3단계] SG, NACL 확인
어떤것을 확인해주어야하는가.
- 위 [1단계], [2단계] 확인 결과 외부 VPC와 연결될 수 있는 !!수상한!! 라우팅 테이블을 가지고 있는 서브넷과 인스턴스의 SG와 NACL을 모두 확인해주자
- 들어오고 나가는 VPC 모두 설정을 해주어야 한다. 아래 내용을 참고해서 확인하자
✅ VPC A → VPC B로 SSH 접속할 때 설정 필요 여부
항목 | VPC A(발신 쪽) | VPC B(수신 쪽) |
보안 그룹 인바운드 | ❌ 필요 없음 | ✅ 필요함 (TCP 22 허용) |
보안 그룹 아웃바운드 | ❌ 필요 없음(기본적으로 All traffic 허용) | ❌ 필요 없음 |
NACL 인바운드 | ✅ 필요함 (all / ssh / rdp allow) | ✅ 필요함 (ssh allow) |
NACL 아웃바운드 | ✅ 필요함 (ssh allow) | ✅ 필요함 (all / ssh / rdp allow) |
- SG와 NACL을 모두 확인하면 좋은데, SG가 더 하부단이라서 EC2단위로 먼저 확인하고 연결되어있으면 NACL 확인하는게 더 편할것같다는게 개인적인 생각이다...
1) SG 확인
📍 확인 위치:
- AWS 콘솔 > VPC(예) 접근되면 안되는 운영VPC) > 수상한 라우팅테이블에 연결되어있는 서브넷 ID 확인 후 그 서브넷에 속한 EC2들의 보안 그룹 확인
다만, AWS 서비스 상 해당 서브넷에 어떤 EC2가 연결되어있는지 바로바로 안나온다... 따라서 아래와 같이 확인해주어야 한다
>📍 서브넷 내 EC2 확인 위치 :
방법1: AWS 콘솔 > EC2 > 수상한 서브넷ID로 필터링걸어서 확인
방법2: AWS 콘솔 > ENI > 수상한 서브넷ID로 필터링 걸어서 확인
🚀 체크할 것
- 위에서 확인해야할 대상 EC2의 보안 그룹에 다른 VPC로의 접근을 허용하는 보안그룹이 있는지 확인.(예) 개발 VPC 혹은 타 운영 VPC의 CIDR로부터 들어오는 SSH, RDP 포트허용)
- SG의 경우, Stateful이므로 받는쪽에서만 열어줘도 통신이 가능하다. 따라서 받는쪽. 접근되면 안되는 쪽(예) 운영VPC)의 EC2 를 확인해서 열려있는지 확인해준다.
2) NACL 확인
📍 확인 위치:
- AWS 콘솔 > VPC(예) 접근되면 안되는 운영VPC) > 수상한 라우팅테이블에 연결되어있는 서브넷의 NACL
🚀 체크할 것
- 위에서 확인해야할 대상 서브넷의 NACL확인. 다른 VPC로부터의 접근을 허용하는 NACL이 있는지. ( 예) 개발 VPC 혹은 타 운영 VPC의 CIDR로부터 들어오는 SSH, RDP 포트허용)
- NACL의 경우, Stateless이므로 인/아웃바운드 모두 열어주어야 통신이 가능하다.
🧭 예제 시나리오로 정리
: VPC A의 EC2 인스턴스(10.1.1.10) → VPC B의 EC2 인스턴스(10.2.1.10)로 SSH 접속 시도
항목 | VPC A (10.1.1.10) | VPC B (10.2.1.10) |
SG 인바운드 | ❌ 필요 없음 | ✅ TCP 22, 소스: 10.1.0.0/16 |
SG 아웃바운드 | ✅ TCP 22, 대상: 10.2.0.0/16 (기본 허용이면 생략 가능) |
❌ 필요 없음 |
NACL 인바운드 | ✅ TCP 1024-65535, 소스: 10.2.0.0/16 | ✅ TCP 22, 소스: 10.1.0.0/16 |
NACL 아웃바운드 | ✅ TCP 22, 대상: 10.2.0.0/16 | ✅ TCP 1024-65535, 대상: 10.1.0.0/16 |
⛔ 자주 하는 실수
- A에서 보낸다고 A쪽 SG/NACL만 봄
> 상대가 받아줘야 통신됨. 받는 쪽을 열어야 함
- NACL을 한쪽 방향만 설정함
> NACL은 stateless라서 인/아웃바운드 양방향 둘 다 열어야 함
- SG에서 포트는 열었는데 CIDR은 0.0.0.0/0이 아님
> 상대 VPC의 CIDR이 정확히 들어가야 허용됨
3. 리전 간 연결(Transit Gateway Peering)
TGW Peering은 TGW를 서로 연결하는 방식이다.
서로 다른 TGW에 연결된 VPC들끼리 트래픽을 주고받게 만들기 위해 사용한다.
보통 언제 사용하냐?
1) 리전 간 VPC 연결이 필요할 때
- 서울 리전에 있는 VPC랑 도쿄 리전 VPC를 연결하고 싶을 때
- VPC Peering은 리전 간 연결이 안 되기 때문에, TGW + TGW Peering으로 연결해야 함
아래와 같이 사용할 수 있다.
- 서울 리전에 TGW-A (운영)
- 도쿄 리전에 TGW-B (개발)
- 각 TGW에는 해당 리전의 VPC들이 붙어 있음
→ TGW Peering으로 A ↔ B를 연결해 놓으면,
→ 서울의 VPC가 도쿄의 VPC로 접근 가능함 (라우팅 허용 시)
[ 운영 VPC ] ─┐
▼
[ TGW-A ] ◀── Peering ──▶ [ TGW-B ]
▲ ▼
[ 개발 VPC ] ─┘ [ 테스트 VPC ]
2) 계정 또는 조직이 나뉘어 있을 때
- A 계정의 VPC, B 계정의 VPC를 서로 연결하고 싶음
- TGW를 각 계정에 하나씩 만들고, TGW Peering으로 연결함
- 조직/보안 경계 유지하면서도 네트워크는 연결됨
✅ 예: 운영 계정 TGW ↔ 보안 계정 TGW
3) 대규모 네트워크 분리·확장 구조
- 리전마다 하나의 TGW를 두고, TGW끼리 Peering 시켜서 메가 네트워크 허브를 구성
- 각 TGW에는 수십~수백 개의 VPC가 붙어 있음
- 이렇게 하면 관리/구성/보안 측면에서 중앙 통제 + 분산 네트워크 모두 가능
✅ 예: "유럽 TGW", "아시아 TGW", "미국 TGW" 이렇게 구성
즉, VPC Peering은 VPC끼리 직접 연결,
TGW Peering은 TGW끼리 연결해서 더 많은 VPC들 간 경로를 만들어주는 구조라고 보면 됨
서로 다른 리전, 계정, 조직의 TGW를 연결해서 더 넓은 네트워크를 만들고 싶을 때 TGW Peering을 한다.
TGW Peering할 경우에는 VPC > TGW Peering 부분을 확인하면 되는데, 라우팅 테이블도 TGW의 라우팅 테이블을 확인해야한다. 이 부분은 나중에 필요 시 추가하도록..
말이 쉽지 너무나 빡세다.. &&^^ 직접 진단해봐야 알것같다 화이팅