Outsider's Dev Story

Stay Hungry. Stay Foolish. Don't Be Satisfied.

Vault의 PostgreSQL 시크릿 백엔드

지난달에 Vault 서버를 구성하고 기본적인 사용방법을 정리했는데 generic 시크릿 백엔드만 사용했으므로 다른 백엔드를 사용해보자. 여러 백엔드를 다 써본 것은 아니지만 대부분 비슷하므로 백엔드를 하나 사용해보면 어떤 식으로 동작하는지 대충 예상할 수 있다.

generic 시크릿 백엔드는 이미 가지고 있는 정보를 저장하는 방식이라면 그 외에 다른 백엔드는 대부분 서비스를 연결해서 필요할 때 시크릿 정보를 동적으로 발급받아서 사용하는 방식이다. 동적으로 발급받는다는 동작이 말로 설명하기가 어려운데 실제로 한번 보면 이해할 수 있을 거라고 생각한다.

PostgreSQL 시크릿 백엔드

PostgreSQL 시크릿 백엔드를 사용하면 PostgreSQL 데이터베이스에 접근이 필요할 때 인증 정보를 동적으로 Vault에서 받아서 접속에 사용할 수 있다.

이전 글에서 설명한 대로 Vault 서버가 설정되어 있고 루트 토큰으로 인증한 상태라고 해보자.(이전 글 1, 2 참고)

$ vault mount postgresql
Successfully mounted 'postgresql' at 'postgresql'!

PostgreSQL 시크릿 백엔드가 잘 마운트되었다. 마운트 목록을 보면 확인할 수 있다.

$ vault mounts
Path         Type        Default TTL  Max TTL  Description
cubbyhole/   cubbyhole   n/a          n/a      per-token private secret storage
postgresql/  postgresql  system       system
secret/      generic     system       system   generic secret storage
sys/         system      n/a          n/a      system endpoints used for control, policy and debugging


PostgreSQL 시크릿 백엔드 구성

개발 중인 서버 애플리케이션에서 사용 중인 데이터베이스가 127.0.0.1:5432에 있다고 해보자.(이는 데모를 위해서이고 실제로는 Vault와 같은 로컬에 있지 않을 것이다.) 이제 vault write postgresql/config/connection에 다음과 같이 커넥션 정보를 저장하면 된다. 계정과 비밀번호가 모두 postgres이고 app이 데이터베이스 이름이다.

vault write postgresql/config/connection \
> connection_url="postgresql://postgres:postgres@127.0.0.1:5432/app?sslmode=disable"


The following warnings were returned from the Vault server:
* Read access to this endpoint should be controlled via ACLs as it will return the connection string or URL as it is, including passwords, if any.

이제 Vault가 데이터베이스에 접근할 권한을 갖게 되었다 여기서 새로운 계정을 만들 것이므로 이 계정(여기서는 postgres)이 사용자를 관리할 수 있는 GRANT OPTION 권한을 가지고 있어야 한다. 마지막에 나온 안내 메시지는 이 경로를 통해 커낵션 정보를 볼 수 있으니 ACL로 잘 관리하라는 주의 메시지일 뿐이다.

시크릿 백엔드 설정이 완료되었으므로 roles을 추가하면 된다. 다음은 app이라는 role을 추가하는 명령어다. 당연히 필요에 따라 여러 가지 role을 만들 수 있다.

$ vault write postgresql/roles/app \
> sql="CREATE ROLE \"{{name}}\" WITH LOGIN PASSWORD '{{password}}' VALID UNTIL '{{expiration}}'; GRANT ALL PRIVILEGES ON ALL TABLES IN SCHEMA public TO \"{{name}}\";"
Success! Data written to: postgresql/roles/app

위의 app role에 지정한 sql은 실제 PostgreSQL에서 Role을 만들 때 사용할 명령어이다. 위에서 보듯이 새로운 Role을 만들고 해당 데이터베이스의 테이블에 모든 권한(ALL PRIVILEGES)을 주었다. Role을 만들 때 위 SQL 문을 사용하는 것이므로 원하는 조건에 맞게 권한 등을 설정할 수 있고 {{ }}안에 있는 값은 Vault가 자동으로 채워주는 것입니다.

PostgreSQL 시크릿 백엔드의 사용

원래는 postgresql/에 대한 ACL 권한을 주고 인증관리를 해야 맞지만 여기서는 편의상 그냥 사용하도록 하겠다.

$ vault read postgresql/creds/app
Key             Value
---             -----
lease_id        postgresql/creds/app/647a4a14-a91f-9c33-c19f-a79acc2d4625
lease_duration  768h0m0s
lease_renewable true
password        f2ba0b61-b2fd-2559-c22b-5c405a00e0eb
username        root-3c25cbde-ca0b-84b9-3e75-1ab466a258e3

generic 백엔드에서 값을 읽어 오듯이 postgresql/creds/app에서 인증정보를 읽어오면 된다. 마지막의 app은 앞에서 만든 role의 이름이다. 여기서 postgresql/creds/app에 값을 저장한 적이 없으므로 앞에서 설정한 대로 SQL을 실행하고 새로 만들어진 usernamepassword를 반환해 준다.

여기서 발급받은 정보로 접속하면 정상적으로 접속되는 것을 확인할 수 있다.

$ psql -h 127.0.0.1 -p 5432 -d app -U root-3c25cbde-ca0b-84b9-3e75-1ab466a258e3
Password for user root-3c25cbde-ca0b-84b9-3e75-1ab466a258e3:
psql (9.6.1)
Type "help" for help.

app=>

개발할 때 대표적인 비밀 정보 중 하나가 데이터베이스 계정정보이다. 서버의 코드가 유출되는 경우가 많지는 않으니 소스코드에 하드 코딩되어 있는 경우가 많고 따로 관리한다고 하더라도 어딘가에는 하드 코딩이 되어 있어야 한다. 서버 애플리케이션을 이미 운영하기 시작하고 나면 이 계정정보는 바꾸기가 쉽지 않다. 개발하면 개발자들이 퇴사 등으로 바뀌게 마련이고 데이터베이스는 네트워크 등으로 접근이 차단되어 있는 데다가 개발자들이 이미 알고 있는 계정정보로 퇴사 후에 뭔가 한다는 것을 말하는 건 아니지만, 정보는 이렇게 빠져나가는 거고 보안은 누군가를 의심해서 하는 건 아니다. 이런 상황은 개발의 생산성을 낮추지 않으면서도 계정정보를 잘 관리할 방법이 별로 없으므로 하는 방식인데 이를 Vault에 넣는다면 전체 데이터베이스 계정 관리하나만 Vault에 넣어두고 개발자나 서버 애플리케이션을 필요할 때 발급받아서 사용할 수 있으므로 관리하에 둘 수 있고 혹여 유출된다고 하더라도 Vault에 저장한 메인 정보가 유출된 게 아니라면 revoke 하면 그만이다.

위에서는 만료시간이 768시간 즉, 32일로 설정되어 있다. 이 시간이 앞에서 입력한 SQL 문에 {{expiration}}에 들어가므로 계정 자체가 이 시간 내에만 유효한 계정으로 만들어지므로 이 시간도 정책에 따라 잘 설정해야 한다. 이 값은 vault write postgresql/config/lease lease=10h lease_max=24h 명령어로 원하는 값으로 바꿀 수 있는데 아직 lease 시간이 되면 어떻게 되고 어떤 정책으로 운영해야 할지는 아직 테스트해보지 못했다.

2017/02/09 03:03 2017/02/09 03:03

기술 뉴스 #71 : 17-02-01

웹개발 관련

  • A Brief History of JavaScript : 제목 그대로 JavaScript의 역사를 다룬 글이다. Brendan Eichr가 JavaScript를 처음 만들게 된 이유부터 현재의 ECMAScript 2016/2017까지 어떻게 진행됐는지가 정리된 글이다. 글이 길어서 부담되는 글이지만 정리 차원에서 읽어볼 만하다.(영어)
  • GitHub's post-CSP journey : GitHub에서 브라우저의 CSP(Content Security Policy)로 공격을 막는 방법을 찾는 과정을 적은 글이다. 다른 데서는 거의 볼 수 없는 공격방법을 막기 위해서 GitHub이 어떤 시도를 했고 어떻게 해결해 나갔는지가 상세하게 나와 있는데 실제로 이렇게 막지는 않더라도 이런 식으로 막는다는 과정을 보는 것만으로도 이 긴 글을 읽어볼 가치가 있다.(영어)
  • How to get a performance boost using WebAssembly : 피보나치 함수를 JavaScript로 다양하게 구현한 로직과 C로 구현한 후 WebAssembly로 변환해서 브라우저에서 실행한 후 WebAssembly가 JavaScript보다 얼마나 빠른지 비교한 글이다. 이 글에서는 C 구현체의 가장 좋은 로직이 JavaScript로 구현한 것보다 375% 빠르다.(영어)
  • WebGL 2 lands in Firefox : Firefox 51에 WebGL 2가 추가되었다. 파이어폭스를 51로 업데이트하면 WebGL 2 데모인 After the Flood을 실행해 볼 수 있다.(영어)
  • webpack bits: Learn and Debug webpack with Chrome Dev Tools! : Node.js의 나이틀리 빌드 버전을 이용해서 Webpack을 크롬 개발자 도구와 연결해서 디버깅하거나 프로파일링을 하는 방법을 설명한 글이다. 크론 개발자 도구의 Node.js 디버깅 기능이 Webpack을 위한 기능은 아니지만 Webpack의 동작을 이해하고 디버깅할 때도 유용하다.(영어)
  • HTML 5.1 변경사항 : 작년 말에 나온 HTML 5.1에서 변경된 내용을 신현석 님이 정리한 글이다. HTML 표준의 변경사항을 일일이 따라가기가 쉽지 않은데 이렇게 한 번에 정리된 글을 통해서 어떤 요소가 추가되고 삭제되었는지 파악해 두는 것은 중요하다.(한국어)

그 밖의 프로그래밍 관련

볼만한 링크

  • [번역] 잘 가요 스크럼, 반가워요 칸반 : Stormpath가 스크럼을 도입했다가 칸반으로 바꾼 이유를 설명한 번역 글이다. 스크럼이 문제 있다기 보다 Stormpath 팀은 스타트업으로 이미 긴밀하게 일하고 있던 가운데 스크럼의 규칙이 오히려 더 느리게 만들었고 그래서 칸반으로 바꾸고 만족하고 있다고 한다. 2015년 글이지만 칸반은 별로 안 해봐서 재미있게 보았다. 스크럼은 시간에 제한을 두어 생산성을 낸다면 칸반은 동시에 처리하는 일의 개수에 제한을 두어 생산성을 낸다는 비교가 흥미로웠다.(한국어)
  • 구글, 설치 없이 실행 가능한 '인스턴트 앱' 공개 : 구글이 앱 설치 없이 사용할 수 있는 안드로이드 인스턴트 앱을 발표했다.(한국어)
  • 압축 알고리즘 르네상스 (1)​ : 압출 알고리즘 영역이 최근에 Zstandrd를 중심으로 발전하는 변화를 설명한 2편의 글이다. 압축 알고리즘이 하는 접근부터 현재 변화에서 시도하는 부분의 차이까지 아주 자세히 나와 있다.(한국어)

IT 업계 뉴스

  • Fabric is Joining Google : 트위터에 인수되었던 모바일 앱 빌드/배포 플랫폼인 Fabric이 구글에 인수되어 Firebase에 소속되게 되었다.(영어)
  • Arrival : Mozilla가 로고를 새로 교체해서 이제 moz://a가 되었다.(영어)

프로젝트

  • RAW : csv, tsv 등의 데이터를 넣고 GUI에서 그래프 타입과 레이블 등을 지정하면 d3로 시각화를 해주는 프로젝트.
  • PyTorch : Pythong 딥러닝 프레임워크.
  • Bluepill : LinkedIn에서 공개한 프로젝트로 하나의 머신에서 시뮬레이터를 돌려서 iOS UI 테스트를 할 수 있다.
  • Matterwiki : Node.js로 만들어진 오픈소스 위키.
  • Pipenv : Python 생태계에 있는 패키지 시스템을 관리해주는 도구.
  • Paints Chainer : 딥러닝을 이용해서 이미지를 자동으로 색칠해 주는 프로그램.
  • date-fns : 날짜를 다루는 JavaScript 라이브러리.
  • mo.js : JavaScript 모션 그래픽 라이브러리.

버전 업데이트

2017/02/01 23:02 2017/02/01 23:02