最近 MongoDB “赎金事件”闹得沸沸扬扬,不少公网上裸奔的 MongoDB 中招,有兴趣的同学可以看下耗子叔写的从 MONGODB “赎金事件” 看安全问题,中招的主要原因还是因为用户的安全意识比较薄弱,部署的 MongoDB 完全没有任何安全防护,可以通过公网访问,并且没有开启鉴权
。
MongoDB 官方文档在安全方面做了很多总结,出了一个MongoDB Security Checklist,但从这次中招的规模来看,大部分用户并没有认真看过这个文档,这次事件也刚好是一个数据库安全科普的好机会,希望所有的数据库用户都要重视自己的数据安全。
MongoDB 安全 Checklist,用户可以做的安全措施包括
- 开启鉴权 Enable Auth,并给所有需要访问MongoDB数据库的用户配置合适的权限(权限最小化原则)
- 限制网络访问,只允许从安全的网络环境访问MongoDB,可以使用系统防火墙,或 MongoDB 自身的配置项bindIp来限制访问来源
- 开启访问审计,记录所有的用户访问行为,万一出问题时有据可查
- 限制MongoDB进程的权限,尽量创建单独的用户来管理MongoDB进程,不要用root帐号启动
- 访问链路加密、存储的数据加密,不过绝大部分场景还不需要这么高的安全级别,实在需要也可以配置上,会对性能有一定影响
- ...
--
为了方便用户快速进行合理的配置,给大家分享一个阿里云数据库MongoDB版的配置模板(为了简化,稍有改动)。
数据组织,一个mongod进程对应一个工作目录,包含data、etc、logs 3个目录,分别存储数据、配置、以及运行日志
|-- $mymongo
|-- data
-- ***
|-- etc
-- keyfile
-- mongod.conf
|-- logs
-- mongod.pid
-- mongod.log
mongod.conf内容 (将$mymongo替换成你的工作目录)
systemLog:
destination: file
logAppend: true
logRotate: rename
path: $mymongo/logs/mongod.log
timeStampFormat: iso8601-local
traceAllExceptions: false
verbosity: 0
processManagement:
fork: true
pidFilePath: $mymongo/logs/mongod.pid
net:
#bindIp: 127.0.0.1
port: 3001
http:
enabled: false
maxIncomingConnections: 1000
unixDomainSocket:
enabled: false
operationProfiling:
mode: slowOp
slowOpThresholdMs: 100
security:
authorization: enabled
keyFile: $mymongo/etc/keyfile
javascriptEnabled: false
replication:
oplogSizeMB: 5120
replSetName: myreplset
storage:
dbPath: $mymongo/data
directoryPerDB: true
syncPeriodSecs: 60
engine: wiredTiger
journal:
enabled: true
commitIntervalMs: 100
wiredTiger:
engineConfig:
cacheSizeGB: 4
基于上述模板,用户可以根据自己的实际情况稍加修改,主要关注如下参数
参数 | 含义 | 说明 |
---|---|---|
systemLog.verbosity | 日志级别 | 建议设置为0,如想记录更多debug信息,可修改该值为1-5,越大日志越详细 |
net.bindIp | 监听的ip地址列表 | 默认监听所有的ip,如果有多块网卡,可以选择性的绑定,以限制不可信的网络访问 |
net.port | 监听断开 | 默认27017,根据需要定制 |
net.maxIncomingConnections | 最大连接数 | 根据需要配置,保证系统最大文件句柄数大于该值(ulimit -n) |
operationProfiling.slowOpThresholdMs | 慢请求阈值 | 如无特殊需求,建议使用默认的100ms,超过该值的请求会记录到对应db的system.profile集合里 |
replication.replSetName | 复制集名字 | 强烈建议部署复制集提供服务,名字随便定制 |
replication.oplogSizeMB | oplog大小 | 默认为磁盘空间5%,无特殊需求建议保持默认值 |
security.authorization | 是否开启鉴权 | 强烈建议开启 |
security.keyFile | 复制集内部鉴权的keyfile路径 | 复制集要开启鉴权,必须配置keyfile,用于复制集成员间的鉴权 |
security.javascriptEnabled | 是否支持server端js,比如$where、mapreduce需要server端js的支持 | 如无必要,建议关闭 |
storage.directoryPerDB | 每个db一个单独的目录存储 | 强烈建议,以充分发挥文件系统优势 |
storage.engine | 存储引擎 | 强烈建议使用wiredtiger,低成本 + 高性能 |
storage.wiredTiger.engineConfig.engineConfig | wireditger cache大小 | 默认 max(1, 0.6 * RAM) |
storage.journal.enabled | 是否开启journal | 强烈建议开启 |
storage.journal.commitIntervalMs | journal 刷盘间隔 | 默认100ms,建议保持默认值 |
上述参数,对于不确定含义或拿不准的参数可以直接使用默认值 (配置项行首加 # 即可注释掉配置)。
使用上述模板启动 MongoDB 服务后,用户可以先通过localhost/127.0.0.1来连接 MongoDB,建立第一个管理用户,接下来就可以用管理用户登录做进一步的操作。
--
要想让MongoDB发挥最佳的效果,了解其各项配置含义来优化配置是非常有必要的,如果想完全免去数据库运维的烦恼,专注于业务开发,则可直接使用阿里云数据库MongoDB版,主要特性包括:
- 完全兼容MongoDB 3.2版本,开启鉴权、保证数据库安全
- 3节点复制集,保证数据高可靠、服务高可用,即将推出分片集群(MongoDB Sharded Cluster)
- 提供全量、增量备份功能,即使数据被误删,也能恢复到任意时间点
- 提供数据库操作审计功能,用户的所有操作都记录审计日志,有据可查
- 支持VPC环境,支持用户白名单功能
- ...