1. 퍼블릭엑세스(Public Access)를 허용하지 않는 이유
*과금, 비용, 돈
AWS 프리티어를 이용해서 몇가지 테스트를 해보고 있었는데, RDS에 퍼블릭 엑세스를 허용하였더니
조금이지만 과금이 된 것을 확인했다.
과금이 된 이유는 VPC때문이다.
VPC는 AWS에서 서비스, 솔루션을 제공할 때 필요한 네트워크 환경인데
퍼블릭엑세스를 허용하게 되면 이 네트워크를 공개적으로 사용할 수 있도록 열어놓는 것이기에 과금이 된다고 한다
원래는 과금이 안됬었는데 2024년부터 바뀌었다고 한다.
* 보안적 위험성
퍼블릭엑세스 허용 시 RDS가 퍼블릭 IP를 가지게 되어 전세계의 누구라도 접속을 시도할 수 있게 된다.
물론 데이터베이스의 id, password도 있고, 보안그룹을 설정할 수 있어서 DB접속을 막을 순 있지만
"접속시도"자체는 막을수가 없다.
무차별 대입공격(Brute force attacks), SQL인젝션 등 자동화된 공격에 노출될 위험이 있다.
그리고 개발자의 실수로 보안정보를 하드코딩하여 github이나 다른곳에 노출이 된다면 너무 위험한 상황이 된다.
2. 로컬 접속은 어떻게? ➡️ EC2 ssh 터널링
그러나 개발할 때 로컬환경에서 DB에 접속하지 못한다면 여간 불편한 것이 아니다.
그래서 로컬환경에서 rds에 접근할 수 있는 방법은 무엇이냐!
바로 EC2를 이용한 SSH 터널링이라는 기술이다.
ec2 인스턴스를 만들어서 접속할 때 보통은 pem ,ppk키값을 가지고 접속해본적이 있을것이다.
그때 사용하는 프로토콜과 포트가 ssh 22번 포트이다.
이 ssh연결을 터널처럼 통과해서 rds에 접근한다는 의미이다.
물론 이것도 ec2가 외부에 노출된 IP를 가지고 있는건 마찬가지 이지만
그pem, ppk 키 값을 가지고 있어야만 데이터베이스에 접근할 수 있어서 보안적으로 더 안전하다.
위 도식처럼 EC2를 타고 RDS에 접근하는 것이다.
EC2는 client로부터 오는 요청받고 그 요청을 다시 RDS로 보내주는 것(Port Forwarding)이다.
3. dbeaver로 ec2 터널링 이용해서 rds연결하기
이제 개념적으로 대충 이해했으니, 실전으로 들어가보자.
일단 준비물은 아래와 같다.
- Public Access가 비활성화된 RDS 인스턴스 (Private Subnet에 위치)
- RDS와 동일한 VPC 내의 Public Subnet에 위치한 EC2 인스턴스 (Bastion Host 역할)
- EC2 인스턴스에 접속할 수 있는 SSH Key Pair (.pem 파일)
- 로컬 DB 클라이언트 - DBeaver (MySQL Workbench, DataGrip 등 다른 클라이언트 프로그램도 가능할것이다.)
Client => EC2(Bastion Host) => RDS 이 순서로 요청이 흘러갈테니
RDS부터 거꾸로 설정을 진행해보자.
RDS 보안설정
- RDS 인스턴스의 보안 그룹(security group) 규칙에 EC2(Bastion Host)의 프라이빗 IP 주소 또는 보안그룹 ID에서 RDS 포트(MySQL 3306)을 허용한다.
Bastion Host(EC2) 보안설정
- Public Subnet에 EC2를 생성하고, SSH접속을 허용하도록 보안그룹을 세팅한다.
- 이 보안그룹의 인바운드 규칙에는 본인 로컬 IP 주소에서 SSH 포트(22)로의 접근만 허용하도록 설정한다.
- (옵션) 탄력적 IP(Elastic IP)를 설정해준다.
* 탄력적 IP는 개념상 필수는 아닌 것 같지만, 나의 경우엔 탄력적 IP를 연결해주었을 때 잘 연결되었다. 아무래도 EC2의 IP가 언제 변할 지 모르니 해두는게 좋겠다.
그림처럼 내 IP 를 누르면 현재 아이피를 찾아준다.
SSH 터널링 설정(로컬 DB 클라이언트 - DBeaver)
[ssh 탭]
- SSH 호스트 : Bastion Host 의 퍼블릭 IP 주소 또는 퍼블릭 DNS
- SSH 사용자 이름 : EC2 인스턴스의 기본 사용자 (예: "ec2-user" for Amazon Linux, "ubuntu" for Ubuntu, "admin" for Windows)
- SSH 키 파일: Bastion Host 생성 시 사용한 .pem 파일
- advanced settings의 implementation SSHJ 선택
Test tunnel configuration 이 잘 되는지 확인
[Main 탭]
- server host: RDS 엔드포인트
- port : RDS 포트 (예: 3306)
- username : RDS생성시 설정한 username
- Password : RDS생성시 설정한 password
- 이렇게 설정하면, ssh 터널링을 이용해서 Main탭에서 설정한 RDS 엔드포인트로 가도록 해줍니다.