Mongodb Manual阅读笔记:CH5 安全性

5 安全性

Mongodb Manual阅读笔记:CH2 Mongodb CRUD 操作Mongodb Manual阅读笔记:CH3 数据模型(Data Models)Mongodb Manual阅读笔记:CH4 管理Mongodb Manual阅读笔记:CH5 安全性Mongodb Manual阅读笔记:CH6 聚合Mongodb Manual阅读笔记:CH7 索引Mongodb Manual阅读笔记:CH8 复制集Mongodb Manual阅读笔记:CH9 Sharding

本章介绍几本的安全和风险管理策略和访问控制

5 安全性

5.1 安全性说明

5.1.1 深入防御(Defense in Depth)

5.1.2 可信任环境

5.1.3 减少风险的可选实践

5.1.4数据加密

5.1.5额外的安全性策略

5.1.6 漏洞通知

5.2安全性概述

5.2.1 访问控制

5.2.1.1 认证

5.2.1.2 授权

5.2.1.3 system.users Collection

5.2.2内部过程的认证

5.2.2.1 在复制集和shard集群启用认证

5.2.3 Shard集群安全性

5.2.3.1 shard集群的访问控制权限

5.2.3.2使用认证访问shard集群

5.2.3.3 localhost上的限制

5.2.4网络曝光和安全性

5.2.4.1配置选项

5.2.4.1防火墙

5.2.4.2虚拟私有网络(VPN)

5.2.5Mongodb API 接口和安全性

5.2.5.1 Mongo Shell中的安全性和Javascript

5.2.5.2HTTP状态接口

5.2.5.3REST API

5.3 安全性教程

5.3.1 网络安全教程

5.3.1.1使用iptables防火墙设置

5.3.1.2Windows下使用netsh配置防火墙

5.3.1.3使用SSL连接到MongoDB

5.3.2访问控制教程

5.3.2.1启动认证

5.3.2.2创建一个管理员

5.3.2.3添加一个用户

5.3.2.4修改用户密码

5.3.2.5生成key文件

5.3.2.6使用Kerberos认证

5.3.3 创建漏洞报告

5.4 安全性指南

5.4.1mongo shell中安全性的方法

5.4.2 安全性指南文档

5.4.2.1Mongodb中角色权限

5.4.2.2 system.users权限文档

5.4.2.3 Mongodb默认端口

5.4.3安全性发布点提醒

5.4.3.1 System.users的访问

5.4.3.2hash密码加密的不安全性

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值是一样的,黑客很容易利用这一点黑掉其他用户

上一篇:PKCS#1规范阅读笔记1--------基本概念


下一篇:QCon 2015 阅读笔记 - 团队建设