이 글에서는 Ubuntu 16.04 환경에서 MongoDB를 안전하게 보호하는 방법을 단계별로 살펴봅니다. 과거 버전의 MongoDB는 기본적으로 인증 기능이 비활성화되어 있어 자동화된 공격(exploit)에 매우 취약했습니다. 누구나 데이터베이스에 접속해 내용을 생성·조회·수정·삭제할 수 있었던 원인은 MongoDB 데몬이 기본 설정상 모든 네트워크 인터페이스에서 연결을 수신하도록 되어 있기 때문입니다.
인증 활성화 및 관리자 사용자 추가
다행히 MongoDB 3.x 버전부터는 이러한 문제가 상당 부분 개선되었습니다. 하지만 여전히 기본 설정에서는 인증이 비활성화되어 있어 누구나 데이터베이스에 전체 권한으로 접근할 수 있습니다. 따라서 이번 가이드에서는 관리자(Admin) 사용자를 생성하고, 인증 기능을 활성화한 뒤, 실제로 인증이 정상 작동하는지까지 테스트해 보겠습니다.
관리자 사용자 추가하기
관리자 사용자를 추가하려면 먼저 Mongo 셸(mongo shell)에 접속합니다.
$ mongo
MongoDB 셸에 접속하면 데이터베이스에 접근 제어가 설정되어 있지 않으며, 데이터 읽기·쓰기 및 구성 접근이 무제한으로 허용된다는 경고 메시지가 여러 개 표시됩니다.
Output: MongoDB shell version v3.4.4 connecting to: mongodb://127.0.0.1:27017 MongoDB server version: 3.4.4 Welcome to the MongoDB shell. For interactive help, type "help". For more comprehensive documentation, see https://docs.mongodb.org/ Questions? Try the support group https://groups.google.com/group/mongodb-user Server has startup warnings: 2017-05-16T12:33:46.819+0530 I STORAGE [initandlisten] 2017-05-16T12:33:46.819+0530 I STORAGE [initandlisten] ** WARNING: Using the XFS filesystem is strongly recommended with the WiredTiger storage engine 2017-05-16T12:33:46.819+0530 I STORAGE [initandlisten] ** See https://dochub.mongodb.org/core/prodnotes-filesystem 2017-05-16T12:33:46.850+0530 I CONTROL [initandlisten] 2017-05-16T12:33:46.850+0530 I CONTROL [initandlisten] ** WARNING: Access control is not enabled for the database. 2017-05-16T12:33:46.850+0530 I CONTROL [initandlisten] ** Read and write access to data and configuration is unrestricted. 2017-05-16T12:33:46.850+0530 I CONTROL [initandlisten] 2017-05-16T12:33:46.850+0530 I CONTROL [initandlisten] ** WARNING: /sys/kernel/mm/transparent_hugepage/enabled is 'always'. 2017-05-16T12:33:46.850+0530 I CONTROL [initandlisten] ** We suggest setting it to 'never' 2017-05-16T12:33:46.850+0530 I CONTROL [initandlisten] 2017-05-16T12:33:46.850+0530 I CONTROL [initandlisten] ** WARNING: /sys/kernel/mm/transparent_hugepage/defrag is 'always'. 2017-05-16T12:33:46.850+0530 I CONTROL [initandlisten] ** We suggest setting it to 'never' 2017-05-16T12:33:46.850+0530 I CONTROL [initandlisten] >
관리자 계정의 사용자 이름은 자유롭게 지정할 수 있습니다. 권한 수준은 userAdminAnyDatabase 역할(role)에서 부여되며, 해당 계정의 자격 증명은 admin 데이터베이스에 저장됩니다.
원하는 사용자 이름을 정했다면, 아래 명령어로 admin 데이터베이스로 전환한 후 강력한 비밀번호를 설정하여 관리자 사용자를 생성합니다.
> use admin switched to db admin
데이터베이스 전환이 완료되면 다음과 같이 관리자 사용자를 생성합니다.
> db.createUser(
... {
... user: "DBAdmin",
... pwd: "DBAdmin'sSecurePassword",
... roles: [ { role: "userAdminAnyDatabase", db: "admin" } ]
... }
... )
Output:
Successfully added user: {
"user" : "DBAdmin",
"roles" : [
{
"role" : "userAdminAnyDatabase",
"db" : "admin"
}
]
}
>
이제 강력한 비밀번호를 가진 관리자 사용자 DBAdmin이 생성되었습니다. 다만 이 계정은 MongoDB 설정에서 인증을 활성화하기 전까지는 실제로 적용되지 않습니다.
MongoDB 인증 활성화하기
/etc 디렉터리에 위치한 mongod.conf 설정 파일에서 인증을 활성화한 뒤 MongoDB 데몬을 재시작해야 합니다.
먼저 편집기로 mongod.conf 파일을 열고 security 섹션을 수정합니다.
$ sudo vi /etc/mongod.conf
설정 파일은 대체로 아래와 같은 구조로 되어 있습니다.
# mongod.conf
# for documentation of all options, see:
# https://docs.mongodb.org/manual/reference/configuration-options/
# Where and how to store data.
storage:
dbPath: /var/lib/mongodb
journal:
enabled: true
# engine:
# mmapv1:
# wiredTiger:
# where to write logging data.
systemLog:
destination: file
logAppend: true
path: /var/log/mongodb/mongod.log
# network interfaces
net:
port: 27017
bindIp: 127.0.0.1
#processManagement:
#security:
#operationProfiling:
#replication:
#sharding:
## Enterprise-Only Options:
security 항목 앞의 주석(#)을 제거해 섹션을 활성화하고, 그 아래에 authorization 설정을 추가합니다. 수정 후 해당 부분은 다음과 같아야 합니다.
#processManagement: security: authorization: "enabled" #operationProfiling: #replication: #sharding:
주의할 점은 security 줄에는 들여쓰기를 하지 않고, authorization 줄은 반드시 두 칸의 공백으로 들여써야 한다는 것입니다. YAML 형식에서는 들여쓰기 오류가 서비스 시작 실패의 주요 원인이 되므로 각별히 신경 써야 합니다. 설정 파일 수정이 끝나면 mongod 데몬을 재시작합니다.
아래 명령어로 MongoDB 서비스를 재시작합니다.
$ sudo systemctl restart mongod
서비스 재시작 후에는 다음 명령어로 MongoDB 서비스 상태를 확인할 수 있습니다.
$ sudo systemctl status mongod Output: mongod.service - High-performance, schema-free document-oriented database Loaded: loaded (/lib/systemd/system/mongod.service; disabled; vendor preset: enabled) Active: active (running) since Tue 2017-05-16 12:52:09 IST; 48s ago Docs: https://docs.mongodb.org/manual Main PID: 3281 (mongod) Tasks: 20 Memory: 33.3M CPU: 734ms CGroup: /system.slice/mongod.service └─3281 /usr/bin/mongod --quiet --config /etc/mongod.conf May 16 12:52:09 ubuntu-16 systemd[1]: Started High-performance, schema-free document-oriented database.
MongoDB 인증 확인하기
먼저 자격 증명 없이 MongoDB에 접속해 보겠습니다.
$ mongo Output: MongoDB shell version v3.4.4 connecting to: mongodb://127.0.0.1:27017 MongoDB server version: 3.4.4 >
이전에 표시되던 접근 제어 관련 경고 메시지들이 모두 사라진 것을 확인할 수 있습니다. 이제 show dbs 명령으로 데이터베이스 목록 조회를 시도하여 인증이 제대로 적용되었는지 테스트해 보겠습니다.
> show dbs
2017-05-16T12:56:17.306+0530 E QUERY [thread1] Error: listDatabases failed:{
"ok" : 0,
"errmsg" : "not authorized on admin to execute command { listDatabases: 1.0 }",
"code" : 13,
"codeName" : "Unauthorized"
} :
_getErrorWithCode@src/mongo/shell/utils.js:25:13
Mongo.prototype.getDBs@src/mongo/shell/mongo.js:62:1
shellHelper.show@src/mongo/shell/utils.js:769:19
shellHelper@src/mongo/shell/utils.js:659:15
@(shellhelp2):1:1
위와 같이 Unauthorized 오류가 반환되며, 인증 없이는 데이터베이스를 생성하거나 조회할 수 없습니다. 이제 셸을 종료한 후, 관리자 계정으로 인증하여 다시 접속해 보겠습니다.
관리자 사용자 접근 권한 확인하기
관리자 사용자(DBAdmin)의 인증 정보를 사용해 admin 데이터베이스에 접속합니다. 사용자 인증으로 데이터베이스에 접속하는 명령어는 다음과 같습니다.
$ mongo -u DBAdmin -p --authenticationDatabase admin MongoDB shell version v3.4.4 Enter password: connecting to: mongodb://127.0.0.1:27017 MongoDB server version: 3.4.4 > show dbs admin 0.000GB local 0.000GB >
비밀번호 입력 후 정상적으로 접속되고, 데이터베이스 목록도 문제없이 조회되는 것을 확인할 수 있습니다.
이 글에서는 관리자 사용자를 추가하고 인증 기능을 활성화하여 MongoDB를 보호하는 방법을 알아보았습니다. 기본 설정에서는 MongoDB의 사용자 인증이 비활성화되어 있어 누구나 데이터베이스를 생성·삭제·수정할 수 있으므로, 운영 환경에서는 반드시 인증을 활성화하는 것이 좋습니다.