본문 바로가기
AWS

[AWS] AWS Private EC2에 접근하기 위한 Bastion / NAT-Instance 설정하기

by 도전하는 린치핀 2024. 3. 13.

 

AWS 내에서 프라이빗 서브넷에 연결되어 있는 프라이빗 인스턴스는 외부와 접근할 일이 없을까?

이전 포스팅에서 설명했지만 Private Instance 또한 외부와 연결되어야 하는 특정한 상황이 있다.

해당 상황이 이해가 가지 않는다면 해당포스팅을 확인하고 오자.

 

[ASAC_04/AWS] AWS 개념 - VPC / Subnet / Route Table / Internet Gateway

1. VPC (Virtual Private Cloud) VPC는 약자 그대로 AWS 클라우드에서 제공하는 사용자의 AWS 계정 전용 가상 네트워크다. 사용자는 AWS에서 제공하는 VPC 내에서 서브넷, 라우팅 테이블, 인터넷 게이트웨이

rnclf1005.tistory.com

 

 

1. “Private” EC2 생성 후 외부 접근 허용 : Inbound 를 위한 Bastion 설정

1-0. SSH Tunneling

프라이빗 인스턴스 내에서 개발자가 작업을 하거나, 외부의 변경사항을 적용하기 위해서 Inbound를 위한 Bastion을 설정해주어야 한다.

이것을 우리는 ssh Tunneling이라고 한다.

 

위의 사진처럼 bastion은 로컬과 서버와의 통로라고 생각하면 된다.

이 통로를 통해서 local의 개발자는 다른 설정이 없이 바로 프라이빗 인스턴스에 접근할 수 있다.

 

그렇다면 AWS에서 bastion을 설정하는 과정은 어떤식으로 이루어져 있을까?

 

1-1. Bastion 호스트 역할을 할 EC2 (Public Subnet) 인스턴스 만들기

먼저 bastion 호스트 역할을 할 수 있는 기본적인 EC2 인스턴스를 생성하자.

 

이때 생성에 신경써야하는 조건은 아래와 같다.

  • 사용할 VPC내의 퍼블릿 서브넷에 할당한다.
  • 퍼블릭 IP 자동할당을 활성화로 변경한다. (이 부분을 통해 인스턴스와 인터넷게이트웨이를 연결할 수 있다)
  • 새로운 보안 그룹을 생성해서 모든 ssh 22번 포트에 대해 열어놓는다.

bastion EC2를 생성한 후 모습

 

그후, 생성한 bastion에 보안그룹이 잘 선택되었는지 확인한 뒤 연결 버튼으로 제대로 생성되었는지 확인한다.

 

이 화면이 나오면 기본 생성은 끝났다.

 

1-2. 추후 Bastion 에서 EC2 (Private Subnet) 에 접근하기 위한 Key Pair (.pem 키) 생성

Bastion에서  private EC2에 접근하기 위해서는 Key Pair가 필요하다.

이때 Key Pair를 생성하는 조건은 아래와 같다.

  • 조건 : 키페어 타입은 RSA 로, 확장자는 .pem 으로 (OpenSSH 사용을 위해) 생성
  • 주의 : 리전 서비스이기 때문에 서울 리전인지 꼭 확인 필요
  • 성공적으로 생성된 key pair의 경우 .pem 키를 다운로드되어 내 컴퓨터 로컬에 저장된다.
  • 이때 로컬에 저장되는 .pem 파일의 경우 private key이다.
  • public key의 경우 aws에서 추후에 인스턴스를 생성할 때 key-pair를 설정하면 기본으로 public key가 할당된다.

 

생성된 bastion-EC2-keypair는 public-key는 좌측의 aws에서 가지고 있고, private-key는 우측의 로컬 컴퓨터에 저장된다.

1-3. EC2 (Private Subnet) 과제용 테스트 인스턴스 만들기

그렇다면 이제 프라이빗 서브넷에 연결되어 있는 private EC2를 생성해야 한다.

이때 프라이빗 인스턴스를 생성하는 조건은 아래와 같다.

  • 1-2)에서 생성한 Key-pair를 설정해주어야 한다.
  • 인스턴스 생성 시 앞서 생성한 Private Subnet 중 하나에 할당한다.
  • 보안그룹은 1-1) 에서 만든 “Bastion EC2 의 SG” 설정해야 한다.

 

private-instance 생성 후 화면

 

프라이빗 인스턴스 생성이 제대로 되었는지 연결 버튼을 클릭해서 확인해보자.

이때 프라이빗 인스턴스에 접근하기 위해서는 1-1)에서 생성한 bastion-EC2에 접근이 가능한지 확인해야 한다.

  • private-instance같은 경우에는 프라이빗 설정이기 때문에 외부에서 아무렇게나 접근이 가능하면 안된다.
  • 우리는 아까 생성한 bastioEC2를 통해 private-instance에 접근이 가능한지 확인해야 한다.
  • 이때 bastion-EC2에서 "ssh ec2-user@{target-private-ip}" 명령을 통해 접근을 해야한다.
  • 이때 {target-private-ip}는 private-instance의 private-ip를 뜻한다.

 

위의 사진을 통해 알 수 있듯이  아직 bastion-EC2를 통해서 private-instance에 접근할 수 없다.

그 이유는 무엇일까?

  • 1-2)에서 생성한 key-pair를 private-instance는 알고 있지만 bastion-EC2는 알지 못한다.
  • 따라서 bastion-EC2에게 private-instance와 통신할 수 있는 key-pair를 설정해주어야 한다.

 

1-4. Bastion EC2 인스턴스 내 Private EC2SSH 접속을 위한 .pem 키 설정 후 접속 성공 확인

위의 1-3)에서 실행한 bastion-EC2 터미널 내에서 key-pair를 설정해줄 수 있다.

 

순서는 아래와 같다.

  • "vi bastion-to-private.pem" 명령을 통해 에디터를 열어 1-2)에서 로컬에 저장되어 있는 private-key를 입력해주면 된다.
  • "chmod 400 bastion-to-private.pem" 명령을 통해 .pem파일의 읽기 권한 부여하여 SSH 접속시 해당 키 읽을 수 있게 해준다.
  • "ssh ec2-user@{target-private-ip} -i bastion-to-private.pem" 명령어를 사용해서 bastion에서 private-instance에 접근한다.
  • 이때 {target-private-ip}는 private-instance의 프라이빗 IP이다.

 

두번째 새 모양이 private-instance에 접근한 이후에 나오는 것이다.

이를 통해서 bastion을 통해서 private-instance에 접근할 수 있다는 것을 확인할 수 있다.

  • 추가적으로 "ping google.com" 명령을 통해 외부로 연결(Outbound)이 가능한지 확인해보았지만 역시 안된다.
  • Out-bound의 경우 이따가 하는 NAT-Instance를 통해서 가능하게 할 수 있다.

1-5. SSH Tunneling 으로 지금 내 컴퓨터 로컬에서 Bastion 을 통해 Private EC2SSH 접속해보기

bastion을 통해서 private-instance와 연결하였으니 로컬 컴퓨터에서 bastion을 통해 private-instance에 바로 접근할 수 있는 ssh-Tunneling을 해보자.

 

SSH-Tunneling의 조건은 아래와 같다.

  • 내 로컬 컴퓨터Bastion EC2 를 이어줄 Key Pair(.pem 키) 생성
    • bastion과 private-instance가 key-pair로 연결된 것처럼 로컬 컴퓨터와 bastion을 연결하기 위해 새로운 key-pair가 필요하다.
  • Bastion-EC2에 생성한 Key Pair (.pem 키) 등록
  • Bastion EC2 잘 접속되는지 내 컴퓨터(로컬) 에서 수행하여 접속 테스트
    • "ssh -i {local-to-bastion-pem-location} ec2-user@{bastion-host-public-ip}" 명령을 통해 로컬에서 접근 가능한지 확인

로컬에서 bastion에 접근이 성공한 스크린샷

  • Bastion EC2SSH Tunneling 열기 = SSH 통로를 위한 터널 열어두기
    • "ssh -i "local-to-bastion.pem" -N -L 33323:{target-private-ip}:22 ec2-user@{bastion-host-public-ip}" 명령을 통해 로컬에서 bastion을 거쳐 private-instance에 접근할 수 있는 터널을 뚫는다.
  • 새로운 터미널에서 "ssh -i "bastion-to-private.pem" -p 33323 ec2-user@localhost" 명령을 통해 private-instance에 접근하면 된다.
  • 이때 포트번호인 33323는 정해진 포트가 아니라 일반적으로 사용하지 않는 포트 번호를 할당해서 ssh-tunneling을 위한 포트라고 생각할 수 있다.

 

이제 외부에서 bastion 인스턴스를 통해 private-instance에 접근하는 In-bound에 대한 방법은 성공했다.

그렇다면 private-instance에서 외부로 접근하는 Out-bound는 어떻게 할 수 있을까?

 

2. “Private” EC2 외부 접근 허용 : Outbound 를 위한 NAT Instance 설정

 

위에서 확인했듯이 bastion을 통해 ssh-tunneling을 완료했다면 로컬에서 private-instance에 접근할 수 있다.

이제 private-instance에서 외부 접근(Out-bound)을 허용하는 방법을 확인해보자

 

Out-bound 같은 경우에는 NAT-Instance를 활용하여 허용할 수 있다.

 

2-1. NAT Instance 역할을 할 EC2 (Public Subnet) 인스턴스 만들기

 

AWS 에서 NAT Instance 공식 지원을 접고 NAT Gateway 를 공식화하였지만 NAT Gatewat같은 경우에는 비용이 많이 드니 해당 실습에서는 NAT-Instance를 만들어서 사용해보자.

 

NAT-Instance역할을 할 수 있는 인스턴스를 생성하는 조건은 아래와 같다.

  • AMI 검색을 통해 커뮤니티 버전으로 나온 NAT 를 위한 AMI 를 사용할것
  • 해당 실습에서는 "amazon/amzn-ami-vpc-nat-2018.03.0.20230807.0-x86_64-ebs" AMI를 선택하였다.
  • 키 페어의 경우 앞서 생성한 "bastion-to-private.pem" 키를 설정하기
  • 인스턴스 생성 시 앞서 생성한 Public Subnet 중 하나에 할당
  • 새로운 보안 그룹(Secure Group)을 생성
    • SSH, Source Type : Anywhere, Source : 0.0.0.0/0 (모든 트래픽)
    • HTTP, Source Type : Custom, Source : 사용중인 VPC CIDR
    • HTTPS, Source Type : Custom, Source : 사용중인 VPC CIDR

 

해당 옵션으로 인스턴스를 생성한 후 추가적으로 작업해줘야 할 것이 있다.

NAT (Network Address Translation) 의 정의에 따라 Src/Dst 는 수행하면 안되기 때문에 Network 설정에서 Source/Destination Check 옵션에서 STOP 체크 필요하다.

 

해당 옵션 설정은 해당 인스턴스를 클릭한 뒤 [작업] - [네트워킹] - [소스/대상 확인  변경] - [소스/대상 확인 중지] 순서로 진행하면 된다.

 

2-2. Private 서브넷의 Route Table 내 “모든 트래픽에 대해서 NAT Instance 로 전달” 설정을 추가

해당 NAT-Instance는 모든 설정이 끝났지만 프라이빗 서브넷에서 트래픽이 외부로 나갈 수 있게 해주는 Route Table을 설정해주어야 해당 트래픽들을 외부로 보낼 수 있다.

 

 

프라이빗 서브넷의 라우팅 테이블을 설정하였다면 추가로 설정해야하는 것들이 있다.

  • Private 서브넷의 Route Table0.0.0.0/0 트래픽에 대해 NAT Instance 로 가게 설정
  • Route Table 설정 시 NAT Instance EC2 인스턴스 명을 넣으면 자동으로 ENI 설정으로 변경
  • Route Table 설정 후 생성한 뒤 명시적 서브넷으로 Private Subnet을 연결

 

위의 사진처럼 좀전에 생성한 NAT-Instance를 설정하면 된다.

 

그렇다면 이제 1번에서 완성한 Bastion을 통해 Private-Instance에 접근하여 "ping google.com" 명령을 실행하면 외부로 연결이 됬을까?

결과는 실패다. 그 이유는 위에서 NAT Instance 의 SG 의 인바운드에 ICMP 오픈 필요하기 때문이다.

 

2-3. NAT Instance EC2SG인바운드 규칙모든 ICMP 요청 풀기

 

Out-bound를 위해 NAT Instance EC2SG 내 다음 인바운드 규칙 추가해줘야 한다.

  • All ICMP - IPv4, Source Type : Custom, Source : 내가 사용하고 있는 VPC의 CIDR로 설정해줘야한다.

 

위의 사진처럼 NAT-SG의 인바운드 규칙을 수정한 뒤, 1번에서 한 것 처럼 내 로컬 컴퓨터에서 bastion을 통해 ssh-Tunneling을 수행하여 private-instance에 접근한 뒤 private-instance에서 외부로 Out-bound가 가능한지 확인하면 접근이 가능한 것을 확인 할 수 있다

.