MongoDB从入门到实战(十五):安全认证(单机)

x33g5p2x  于2021-12-25 转载在 Go  
字(4.3k)|赞(0)|评价(0)|浏览(525)

一:用户和角色权限简介

默认情况下,MongoDB实例启动运行时是没有启用用户访问权限控制的,也就是说,在实例本机服务
器上都可以随意连接到实例进行各种操作,MongoDB不会对连接客户端进行用户验证,这是非常危险
的。mongodb官网上说,为了能保障mongodb的安全可以做以下几个步骤:

  1. 使用新的端口,默认的27017端口如果一旦知道了ip就能连接上,不太安全。
  2. 设置mongodb的网络环境,最好将mongodb部署到公司服务器内网,这样外网是访问不到的。公
    司内部访问使用vpn等。
  3. 开启安全认证。为了强制开启用户访问控制(用户验证),则需要在MongoDB实例启动时使用选项 --auth 或在指定启动配置文件中添加选项 auth=true 。认证要同时设置服务器之间的内部认证方式,同时要设置客户端连接到集群的账号密码认证方式。

1.1 启用访问控制

MongoDB使用的是基于角色的访问控制(Role-Based Access Control,RBAC)来管理用户对实例的访问。通过对用户授予一个或多个角色来控制用户访问数据库资源的权限和数据库操作的权限,在对用户分配角色之前,用户无法访问实例。在实例启动时添加选项 --auth 或指定启动配置文件中添加选项 auth=true 。

1.2 角色

在MongoDB中通过角色对用户授予相应数据库资源的操作权限,每个角色当中的权限可以显式指定,也可以通过继承其他角色的权限,或者两都都存在的权限。

1.3 权限

权限由指定的数据库资源(resource)以及允许在指定资源上进行的操作(action)组成。

  1. 资源(resource)包括:数据库、集合、部分集合和集群;
  2. 操作(action)包括:对资源进行的增、删、改、查(CRUD)操作。
    在角色定义时可以包含一个或多个已存在的角色,新创建的角色会继承包含的角色所有的权限。在同一
    个数据库中,新创建角色可以继承其他角色的权限,在 admin 数据库中创建的角色可以继承在其它任意
    数据库中角色的权限。

1.4 常用的内置角色

  1. // 查询所有角色权限(仅用户自定义角色)
  2. > db.runCommand({ rolesInfo: 1 })
  3. // 查询所有角色权限(包含内置角色)
  4. > db.runCommand({ rolesInfo: 1, showBuiltinRoles: true })
  5. // 查询当前数据库中的某角色的权限
  6. > db.runCommand({ rolesInfo: "<rolename>" })
  7. // 查询其它数据库中指定的角色权限
  8. > db.runCommand({ rolesInfo: { role: "<rolename>", db: "<database>" } }
  9. // 查询多个角色权限
  10. > db.runCommand( { rolesInfo: [ "<rolename>", { role: "<rolename>", db: "<database>" }, ... ] } )

常用的内置角色:

  • 数据库用户角色:read、readWrite
  • 所有数据库用户角色:readAnyDatabase、readWriteAnyDatabase、
    userAdminAnyDatabase、dbAdminAnyDatabase
  • 数据库管理角色:dbAdmin、dbOwner、userAdmin
  • 集群管理角色:clusterAdmin、clusterManager、clusterMonitor、hostManager
  • 备份恢复角色:backup、restore
  • 超级用户角色:root
  • 内部角色:system

二:单实例认证

2.1 关闭服务器

2.1.1 标准的关闭方法(数据不容易出错)

目标:通过mongo客户端中的shutdownServer命令来关闭服务

  1. // 客户端登录服务,注意,这里通过localhost登录,如果需要远程登录,必须先登录认证才行。
  2. mongo --port 27017
  3. // 切换到admin库
  4. > use admin
  5. // 关闭服务
  6. > db.shutdownServer()

2.1.2 快速关闭方法(快速,简单,数据可能会出错)

通过系统的kill命令直接杀死进程:
杀完要检查一下,避免有的没有杀掉。

  1. // 通过进程编号关闭节点
  2. ps -ef |grep mongod
  3. kill -2 54410

如果一旦是因为数据损坏,则需要进行如下操作:

  1. // 1. 删除lock文件:
  2. rm -f xxx/data/db/*.lock // 2. 修复数据 ./bin/mongod --repair --dbpath=./data/db

2.2 使用配置文件重新启动

  1. systemLog:
  2. # MongoDB发送所有日志输出的目标指定为文件
  3. destination: file
  4. #mongod或mongos应向其发送所有诊断日志记录信息的日志文件的路径
  5. path: "/Users/mengday/Softwares/mongodb-4.4.5/log/mongod.log"
  6. #当mongos或mongod实例重新启动时,mongos或mongod会将新条目附加到现有日志文件的末尾
  7. logAppend: true
  8. storage:
  9. #mongod实例存储其数据的目录。storage.dbPath设置仅适用于mongod。
  10. #The directory where the mongod instance stores its data.Default Value is "/data/db".
  11. dbPath: "/Users/mengday/Softwares/mongodb-4.4.5/data/db"
  12. journal:
  13. #启用或禁用持久性日志以确保数据文件保持有效和可恢复。
  14. enabled: true
  15. processManagement:
  16. #启用在后台运行mongos或mongod进程的守护进程模式。
  17. fork: true
  18. #指定用于保存mongos或mongod进程的进程ID的文件位置,其中mongos或mongod将写入其PID
  19. pidFilePath: "/Users/mengday/Softwares/mongodb-4.4.5/log/mongod.pid"
  20. net:
  21. #服务实例绑定的IP,默认是localhost,多个用逗号分隔
  22. #bindIp: 127.0.0.1
  23. #绑定的端口,默认是27017
  24. port: 27000

启动mongo服务

  1. ./bin/mongod -f ./config/mongod.conf

2.3 创建超级用户

  1. ./bin/mongo --host 127.0.0.1 --port 27000
  1. //切换到admin库
  2. > use admin
  3. // 创建专门用来管理admin库的账号myadmin,只用来作为用户权限的管理
  4. > db.createUser({user:"myadmin",pwd:"123456",roles: [{role:"userAdminAnyDatabase",db:"admin"}]})
  5. // 创建系统超级用户 myroot,设置密码123456,设置角色root
  6. > db.createUser({user:"myroot",pwd:"123456",roles:["root"]})
  7. //查看已经创建了的用户的情况:
  8. > db.system.users.find()
  9. //删除用户
  10. > db.dropUser("myadmin")
  11. //修改密码
  12. > db.changeUserPassword("myroot", "123456")
  13. // 认证密码
  14. > db.auth("myroot","123456")
  15. 1

和其它数据库(MySQL)一样,权限的管理都差不多一样,也是将用户和权限信息保存到数据库对
应的表中。Mongodb存储所有的用户信息在admin 数据库的集合system.users中,保存用户名、密码
和数据库信息。如果不指定数据库,则创建的指定的权限的用户在所有的数据库上有效,如 {role: "userAdminAnyDatabase", db:""}

2.4 创建普通用户

创建普通用户可以在没有开启认证的时候添加,也可以在开启认证之后添加,但开启认证之后,必须使
用有操作admin库的用户登录认证后才能操作。底层都是将用户信息保存在了admin数据库的集合
system.users中。

  1. // 切换数据库
  2. > use test
  3. // 为test数据库添加用户
  4. > db.createUser({user: "test", pwd: "123456", roles: [{ role: "readWrite", db: "test" }]})
  5. //测试是否可用
  6. > db.auth("test","123456")

2.5 服务端开启认证和客户端连接登录

关闭服务

  1. > use admin
  2. > db.shutdownServer()

开启认证
方式一:在命令行中使用auth参数

  1. ./bin/mongod -f ./config/mongod.conf --auth

方式二:在mongod.conf中配置,在命令行中就不需要是使用auth参数了

  1. security:
  2. #开启授权认证
  3. authorization: enabled
  1. ./bin/mongod -f ./config/mongod.conf

开启认证后再登录,发现打印的日志比较少了。

  1. // 先进入shell,再使用db.auth(username, password)进行认证
  2. ./bin/mongo --host 127.0.0.1 --port 27000
  3. // 直接使用用户名和密码来登录到某个数据库
  4. ./bin/mongo --host 127.0.0.1 --port 27000 -u test -p 123456 --authenticationDatabase test

相关文章