회고

Dokkaebi #2 오픈소스 프로젝트 DB 비밀번호 노출 해결

돌멩이1 2022. 6. 30. 00:14

쉽고 빠른 배포 솔루션 도깨비 (구 도커비)는 오픈소스 프로젝트로 퍼블리싱 하는 것을 전제로 진행한 프로젝트이다.

Mariadb를 사용한 이유

도깨비의 요구사항에 따르면 아래와 같은 정보를 저장하고 관리해야했다.

  • 회원 정보 (아이디, 비밀번호, 닉네임, 등록일, 최근수정일)
  • 프로젝트 정보 (프로젝트 제목, 최근 빌드 상태, 등록일, 최근 수정일)
  • 깃랩 정보 (프로젝트를 Clone할 깃 정보, Web hook을 위한 Secret token)
  • 빌드 정보(프로젝트별 빌드 정보 - 빌드 번호, 타입, 상태, 등록일, 최근 수정일)
  • 웹훅 히스토리 (빌드가 웹훅을 통해 이루어진 경우 이벤트 종류, 깃 유저 이름, 깃 url, 브랜치 이름
  • 프로그래밍 언어별 버전과 Docker image:tag 정보 (도커 이미지 버전)
  • 데이터베이스 별 버전 (MySQL, mariadb, mongodb)

위 데이터들을 관리하기 위한 데이터베이스가 필요했다. NoSQL,과 RDB와 고민을 했다.

데이터의 삽입 또한 빈번하게 이루어지기 때문에 NoSQL보다 RDB가 적합할 것이라고 판단했다.
Docker container의 linux는 MySQL 설치 대신 mariadb가 설치되는 이슈가 있었기에 MySQL -> mariadb로 변경했다.
파일 형식을 고민해보기도 했지만 빌드 번호 별 상태 관리를 모두 저장하고 사용자에게 보여주어야했기에 최종적으로 RDB를 선택했다.

하지만 데이터베이스 컨테이너의 필수 환경변수 (MYSQL_ROOT_PASSWORD, MYSQL_DATABASE 등)에 대한 정보는 비정형이기 때문에 파일로 관리했다.

DB 비밀번호 노출???

앞서 도깨비 프로젝트는 오픈소스로 기획된 프로젝트임을 설명했다. 이는 즉 ROOT 비밀번호는 필수적으로 노출될 수 밖에 없음을 시사한다.
도깨비 프로젝트는 서버에 직접 설치한 뒤 서버의 8482로 접속해 웹 브라우저에서 배포를 할 수 있는 솔루션이다.

즉 외부 사용자에게 서버 컨트롤이 노출될 가능성이 존재하기 때문에 최대한으로 서버 관리자 혹은 인증된 사용자임을 검증하는 것이 중요하다고 생각했다. 

'사용자가 도깨비를 설치할 때 입력하도록 하면 되는 것 아니냐?' 같은 의견을 제시할 수 있다.
도깨비 프로젝트는 인프라에 대한 지식이 전무한 주니어 개발자들을 타겟으로한 솔루션이다.
이말은 즉 사용자는 Docker가 무엇인지, 배포를 어떻게 하는 것인지 모른다는 뜻이다. 
최대한 Docker 설치와 솔루션 설치를 간편하게 가져가기 위해서는 설치할 때 비밀번호를 설정하는 방법을 가져가기엔 부적합하다고 생각했다.

 그래서 최종적으로 선택한 방법이 프로세스를 설치할 때 UUID(uuidgen 사용)로 사용자 인증 토큰을 생성했다.
UUID는 고유값을 100% 보장하지는 못하기 때문에 설치하는 순간의 timestamp를 base64로 인코딩해 SALT 방식으로 UUID 키값 뒤에 붙여주는 방법으로 100% 고유성을 보장하기 위해 노력했다.

해결

#!/bin/bash

# key gen
AuthKey=`uuidgen`
Time=`date +%H%M%S`
Time=`echo $Time | base64`
AuthKey=${AuthKey//-/}$Time
AuthKey=${AuthKey//=/}
echo $AuthKey > /AuthKey
echo -n $AuthKey > /home/conf/AuthKey

# service 
service mariadb start
service nginx start
mysql -uroot -pdokkaebi  -t < home/conf/db/init.sql
mysql -uroot -p -e "set password for 'root'@'localhost' = PASSWORD('$AuthKey')"
java -jar -Duser.timezone=Asia/Seoul home/conf/app.jar
#java -Xdebug -agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=*:5005 -jar home/conf/app.jar

위 코드는 AuthKey를 생성하는 shell script이다. [바로가기]

이렇게 생성한 AuthKey를 도깨비 컨테이너의 /home/conf에 저장해 도깨비 솔루션에 회원가입 할 때 사용하도록 비즈니스 로직을 작성했다.

도깨비 컨테이너에 접속할 수 있는 권한은 서버 관리자에게 있기 때문에 AuthKey를 확인할 수 있다는 것으로 적합한 사용자라고 인증을 할 수 있기 때문에 위와 같은 방법을 사용했다.