MongoDb副本集安全认证

前言

对于搭建好的mongodb副本集,为了安全,启动安全认证,使用账号密码登录。
副本集环境使用之前搭建好的,架构如下:

MongoDb副本集安全认证

对副本集执行访问控制需要配置两个方面 :
1)副本集和共享集群的各个节点成员之间使用内部身份验证,可以使用密钥文件或x.509证书。密钥文件比较简单,本文使用密钥文件,官方推荐如果是测试环境可以使用密钥文件,但是正式环境,官方推荐x.509证书。原理就是,集群中每一个实例彼此连接的时候都检验彼此使用的证书的内容是否相同。只有证书相同的实例彼此才可以访问

2)使用客户端连接到mongodb集群时,开启访问授权。对于集群外部的访问。如通过可视化客户端,或者通过代码连接的时候,需要开启授权。
在keyfile身份验证中,副本集中的每个mongod实例都使用keyfile的内容作为共享密码,只有具有正确密钥文件的mongod或者mongos实例可以连接到副本集。密钥文件的内容必须在6到1024个字符之间,并且在unix/linux系统中文件所有者必须有对文件至少有读的权限。

关闭已开启的副本集服务

增加副本集的安全认证和服务鉴权功能,可以在副本集搭建的时候直接添加,也可以在之前搭建好的副本集服务上添加。
本文使用之前搭建好的副本集服务,因此,先停止之前的集群服务停止服务的方式有两种:快速关闭和标准关闭,下面依次说明:

(1)快速关闭方法(快速,简单,数据可能会出错)
目标:通过系统的kill命令直接杀死进程:
依次杀死仲裁者、副本节点、主节点,直到所有成员都离线。建议主节点最后kill,以避免潜在的回滚。
杀完要检查一下,避免有的没有杀掉。

#通过进程编号关闭节点 kill -2 54410
如果一旦是因为数据损坏,则需要进行如下操作(了解):
1)删除lock文件:

rm -f /mongodb/replica_sets/myrs_27017/data/db/*.lock \
/mongodb/replica_sets/myrs_27018/data/db/*.lock \
/mongodb/replica_sets/myrs_27019/data/db/mongod.lock \

2 )依次修复数据:

/usr/local/mongodb/bin/mongod --repair --dbpath=/mongodb/replica_sets/myrs_27017/data/db
/usr/local/mongodb/bin/mongod --repair --dbpath=/mongodb/replica_sets/myrs_27018/data/db
/usr/local/mongodb/bin/mongod --repair --dbpath=/mongodb/replica_sets/myrs_27019/data/db

(2)标准的关闭方法(数据不容易出错,但麻烦):
目标:通过mongo客户端中的shutdownServer命令来依次关闭各个服务
关闭副本集中的服务,建议依次关闭仲裁节点、副本节点、主节点。主要的操作步骤参考如下

//客户端登录服务,注意,这里通过localhost登录,如果需要远程登录,必须先登录认证才行。
mongo --port 27017
//告知副本集说本机要下线
rs.stepDown()
//#切换到admin库
use admin
//关闭服务
db.shutdownServer()

通过主节点添加一个管理员帐号

只需要在主节点上添加用户,副本集会自动同步。
开启认证之前,创建超管用户:myroot,密码:123456

[root@localhost replica_sets]# /usr/local/mongodb/bin/mongo --port 27018
MongoDB shell version v4.0.10
connecting to: mongodb://127.0.0.1:27018/?gssapiServiceName=mongodb
Implicit session: session { "id" : UUID("278324b8-7825-49d1-9b3a-fdf9efb32030") }
MongoDB server version: 4.0.10
myrs:PRIMARY> use admin
switched to db admin
myrs:PRIMARY> db.createUser({user:"myroot",pwd:"123456",roles:["root"]})
Successfully added user: { "user" : "myroot", "roles" : [ "root" ] }
myrs:PRIMARY> db.auth("myroot","123456")
1
myrs:PRIMARY> use articledb
switched to db articledb
myrs:PRIMARY> db.createUser({user: "bobo", pwd: "123456", roles: ["readWrite"]})
Successfully added user: { "user" : "bobo", "roles" : [ "readWrite" ] }
myrs:PRIMARY>

创建副本集认证的key文件

第一步:生成一个key文件到当前文件夹中。
可以使用任何方法生成密钥文件。例如,以下操作使用openssl生成密码文件,然后使用chmod来更改文件权限,仅为文件所有者提供读取权限

提示:
所有副本集节点都必须要用同一份keyfile,一般是在一台机器上生成,然后拷贝到其他机器上,且必须有读的权限,否则将来会报错: permissions on /mongodb/replica_sets/myrs_27017/mongo.keyfile are too open
一定要保证密钥文件一致,文件位置随便。但是为了方便查找,建议每台机器都放到一个固定的位置,都放到和配置文件一起的目录中。
这里将该文件分别拷贝到多个目录中:

[root@localhost replica_sets]# openssl rand -base64 90 -out ./mongo.keyfile
[root@localhost replica_sets]#  chmod 400 ./mongo.keyfile
[root@localhost replica_sets]#  cp mongo.keyfile /mongodb/replica_sets/myrs_27017
[root@localhost replica_sets]# cp mongo.keyfile /mongodb/replica_sets/myrs_27018
[root@localhost replica_sets]# cp mongo.keyfile /mongodb/replica_sets/myrs_27019

修改配置文件指定keyfile

分别编辑几个服务的mongod.conf文件,添加相关内容:

security:
 #KeyFile鉴权文件
 keyFile: /mongodb/replica_sets/myrs_27017/mongo.keyfile
 #开启认证方式运行
 authorization: enabled
security:
 #KeyFile鉴权文件
 keyFile: /mongodb/replica_sets/myrs_27018/mongo.keyfile
 #开启认证方式运行
 authorization: enabled
security:
 #KeyFile鉴权文件
 keyFile: /mongodb/replica_sets/myrs_27019/mongo.keyfile
 #开启认证方式运行
 authorization: enabled

重新启动副本集

如果副本集是开启状态,则先分别关闭关闭复本集中的每个mongod,从次节点开始。直到副本集的所有成员都离线,包括任何仲裁者。主节点必须是最后一个成员关闭以避免潜在的回滚。

[root@localhost replica_sets]# /usr/local/mongodb/bin/mongod -f /mongodb/replica_sets/myrs_27017/mongod.conf
about to fork child process, waiting until server is ready for connections.
forked process: 68161
child process started successfully, parent exiting
[root@localhost replica_sets]# /usr/local/mongodb/bin/mongod -f /mongodb/replica_sets/myrs_27018/mongod.conf
about to fork child process, waiting until server is ready for connections.
forked process: 68225
child process started successfully, parent exiting
[root@localhost replica_sets]# /usr/local/mongodb/bin/mongod -f /mongodb/replica_sets/myrs_27019/mongod.conf
about to fork child process, waiting until server is ready for connections.
forked process: 68291
child process started successfully, parent exiting
[root@localhost replica_sets]#  ps -ef |grep mongod
root      68161      1 13 17:28 ?        00:00:02 /usr/local/mongodb/bin/mongod -f /mongodb/replica_sets/myrs_27017/mongod.conf
root      68225      1 15 17:28 ?        00:00:02 /usr/local/mongodb/bin/mongod -f /mongodb/replica_sets/myrs_27018/mongod.conf
root      68291      1 24 17:28 ?        00:00:02 /usr/local/mongodb/bin/mongod -f /mongodb/replica_sets/myrs_27019/mongod.conf
root      68341  68113  0 17:29 pts/0    00:00:00 grep --color=auto mongod

查看进程情况:

[root@localhost ~]# ps -ef |grep mongod
root      68161      1  1 17:28 ?        00:00:14 /usr/local/mongodb/bin/mongod -f /mongodb/replica_sets/myrs_27017/mongod.conf
root      68225      1  1 17:28 ?        00:00:14 /usr/local/mongodb/bin/mongod -f /mongodb/replica_sets/myrs_27018/mongod.conf
root      68291      1  1 17:28 ?        00:00:09 /usr/local/mongodb/bin/mongod -f /mongodb/replica_sets/myrs_27019/mongod.conf
root      68358  68113  0 17:30 pts/0    00:00:00 /usr/local/mongodb/bin/mongo --port 27018
root      68415  68390  0 17:41 pts/2    00:00:00 grep --color=auto mongod
[root@localhost ~]#

重新进入客户端:

[root@localhost ~]# /usr/local/mongodb/bin/mongo --port 27018
MongoDB shell version v4.0.10
connecting to: mongodb://127.0.0.1:27018/?gssapiServiceName=mongodb
Implicit session: session { "id" : UUID("54e8c8cc-f32c-4870-a1a0-ec66f7189c7b") }
MongoDB server version: 4.0.10
myrs:PRIMARY> use admin
switched to db admin
myrs:PRIMARY> db.system.users.find()
Error: error: {
        "operationTime" : Timestamp(1603273480, 1),
        "ok" : 0,
        "errmsg" : "command find requires authentication",
        "code" : 13,
        "codeName" : "Unauthorized",
        "$clusterTime" : {
                "clusterTime" : Timestamp(1603273480, 1),
                "signature" : {
                        "hash" : BinData(0,"Vpy5BfZAYFjb0jAvVauPH5iJOX4="),
                        "keyId" : NumberLong("6882670673634787329")
                }
        }
}
myrs:PRIMARY> db.auth("myroot","123456")
1
myrs:PRIMARY> db.system.users.find()
{ "_id" : "admin.myroot", "userId" : UUID("aeab3622-2543-463f-a093-ab13f609cb45"), "user" : "myroot", "db" : "admin", "credentials" : { "SCRAM-SHA-1" : { "iterationCount" : 10000, "salt" : "Ev5Skt7TTioQXWdREI3MsA==", "storedKey" : "6wuPR0QONHSOLPdXQNF4VRV+pQY=", "serverKey" : "rf2z8Z6Onmwrc4vSPWnStKWdY40=" }, "SCRAM-SHA-256" : { "iterationCount" : 15000, "salt" : "SIFiUxuZl1X9iLlIhC6zD+4XxaI/6do+fD5KUw==", "storedKey" : "UJ3VuITQQiDb0zua88pHVJRURKXSy8w0+6iurmJ2re8=", "serverKey" : "+PvIaOPtIYS7NEnir9a4LCHN620MmYprU0mj64niSzk=" } }, "roles" : [ { "role" : "root", "db" : "admin" } ] }
{ "_id" : "articledb.bobo", "userId" : UUID("3afbed61-f025-4689-add5-86dc6f83ed35"), "user" : "bobo", "db" : "articledb", "credentials" : { "SCRAM-SHA-1" : { "iterationCount" : 10000, "salt" : "Sj93IS+qxemlh26hJgI7cQ==", "storedKey" : "t5w5d2TSgWa6GZyCfv5yjfYozik=", "serverKey" : "vc8BOgWXLYs6Lgq78haIb1V/2o8=" }, "SCRAM-SHA-256" : { "iterationCount" : 15000, "salt" : "bSSCiu+bL0qmKAKAa5PyRZfhn36RaOtAdeCnWg==", "storedKey" : "fNhUoqzdP8unN9bcly6th+VNiRg7xSB4W25YqFuCwnA=", "serverKey" : "6VZtJ465HuIVfOje9znhCpZIzxgAjVRaH7Yh70uCqFg=" } }, "roles" : [ { "role" : "readWrite", "db" : "articledb" } ] }
myrs:PRIMARY>

上一篇:初识 Redis


下一篇:Redis之Sorted Sets