데이터베이스 비밀번호를 바꿨더니 사이트는 정상인데 crontab 에 건 새벽 배치가 실패했다. 배치 스크립트가 옛 비밀번호를 들고 있었다.
Table of contents
Open Table of contents
세 곳에 있었다
grep -rl 로 옛 값이 든 파일을 찾으니 config.php 와 백업 스크립트와 정산 스크립트 셋이었다. 각각 다른 시점에 만들어졌고 그때마다 값을 복사해 넣은 것이었다.
같은 값이 세 곳에 있으면 바꿀 때도 세 곳이다. 한 곳을 빠뜨리면 그 하나만 실패하는데 나머지가 정상이라 문제가 없어 보인다.
한 곳에서 읽게 했다
값을 한 파일에 두고 나머지가 그것을 읽게 했다.
# /etc/shop/db.conf
DB_HOST=10.0.0.22
DB_USER=shop
DB_PASS=***
DB_NAME=shopdb
셸 스크립트에서는 source 로 읽어 쓰고 PHP 에서는 parse_ini_file 로 같은 파일을 읽는다. 바꿀 자리가 하나가 됐다.
권한도 봤다. 만들어 놓고 보니 다른 사용자도 읽을 수 있는 상태였다.
$ chown root:www-data /etc/shop/db.conf
$ chmod 640 /etc/shop/db.conf
chmod 640 과 chown 으로 웹 서버 계정만 읽게 하고 다른 계정으로 도는 배치는 그 그룹에 넣었다. 한 곳으로 모으면 그 한 곳의 권한이 전부를 결정한다.
명령줄과 로그에 값이 보였다
파일로 모으고 나서 다른 것이 보였다. -p 뒤에 붙여 명령줄로 넘기면 실행 중에 ps 목록에 값이 그대로 나온다.
$ ps -ef | grep mysqldump
deploy 12043 ... mysqldump -h 10.0.0.22 -u shop -p*** shopdb
같은 서버에 들어올 수 있는 사람이면 다 본다. MySQL 매뉴얼도 명령줄에 비밀번호를 주는 것은 안전하지 않다고 보고 옵션 파일을 쓰라고 안내한다. --defaults-extra-file 로 넘기고 그 파일을 chmod 600 으로 좁혔다. 명령줄에는 값이 안 나오고 대신 파일 권한이 방어선이 된다.
로그에도 값이 찍히고 있었다. 스크립트 맨 위에 set -x 가 켜져 있어서 도는 명령이 그대로 출력됐다. 필요한 구간에만 켜고 set +x 로 끄게 했다.
set -x
# 확인할 구간
set +x
mysqldump ...
옛 값이 남은 자리
한 곳으로 모은 뒤 옛 값이 남은 데가 없는지 다시 훑었더니 두 군데가 더 나왔다. 옛 백업 스크립트 사본과 몇 달 전 작업 로그 파일이었다.
편집 전에 .bak 사본을 원본 옆에 만들어 두고 안 지우는 습관이 있었는데 그 안에 값이 그대로 있었다. 사본은 아무도 안 보므로 정리 대상에서도 빠진다.
다음에 비밀번호를 바꿀 때 확인할 목록도 적어 뒀다. 설정 파일을 고치고 웹 서버를 재시작한다. 배치 스크립트를 한 번 손으로 돌려 본다. 다음 날 새벽 배치 로그를 확인한다. 마지막으로 grep -rl 로 옛 값이 남았는지 검색한다. 세 번째와 네 번째가 이번에 빠졌던 것이다.
정리
- 같은 값이 여러 곳에 있으면 바꿀 때도 여러 곳이다
- 하나가 빠지면 그것만 실패하고 나머지가 정상이라 안 보인다
- 값을 한 파일에 두고
source와parse_ini_file로 읽게 한다 chmod 640과chown으로 그 한 파일이 전부를 결정하게 한다-p뒤에 붙이면ps에 보인다 —--defaults-extra-file로 넘긴다set -x가 켜져 있으면 비밀번호가 든 명령도 찍힌다grep -rl로 다시 검색한다..bak사본과 로그에 남아 있다- 바꿀 때 확인할 목록을 만든다. 웹만 보면 배치 실패를 다음 날 안다