sudo 권한, 유지 중인 SSH 세션과 별도 콘솔 복구 경로
DATABASE · 설치·설정 레시피
MongoDB 설치·인증·제한된 외부 접속
MongoDB 8.0 Community Edition을 공식 저장소에서 설치하고, 로컬에서 관리자와 애플리케이션 사용자를 만든 뒤 SCRAM 인증·CA 서명 TLS·사설 IP 바인딩·클라이언트 CIDR 방화벽을 순서대로 적용합니다.BEFORE YOU START
시작 전에 준비하세요
MongoDB 서버의 고정 사설 IP·내부 DNS 이름·허용할 애플리케이션 CIDR
내부 CA 또는 공인 CA가 발급한 서버 인증서·개인 키·CA 체인과 SAN 일치 확인
기존 데이터가 있다면 mongodump 또는 일관성 있는 스냅샷의 복원 시험 결과
권장 대상 사설망 애플리케이션에서 사용할 자체 관리 MongoDB 단일 서버를 안전하게 준비하는 개발자·운영자
FOLLOW THE RECIPE
8단계 구성·점검 레시피
지원 운영체제와 MongoDB 계열 확인
공식 mongodb-org 패키지는 Ubuntu의 이름이 비슷한 mongodb 패키지와 다릅니다. 배포판·아키텍처·저장소 후보를 먼저 확인해 서로 다른 패키지 계열을 섞지 않습니다.
cat /etc/os-releasedpkg --print-architecturedpkg -l | grep -E 'mongodb|mongosh'apt-cache policy mongodb-org mongodb mongod- Ubuntu 24.04 또는 22.04 LTS의 지원 아키텍처다.
- Ubuntu mongodb 패키지와 공식 mongodb-org 패키지가 혼재하지 않는다.
- 운영에 사용할 MongoDB 주 버전과 드라이버 호환성을 확인했다.
기존 패키지가 보이면 바로 교체하지 말고 소유 팀·데이터 경로·버전·백업을 확인합니다. 이 가이드는 신규 단일 서버 기준이며 복제 세트에는 별도 키 파일과 멤버별 절차가 필요합니다.
기존 서비스·포트·데이터·인증서 상태를 읽기 전용으로 조사합니다.
기존 데이터와 네트워크 변경 전 점검
27017 포트, mongod 서비스, 데이터 용량과 현재 바인딩을 기록합니다. 원격 공개 전에 복구 가능한 백업과 콘솔 경로가 있어야 합니다.
systemctl status mongod --no-pagersudo ss -ltnp | grep ':27017 'df -hT /var/lib/mongodb /var/log/mongodbsudo grep -nE '^[[:space:]]*(bindIp|port|authorization|mode|certificateKeyFile|CAFile|dbPath):' /etc/mongod.confopenssl x509 -in <MONGODB_SERVER_CERT> -noout -subject -issuer -dates -ext subjectAltName
openssl verify -CAfile <MONGODB_CA_CERT> <MONGODB_SERVER_CERT>- 기존 mongod가 있다면 소유 팀과 연결 중인 클라이언트를 확인했다.
- 백업 파일의 존재가 아니라 별도 환경의 복원 성공까지 확인했다.
- 인증서 SAN에 <MONGODB_PRIVATE_DNS>가 있고 CA 검증이 성공한다.
- 클라우드 보안 그룹 또는 상위 방화벽도 <APP_CLIENT_CIDR>로 제한할 계획이 있다.
활성 서비스나 데이터가 있으면 신규 설치가 아니라 변경 작업입니다. 백업·복원·중단 시간 합의 없이 계속하지 않습니다.
공식 키를 직접 확인한 뒤 MongoDB 저장소와 패키지를 설치합니다.
공식 서명 저장소에서 MongoDB 설치
공식 공개키를 파일로 내려받아 지문을 사람이 확인한 뒤 키링으로 변환합니다. 설치 후보와 변경 목록을 검토하고 무인 승인 없이 설치합니다.
sudo apt-get install gnupg curlcurl --proto '=https' --tlsv1.2 --fail --location --output /tmp/mongodb-server-8.0.asc https://pgp.mongodb.com/server-8.0.ascgpg --show-keys --fingerprint /tmp/mongodb-server-8.0.ascMongoDB 공식 설치 문서에 게시된 키 정보와 대조한 뒤 다음 단계로 이동합니다.sudo gpg --dearmor --output /usr/share/keyrings/mongodb-server-8.0.gpg /tmp/mongodb-server-8.0.ascsudoedit /etc/apt/sources.list.d/mongodb-org-8.0.listsudo apt-get updateapt-get --simulate install mongodb-orgsudo test ! -e /root/mongodb-change/<CHANGE_ID>
sudo install -d -o root -g root -m 0700 /root/mongodb-change/<CHANGE_ID>
LC_ALL=C apt-get --simulate install mongodb-org | sed -n 's/^Inst \([^ ]*\).*/\1/p' | sort -u | sudo tee /root/mongodb-change/<CHANGE_ID>/packages.planned >/dev/null
sudo bash -euo pipefail -c 'state=/root/mongodb-change/<CHANGE_ID>; test -s "$state/packages.planned"; : > "$state/packages.before"; while read -r pkg; do case "$pkg" in mongodb-org*|mongodb-mongosh*|mongodb-database-tools*) ;; *) exit 1;; esac; if dpkg-query -W -f="\${db:Status-Abbrev}" "$pkg" 2>/dev/null | grep -qx ii; then printf "%s=installed\n" "$pkg"; else printf "%s=absent\n" "$pkg"; fi; done < "$state/packages.planned" > "$state/packages.before"; chmod 0600 "$state"/*'APT simulation의 실제 Inst 목록만 허용된 MongoDB 패키지 이름으로 기록합니다. 기존 설치 패키지는 installed, 신규 후보는 absent로 남겨 롤백 시 기존 패키지를 제거하지 않게 합니다.sudo apt-get install mongodb-orgsudo bash -euo pipefail -c 'state=/root/mongodb-change/<CHANGE_ID>; : > "$state/packages.new"; while read -r pkg; do dpkg-query -W -f="\${db:Status-Abbrev}" "$pkg" | grep -qx ii; if grep -Fqx "$pkg=absent" "$state/packages.before"; then printf "%s\n" "$pkg" >> "$state/packages.new"; fi; done < "$state/packages.planned"; test -s "$state/packages.new"; sort -u -o "$state/packages.new" "$state/packages.new"; chmod 0600 "$state/packages.new"'설치 뒤 실제 ii 상태이며 사전 absent였던 패키지만 packages.new에 남깁니다. 이후 추가 설치된 비MongoDB 패키지나 기존 패키지는 자동 제거 대상이 아닙니다.deb [arch=amd64,arm64 signed-by=/usr/share/keyrings/mongodb-server-8.0.gpg] https://repo.mongodb.org/apt/ubuntu noble/mongodb-org/8.0 multiverseUbuntu 22.04라면 공식 문서의 jammy 항목을 사용합니다. 운영체제 코드명을 추측해 섞지 않습니다.- 키 지문을 공식 문서와 직접 대조했다.
- APT 후보가 repo.mongodb.org에서 제공되는 mongodb-org 8.0 계열이다.
- 설치 미리 보기에 의도하지 않은 패키지 제거가 없다.
키·저장소·운영체제 코드명 중 하나라도 일치하지 않으면 설치를 중단합니다. 저장소 오류를 TLS 검증 우회로 해결하지 않습니다.
외부 바인딩 전에 로컬에서 사용자와 TLS 설정을 준비합니다.
로컬 사용자 생성 후 인증·TLS·사설 IP 구성
mongod가 루프백에만 바인딩된 상태에서 첫 사용자 관리자와 애플리케이션 전용 사용자를 만듭니다. 그 뒤 설정과 인증서를 백업·배치하고 인증, TLS, 사설 IP를 한 번에 적용합니다.
sudo systemctl start mongodmongosh --host 127.0.0.1admin 데이터베이스에서 db.createUser({ user: '<MONGODB_USER_ADMIN>', pwd: passwordPrompt(), roles: [{ role: 'userAdminAnyDatabase', db: 'admin' }] })를 실행합니다. 비밀번호는 프롬프트에만 입력합니다.mongosh --host 127.0.0.1 --username <MONGODB_USER_ADMIN> --authenticationDatabase admin --passwordappdb 데이터베이스에서 db.createUser({ user: '<MONGODB_APP_USER>', pwd: passwordPrompt(), roles: [{ role: 'readWrite', db: 'appdb' }] })를 실행합니다. 실제 DB와 권한을 더 좁힐 수 있으면 좁힙니다.date -u +%Y%m%dT%H%M%SZsudo cp --preserve=all --no-clobber /etc/mongod.conf /etc/mongod.conf.<BACKUP_SUFFIX>.baksudo install -o root -g mongodb -m 0644 <MONGODB_CA_CERT> /etc/ssl/certs/mongodb-ca.crtsudo install -o mongodb -g mongodb -m 0600 <MONGODB_CERTIFICATE_KEY_PEM> /etc/ssl/private/mongodb-server.pem원본은 승인된 비밀 전달 경로에서 받고 PEM에 서버 인증서와 대응하는 개인 키가 포함되었는지 확인합니다.sudoedit /etc/mongod.confnet:
port: 27017
bindIp: 127.0.0.1,<MONGODB_PRIVATE_IP>
tls:
mode: requireTLS
certificateKeyFile: /etc/ssl/private/mongodb-server.pem
CAFile: /etc/ssl/certs/mongodb-ca.crt
security:
authorization: enabled파일 전체를 덮어쓰지 말고 기존 storage·systemLog·processManagement 항목과 병합합니다. <MONGODB_PRIVATE_IP>는 서버에 실제 할당된 사설 IP 한 개입니다.- 첫 사용자 관리자 비밀번호와 앱 비밀번호가 서로 다르고 비밀 저장소에만 보관된다.
- 애플리케이션 사용자에는 appdb의 readWrite만 부여했다.
- 인증서 키 파일은 mongodb 계정만 읽을 수 있다.
- bindIp에는 루프백과 실제 사설 IP만 있다.
첫 사용자를 만들기 전에 외부 주소에 바인딩하면 인증 없는 창이 생길 수 있습니다. 반드시 루프백에서 사용자 생성이 끝난 뒤 인증·TLS·바인딩을 함께 반영합니다.
현재 SSH 세션과 콘솔을 유지한 채 mongod를 재시작합니다.
mongod 재시작과 실패 로그 확인
설정 변경은 서비스 재시작이 필요합니다. 기존 원격 세션과 콘솔을 유지하고, 실패하면 반복 재시작하지 않고 첫 오류를 확인합니다.
sudo namei -l /etc/mongod.conf /etc/ssl/private/mongodb-server.pem /etc/ssl/certs/mongodb-ca.crtsudo systemctl restart mongodsudo systemctl enable mongodsystemctl status mongod --no-pager
sudo journalctl -u mongod -n 100 --no-pager- mongod가 active 상태다.
- 로그에 YAML 파싱·인증서·권한 오류가 없다.
- 서비스가 enabled 상태다.
시작 실패 시 인증서 이름, PEM 권한, YAML 들여쓰기부터 확인합니다. 데이터 파일을 이동하거나 초기화하지 않습니다.
로컬 TLS·인증을 먼저 검증한 뒤에만 CIDR 방화벽 규칙을 추가합니다.
로컬 인증과 제한된 원격 접속 검증
인증서 검증을 우회하지 않고 DNS 이름으로 연결합니다. 로컬 성공 후 허용 CIDR 규칙을 추가하고 승인된 클라이언트에서 실제 앱 사용자 권한을 확인합니다.
sudo ss -ltnp | grep ':27017 'mongosh --tls --tlsCAFile /etc/ssl/certs/mongodb-ca.crt --host <MONGODB_PRIVATE_DNS> --username <MONGODB_USER_ADMIN> --authenticationDatabase admin --eval 'db.runCommand({ connectionStatus: 1 })'사용자 이름이 지정되면 mongosh가 비밀번호를 대화형으로 묻습니다. 명령 인자나 셸 기록에 비밀번호를 넣지 않습니다.sudo ufw allow from <APP_CLIENT_CIDR> to <MONGODB_PRIVATE_IP> port 27017 proto tcp현재 SSH 세션과 콘솔을 유지하고 상위 보안 그룹도 같은 CIDR로 제한한 뒤 실행합니다.mongosh --tls --tlsCAFile <MONGODB_CA_CERT> --host <MONGODB_PRIVATE_DNS> --username <MONGODB_APP_USER> --authenticationDatabase appdb --eval 'db.runCommand({ connectionStatus: 1 })'허용 클라이언트에서 프롬프트에 비밀번호를 입력합니다. 연결 문자열이나 스크립트에 자격 증명을 저장하지 않습니다.sudo ufw status numbered
systemctl is-active mongod- 27017은 루프백과 지정한 사설 IP에서만 리슨한다.
- CA 검증과 호스트 이름 검증을 유지한 연결이 성공한다.
- 승인 CIDR 클라이언트는 연결되고 비승인 네트워크에서는 연결되지 않는다.
- 앱 사용자는 appdb 이외의 관리자 작업을 수행할 수 없다.
로컬 연결은 되지만 원격이 실패하면 bindIp, UFW, 상위 보안 그룹, 라우팅 순서로 확인합니다. 전체 네트워크 허용으로 우회하지 않습니다.
권한·백업·감사와 인증서 갱신 운영 항목을 마감합니다.
최소 권한·백업·인증서 운영 점검
DB 인증은 네트워크 경계를 대신하지 않습니다. 애플리케이션 계정과 운영 계정을 분리하고 백업도 전용 역할과 TLS를 사용합니다.
mongosh --tls --tlsCAFile /etc/ssl/certs/mongodb-ca.crt --host <MONGODB_PRIVATE_DNS> --username <MONGODB_USER_ADMIN> --authenticationDatabase admin --passwordadmin에서 db.getUsers({ showCredentials: false })와 appdb에서 db.getUsers({ showCredentials: false })를 실행해 역할만 검토합니다.openssl x509 -checkend 2592000 -noout -in <MONGODB_SERVER_CERT>30일 이내 만료면 종료 코드가 0이 아니므로 갱신 절차를 시작합니다.sudo journalctl -u mongod --since '24 hours ago' --no-pager | grep -Ei 'authentication|authorization|TLS|certificate'mongodump --version
mongorestore --version- MongoDB 포트는 승인된 사설 CIDR 외부에서 접근할 수 없다.
- 모든 원격 연결이 CA 검증 TLS와 SCRAM 인증을 사용한다.
- 애플리케이션·사용자관리·백업 역할과 자격 증명을 분리했다.
- 인증서 만료 알림과 자격 증명 교체 절차가 있다.
- 암호화된 백업을 별도 장애 도메인에서 보관하고 정기 복원 시험을 한다.
인증 실패 급증은 잘못된 배포뿐 아니라 공격 신호일 수 있습니다. 로그에 자격 증명이나 전체 연결 문자열을 남기지 않고 출발지와 계정 단위로 조사합니다.
실패 시 설정·방화벽을 안전하게 되돌릴 명시적 복구 절차를 기록합니다.
설정 복원과 CIDR 규칙 롤백
현재 세션과 콘솔을 유지하고 이번 작업의 <BACKUP_SUFFIX>를 변경 기록에서 선택합니다. 먼저 외부 트래픽을 상위 ACL에서 차단하고 기존 설정을 복원한 뒤 서비스가 정상인지 확인합니다.
sudo find /etc -maxdepth 2 -type f -name 'mongod.conf.*.bak' -printf '%TY-%Tm-%Td %TH:%TM:%TS %p\n' | sortsudo test -f /etc/mongod.conf.<BACKUP_SUFFIX>.baksudo cp --preserve=all --no-clobber /etc/mongod.conf /etc/mongod.conf.failed.<ROLLBACK_SUFFIX>sudo cp --preserve=all /etc/mongod.conf.<BACKUP_SUFFIX>.bak /etc/mongod.confsudo systemctl restart mongod && systemctl status mongod --no-pagersudo ufw delete allow from <APP_CLIENT_CIDR> to <MONGODB_PRIVATE_IP> port 27017 proto tcp복원된 mongod의 로컬 상태를 확인하고 상위 ACL 차단이 유지된 상태에서 이번에 추가한 정확한 규칙만 제거합니다.sudo bash -euo pipefail -c 'state=/root/mongodb-change/<CHANGE_ID>; test -s "$state/packages.planned"; test -s "$state/packages.before"; test -s "$state/packages.new"; systemctl stop mongod; systemctl disable mongod; mapfile -t packages < "$state/packages.new"; test "${#packages[@]}" -gt 0; for pkg in "${packages[@]}"; do case "$pkg" in mongodb-org*|mongodb-mongosh*|mongodb-database-tools*) ;; *) exit 1;; esac; grep -Fqx "$pkg=absent" "$state/packages.before"; dpkg-query -W -f="\${db:Status-Abbrev}" "$pkg" | grep -qx ii; done; apt-get remove -- "${packages[@]}"'신규 설치를 완전히 철회할 때만 사용합니다. 사전 absent였고 설치 직후 실제 신규로 확정한 서버·mongos·mongosh·tools 등 패키지를 모두 명시적으로 제거하며 기존 installed 패키지는 유지합니다. purge·autoremove를 사용하지 않고 데이터 디렉터리와 인증서·백업은 자동 삭제하지 않습니다.- 상위 ACL·보안 그룹에서 신규 외부 경로를 먼저 닫았다.
- 복원할 백업 접미사를 기록과 내용으로 명시적으로 선택했다.
- 현재 실패 설정도 고유한 접미사로 보존했다.
- 복원 후 로컬 접속과 로그를 확인한 다음 이번 UFW 규칙만 제거했다.
- 데이터 삭제나 빈 DB 초기화를 롤백 수단으로 사용하지 않았다.
설정 복원 후에도 시작하지 않으면 데이터 조작을 멈추고 첫 로그 오류와 파일 권한을 확인합니다. 데이터 손상 가능성이 있으면 검증된 백업 복구 절차로 전환합니다.
서비스 실패·포트·디스크·TLS 장애 대응 가이드로 이어갑니다.
SECURITY CHECK
운영 전 마지막 보안 점검
- 27017을 공인 인터넷에 직접 공개하지 않고 사설 IP와 승인 CIDR만 사용한다.
- SCRAM 인증을 켜고 관리자와 애플리케이션 계정의 역할·비밀번호를 분리한다.
- 원격 연결은 requireTLS와 신뢰 가능한 CA·정확한 SAN 검증을 사용한다.
- 비밀번호를 명령 인자·연결 문자열·Git·로그에 남기지 않는다.
- 백업 암호화, 별도 보관, 복원 시험, 인증서 만료 알림을 운영한다.
COMMON ERRORS
자주 막히는 지점
TLS 적용 후 mongod 시작 실패
- 증상
- mongod가 failed 상태이고 로그에 PEM 또는 key permission 오류가 표시됩니다.
- 가능한 원인
- 인증서와 키가 한 PEM에 없거나, 키가 대응하지 않거나, mongodb 계정이 파일을 읽지 못하는 경우가 많습니다.
- 확인 순서
- openssl로 체인·SAN·키 대응을 확인하고 namei로 전체 경로 권한을 점검한 뒤 백업 설정과 비교합니다.
원격 연결 시간 초과
- 증상
- 로컬 TLS 연결은 성공하지만 애플리케이션 서버에서 27017 연결이 시간 초과됩니다.
- 가능한 원인
- bindIp, 호스트 방화벽, 상위 보안 그룹 또는 사설망 라우팅이 일치하지 않습니다.
- 확인 순서
- 리스닝 주소부터 UFW·상위 ACL·라우팅 순서로 확인하고 허용 범위를 넓혀 우회하지 않습니다.
Authentication failed
- 증상
- 네트워크와 TLS는 연결되지만 MongoServerError Authentication failed가 발생합니다.
- 가능한 원인
- authenticationDatabase, 사용자 이름, 비밀번호 또는 SCRAM 호환 설정이 다를 수 있습니다.
- 확인 순서
- 비밀번호를 로그에 출력하지 말고 사용자 생성 DB와 역할을 관리자 세션에서 확인합니다.
PRIMARY REFERENCES
공식 문서
- MongoDB 8.0 Community Edition Ubuntu 설치
- MongoDB SCRAM 인증 구성
- MongoDB 자체 관리 배포 네트워크 보안 강화
- MongoDB TLS 암호화 구성
- MongoDB Database Tools 백업과 복원
설치 저장소와 지원 버전은 바뀔 수 있습니다. 검토일 이후에는 링크된 공식 문서와 현재 서버의 패키지 후보 버전을 함께 확인하세요.