INFRA & DEVOPS/AWS

[AWS] SSH 포트포워딩 및 SSM을 통해서 로컬에서 Private Subnet에 있는 RDS 접근하기

Ray123 2023. 8. 9. 22:42

소마 프로젝트를 진행하면서, 인프라 쪽을 내가 어느 정도 담당하고 있어서(사실 담당한다고 하기에도 민망할 정도로 기본적인 부분들만 담당하긴 하지만) RDS를 띄워보기로 했다. Private Subnet에 RDS를 띄우기로 했는데, 문제는 "로컬에서 Private Subnet에 어떻게 접근하는가?" 였다.

 

Private Subnet은 외부와 단절된 네트워크로, 외부에서 직접 접근이 불가능하다. NAT Gateway를 둬서 Private Subnet에서 외부로 트래픽을 보낼 순 있어도, 외부에서 먼저 Private Subnet으로 트래픽을 보낼 순 없다. VPN등을 통해 직접 로컬에서 Private Subnet으로 연결할 순 있으나, 비용이 무시무시하다는 소문이 들려서 다른 방법을 찾아보기로 했다

 

당장 떠오르는 방법은 Public Subnet에 EC2를 둔 후, ssh로 EC2에 원격으로 연결한 다음 거기서 Private Subnet으로 접근하는 것. 같은 VPC안의 애들끼리는 서로 통신이 가능하기 때문에 이 방법을 쓸 수 있을 것이다. 이렇게 외부에서 내부 네트워크로의 안전한 접근을 제어하기 위해 사용되는 중간 서버를 Bastion Host라고 부른다.

 

로컬에서 ssh로 Public Subnet의 EC2에 원격으로 연결한 뒤, 거기서 Private Subnet의 RDS로 직접 쿼리를 날릴 순 있다.

 

이렇게 하면 로컬에서 Private Subnet에 있는 RDS로 create등의 쿼리를 작성해 날릴 수 있다. 그러나 "얘를 로컬에서 돌리고 있는 스프링부트와 어떻게 연결하는가"가 숙제. 스프링부트에서 만들어지는 쿼리를 터미널에 인풋으로 주도록 내가 직접 구축을 해야 하나..? 그건 너무 에바같은데.. 

 

이 때 ssh 포트 포워딩(다른 말로는 ssh 터널링)을 통해 이 문제를 해결할 수 있다. ssh 포트포워딩이란 ssh를 사용해 로컬 머신과 원격 서버 사이에서 포트 전달을 설정하는 것으로, 이를 통해 로컬에서 특정 포트로 트래픽을 보내면 ssh터널(ssh를 통해 연결된 통로라고 생각)을 통해 원격서버의 특정 포트로 보낼 수가 있다. 즉 내가 로컬의 3306포트와 원격 서버의 3306포트를 포트포워딩하면, 내가 로컬의 3306포트로 보내는 트래픽을 원격 서버의 3306포트로 보낼 수가 있는 거다. (참고로 이 예시는 로컬 포트 포워딩에 해당하며, 리모트 포트 포워딩을 하면 원격 서버에서 특정 포트로 들어오는 트래픽을 내 로컬 머신의 포트에서 받을 수 있다)

 

이런 로컬 포트 포워딩은 다음과 같이 설정해 사용 가능하다

ssh -L [로컬에서 사용할 포트]:[최종적으로 접근할 곳(ip:port형태)] [SSH Server 주소]

예시로, aws에서 지급받은 pem키와 함께 사용하려면 다음과 같이 하면 된다.

ssh -i [pem키 경로] -L 3306:[RDS 엔드포인트]:3306 [사용자명(ex:ubuntu)]@[Bastion Host public ip]

 

이렇게하면 로컬의 3306포트와 Private RDS의 3306이 연결됐으니 이제 스프링부트에서도 datasource를 내 로컬의 3306으로 한 뒤 쓰면 된다. 물론 각각 보안그룹들이 다 설정돼있어야 한다!(RDS는 Bastion으로부터 3306포트로 오는 인바운드 허용, Bastion은 22번 인바운드와 3306아웃바운드 허용 등..) 이 때 Public Subnet에 둔 EC2는 점프호스트로 쓰는 거라고 볼 수 있다

 

 

하지만! SSM이란 서비스를 사용하면 좀 더 쉽게 Private Subnet접근이 가능하다.

 

 

SSM이란?

AWS System Manager. Simple System Manager라고도 불리며 이의 줄임말이 SSM이다. 다양한 기능들을 제공하는데, Session manager라는 걸 통해 EC2접속을 할 수 있는 서비스도 제공한다.

 

https://aws.amazon.com/ko/blogs/architecture/how-wego-secured-developer-connectivity-to-amazon-relational-database-service-instances/

https://docs.aws.amazon.com/systems-manager/latest/userguide/session-manager.html

 

AWS Systems Manager Session Manager - AWS Systems Manager

AWS Systems Manager Session Manager Session Manager is a fully managed AWS Systems Manager capability. With Session Manager, you can manage your Amazon Elastic Compute Cloud (Amazon EC2) instances, edge devices, on-premises servers, and virtual machines (

docs.aws.amazon.com

 

Session Manager를 사용하면 기존에 했던 것처럼 Bastion Host를 둘 필요 없이 Private Subnet에 있는 EC2인스턴스에 직접 접근이 가능하다(당연히 퍼블릭도 가능). ssh로 연결할 때 사용하던 pem키 관리 및 EC2인스턴스들에 22번 포트를 여는 인바운드 설정도 할 필요가 없다. 즉 더 안전하게 사용 가능한 방법이라고도 볼 수 있다. 또한 포트포워딩도 지원하기 때문에 로컬에서 Private Subnet에 있는 RDS로의 접근 역시 가능하다!

(Session Manager를 통해 EC2들에 대한 직접 액세스는 가능하나 RDS등은 직접 액세스는 안 돼서 포트포워딩을 거쳐야 함. 즉 EC2라는 관리 인스턴스를 "점프 호스트"로 사용해 RDS로 접근하는 것이며, ssh 포트포워딩을 통해 public에 있던 EC2를 점프호스트로 쓰던 것과 같은 원리이다.)

 

참고로 이때 SSM을 통해 직접 액세스하게 되는 EC2는 22번 인바운드는 열릴 필요가 없으나, 443번 아웃바운드는 열려있어야 한다. 해당 EC2에서 AWS SSM에게 지속적인 폴링을 통해 연결을 유지하기 때문이다. 따라서 보안그룹 설정시 꼭 주의할 것. 관련된 내용은 아래 링크의 [엔드포인트에 연결] 섹션을 참고하면 된다

 

https://docs.aws.amazon.com/ko_kr/systems-manager/latest/userguide/session-manager-prerequisites.html

 

1단계: Session Manager 사전 조건 완료 - AWS Systems Manager

이 페이지에 작업이 필요하다는 점을 알려 주셔서 감사합니다. 실망시켜 드려 죄송합니다. 잠깐 시간을 내어 설명서를 향상시킬 수 있는 방법에 대해 말씀해 주십시오.

docs.aws.amazon.com

 

그럼 본격적으로 SSM으로 포트포워딩을 설정해 로컬에서 Private Subnet의 RDS에 접속하는 법을 알아보자.

 


1. 로컬환경에 aws cli 설치하기

https://docs.aws.amazon.com/ko_kr/cli/latest/userguide/getting-started-install.html#getting-started-install-instructions

 

최신 버전의 AWS CLI 설치 또는 업데이트 - AWS Command Line Interface

이전 버전에서 업데이트하는 경우 unzip 명령을 실행하면 기존 파일을 덮어쓸지 묻는 메시지가 표시됩니다. 스크립트 자동화와 같은 경우에 이러한 프롬프트를 건너뛰려면 unzip에 대한 -u 업데이

docs.aws.amazon.com

 

2. aws IAM을 만든 다음, Access Key와 Secret Access Key를 발급받는다.

 

3. 로컬에서 터미널을 띄우고 aws configure를 입력해 구성한다

$ aws configure
AWS Access Key ID [None]: {각자에게 주어진 Access Key}
AWS Secret Access Key [None]: {각자에게 주어진 Secret Access Key}
Default region name [None]: ap-northeast-2
Default output format [None]: json

 

4. 로컬에 Session Manager Plugin을 설치한다

https://docs.aws.amazon.com/ko_kr/systems-manager/latest/userguide/session-manager-working-with-install-plugin.html

 

용 Session Manager 플러그인 설치 AWS CLI - AWS Systems Manager

이 페이지에 작업이 필요하다는 점을 알려 주셔서 감사합니다. 실망시켜 드려 죄송합니다. 잠깐 시간을 내어 설명서를 향상시킬 수 있는 방법에 대해 말씀해 주십시오.

docs.aws.amazon.com

 

5. EC2를 띄우고, 그 EC2에 AmazonSSMManagedInstanceCore라는 정책이 있는 역할을 부여한다

참고로 EC2에 SSM agent가 설치돼있어야 한다. aws에서 제공하는 AMI로 만들어진 EC2들은 ssm agent가 기본적으로 깔려있는 애들이 많다! 다음 링크의 [SSM Agent의 상태 확인] 섹션을 참고해 SSM agent가 설치돼있는지 살펴보고, 안돼있으면 설치해야한다. 설치된 상황이라면 해당 역할을 부여한 후 SSM agent를 재시작해준다.

 

재시작하는 커맨드는 상태 확인 커맨드에서 status만 restart로 바꾸면 된다.

 

https://docs.aws.amazon.com/ko_kr/systems-manager/latest/userguide/ami-preinstalled-agent.html

 

Amazon Machine Images(AMIs), SSM Agent 사전 설치 - AWS Systems Manager

SSM Agent가 이 목록에 없는 AWS 관리형 AMIs에 사전 설치되어 있을 수 있습니다. 이 경우 일반적으로 운영 체제(OS)에서 모든 Systems Manager 기능이 완벽하게 지원되지 않습니다. 또는 SSM Agent가 AWS Marketp

docs.aws.amazon.com

 

6. 터미널에 다음 커맨드를 입력한다

aws ssm start-session --target {EC2 인스턴스의 id} \
                       --document-name AWS-StartPortForwardingSessionToRemoteHost \
                       --parameters '{"portNumber":["3306"],"localPortNumber":["3306"],"host":["{RDS 엔드포인트}"]}'

 

그러면 ssh 포트포워딩을 했을 때처럼 로컬의 3306포트와 RDS의 3306포트가 연결된다.

 

 

 

 

 

참고한 글

https://blog.naver.com/PostView.naver?blogId=alice_k106&logNo=221364560794 

 

150. [SSH, Network] SSH 포트 포워딩(SSH 터널링)의 개념 및 사용 방법

이번 포스트에서는 'SSH 포트 포워딩' 또는 'SSH 터널링' 이라고 불리는 것에 대해서 설명한다. 1. ...

blog.naver.com

https://musma.github.io/2019/11/29/about-aws-ssm.html

 

AWS SSM으로 EC2 인스턴스에 접근하기 (SSH 대체)

목차 서론 들어가기: 더 좋은 방법 대상 독자 SSM: AWS Systems Manager 원격 호스트 접속 방법 비교: SSH (기존) vs. SSM (개선) S...

musma.github.io

https://hbase.tistory.com/328

 

[Linux] ssh 터널링(ssh port forwarding) - Local / Remote / Dynamic Tunneling

sh는 Secure SHell의 줄임말로 원격 호스트에 접속하기 위해 사용되는 보안 프로토콜이다. 당연하게도 ssh는 원격 호스트로 접속하기 위해 가장 많이 사용된다. 그런데 ssh는 원격 호스트로의 접속과

hbase.tistory.com

https://hwan-shell.tistory.com/382

 

AWS Session manager 란? (설명 및 설정 방

EC2를 접속할 때 기본적으로 SSH를 통해서 접속합니다. SSH를 통해서 접속하려면 SSH key가 필요하고 EC2 Inbound 22 port를 허용해 줘야 합니다. SSH를 사용하게 되면 Key 없이는 접속할 수 없고, Key를 분실

hwan-shell.tistory.com

https://aws.amazon.com/ko/about-aws/whats-new/2022/05/aws-systems-manager-support-port-forwarding-remote-hosts-using-session-manager/

 

AWS Systems Manager, Session Manager를 사용한 원격 호스트로의 포트 포워딩 지원 발표

AWS Systems Manager가 Session Manager를 사용한 원격 호스트로의 포트 포워딩 지원을 발표합니다. AWS Systems Manager는 AWS 애플리케이션 및 리소스를 위한 운영 허브이며, 하이브리드 클라우드 환경에 대해

aws.amazon.com