프라이빗 데이터베이스에 안전하게 접근하기 : SSH 터널링과 Read-only 유저의 활용

김태훈·2023년 12월 2일
0

성균관대 Skkuding

목록 보기
8/19
post-thumbnail

현재 SKKUDING 동아리에서 PostgreSQL로 RDS를 운영하고 있다. 하지만 백엔드 팀원들이 개발을 하는 과정 중, DB에 직접 접속할 수 없어서 불편함을 느끼고 있다고 하였고, 이를 해결한 과정을 설명한다.

1. Bastion Host 사용

(1) Bastion Host란

Bastion Host란 외부 네트워크와 내부 네트워크(VPC) 사이에 놓여 일종의 보안역할을 담당한다.(Bastion이 군사 요새로 사용되었다는 것에서 유래)

하지만 이외에도 내부 네트워크의 로그들을 수집하고, Private IP에 존재하는 리소스에 접근하기 위한 경유지로 사용 되기도 한다. 이렇게 사용될 수 있는 이유는 Bastion Host가 외부에서 접근이 가능하기도 하지만, 내부 네트워크와 통신도 가능하기 때문이다. 즉, 내부 네트워크와 외부 네트워크를 연결하는 징검다리 역할을 한다.

(2) 도입 배경

지금 겪고 있던 문제상황이 그러하다. 현재 AWS RDS를 Private Subnet에 두고 사용하고 있고, 네트워크 외부에서 들어오는 모든 Public Access를 막아두었다. 하지만 이러한 경우에도, 엄연히 DB를 관리할 수 있어야한다. 이를 위해서 Bastion Host를 사용하였다.

(3) Bastion Host 구현

Bastion Host는 더도말고 덜도말고 매우 값싼 EC2 하나로도 충분했다. 통신의 징검다리 역할만 하면 충분하다.

1. EC2 사용

EC2는 다음 조건을 만족하게 구성하였다.

  1. ssh(22) port만 허용
  2. Public Subnet에 포함
  3. 가장 가격이 적은 arm기반 t4g.nano (0.0052/h) 사용

2. 외부 통신을 위한 부가 설정

  1. 해당 EC2에 Elastic IP를 부여 (안해도 되지만 하는게 속편함)
  2. Public Subnet을 Internet Gateway와 연결된 Routing table에 포함
  3. ssh로 EC2의 Elastic IP로 pem Key와 함께 접속 가능

2. SSH 터널링을 활용한 DB 연결

기본적으로 DBMS IDE들이 DB 통신을 위해 SSH터널링 방식을 지원한다.

이번에 사용한 DBMS IDE는 JetBrains사의 DataGrip이다. 성균관대학교 학생이면 학생의 슈퍼파워로 JetBrains를 무료로 사용할 수 있다. 그래서 원래였으면 비싸서 꿈도 꾸지 못할 DataGrip을 사용하기로 하였다.

그럼, 본격적으로 DataGrip을 활용하여 어떻게 Private DB와 통신하는지 알아보자.

(1) DataSource 추가하기

  1. 열면 이런창👇이 뜰 것이다. 좌측 상단에 + 를 눌러서 Data Source를 추가시키자.

  2. 클릭 클릭!

  3. 그럼 요런 창👇이 뜨는데 General한 설정은 이따가 알아보고 SSH터널링 설정부터 하자.

  4. 여러분들은 SSH config에 공백이어야 정상입니다. 오른쪽에 문서 표시 아이콘을 눌러줍시다.

  5. 사실 Host는 Public IP라 안가려도 되지만, 공개할 필요는 없을 것 같아서 그냥 가렸습니다.

  • Host : Public IP (Elastic IP)
  • Username : ec2 사용자 이름
  • Authentication Type : Key Pair (따로 공유 드림)
  • Private Key File : 공유드린 key 파일 다운로드 경로로 그대로 열어주시면 됩니다.
  1. Test Connection 실행 -> Username@Host 연결되었다고 뜨면 성공이에요

  2. 아까본 general 탭으로 가서 여러 설정을 합시다.

  • Host : DataBase 엔드포인트와 동일
  • Port : 원래 PostgreSQL은 5432이지만 저희는 5433을 사용합니다.
  • Authentication : 이거는 제가 따로 DBMS에서 만든 계정이에요. 혹여나 실수로 DB내용을 수정/삭제해서 정합성이 깨지거나 DB가 날려먹는 일을 방지하고자 Read Only (usage Grant) 권한만 존재하는 계정으로 User & Password 방식을 사용하였습니다. 이와 관련한 내용은 따로 뺄게요.
    제가 알려드린 User와 Password 입력하시면 됩니다.
  • database: 저거는 RDS에 존재하는 DB이름을 나타내는건데, 여기서 직접 설정해주셔도 되는데, 저대로 둬도 상관 없습니다. 이따가 다시 설정할거에요. 보통 DB 사용할때, 다른 DB선택하고 다시 돌아오기도 합니다.
  • URL : 따로 설정할 필요없이 저거 다 입력하면 알아서 URL기입해줍니다. 보안상 가려놓은 거에요.
  1. Test Connection 클릭 아래창 뜨면 성공입니다.

  2. Apply 해주세요.

(2) DB 보는 방법

10.그러면 왼쪽에 네비 바에 이렇게 뜹니다. 근데 뭔가 이상할거에요. 아무리 찾아봐도 DB Table은 없어요. 어떻게 된걸까요?

  1. 저기 1 of 4 이친구 눌러줍시다.

  2. 그럼 이렇게 뜰건데 여기서 체크표시해서 가려진 친구들을 볼 수 있어요. 다 필요없고 skkuding만 체크해줍시다.

  3. 근데도 또 없을 수도 있어요. 옆에 3 눌러주셔서 모든 schema 체크합시다.

  4. 그래도 안보이시면, 상단에 새로고침을 눌러주세요! 매번 새로운 상태로 갱신합니다. 보통 반영이 조금 느려요.

  5. 그후 public schema에 가보시면 모든 테이블을 다 볼 수 있습니다!

3. user 권한 설정 방법

어떻게 권한을 설정했는지 궁금하신 분 & 유지 보수 하시는 분은 읽어주시면 좋을 것 같습니다.

AWS에 DB를 띄우면, 마스터 사용자 ID랑 비밀번호를 설정하라고 합니다. 그 사용자 ID와 비밀번호가 해당 DB의 super 권한을 가진 super user입니다.
결국 초기상태는 super user 밖에 존재하지 않습니다.

하지만, super user계정을 모든 개발자들에게 공유하는 것은 사람들이 실수로 테이블을 날려먹고, 정합성이 깨지는 DB수정을 하는 경우가 많을 거라고 생각이 됩니다.

그래서, Read Only만 가능한 User를 생성하고, 이를 팀원에게 공유한 것입니다. DB를 유지보수하는 역할을 하시는 분들은 Super User계정을 이용하시면 됩니다.

(1) 유저 생성하기

GUI상에서 해도 됩니다. 저기서 새로운 user를 직접 만드시면 되요.

그러면,

요런 창이 뜹니다.
여기에서 Grants에 특정 schema의 권한같은 것들을 줄 수가 있는데, 이게 GUI상에서 잘 안먹힙니다.. 이거때문에 시간을 많이 날렸어요. 나는 skkuding db에 위치하는 schema에 권한을 걸었는데, 다른 db schema에 권한이 걸리는 문제가 발생했습니다.

그래서 결국 직접 command로 다 해결했습니다. command가 만능임을 잘 알아주세요.

쿼리는 다음과 같습니다.

create role codedang_guest with
    LOGIN
    PASSWORD '머시기머시기'
    INHERIT;

grant usage on schema public to codedang_guest;
grant select on all tables in schema public to codedang_guest;
  1. LOGIN 설정 : 로그인해야 해당 유저 권한을 부여받은 계정을 사용할 수 있습니다.
  2. PASSWORD : login을 하려면 패스워드가 필요합니다. 처음엔 안해봤는데, 패스워드 입력하라고 하길래 그냥 password도 추가로 입력하였습니다.
  3. INHERIT : 사실 이 설정은 정확히 모르겠는데, ROLE을 상속받을 수 있는거라고 하더군요? 그래서 일단 체크했습니다.. ㅎㅎ
  4. usage 권한 부여 : grant usage권한을 public schema에 다 적용시켰습니다.
    근데 여기서 중요한거는 schema가 public인데 어느 데이터베이스의 schema인지 명시할 수 없습니다. 그래서 반드시 현재 database가 skkuding인지 반드시 확인해주세요. 여기서 usage권한이란 db 조회만 가능한 권한입니다.
  5. 근데 usage 권한을 줘도 처음에는 조회조차 안되더라고요? 그래서 그냥 모든 테이블에 select 권한을 다시 주었습니다. 이건 왜그런지 잘 모름. 아마 권한이 Schema 자체에만 걸렸기 때문이 아닐까 추측합니다.

(2) 근데 발생한 문제점이 있어요..

테이블내용 수정, 삭제는 안되는걸 확인했는데, 테이블이 만들어지고 삭제되는게 가능하더군요. 분명 전 이러한 권한을 부여하지 않았는데요..
그래서 구글링한 결과 다음 내용이 나왔습니다.
https://dba.stackexchange.com/questions/35316/why-is-a-new-user-allowed-to-create-a-table

When you create a new database, any role is allowed to create objects in the public schema.

그래서 public schema에 부여된 권한을 삭제하였습니다.
이건 GUI상에서 진행했습니다.

저기에서 public 의 grant 부분에서 create권한을 삭제해주었습니다.
이를 통해 문제를 해결할 수 있었습니다.

(3) 정리하자면..

GUI가 솔직히말해서 조금 반영도 늦고, 저희 예상과 다르게 움직이는 부분이 많아서 웬만하면 커맨드로 직접 해결하시는 것을 추천드립니다.
그리고 이러한 DB작업하실 때, 백업 스냅샷 하나만 찍고 진행하시는 것을 추천드립니다. (사실 전 안했는데.. 꼭 하세요 생각난 김에 찍고왔네요)

profile
기록하고, 공유합시다

0개의 댓글