네트워크·보안
시놀로지 MariaDB를 127.0.0.1에만 묶기 전에 확인한 세 가지
인터넷에 열려 있던 MariaDB를 bind-address=127.0.0.1로 막기 전에 TCP 클라이언트, 웹사이트의 소켓 접속, Docker 컨테이너의 DB 사용 여부를 확인한 순서와 적용·되돌리기 방법입니다.
NAS 포트를 바깥에서 하나씩 두드려 보다가, MariaDB가 인터넷에 그대로 열려 있는 걸 발견했습니다. 공유기에 예전에 만들어 둔 포트 포워딩이 남아 있었고, DB는 모든 주소에서 접속을 받고 있었습니다. 비밀번호가 있다고는 해도 DB 포트가 밖에 열려 있을 이유는 없습니다.
해결 자체는 설정 한 줄, bind-address=127.0.0.1입니다. 그런데 이걸 넣는 순간 NAS 밖에서 TCP로 붙던 프로그램은 전부 끊깁니다. 그래서 넣기 전에 누가 TCP로 붙고 있는지부터 확인했습니다.
확인 1. 지금 TCP로 붙어 있는 클라이언트
MariaDB에 붙는 방법은 두 가지입니다. 같은 기기 안에서 유닉스 소켓 파일로 붙거나, 네트워크 TCP 포트로 붙거나. bind-address는 TCP에만 영향을 줍니다.
DB 안에서 보면 접속마다 어디서 왔는지 나옵니다. 소켓으로 붙은 건 localhost, TCP로 붙은 건 주소:포트 형태로 찍힙니다.
SELECT user, host, db, command, time
FROM information_schema.PROCESSLIST
WHERE host <> 'localhost' AND host <> '';
운영체제 쪽에서는 DB 포트에 연결된 TCP 세션을 봅니다. 표준 포트가 3306이라면 이렇게 합니다.
netstat -tn | grep ':3306 ' | grep ESTABLISHED
두 쪽 다 비어 있었습니다. 외부 클라이언트는 0건이었습니다. 한 번 보고 끝내지 말고 몇 시간 간격으로 다시 보는 게 좋습니다. 하루 한 번 도는 백업 프로그램 같은 건 한 번 볼 때 안 잡힐 수 있습니다.
확인 2. 웹사이트는 소켓으로 붙고 있는지
NAS의 워드프레스와 PHP 사이트들이 DB에 어떻게 붙는지 봤습니다. 시놀로지의 MariaDB 10 패키지는 소켓 파일을 만들어 둡니다.
$ ls -la /run/mysqld/
lrwxrwxrwx mysqld.sock -> /run/mysqld/mysqld10.sock
srwxrwxrwx mysqld10.sock
워드프레스의 wp-config.php에서 DB_HOST가 localhost:/run/mysqld/mysqld10.sock처럼 소켓 경로를 쓰고 있으면 TCP를 안 탑니다. PHP의 mysqli는 호스트가 localhost면 기본적으로 소켓을 씁니다. 반대로 127.0.0.1이나 NAS의 IP를 적어 뒀다면 TCP입니다. 이 경우 127.0.0.1은 바인드 후에도 붙지만 NAS IP는 끊깁니다.
grep -rn "DB_HOST" /volume*/web/*/wp-config.php /volume*/web/*/*/wp-config.php
제 사이트들은 전부 소켓이었습니다.
확인 3. Docker 컨테이너
여기가 제일 놓치기 쉽습니다. Docker 컨테이너 안에서 보면 NAS는 "바깥"입니다. 컨테이너가 DB를 쓴다면 NAS의 IP나 Docker 브리지 게이트웨이 주소로 TCP 접속을 합니다. 127.0.0.1에만 묶으면 이게 전부 끊깁니다.
컨테이너마다 환경 변수에 DB 관련 설정이 있는지 훑었습니다.
for c in $(docker ps --format '{{.Names}}'); do
printf '%s: ' "$c"
docker inspect -f '{{range .Config.Env}}{{println .}}{{end}}' "$c" \
| grep -i -c -E 'DB_|MYSQL|MARIADB|DATABASE'
done
돌고 있는 컨테이너 5개 모두 0이었습니다. 워크플로 자동화 도구는 자체 SQLite를 쓰고, 모니터링 도구도 자기 파일 DB를 씁니다. 환경 변수 말고 설정 파일로 DB 주소를 받는 컨테이너도 있으니, 모르는 컨테이너가 있으면 설정 파일도 같이 봐야 합니다.
적용과 확인
설정은 사용자 설정 파일인 /var/packages/MariaDB10/etc/my.cnf의 [mysqld] 아래에 넣었습니다. 이 폴더에는 시놀로지가 관리하는 synology.cnf도 있는데, 같은 키가 양쪽에 있으면 그쪽이 이깁니다(버퍼 풀 설정에서 겪은 일). bind-address는 synology.cnf에 없어서 my.cnf에 넣은 값이 그대로 먹었습니다.
[mysqld]
bind-address=127.0.0.1
# root 권한. 원본 백업 후 패키지 재시작
cp -p /var/packages/MariaDB10/etc/my.cnf ~/mariadb_my.cnf.bak
synopkg restart MariaDB10
재시작 뒤 어디서 듣고 있는지 확인합니다. 0.0.0.0이나 :::가 아니라 127.0.0.1만 나와야 합니다.
$ netstat -tln | grep 3306
tcp 0 0 127.0.0.1:3306 0.0.0.0:* LISTEN
사이트들이 전부 정상 응답하는 것까지 확인했습니다. 그리고 바깥에서 같은 포트로 다시 접속해 보니 닫혀 있었습니다. 공유기의 포워딩 규칙도 지워야 깔끔하지만, NAS 쪽에서 막아 두면 공유기 설정이 남아 있어도 들어올 수 없습니다.
되돌리는 방법은 넣은 줄을 지우고 다시 synopkg restart MariaDB10을 하면 됩니다. 컨테이너에서 DB를 써야 하는 상황이 생기면, 전체를 다시 여는 것보다 컨테이너에 소켓 파일을 볼륨으로 마운트해 주는 쪽이 안전합니다.
확인한 공식 자료
구현 과정에서 판단 기준을 교차 확인한 공식 문서입니다. 글의 사례와 결론은 운영자가 직접 겪은 작업을 바탕으로 작성했습니다.