5 安全性
本章介绍几本的安全和风险管理策略和访问控制
5.2.1.3 system.users Collection
5.2.5.1 Mongo Shell中的安全性和Javascript
5.1 安全性说明
5.1.1 深入防御(Defense in Depth)
用减少风险点的,在一个可信的环境限制访问,最小化权限。
5.1.2 可信任环境
可信任环境一般使用以下策略来控制访问:
1.使用防火墙来过滤访问
2.mongod,mongos指定只能由某些ip访问
3.限制mongod在非公开网络中
5.1.3 减少风险的可选实践
用mongodb的认证授权来减少风险。最佳应用程序部署和应用程序实践是,验证所有数据,管理会话,应用程序级别的访问控制。最小化一个用户的权限,更多的限制,可以让mongod和mongos运行在chroot环境。
5.1.4数据加密
MongoDB有partnership和Gazzang加密敏感数据,为了保证实时的加密数据,Gazzang提供了密钥管理方法,保证只有验证的进程才能访问数据。
5.1.5额外的安全性策略
MongoDB企业版还提供了,Kerberos认证方式
5.1.6 漏洞通知
如果发现了漏洞,那可通过漏洞报告来报告漏洞,看手册p265
5.2安全性概述
本节介绍:访问控制,内部过程的认证,shard集群安全性,网络曝光和安全性,安全性和Mongodb API接口。
5.2.1 访问控制
mongodb每个数据库提供了授权和认证
5.2.1.1 认证
Mongodb认证,授权用户,是在数据库级别上,Mongodb把用户的凭据放在system.users collection中,认证默认是关闭的,可以通过auth,keyFile配置选项设置。对于Mongodb企业版可以使用kerberos来认证。
在一个数据库上,你只能认证一个用户,如果认证了第二个,第一个就会被放弃。
5.2.1.2 授权
Mongodb规定授权是以role为基础的。每个授权的用户都保存在system.users中,要给用户分配角色,必须要有一个管理角色的用户在数据库中,如果没有就必须创建一个。
5.2.1.3 system.users Collection
每个数据库的system.users collection中保存了授权和认证信息,用户要有userAdmin或者userAdminAnyDatabase权限才能访问这个collection。
5.2.2内部过程的认证
对于复制集和shard集群的管理员,不需要有带过的考虑,只要确保:
1.复制集中的成员可以互相通信
2.如果mongodb认证系统限制访问你的基础设备,确保在每个成员上配置keyFile,允许认证。
最有效的控制复制集网络安全的方法是使用网络级别的访问控制,即使用防火墙保证流量只来自于客户端或者复制集的其他成员。
5.2.2.1 在复制集和shard集群启用认证
启用认证可以使用选项keyFile=<path>,设置了keyFile启用了认证也为复制集指定了key文件,用户成员之间的认证。keyFile虽然是随意的,但是成员之间必须相同。keyFile生成可以看手册261。生成一个KEY文件
5.2.3 Shard集群安全性
shard的安全性和其他的mongodb实例的基本类似,shard集群使用相同的keyfile和访问控制。
5.2.3.1 shard集群的访问控制权限
Mongodb给每个shar集群和shard独立的管理权限
Shard集群认证:当连接到mongos,可以被同意访问集群的admin数据库,这些凭据也被存放在config服务中。
用户根据授权来访问集群,在登陆时认证,来获取用户在集群中的权限
Shard服务认证:mongo允许管理员直接连接指定的shard,创建用户或复制集
5.2.3.2使用认证访问shard集群
可以直接在shell用认证选项认证,也可以先连接然后用db.auth()认证。
5.2.3.3 localhost上的限制
Shard集群在使用localhost的时候有限制,如果host指明本地,要不是localhost或者127.0.0.1如果应用到addShard中,localhost和远程host混用,可能会导致集群不正常。
5.2.4网络曝光和安全性
Mongodb可以限制让那些地址访问,本节也介绍一些选项来限制mongodb的访问。
5.2.4.1配置选项
Mongodb可以使用nohttpinterface,rest,bind_ip和port,来限制曝光,也可以在配置文件指定。
Nohttpinterface:这个选项表示不能再用http通过端口28017访问mongod或者mongos状态。
Rest:REST设置启动管理的rest接口,默认是禁用的,但是状态接口默认启用,这个设置可以让rest交互,rest接口并不支持认证,只支持可信任网络。
Bind_ip:bind_ip设置mongod和mongos限制mongodb的income的监听网络。
Port:mongod和mongos的监听端口,默认为27017,http状态接口默认为28017比port大1000
5.2.4.1防火墙
防火墙允许管理员过滤一些访问和做一些访问控制。
5.2.4.2虚拟私有网络(VPN)
VPN可以在2个网络之间做个加密和访问限制的可信任网络。
5.2.5Mongodb API 接口和安全性
本节介绍mongodb可用的接口如javascript,http,rest接口的风险管理。
5.2.5.1 Mongo Shell中的安全性和Javascript
Javascript表达式和Javascript文件
Mongo可以通过—eval,直接执行javascript,然后mongo javascript.js直接运行js文件。
如果存在.mongorc.js文件,shell启动时要先执行这个文件,除非指定了选项—norc。
5.2.5.2HTTP状态接口
Mongodb提供了基于http的状态接口,默认端口28017,当不启动rest设置,接口是只读的并且限制了范围,可以通过nohttpinterface选项禁用,http状态接口。
5.2.5.3REST API
REST API不提供insert,update,remove文档,但是支持管理上的访问。但是它的可访问对于一个安全的环境而言是一个漏洞。要控制要rest,因为不支持认证,即使启用了auth选项。
5.3 安全性教程
5.3.1 网络安全教程
主要介绍linux iptables设置,windows netsh设置,使用SSL连接Mongodb
5.3.1.1使用iptables防火墙设置
概述
在iptables上的规则形成链,包必须通过链上的每一个节点,iptables有2个链:
INPUT:控制所有income流量
OUTPUT:控制所有outcome流量
默认iptables是允许所有的连接访问,除了指定的连接,但是一般设置防火墙是指定允许的连接,这个可以通过修改iptables行为:
iptables -P INPUT DROP
iptables -P OUTPUT DROP
方式
Mongod上的流量:
iptables -A INPUT -s <ip-address> -p tcp --destination-port 27017 -m state --state NEW,ESTABLISHED -j ACCEPT
iptables -A OUTPUT -d <ip-address> -p tcp --source-port 27017 -m state --state ESTABLISHED -j ACCEPT
Mongos上的流量:
Mongos为shard集群提供路由,客户端可以透明的访问shard集群像访问mongod一样。可以使用控制mongod的流量来控制mongos。
Mongodb Config服务上的流量:
一旦被职位config,config服务侦听在27019上的连接,所以要再27019上开通防火墙
iptables -A INPUT -s <ip-address> -p tcp --destination-port 27019 -m state --state NEW,ESTABLISHED -j ACCEPT
iptables -A OUTPUT -d <ip-address> -p tcp --source-port 27019 -m state --state ESTABLISHED -j ACCEPT
Mongodb Shard服务上的流量:
实例启用了shardsvr,默认监听27018端口,所以必须开通:
iptables -A INPUT -s <ip-address> -p tcp --destination-port 27018 -m state --state NEW,ESTABLISHED -j ACCEPT
iptables -A OUTPUT -d <ip-address> -p tcp --source-port 27018 -m state --state ESTABLISHED -j ACCEPT
还要和其他shard沟通,shard内的复制集也要沟通,还要和所有的mongos实例沟通,和所有的config server沟通。
为监控系统提供访问
1.所有的组件都要设置选项—disvocer,包括config服务,shard服务,mongos实例
2.若要被http接口访问,还要启动28017端口的防火墙:
iptables -A INPUT -s <ip-address> -p tcp --destination-port 28017 -m state --state NEW,ESTABLISHED -j ACCEPT
对于mongod的http防火墙:iptables -A INPUT -s <ip-address> -p tcp --destination-port 28018 -m state --state NEW,ESTABLISHED -j ACCEPT
对于mongos的http防火墙:iptables -A INPUT -s <ip-address> -p tcp --destination-port 28019 -m state --state NEW,ESTABLISHED -j ACCEPT
修改默认策略到DROP
设置好所有的规则之后,把iptbales的策略设置为drop
iptables -P INPUT DROP
iptables -P OUTPUT DROP
管理和维护iptables配置
让iptables的规则持久:
在Red Hat企业版中,可以使用service iptables save保持当前的规则
在Debian,Ubuntu中,可以使用iptables-save > /etc/iptables.conf
还原规则可以使用:iptables-restore < /etc/iptables.conf
List所有iptables规则:iptables –L
刷新所有的iptables规则:iptables –F,刷新掉所有规则
5.3.1.2Windows下使用netsh配置防火墙
不介绍,看手册p249
5.3.1.3使用SSL连接到MongoDB
给Mongod和Mongos配置SSL
绑定SSL证书和密钥
在使用SSL之前必须要有一个.pem文件包含了公钥,私钥。可以使用一下命令生成自签名的证书和私钥:
cd /etc/ssl/
openssl req -new -x509 -days 365 -nodes -out mongodb-cert.crt -keyout mongodb-cert.key
然后写入到pem文件中
cat mongodb-cert.key mongodb-cert.crt > mongodb.pem
使用SSL证书和密钥安装mongod,mongos
使用SSL设置一下选项:
1.sslOnNormalPorts
2.sslPEMKeyFile指向包含SSL证书和密钥
mongod --sslOnNormalPorts --sslPEMKeyFile /etc/ssl/mongodb.pem
也可以在配置文件中设置:
sslOnNormalPorts = true
sslPEMKeyFile = /etc/ssl/mongodb.pem
连接到使用了SSL的mongod,mongos,mongo shell要使用—ssl选项。
安装证书验证
安装证书验证涉及到一下选项:
1.sslOnNormalPorts
2.sslPEMKeyFile指向包含SSL证书和密钥
3.sslCAFile直线包含了一个pem文件,包含了证书发布机构发布的证书(the root certificate chain from the Certificate Authority)。
mongod --sslOnNormalPorts --sslPEMKeyFile /etc/ssl/mongodb.pem --sslCAFile /etc/ssl/ca.pem
也可以用配置文件设置:
sslOnNormalPorts = true
sslPEMKeyFile = /etc/ssl/mongodb.pem
sslCAFile = /etc/ssl/ca.pem
连接到使用了SSL的mongod,mongos,mongo shell要使用—ssl选项和—sslPEMKeyFile选项。
堵塞吊销的证书登陆
mongod --sslOnNormalPorts --sslCRLFile /etc/ssl/ca-crl.pem --sslPEMKeyFile /etc/ssl/mongodb.pem --sslCAFile /etc/ssl/ca.pem
证书在/etc/ssl/ca-crl.pem中的都无法访问。
证书验证只提供证书的客户端
使用选项sslWeakCertificateValidation,来启动证书验证只提供证书的客户端,
mongod --sslOnNormalPorts --sslWeakCertificateValidation --sslPEMKeyFile /etc/ssl/mongodb.pem --sslCAFile /etc/ssl/ca.pem
当客户端连接的时候,要使用—ssl没有证书,或者—ssl有正确可用的证书才能访问。
客户端设置SSL
Mongo shell配置:为了支持mongo shell的SSL配置,mongo有以下设置:
1.—ssl
2. –sslPEMKeyFile 指向一个包含key和证书的pem文件
3.—sslCAFile 指向一个由证书发布机构发布的证书
4.--sslPEMKeyPassword 如果 certificate-key file是加密的需要提供密码。
使用SSL连接:mongo –ssl
需要客户端证书的连接:mongo --ssl --sslPEMKeyFile /etc/ssl/client.pem
当提供证书的时候验证证书:
mongo --ssl
mongo --ssl --sslPEMKeyFile /etc/ssl/client.pem
MMS 监控器代理:在配置host页面直接启用SSL即可。
5.3.2访问控制教程
介绍启用认证,添加用户,修改密码,生产key文件,使用kerberos认证部署。
5.3.2.1启动认证
启用认证可以使用选项auth或者keyFile。Auth用户单个实例,keyFile用于复制集和shard集群。keyFile允许成员之间内部认证。
认证至少要求在admin数据库中有一个管理员,如果没有可以创建。
过程
1.启动mongod,或者mongos,不是用auth或keyfile
2.创建一个管理员
3.重启mongod,mongos带上auth或keyfile
也可以
1.启动mongod,mongos带上auth或者keyfiel
2.本地连接,并创建管理员
3.重启
查询认证用户
用户全部存在system.users下,所以直接find()这个collection即可
5.3.2.2创建一个管理员
在Mongodb中用户有角色userAdmin或者userAdminAnyDatabase,就像是超级管理员。这个权限,可以给任何用户修改权限包括自己。
userAdminAnyDatabase角色用户可以直接给自己或者用户赋予访问整个实例的权限,所以要谨慎。
对于有userAdmin或者userAdminAnyDatabase自己并没有权限,还是需要先授权才能访问。
userAdmin是数据库级别的,如果角色是在admin数据库上的,那么可以把自己修改为userAdminAnyDatabase,然后可以访问整个实例。
创建一个管理员用户
1.连接到mingod或者mongos,可以用已经存在的用户认证,也可以使用localhost 认证。
2.切换到admin数据库,use admin
3.使用语句添加管理员用户,db.addUser( { user: "<username>",pwd: "<password>",roles: [ "userAdminAnyDatabase" ] } )。
通过本地认证获取管理员访问
当admin没有用户的时候,localhost登录的或有超级管理员权限,当然可以通过mongod --setParameter enableLocalhostAuthBypass=0禁用
5.3.2.3添加一个用户
第一次添加给这个用户添加数据库应该添加为userAdmin或者userAdminAnyDatabase,这样才好管理。
一个用户要添加到不同的数据库中,必须定义多次。因为以数据库级别的认证。
通过addUser添加用户,用户资料会被保存在system.user下面。
5.3.2.4修改用户密码
通过db.changeUserPassword修改用户密码。
5.3.2.5生成key文件
如果要使用key文件,那么在mongod或者mongos启动的时候制定keyfile选项。
生成keyfile文件
一般使用openssl生成keyfile文件:
openssl rand -base64 741
Key File属性
MongoDB会跳过keyfile里面的空格。
5.3.2.6使用Kerberos认证
有需要自己看手册p261
5.3.3 创建漏洞报告
有需要自己看手册p265
5.4 安全性指南
5.4.1mongo shell中安全性的方法
db.addUser:添加一个用户到数据库中,允许管理员配置这个用户的权限
db.auth:认证一个用户到一个数据库中
db.changeUserPassword:修改一个已存在用户的密码
5.4.2 安全性指南文档
本节介绍:mongodb中的角色权限,system.users权限文档,默认mongodb端口。
5.4.2.1Mongodb中角色权限
角色
在mongodb中角色是允许访问,而不是限制访问。
数据库用户角色
Read:可以读取任何指定数据库中的数据,除了可以使用find之外,还可以使用,aggregate,checkShardingIndex,cloneCollectionAsCapped,collStats,count,dataSize,dbHash,dbStats,distinct,filemd5,geoNear,geoSearch,geoWalk,group,mapReduce,text
ReadWrite:可以读写指定数据库的任何数据,除了可以insert,remove,update和read的权限之外之外,还可以使用,cloneCollection,convertToCapped,create,drop,dropIndexes,emptycapped,ensureIndex(),findAndModify,mapReduce(输出到一个collection),renameCollection。
DbAdmin:提供了一些管理性的操作,clean,collMod,collStats,compact,convertToCapped,create,db.createCollection(),dbStats,drop(),dropIndexes,ensureIndex(),indexStats,profile,reIndex,renameCollection,validate
userAdmin:可以读写system.users Collection
管理上的角色
clusterAdmin:clusterAdmin获取了多个管理操作会影响整个系统,而不是单个数据库。clusterAdmin只适用于admin数据库,并且不会授予访问local,config数据库。具体操作看手册p270
任意数据库权限
这种权限只有在admin下授权才能使用。
readAnyDatabase:可以访问所有的数据库,和read类似
readWriteAnyDatabase:可以读写任何数据库中的collection
userAdminAnyDatabase:可以管理任何数据库的用户
dbAdminAnyDatabase:可以管理所有数据库
组合访问
1.sh.status()需要clusterAdmin,在config上的read
2.applyops,eval需要readWriteAnyDatabase,userAdminAnyDatabase,dbAdminAnyDatabase和clusterAdmin
3.re.config,需要在local的read
4.sh.addShard,需要config上的readWrite
5.4.2.2 system.users权限文档
数据模型
{
user: "<username>",
pwd: "<hash>",
roles: []
}
{
user: "<username>",
userSource: "<database>",
roles: []
}
Pwd和userSource是互斥的,一个文档中2个不能同时存在。
{
user: "<username>",
userSource: "<database>",
otherDBRoles: {
<database0> : [],
<database1> : []
},
roles: []
}
其他数据库角色指定了在其他数据库中的角色,只有在admin下才能支持。
<database>.system.users.user:唯一的表示一个用户
<database>.system.users.pwd:用户密码通过hash加密
<database>.system.users.roles:指定了一个可用的用户角色
<database>.system.users.userSource:字符串指定了一个用户的凭据
Admin.system.users.otherDBRolse:指定了在其他数据库的角色:
{
user: "admin",
userSource: "$external",
roles: [ "clusterAdmin"],
otherDBRoles:
{
config: [ "read" ],
records: [ "dbAdmin" ]
}
}
Mongodb认证凭据代理
Mongodb支持凭据代理,代理其他数据库的凭据。
设置,现在account数据库下创建用户:
{
user: "application0",
pwd: "YvuolxMtaycghk2GMrzmImkG4073jzAw2AliMRul",
roles: []
}
然后再要访问的数据库中添加以下信息:
{
user: "application0",
roles: [‘readWrite‘],
userSource: "accounts"
}
禁用非法的权限文档
留着这个是为了向下兼容,可以通过supportCompatibilityFormPrivilegeDocuments禁用如:
mongod --setParameter supportCompatibilityFormPrivilegeDocuments=0
5.4.2.3 Mongodb默认端口
27017:mongos和mongod实例的默认端口,通过port修改
27018:shard服务的默认端口,当设置—shardsvr时启用
27019:config服务的默认端口,--config启用
28017:web状态页的端口比mongos,mongod端口大1000
5.4.3安全性发布点提醒
5.4.3.1 System.users的访问
在2.4版本之后只能有userAdmin的角色才能访问system.users
5.4.3.2hash密码加密的不安全性
相同的密码在system.users中保存的hash值是一样的,黑客很容易利用这一点黑掉其他用户