본문 바로가기

AWS/EC2

[AWS] Bastion Instance를 NAT Instance(Gateway)로도 써보자!

안녕하세요.

오늘은 많은 분들이 단순하게는 Private Subnet에 있는 Instance에 접속하는 용도로 사용중인

Bastion Instance의 의미와 해당 Bastion Instance를 외부 Gateway 역할을 하는 NAT Instance로도

사용할 수 있는 방법을 공유하려 합니다.

 

우선 Bastion의 의미부터 살펴보시겠습니다.

 

많은 분들이(저 또한 마찬가지..) Bastion Server의 역할을 단순히 내부 사설 네트워크에 존재하는

서버로 접근하기위한 점프서버용도로만 알고계시는데, 물론 점프서버의 역할도 수행하지만

그 외에도 보안적인 측면에서 많은 이점을 주는 용도로 사용됩니다.

 

예를 들어, 내부 사설 네트워크에 존재하는 서버에 접근하기 위해서는 꼭! Bastion Server를 거쳐야만

내부 서버로 접근할 수 있습니다.(물론 AWS에서 제공하는 Session Manager 라는 서비스도 있습니다..!)

이 말인즉, 내부로 연결되는 통로가 하나라는 뜻 이고 해당 통로만 모니터링을 해도
내부 서버로 향하는 트래픽 대부분을 모니터링 할 수 있다는 뜻입니다. 즉! 관리 및 로깅의 중앙화를 할 수 있죠!!

 

조금 더 쉽게 예를 들어볼까요 ??

예전에 게임을 즐겨하셨던 분들이라면 스타크래프트 라는 게임을 아실겁니다.

저도 그 게임을 참 좋아했는데요(사실 블리자드 게임 다 좋ㅇ...)

스타크래프트에서 테란이란 종족은 통칭 '입구막기' 라는 플레이를 자주 했습니다.

인게임 내에서 본진으로 향할 수 있는 길목이 하나인 맵이 대부분 이였는데, 그 길목에 배럭과 벙커 등으로
본진으로 향하는 입구를 봉쇄하여 적들의 침입을 효과적으로 막아내어 손실을 입히고
그 차이를 이용하여 자본에서의 우위를 가져간 후 승리로 이끌어내는 플레이를 자주 했습니다.

 

만약, 입구가 두개라면 어땟을까요 ?? 입구를 막는데 필요한 배럭과 벙커 마린의 수가 2배로 늘어나야 할 것이며,

필요한 자원 또한 두배로 늘어나겠죠.
Bastion Server도 마찬가지입니다. 입구가 하나이기 때문에 집중적으로 관리할 수 있고, 필요한 비용 또한 절감됩니다.

 

또한, 말씀드린 것 처럼 Bastion Server를 통해서만 내부 서버로 접속할 수 있기때문에, Bastion의 ID와 PW나 Pem Key가유출되더라도 내부 서버의 계정정보를 모른다면 접근할 수가 없고, 꼭 거쳐가야만 하는 길목이기에 해당
Bastion Server에 각종 방화벽 등의 보안솔루션을 설치하기도 한답니다.

 

 

실제로 중세시대에 성 외곽을 보호하기 위해 돌출된 부분을 Bastion이라고 불렀습니다.

즉, 배스천에서는 적을 가장 효과적으로 방어할 수 있는 것인데요. 이처럼 중세시대에 성 외곽을 보호하기 위한

Bastion의 어원이 IT에도 접목되어 같은 의미로 쓰이고 있다고 생각하실 수 있겠습니다!

 

 

그럼.. 이제 다시 원점으로 돌아와서 해당 Bastion Instance를 NAT Instance 역할도 겸용하게끔 하여,

내부 사설 네트워크에 있는 서버들이 외부와 통신도 할 수 있도록 설정해보겠습니다!

(사실 제일 좋은건 돈 주고 관리형 서비스인 NAT Gateway 쓰는게 짱이에요..)

 

 

 

자 그럼 정말 본격적으로 시작하겠습니다 !!

 

- Bastion Instance를 NAT Instance의 역할도 겸하게 한다면, Instance의 사양(Type)에 따라 단일 병목지점으로
  장애가 발생할 수 있습니다. (NAT Gateway는 최대 45Gbps까지 자동 확장합니다. 자본 만만세!!)

 

- 테스트 환경에서는 이미 사용중인 Bastion Instance가 존재한다고 가정합니다.

- 해당 매뉴얼의 구성도는 하나의 VPC(10.10.0.0/16) 에서 Public Subnet(10.10.0.0/24), Private Subnet(10.10.1.0/24)
  총 2개의 Subnet으로 구성되어 있습니다.

- 해당 메뉴얼에서는 NACL이나 SG의 Outbound 정책설정이 없습니다.

- 해당 메뉴얼의 최종 아키텍처는 아래와 같습니다.

 

 

Bastion & NAT Instance

 

  • Public Subnet에서 사용 중인 Bastion Instance의 보안그룹을 수정합니다.
    (VPC 대역(10.10.0.0/16)의
     80, 443, ICMP TrafficBastion ServerInbound rule에서 허용)

Bastion Instance의 보안그룹

 

  • Bastion InstanceSource/Destination IP CheckDisabled 합니다.
    Bastion Instance -> Action -> Networking -> Change Source/Dest. Check -> Yes. Disable

Bastion Instance의 Src, Dst 주소체크 비활성화

 

  • Private SubnetRouting table에 외부로 나가는 대역의 Target을 Bastion Instance의 ID로 추가합니다.
    환경에 따라 해당 Routing table에 명시적으로 연결되어있는 Subnet에 주의하세요!!

 

Routing table 편집
외부로 나가는 대역의 Target을 Bastion Instance의 ID로 설정

 

 

  • Bastion Instance로 접속하여 마스커레이드(Masquerade) 설정을 진행합니다.
    먼저 리눅스 커널에서 패킷을 포워딩 하도록 다음과 같이 설정합니다.
[root@Bastion]# vi /etc/sysctl.d/nat.conf

net.ipv4.ip_forward = 1
net.ipv4.conf.eth0.send_redirects = 0

[root@Bastion]# sysctl -p /etc/sysctl.d/nat.conf

 

  • 다음으로 iptables에 NAT 체인 마스커레이드 설정을 해줍니다.
[root@Bastion]# vim /etc/iptables.rules

*nat
:PREROUTING ACCEPT [0:0]
:INPUT ACCEPT [0:0]
:OUTPUT ACCEPT [0:0]
:POSTROUTING ACCEPT [0:0]
-A POSTROUTING -o eth0 -j MASQUERADE
COMMIT

[root@Bastion]# /sbin/iptables-restore < /etc/iptables.rules

 

이렇게 설정은 끝이 났습니다 !!

이 후, Private Subnet에 있는 Instance에서 IP 도달성 체크를 진행합니다. (예제에서는 간단하게 ping과 curl로..)

[root@PrivateServer]# ping 8.8.8.8
[root@PrivateServer]# curl www.google.com

 

  • 아래의 사진은 실제 Private Subnet에 있는 Instance에서 외부 통신을 테스트한 사진입니다.

Private Subnet의 Instance가 Bastion&NAT Instance를 통해 외부 통신

 

 

자 이렇게, 사용하고 있는 Bastion Instance를 NAT Instance 역할도 겸하게 하여 외부 Gateway로 사용해봤는데요!

위에서 말씀드린 것 처럼 해당 Instance의 사양(Type)과 네트워크 환경, 부하도에 따라 단일 병목지점이 되어

장애를 발생시킬 수 있으니 돈주고 NAT Gateway 씁시다..! 주의하시기 바랍니다!!!