도커 PostgreSQL 랜섬웨어 경보... 포트 5432 그냥 열었다가 DB 날아간 개발자들 통곡 실황 🚨
개발용 토이 프로젝트나 클라우드 서버 구축하면서 docker run -p 5432:5432 쓰시나요? 지금 도커 PostgreSQL 랜섬웨어 공격이 기승을 부리면서 5432 포트 바깥에 열어둔 개발자들 데이터베이스가 무차별로 털리고 있습니다.
아침에 출근해서 DBeaver나 pgAdmin 열었는데 테이블 다 날아가고 README_RECOVER_YOUR_DATA 테이블 하나만 덩그라니 남아서 "0.1 비트코인 보내라"는 메시지 떠 있는 거 보고 오열하는 개발자들 썰이 커뮤니티마다 터져 나오고 있습니다.
"아니 분명 어제까지 쿼리 잘 짰는데 오늘 접속하니까 DB 통째로 드롭되고 비트코인 주소 적혀있음... 실화냐 이거???"
컨테이너 권한 보안 자체를 강화하려면 도커 컨테이너 루트리스 모드 설정 가이드를 적용해두는 것도 좋은 방어책이 되지만, 일단 당장 급한 건 외부로 뻥 뚫려있는 5432 포트 문단속입니다.
도커 PostgreSQL 랜섬웨어 포트 5432 바인딩 취약점 공격 실황
공격자들은 무차별 스캐닝 봇을 돌려 공인 IP의 5432 포트 오픈 여부를 탐지한 후 데이터베이스를 삭제하고 덤프를 탈취합니다.
도커에서 옵션 생각 없이 -p 5432:5432를 주면 도커가 iptables를 알아서 건드려서 호스트 시스템의 방화벽(ufw)까지 바이패스해 버립니다. 즉, 서버 방화벽 켜놨다고 안심하고 있다가 뒷문으로 침입당하는 꼴이죠.
스캐너 봇이 5432 포트를 발견하면 기본 계정인 postgres에 무차별 대입 공격(Brute-force)을 넣거나 약한 패스워드를 뚫고 들어와서 내부 테이블을 모조리 DROP 시켜버립니다. 그러고는 0.05~0.2 비트코인을 송금하면 복구해 주겠다고 지갑 주소를 덜컥 남겨놓고 갑니다.
"비트코인 입금하면 복구해 주냐고요? 99% 돈만 먹고 튀거나 백업본 파일조차 안 만들어두고 일단 삭제부터 지지니까 절대 돈 보내지 마세요 ㅋㅋㅋ"
평소 쿼리 튜닝이나 락 이슈에 관심 많아서 PostgreSQL 데드락 원인 분석 및 해결 가이드 공부하던 개발자들도 이런 어처구니없는 기본 포트 노출 한 번에 서비스 전체가 멈추는 대참사를 맞이하고 있습니다.
docker-compose localhost 제한 5432 포트 외부 노출 즉시 차단법
docker-compose.yml 파일의 ports 바인딩에 127.0.0.1: 지정을 추가하면 외부 공인 IP를 통한 접근을 1초 만에 차단할 수 있습니다.
가장 흔하게 하는 실수가 아래처럼 작성하는 겁니다.
# ❌ 이렇게 쓰면 전 세계 해커들에게 어서오세요 하는 꼴
ports:
- "5432:5432"
이걸 당장 아래처럼 고쳐서 컨테이너를 재시작해야 합니다.
# ✅ 127.0.0.1을 붙여서 서버 내부(루프백) 접속만 허용
ports:
- "127.0.0.1:5432:5432"
이렇게 고쳐두면 같은 서버 내부에서 동작하는 Spring Boot나 Node.js 백엔드 앱, 혹은 SSH 터널링을 통한 로컬 DB 툴 접속만 허용되고 외부에선 포트 자체가 닫힌 것으로 보여서 안전해집니다.
PostgreSQL 보안 설정 pg_hba.conf 및 계정 권한 최소화 꿀팁
pg_hba.conf 파일에서 허용할 IP 대역을 엄격하게 제한하고 슈퍼유저 postgres 계정을 서비스용으로 쓰지 않아야 합니다.
기본 계정인 postgres 슈퍼유저 비밀번호를 root나 1234, 혹은 postgres로 해놓고 운영 서버 올리는 분들이 의외로 엄청 많습니다. 봇들이 들어와서 0.1초 만에 뚫고 들어가는 일등 공신이죠.
- 비밀번호는 대소문자+특수문자 조합으로 최소 16자리 이상 강력하게 설정
- 서비스 애플리케이션용으로는 필요한 DB만 접근할 수 있는 전용 계정 생성
- 외부 정기 백업(cron + pg_dump)을 서버와 물리적으로 분리된 오프라인/S3에 저장
데이터 백업 없는 랜섬웨어 피해는 그냥 서비스 사망선고나 다름없으니 오늘 당장 cron으로 덤프 파일 굴러가고 있는지 체크해 보셔야 합니다.
자주 묻는 질문 (FAQ)
Q. Docker 포트 바인딩 시 127.0.0.1을 지정해도 다른 컨테이너에서 DB 접속이 가능한가요?
동일한 Docker 네트워크(bridge)에 묶여 있다면 ports 옵션 없이도 컨테이너 이름(예: db:5432)으로 내부 통신이 정상적으로 작동합니다.
Q. ufw 방화벽으로 5432 포트를 막아뒀는데 왜 도커로 띄운 DB가 외부에서 접속되나요?
Docker는 내부적으로 iptables 규칙을 직접 수정하여 ufw 방화벽 설정보다 먼저 포트를 포워딩하기 때문에 방화벽을 우회하게 됩니다.
Q. 이미 랜섬웨어 공격으로 테이블이 싹 날아갔는데 복구할 수 있는 방법이 없나요?
공격자가 실제 데이터 덤프를 남겨두지 않고 테이블을 삭제하는 경우가 많으므로 오프라인으로 보관된 별도의 pg_dump 백업본이 없다면 복구할 수 없습니다.
서버 포트 하나 안일하게 열어뒀다가 밤샘 작업한 데이터 한순간에 날려먹고 피눈물 흘리지 마시고 지금 당장 docker-compose 파일 열어서 체크해 보세요!
혹시 도커 PostgreSQL 랜섬웨어 때문에 심장 덜컥 내려앉았거나 가까스로 털리기 직전에 방어한 썰 있으신가요? 여러분의 보안 대책이나 경험담을 댓글로 공유해 주세요! 🚨