보안 공부 회고록

AWS bastion host 구축하기 본문

sdc: 그 외 컴퓨터 공학/클라우드

AWS bastion host 구축하기

김 간장 2024. 7. 20. 22:02

AWS를 공부하다보니 알게된 사실인데 많은 기업들이 bastion host 혹은 session manager를 통해서 클라우드의 보안을 강화하는 것 같다.

그래서 bastion host를 구축해보기로 했다.

 


일단 bastion host를 한번도 구축해본 적이 없기 때문에 AWS 참조 자료를 찾아봤다.

 

https://aws.amazon.com/ko/solutions/implementations/linux-bastion/

 

Linux Bastion Hosts on AWS - 솔루션

 

aws.amazon.com

 

대충 그림을 통해서 필요한 서비스를 정리해보자.

 

"두 가용 영역(AZ)에 걸쳐 있는 고가용성 아키텍처"라고 하는 것 보니까 2개의 AZ에 동일한 설정을 구성해서 이중화를 하라는 의미같다. 그럼 AZ가 2개 필요할 것 같다.

 

"자체 가상 네트워크를 제공하기 위해 퍼블릭, 프라이빗 서브넷으로 구성된 VPC"이라고 하는 걸로 보아 퍼블릭 서브넷과 프라이빗 서브넷이 필요한 것 같고... 퍼블릿 서브넷에 bastion host가 있고 프라이빗 서브넷에 내부 호스트를 설정하면 되는 것 같다.

 

퍼블릿 서브넷은 인터넷 액세스를 허용하기 위해 마련되는 관리형 NAT 게이트웨이가 필요한 것 같다.

 

구성을 어떻게 하느냐에 따라 다른 것 같긴한데 오토 스케일링 그룹도 설정하면 좋은 것 같고, CloudWatch 로그 그룹과 System Manager를 함께 설정하면 되는 것 같다.

 


1. VPC 생성하기

 

이중화를 하면 좋겠지만, 테스트 용도이니까 그냥 하나만 구축하기로 했다.

일단 VPC를 구성하여야 한다.

 

VPC > VPC > VPC 생성으로 이동한다.

생성할 리소스를 설정할 수 있는데, VPC만 생성할 수도 있고 VPC, 서브넷, 라우팅 테이블, 네트워크 연결을 모두 한번에 생성할 수도 있다.

 

AWS VPC를 공부하려면 VPC만 생성하고 서브넷, 라우팅 테이블 등을 수동으로 하나씩 생성해보면 좋겠지만...

지금은 테스트 목적으로 bastion host를 구축하는게 목적이니까 존재하는 기능을 사용하기로 했다.

 

설정 값은 다음과 같다.

  • 생성할 리소스 : VPC 등
  • 이름 태그의 값 : tempVPC
  • IPv4 CIDR 블록 : 10.0.0.0/16
  • IPv6 CIDR 블록 : IPv6 CIDR 블록 없음
  • 테넌시 : 기본값
  • 가용 영역(AZ) 수 : 1 (ap-northeast-2a)
  • 퍼블릭 서브넷 수 : 1
  • NAT 게이트웨이 : 없음
  • VPC 엔드포인트 : 없음
  • DNS 옵션 : DNS 호스트 이름 활성화 체크, DNS 확인 활성화 체크

테스트 목적이니까 AZ는 1개만 구축하였고, ap-northeast-2a로 설정했다.

bastion host가 있어야 하기 때문에 퍼블릿 서브넷 1개로 설정했다.

프라이빗 서브넷은 여러개 해도 상관없긴 한데, 전부 다 돈이라서(...) 그냥 1개만 만들고 거기에 백엔드 리소스를 모두 넣기로 했다.

NAT 게이트웨이도 구성해보고 싶었지만 비용이 발생한다고 해서 포기했다.

 

결과적으로 아래와 같이 구성되었다.

 

 

생성된 VPC를 보면 기본적으로 존재하는 VPC 1개와 방금 만든 tempVPC-vpc 1개가 있다.

이 tempVPC-vpc는 아래에서 사용하게 될 예정이다.

 

 


2. Bastion host 만들기

이제 Bastion host를 생성해보자.

Bastion host는 AWS EC2로 만들 예정이다.

Bastion host는 외부와의 통신이 필요하기 때문에 Public subnet에 구축하여야 한다.

 

설정값은 다음과 같이 구성하였다. 다른 부분은 상관없는데 네트워크 부분은 잘 봐두어야 한다.

  • AMI : Amazon Linux 2023 AMI (아무거나 상관없다)
  • 인스턴스 유형 : t2.micro (아무거나 상관없다)
  • 키페어 : bastion-key 라는 이름의 키 페어를 하나 만들었다
  • 네트워크(VPC) : tempVPC-vpc
  • 네트워크(서브넷) : public subnet을 선택해야한다 (private subnet을 선택하면 안된다)
  • 네트워크(퍼블릭 IP 자동 할당) : 활성화
  • 방화벽(보안 그룹) : 보안 그룹 이름은 public-security-group으로 설정하였고 인바운드 보안 그룹 규칙은 ssh(22/tcp)를 모든 IP주소(0.0.0.0/0)에서 허용해주었고, 모든 ICMP(IPv4)도 모든 IP주소에서 허용해주었다.
  • 스토리지 : 8GiB gp3 루트볼륨 (아무거나 상관없다)

물론 위에 적어놓았지만 보안 그룹은 사진으로 보는게 더 빠를 것 같아서 캡처해왔다.

보안 그룹은 다음과 같이 설정하였다.

 

이렇게 Bastion host는 Public Subnet에 생성하였다.

이제 Bastion host를 통해 접근할 내부 백엔드 서버를 하나 만들자!

 


3. Private에서만 접근 가능한 EC2 만들기

인터넷 <------> Bastion host  <------> 백엔드 리소스(서버 등)

이렇게 접근할 것이기 때문에 백엔드 리소스가 하나라도 있어야 한다.

 

하여튼 그러므로  Private Subnet에 EC2를 하나 구축해보자.

 

설정값은 다음과 같다.

  • AMI : Amazon Linux 2023 AMI (아무거나 상관없다)
  • 인스턴스 유형 : t2.micro (아무거나 상관없다)
  • 키페어 : server1-key 라는 이름의 키 페어를 하나 만들었다
  • 네트워크(VPC) : tempVPC-vpc
  • 네트워크(서브넷) : private subnet을 선택해야한다 (public subnet을 선택하면 안된다)
  • 네트워크(퍼블릭 IP 자동 할당) : 비활성화
  • 방화벽(보안 그룹) : 보안 그룹 이름은 private-security-group으로 설정하였고, Public Subnet에 있는 Bastion host만 이 EC2에 접근할 수 있어야 한다. 때문에 보안 그룹은 SSH(22/tcp)를 public-security-group만 허용하도록 설정하고, 모든 ICMP(IPv4)도 public-security-group만 허용하도록 설정해주어야 한다.
  • 스토리지 : 8GiB gp3 루트볼륨 (아무거나 상관없다)

 

보안 그룹이 좀 어려울 수 있기 때문에 캡처해서 가져왔다.

보안 그룹에는 앞서 만든 public-security-group만 허용해주어야 한다.

 

이렇게 하면 아래와 같이 구성하게 된다.

 

여기에서 ICMP - IPv4의 프로토콜을 설정해주지 않으면 Invalid integer value NaN 이라는 오류가 발생하면서 보안 그룹 규칙이 생성되지를 않는다.

그래서 프로토콜은 임의로 지정해주었다.

사실 ICMP - IPv4는 허용할 생각이 없었는데 ping은 되어야할 것 같아서 설정해주었다..

 


이렇게 해서 bastion host와 private에 있는 서버가 1대씩 만들어졌다.

 

 


4. 접속 시도

일단 bastion host에 접속해보자.

 

bastion host에는 잘 접속을 했다.

 

그렇다면 내 맥북에서 private EC2에도 그냥 접속이 될까?

물론 퍼블릭 IP주소가 없어서 당연히 접속이 안될 것을 알고 있다. 그래도 직접 보는게 빠르니까 시도해보자.

 

 

당연히 접속이 안된다.

 

그럼 private EC2에는 어떻게 접근할 수 있을까?

bastion host에서 ssh를 이용해서 접근할 수 있다.

 

private EC2에 접속해보자.

먼저 bastion host로 private EC2의 pem키(server1-key.pem)을 옮겨야 한다.

그리고 bastion host에 접속해보자.

 

bastion host에 옮겨 놓은 private EC2의 pem키(server1-key.pem)를 이용해서 private EC2에 접속을 시도한다.

 

그럼 접속에 성공한다!

 


 

private EC2가 외부에 노출되어 있지 않기 때문에 좀 더 보안상 안전한 건 맞다.

하지만 bastion host에 ssh 키가 계속 있으면... bastion host를 제대로 관리하지 못하면 오히려 더 위험해 질 수 있다.

그렇다고 bastion host를 안 쓸 수는 없으니까... 차라리 bastion host에 ssh 키를 모아두지 말고, 로컬 PC에 키를 두는건 어떨까 싶다.

 

물론, private EC2에 접속을 할 때마다 pem키를 bastion host에 옮겨서 접속하고, 다 사용한 후 삭제하고... 하면 너무 불편하고 번거로우니까

PuTTY의 SSH 터널링 기능을 이용하는게 어떨까 싶다..

 

SSH 터널링 사용법은 따로 정리해두었다.

https://kimsoy-security.tistory.com/170

 

Putty의 SSH 터널링 사용해서 private EC2에 접속하기

AWS를 사용하다보면 bastion host를 두고 SSH 터널링을 이용해서 내부의 서버로 접속해야하는 경우가 있다.그러니까 이런 경우 말이다. 외부망(인터넷망) bastion host private EC2 최근에 Putty를 많이 사용

kimsoy-security.tistory.com

 

예전에 듣기로는 session manager가 더 안전하다고 하던데 그것도 언젠간 실습해봐야겠다.

VPC만 만들고 서브넷, 인터넷 게이트웨이, 라우팅 테이블도 직접 수동으로 생성해보는 것도 나중에 한번 해봐야지..