AWS SSM로 VPN없이 Private 자원 접근하기

AWS SSM로 VPN없이 Private 자원 접근하기

AWS EC2 혹은 RDS를 사용할때 가장 편리한 방법은 EIP를 부여받아 고정 IP를 할당한 뒤 직접 SSH등으로 접속해 제어하는 방법이다. 하지만 이러한 방법은 보안상 취약하기 때문에 DB등 중요한 데이터가 들어있는 자원은 외부 IP를 부여하지 않고 사용하게 된다.

하지만 이렇게 될 경우, “VPC 내부에서만 액세스 가능하다”는 문제가 생긴다. 즉, AWS의 같은 VPC, 같은 내부 IP를 받은 자원에서만 접근이 가능하다는 점이다.

공개 ip가 부여되지 않기 때문에 인터넷에서 직접적으로 요청을 받는 것이 불가능하다.

이를 해결하기 위해서는..

  1. ❌ AWS에 VPN 서버를 세팅하고 VPN에 연결해 작업한다.
    👉 VPN 서버를 따로 관리해야하는 어려움이 있다.

  2. ❌ AWS Client VPN 서비스(AWS Managed)를 사용한다.
    👉 요금이 비싸다. (최소 월 $70+)

  3. 🤩 AWS SSM + Bastion EC2 + SSH 터널링을 이용한다.
    👉 이번 글에서 다루는 내용! EC2 비용 하나로 서버 세팅 없이 간단히 접속하기

이번 글에서는 3번 방법을 이용해 SSM으로 SSH를 대체하고, SSM 연결을 SSH 세션처럼 이용해 SSH 터널링을 이용해 내부 RDS에 접근하는 과정을 다뤄본다.

0. AWS SSM?

AWS SSM으로 VPN 없이 EC2 접근하기

AWS SSM은 VPN을 이용하지 않고서 안전하게 AWS 자원에 접근할 수 있도록 만들어주는 명령어다. EC2 등 인스턴스들에 연결된 Security Group에서는 SSH 서비스를 위한 22번 포트를 열지 않아도 되며, 개발자들이 EC2에 접근하기 위해 키 파일을 공유하지 않아도 되며, AWS에 생성한 유저의 접근권한 조절을 통해 어떤 EC2에 로그인 할 수 있는지도 제어할 수 있다. 또한, SSH Session 기능을 통해 일반적인 SSH의 Remote Proxy를 이용할 수도 있다.

@2020. 02. 14. SSM은 Bastion 인스턴스 없이 사용할 수 있도록 만들어졌지만, 아직 localhost 에 대해서만 SSH Forwarding을 지원하기 때문에 RDS 등 다른 인스턴스에 접근하려면 Bastion EC2를 생성해야 한다. 이후 업데이트로 추가되면 EC2조차도 필요 없어지면 더 사용성이 높아질 듯 하다.

1. AWS EC2에 SSM 세팅하기

Security Groups 설정하기

AWS 내 자원끼리 통신하기 위해서는 여러 설정이 필요하지만, 만약 default vpc를 사용한다면 기본적으로 내부 자원끼리 통신하도록 Route Table이 설정되어있다.

이와 함께 해당 자원들이 있는 Security Group에 대해 같은 Security Group 내의 모든 트래픽을 열어줄 수 있다.

보안그룹 내 모든 트래픽 허용하기

모든 트래픽이 아닌 특정 프로토콜과 포트만을 열어서 사용할 수도 있다.

또한, 이후 Bastion으로 사용하는 EC2를 소스로 지정해 해당 EC2에서만 접근 가능하도록 설정할 수도 있다.

IAM EC2 역할 설정하기

IAM 역할 생성 첫 페이지

위 스크린샷처럼 AWS IAM에서 새 역할 생성을 한 뒤, AWS 서비스 - EC2 를 선택한다.

AmazonSSMManagedInstanceCore 권한 연결하기

정책에서 AmazonSSMManagedInstanceCore 를 검색한 뒤 체크박스를 클릭해 권한 정책을 연결한다.

태그 추가는 옵션

태그 추가는 옵션이니 빈칸으로 두고 넘어가도 된다.

역할 이름 붙이기

역할 이름은 적당한 이름으로 붙이고 ‘역할 만들기’ 버튼을 누르면 역할이 생성된다.

EC2 생성하기

이제 위에서 만들어준 Security Group과 IAM Role을 가진 EC2 인스턴스를 생성해보자.

인스턴스 종류는 AmazonLinux2, t3.nano를 이용한다.

Amazon Linux2 AMI를 이용해 인스턴스 생성하기

사실 아마존에서 제공하는 모든 AMI에는 SSM을 위한 세팅이 이미 되어있다.
따라서 개발자에게 편리한 OS를 선택하면 된다.

우리가 사용하는 인스턴스는 이후 RDS등과 연결하기 위한 내부 네트워크를 제공하기 때문에, 네트워크 성능이 적절히 나오며 저렴한 EC2를 선택해주면 된다. 이번 글에서는 저렴한 t3a.nano 인스턴스를 이용해본다.

t3a.nano 인스턴스 선택하기

❗️(중요) 인스턴스를 선택한 뒤, 해당 인스턴스의 IAM 역할을 지정해줘야 한다.

앞서 만들어준 EC2-SSM-Bastion 역할을 선택해 준 뒤, 다음을 눌러준다.

EC2 인스턴스에 IAM 역할 붙이기

스토리지 설정과 태그는 기본값 그대로 넘기면 된다. 이후 Security Group 설정에서 ‘기존 보안그룹 선택’을 고른 뒤, 앞서 만든 ssmProxyAllow 보안그룹을 선택한 뒤 인스턴스를 시작해준다.

Security Group 설정하기

RDS 보안그룹 바꾸기

기존에 사용하던 Private Subnet의 RDS 혹은 Aurora Serverless DB가 있다면 해당하는 자원들의 Security Groups에 ssmProxyAllow 그룹을 추가한다.

RDS에 VPC 보안그룹 ssmProxyAllow 추가

‘퍼블릭 액세스 가능성’이 ‘아니오’인 경우에는 엔드포인트 역시 내부 IP를 반환합니다.

`172.31.3.x`로 내부 IP 대역을 반환하는 엔드포인트

사용자 IAM에 권한 추가하기

유저가 만약 Admin 권한이 아니라면 아래 권한을 추가해줘야 SSM을 통해 SSH 세션등을 열고 프록시를 쓸 수 있다.

만약 특정 인스턴스만 지정하고 싶다면 아래 json의 10,11번째에서 * 대신 인스턴스 명을 지정해주면 된다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"ssm:StartSession"
],
"Resource": [
"arn:aws:ec2:*:*:instance/*",
"arn:aws:ssm:*:*:managed-instance/*",
"arn:aws:ssm:*:*:document/AWS-RunShellScript",
"arn:aws:ssm:*:*:document/AWS-StartPortForwardingSession",
"arn:aws:ssm:*:*:document/AWS-StartSSHSession"
]
},
{
"Effect": "Allow",
"Action": [
"ssm:TerminateSession"
],
"Resource": [
"arn:aws:ssm:*:*:session/${aws:username}-*"
]
}
]
}

2. 로컬 PC에 SSM Client 설치하기 - macOS 기준

AWSCLI 설치하기

1
brew install awscli

aws 명령어를 사용하기 위해 awscli 를 설치해준다.

첫 설치인 경우 아래 명령어로 AWS AccessKey와 SecretKey를 등록해줍니다. (해당 유저는 당연히 앞서 설정한 SSM 권한을 가진 유저여야 합니다.)

1
aws configure

AWS SSM Extension 설치하기

1
2
brew tap dkanejs/aws-session-manager-plugin
brew install aws-session-manager-plugin

위 과정을 진행하면 aws ssm 명령어를 사용할 수 있다.

3. 로컬 SSH Config 수정하기

SSH 명령어로 인스턴스 접근하기

ssh 인스턴스-id 명령어를 통해 SSH에 접근하기 위해서는 아래 부분을 ~/.ssh/config 파일 가장 아래에 붙여넣으면 된다.

User와 IdentityFile은 적절한 유저명과 파일 위치 절대경로로 설정해주면 된다.

1
2
3
4
Host i-* mi-*
ProxyCommand sh -c "aws ssm start-session --target %h --document-name AWS-StartSSHSession --parameters 'portNumber=%p'"
User ec2-user # 혹은 ubuntu 등, 실제 유저 이름
IdentityFile ~/.keys/키파일이름.pem

이후 위 스크린샷처럼 ssh 인스턴스명 으로 해당 인스턴스에 SSH로 접근할 수 있다.

4. SSH 터널링으로 Private RDS 연결하기

3번과 같이 ssh 인스턴스명 으로 Bastion EC2에 접근할 수 있게 되면 SSH 터널링을 이용해 내부 IP를 가진 RDS에 접속할 수 있다.

아래 명령어를 입력하면 127.0.0.1:3306database-1.crp78xs4s1n9.ap-northeast-2.rds.amazonaws.com:3306 가 연결된다. 즉, DB연결 툴에서 127.0.0.1:3306 으로 접속하면 위 RDS에 접근할 수 있다.

1
ssh -L 127.0.0.1:3306:database-1.crp78xs4s1n9.ap-northeast-2.rds.amazonaws.com:3306 i-0f067ac2deb58ee88

References

#
Your browser is out-of-date!

Update your browser to view this website correctly. Update my browser now

×