AWS - Private Database 구축하기(3) - SSH Tunneling 으로 Private DB 접속하기(Mac)

# SSH Tunneling의 필요성

  • 이전 글에서 다뤘듯이, Private Database는 외부에서 인터넷을 통해 접근할 수 없다. public IP가 할당되지 않았고, Internet Gateway을 Subnet의 라우팅 테이블에 추가하지 않았기 때문이다. 그렇다 보니, 로컬(local) 환경에서 일반적인 SSH 연결로는 Private DB와 통신을 주고받는 것이 불가능하다.

    • 일반적인 SSH 연결이란 SSH host, SSH user, SSH key 값을 입력하여 DB에 접근하는 것을 말한다. 아래 이미지는 DB 관리 툴(tool) Sequel Pro를 이용해 Public DB에 접근할 때 사용하는 방법이다.
  • SSH Tunneling이 필요한 것도 그래서다. SSH Tunneling의 의미는 대략 다음과 같다.

    SSH 터널링이란 터널링을 SSH 프로토콜을 이용하여 구현하는 것이다. 사내 내부망에 있는 서버로 직접 접속을 허용하지 않는 경우 외부에서 내부에 접근하기 위해서 터널링 기술을 이용하고 이때, SSH 프로토콜을 이용하여 패킷을 암호화하는 것이다.

    • 쉽게 말하면, Public EC2와 Private DB를 엮어 SSH 터널을 생성한 뒤, 로컬(local)에서 Public EC2로 요청을 보내면, 해당 요청이 Public EC2로 전송된 뒤 서버 내부에서 다시 포워딩되어 Private DB로 도달하게 만드는 것이다. 포트 포워딩을 떠올리면 된다. 포트 포워딩이 가능한 이유는 이전 글에서 언급했던 것처럼, Private EC2의 22번 SSH 포트를 허용해뒀기 때문이다.

    • 우선, Public EC2와 Private DB를 엮어 SSH 터널을 생성해보자.

# Public EC2와 Private DB 사이에 터널(Tunnel) 생성하기

  • 우선 Public EC2로 접속한다. 그다음 아래 명령어를 참고해 SSH Tunnel을 생성한다.
 # 명령어 형식
 ssh -i [pem키 경로] -CNf -L [local port]:[database host]:[remote port] [username]@[remote host]
 
 # 예시
 ssh -i [pem키 경로] -CNf -L 33306:127.0.0.1:3306 ubuntu@[EC2 프라이빗 IPv4 주소 or 호스트 이름]
  • 명렁어 세부 설명

    • [local port]: Private DB와 연결할 Public EC2의 포트 번호. 필자의 경우 Public EC2 내부에 설치된 MariaDB가 3306번을 사용 중이었기 때문에, 임의의 번호인 33306번을 지정했다.

    • [database host]: Private DB의 IP 주소나 호스트 이름을 적어주면 된다. Private DB가 Private EC2 안에서 localhost로 존재한다면 127.0.0.1을 입력한다.

    • [remote port]: Private DB가 사용 중인 포트 번호를 입력한다.

    • [username]: remote host의 username

    • [remote host]: tunnel을 연결할 Private Instance(EC2)프라이빗 IPv4 주소나 호스트 이름을 입력한다. 필자의 경우 프라이빗 IPv4 주소를 입력했다.

    • N: 서버에 대한 포트 포워딩 접속을 유지

    • F: backgroundssh 터널을 등록. 주기적으로 터널링 명령어를 입력할 필요가 없어진다.

    • L: Private EC2로 접속한 후, 127.0.0.1 서버의 3306에 접속하는 터널을 33306 포트에 등록

    • C: 이에 대한 모든 데이터를 압축하여 명령을 요청

  • Private DB 접속

    • Public EC2에서 로컬 포트 번호 33306번으로 DB 접속을 하면 된다.
# MariaDB 접속 명령어
mysql -u root -p -h [database host] -P [local port] -> password 입력 -> 접속 성공

# 예시
mysql -u root -p -h 127.0.0.1 -P 33306
  • mysql error: Access denied for user 'root'@'localhost’발생했을 경우

    • mysql이나 mariaDB를 처음 설치했을 때 마주할 수 있는 에러다. 처음 설치하는 경우, root 계정에 대한 password가 지정되지 않아서 이러한 에러가 발생한다. 아래의 순서에 따라 진행하면 해결할 수 있다.
# Mysql(MariaDB)접속 
sudo mysql -u root -p 

# root 계정 확인
SELECT User, Host, plugin FROM mysql.user;

# root 계정에 비밀번호 지정 
ALTER user 'root'@'localhost' IDENTIFIED BY '[password]';

# 로컬(local)과 Private DB 사이에 터널(Tunnel) 생성하기

  • 로컬(local)과 Private DB를 연결하는 터널을 생성하려면, 두 가지 설정이 선행돼야 한다. 첫 번째는 Private EC2의 3306포트를 개방하여 localhost 이외의 ip가 Private DB에 접근할 수 있도록 하는 것이다. 다른 하나는 로컬(외부)에서 Database에 로그인할 수 있도록 외부 접속용 계정을 생성하는 일이다.

  • 우선 AWS 계정으로 로그인하여 Private EC2가 3306 포트로의 외부 접속을 허용하도록 보안 규칙을 편집하자.

  • 외부 접속이 허용되도록 Private DB 설정 파일(mysql.conf.d 혹은 mariadb.conf.d)을 편집하는 것도 잊지 말자. bind-address를 주석처리하면 DB에 127.0.0.10.0.0.0 모두에서 접근할 수 있다.

  • 이제 외부 접속용 DB 계정을 생성하자. 생성 방법에 관한 설명은 생략하겠다. 구글에서 'mysql 외부 접속 계정'이라고 검색하면 관련 자료를 쉽게 찾을 수 있다. 계정이 정상 생성됐다면, 아래 이미지처럼 Host 값이 '%'인 계정이 만들어진다.

    • 계정 Host 값 확인 방법
      • mysql -u root -p -> DB 접속
      • USE mysql
      • SELECT user, host FROM user;

  • 이제 모든 준비가 끝났다. 로컬 환경에서 터미널을 열고 터널(Tunnel) 생성 명령어를 입력한다.
 # 명령어 형식
 ssh -N -L [local port]:[Private EC2 host name]:[remote port] -i [pem키 경로] [username]@[Public EC2 host name OR public IP]
 
 # 예시
 ssh -N -L 33306:ip-172-xx-xx-xxx.ap-northeast-2.compute.internal:3306 -i  xxx-xxxxxxx-xxxx.pem [email protected]
  • 터널이 제대로 생성됐는지 확인 후 Private DB에 원격 접속한다.
 # 터널 생성 확인
 lsof -i :[local port]
 
 # 예시
 lsof -i :33306 
  • 입력 후 해당 포트(local port)에 대한 정보가 출력되면 터널이 문제없이 생성된 것이다. 다음으로 DB에 접속한다.
 # DB 접속
 myysql -u [외부 접속용 계정] -p -h 127.0.0.1 -P [local port]

 # 예시
 mysql -u sangxxx -p -h 127.0.0.1 -P 33306
  • Private DB 접속에 성공했다.

좋은 웹페이지 즐겨찾기