吹个牛B,自己的MongoDB裸奔了快半年,从未遭受黑客攻击。也不知道是自己运气好,还是黑客对我的乞丐版服务器看不上眼。不过既然知道了数据库裸奔的危险性,就要给它上把锁。然而上锁对我这种刻意回避数据库知识的人来说,也实在不是一件容易的事。

在学习上锁的过程中,看了好些文章。为了防止大家看我这篇没懂后还有的看,先给出参考文档:

  • https://www.cnblogs.com/chunlei36/p/6506048.html
  • https://blog.csdn.net/u012900400/article/details/79207822
  • https://blog.csdn.net/wangmao01/article/details/80805643

裸奔有多危险

一句话,没有密码的数据库,而且又没有改27017这个MongoDB默认端口号,别人一个命令就可以连上去:


mongo 192.168.0.5:27017

这篇文章也给出了关于MongoDB安全性的详细说明

当然你可能说,他怎么知道我用的什么数据库,然后猜到我的端口。我在这里只能说,我们要相信黑客的技术😂。

mongoDB修改默认端口号

在设置权限之前,我们要首先改掉默认端口号,这是防止被攻击的第一步。

修改默认端口号可分为两步,第一步,关掉MongoDB;第二步,用新的端口号启动MongoDB

关闭MongoDB

关闭MongoDB也有两种方式,第一是借助mongo shell,使用db.shutdownServer(),第二是直接杀进程。

shutdownServer的使用方法如下:

# 进入mongo shell
mongo

# 显示现有的数据库
show dbs

# 进入admin数据库
use admin

# 关闭数据库
db.shutdownServer()

当然,我更喜欢另外一种简单粗暴的方式:kill

# mac
lsof -i :27017

# centOS
netstat -pan | grep 27017

# 查到pid后,kill
kill 36954

重启MongoDB

重启MongoDB也有两种方式:命令行参数启动 和 加载配置文件启动。两者的唯一区别就是后面的方法将配置参数放到了一个配置文件之中。两种方法中,我们要做的都是改掉默认端口号,先来看第一种方式:

# 这个命令可以查看mongod可以接受哪些参数
mongod --help

# -p 可以用来设置port端口号

mongod --fork --logpath 你的log存放路径 --dbpath  你的数据库存放路径 -p 12345 

这里讲一下 --fork 的意思,如果不带这个参数,MongoDB的日志会在前台运行,日志会直接打印到shell里面。带上这个参数则会将MongoDB转到后台运行,同时将运行日志写到logpath里面,而不是直接打印到命令行。

设置密码

接下来,讲到设置密码的关键环节了,没有密码,只改变端口,就好像把门从朝东改成了朝南,却还是没有上锁。所以再加上密码这一步才算安全。在设置MongoDB的密码前,我们要知道以下几点:

  1. 每个数据库之间的密码是独立的。
  2. 数据库权限是分角色的。

这里不讲每个角色(role)有哪些权限,更多角色相关的内容可以参考官方文档build-in roles。下面设置密码的步骤主要参考MongoDB官方文档:https://docs.mongodb.com/manual/tutorial/enable-authentication/

第一步:开启MongoDB服务

mongod --port 23456 --dbpath /data/db1

第二步:进入MongoDB shell,类似于node.js的node命令

mongo --port 23456

第三步:进入admin数据库,以 userAdminAnyDatabase 的角色创建admin账号,这个账号创建后,可以为任何数据库创建用户

use admin #进入admin数据库

# 创建admin账号
db.createUser(
  {
    user: "myUserAdmin", #用户名
    pwd: "abc123", #密码
    roles: [ { role: "userAdminAnyDatabase", db: "admin" }, "readWriteAnyDatabase" ]
  }
)

创建完成后推出mongo shell。

第四步:加入授权重启MongoDB,方法上面介绍过了,但是要加上授权参数--auth

mongod --auth --port 23456 --dbpath /data/db1

第五步:使用--auth启动后,登录mongo shell就需要输入密码了,可以将账号密码放在一条命令中,也可以先进入shell,再输入账号密码鉴权,分别对应如下两条语句:



mongo --port 23456 -u "myUserAdmin" -p "abc123" --authenticationDatabase "admin"

或者先登录再使用auth授权

# 先进入mongo shell
mongo --port 23456

# 使用auth函数输入admin数据库的账号密码

use admin
db.auth("myUserAdmin", "abc123" )

第六步:你登录 admin 数据库后,就可以为别的业务数据库创建账号密码了,比如为 test 和 reporting数据库创建账号密码:

use test # 进入test数据库
db.createUser(
  {
    user: "myTester",
    pwd: "xyz123",
    roles: [ { role: "readWrite", db: "test" },
             { role: "read", db: "reporting" } ]
  }
)

第七步:推出shell后,现在可以用新创建的账号密码登录test数据库了:

# 直接登录
mongo --port 23456 -u "myTester" -p "xyz123" --authenticationDatabase "test"

# 连接后登录

mongo --port 23456

use test
db.auth("myTester", "xyz123" )

如果你用moogoose登录,那你的url应该改成如下格式:

mongodb://myTester:xyz123@127.0.0.1:23456/test

本文完

01-20 14:16