【运维相关】MongoDB那些坑
前言
某个早期技术债务项目线上有一个mongoDB服务,用途很简单,存一些文件而已。不过用户那边突然报个bug说上边的图片丢失了,起初没当回事认为是代码遇到错了,直到后来看了用户详细的bug复现后,登进db一看,发现竟然是被入侵了。还被入侵者留了个Warning数据库,只写了一句: 你丫的数据备份在我们安全服务器上,0.2个比特币就还你。
【入侵分析】
当然,根据大家前段时间的比特币勒索的情况看,支付也没用的概率极大,何况也仅仅是大约10M的文件而已。既然不影响生产,也就无所谓恢复不恢复了。
从MongoDB的日志中发现几个被ipip.Net标注为机器人、肉鸡的地址,反查了下时间发现正好对得上被清除的数据时间。当然,这个攻击是来自公网的,很不走运,被攻击的那段时间某个坑逼图方便把到db的端口映射到了公网上,然后就GG了。
当然GG的更深原因是,项目时间太早,MongoDB版本还是2.x,写文件服务的人还在用一个很早版本的.Net Driver,据开发说这个Driver最大的bug是不能执行用户名密码登录,会报错,而Java版本却没问题,因此在配置时就没有要求mongoDB带验证,更别说ssl了。【根据目前对mongoDB的研究,个人对此表示怀疑...】 总之,这次事件铁定是某开发的锅,当然没有及时采用新版Driver等也是不合理的。
在及时止损把服务端口从路由器上去掉、服务器全盘查杀并重新配置了防火墙策略后,还是决定重新建独立的文件服务,让MongoDB不会有机会再暴露,也正好迭代一下旧产品的技术。
【正文开始】
这篇博客主要聊聊部署测试环境时遇到的几个坑。
首先,MongoDB已经升级到3.6版本,最新的Driver是2.5版本,是17年12月发布的Release,同样可以在Nuget上更新。因此,测试环境放在Server 2016服务器上,防火墙开启,MongoDB采用配置文件方式启动并注册为服务。
mongoDB如今支持通过配置文件形式启动,这就远比之前编写bat方便得多。其配置文件语法为YAML,是从2.6开始引入的方式。官方介绍地址:https://docs.mongodb.com/manual/reference/configuration-options
这么一看发现配置项还真不少。很长时间没再回来细看MongoDB的东西,发现原来这么复杂。当然目前的用途我们只需要配置以下这些信息即可:

带配置文件启动很简单:
.\mongod --config ".\MongoDB\mongo.conf" --install
--install参数是用来安装Windows服务的,关于服务的设置,参见配置文件中 processManagement部分。
然而现实是:

仔细对比了很久也没发现配置上有错,并且这个error的提示基本等于没说。
在调整了几遍配置顺序后几近崩溃,最终决定复制错误信息去查,结果发现还真是同样的报错信息,原因是——配置文档中不能用Tab
当然附带的一个小问题是文件的编码必须是ASCI,否则会解析出错。
改完之后,服务正确安装了,启动后可以进行连接。

切换到admin数据库,由于我们是设置带验证登录,目前是没有账户的,所以需要在Admin中创建。
于是我们尝试执行:
db.createUser({user:"user01"})
然而报错:

到这我们是可以想到的,由于服务已经带验证启动了,所以目前直接登录虽然允许访问admin数据库,但是没有任何权限。
所以我们要将服务改为不带验证的方式。
因为服务安装时指定了配置文件,所以我们只需要注释掉配置文件中的authoriation项或改为disabled即可,重启服务后生效。
这时候我们跟着官方文档走,创建一个管理员账户:
db.createUser(
{
user:"usr01",
pwd:"123456",
roles:["dbAdmin"]
}
)
参考官方介绍, roles参数是一个Bson结构的数组,写法可以是简化的角色名,也可以是完整的角色对象:
roles:[
{role:"readWrite", db:"file"},
{role:"DbAdmin", db:"file"}
]
用户创建好了之后,就可以将服务改回带验证启动了。
再登录:
.\mongo.exe -u usr01 -p 123456rt --authenticationDatabase "admin" -port 27018
即可进入被授权的admin数据库。
关于mongoDB的用户角色分为内置角色和用户定义角色,具体可参考:
https://docs.mongodb.com/manual/reference/built-in-roles/#built-in-roles
这里有一点坑的是,当我在localhost下以前边创建的usr01账户登录,并且希望为新的Collection创建一个专用账户并赋予权限时,始终报错提示我没有权限进行操作,即便我重新使用root账户登录,也依然不行。
最后是在官方文档里发现这样一段:

换到另一台机器上,使用客户端连接,可以修改或新增用户了。
【其他】
顺便一提,配置文件中的BindIP选项不知道是什么原理,如果第一位写了127.0.0.1,虽然官方文档说可以 用逗号分隔,设置多个地址,但这样配置之后只能通过localhost客户端去连接。大概需要把范围更大的放前边吧。。
【运维相关】MongoDB那些坑的更多相关文章
- Open edX 学习、开发、运维相关链接整理
原文地址:http://edustack.org/ 所需知识: Linux Git Python (Django Mako coffeescript sass) (MongoDB Mysql) Ans ...
- redis运维相关(基本数据库命令)【十四】
-----------------------------运维相关------------------------- redis持久化,两种方式1.rdb快照方式2.aof日志方式 --------- ...
- Linux系统运维相关的面试题 (问答题)
这里给大家整理了一些Linux系统运维相关的面试题,有些问题没有标准答案,希望要去参加Linux运维面试的朋友,可以先思考下这些问题. 一.Linux操作系统知识 1.常见的Linux发行版本都有 ...
- Linux运维相关目录
- 转载---linux运维相关
前段时间,我在准备面试的时搜到的一套Linux运维工程师面试题,感觉比较全面,一直保存在草稿,刚在整理后台时翻了出来,干脆就发出来好了,以备不时之需. 1.linux如何挂在windows下的共享目录 ...
- Linux网络运维相关
删除特殊的用户和用户组 userdel games group games 关闭不需要的服务 chkconfig chkconfig --level 345 bluetooth off 删减系 ...
- redis运维相关
一.redis都有哪些数据类型?分别在哪些场景下使用比较合适?二.redis双写不一致三.雪崩和穿透四.redis的过期策略,LRU五.redis是如何实现高性能高并发六.如何保证Redis的高并发和 ...
- mysql运维相关
1.为什么要分库分表(设计高并发系统的时候,数据库层面该如何设计)?用过哪些分库分表中间件?不同的分库分表中间件都有什么优点和缺点?2.现在有一个未分库分表的系统,未来要分库分表,如何设计才可以让系统 ...
- MongoDB 运维相关的命令
1.在线释放内存 use admindb.runCommand({closeAllDatabases:1}) 注:3.2 版本 已经去掉了这个命令了 2.rs.status() 查询复制集状态 3.d ...
随机推荐
- Linux — 基础知识
一 从认识操作系统开始 1.1 操作系统简介 我通过以下四点介绍什么操作系统: 操作系统(Operation System,简称OS)是管理计算机硬件与软件资源的程序,是计算机系统的内核与基石: 操作 ...
- vue项目1-pizza点餐系统5-全局守卫
一.导航守卫描述 当问我们点击主页.菜单等非登陆和注册按钮都会提示先登陆然后跳转到登陆界面. 1.在main.js中引入全局守卫 //全局守卫 //to是要进入那个路由,from是从那个路由出来,ne ...
- python基础知识之数据类型
一.与用户的交互 古时候,我们去银行取钱,需要有一个银行业务员等着我们把自己的账号密码输入给他, 然后他去进行验证,成功后,我们再将取款金额输入/告诉他 骄傲的现代人,会为客户提供一台ATM机(就是一 ...
- Spring Boot 支持https
1. 生成key JDK下 keytool -genkeypair -alias mySSL -keyalg RSA -keystore E:\tomcat.key 其中-alias是证书的别名,RS ...
- 牛客练习赛33 C tokitsukaze and Number Game (结论+字符串处理)
链接:https://ac.nowcoder.com/acm/contest/308/C 来源:牛客网 tokitsukaze and Number Game 时间限制:C/C++ 1秒,其他语言2秒 ...
- AtCoder Regular Contest 066 E - Addition and Subtraction Hard (结论+DP)
Time limit : 2sec / Memory limit : 256MB Score : 900 points Problem Statement Joisino has a formula ...
- JavaScript设计模式 样例一 —— 工厂模式
工厂模式(Factory Pattern): 定义:定义一个创建对象的接口,但让实现这个接口的类来决定实例化哪个类.工厂方法让类的实例化推迟到子类中进行. 目的:工厂模式是为了解耦,把对象的创建和使用 ...
- GUI学习之二十四——QDialog学习总结
今天学习对话框输入控件的基类(QDialog). 一.描述 是对话类窗口(字体框.颜色选择.文件选择框等)的基类. 对话框窗口是顶级窗口(就是说不包含于哪个父类的显示界面里),主要用于短期任务和与用户 ...
- C#基础知识之DirectorySearcher 类
活动目录(Active Directory)是从一个数据存储开始的,它采用了类似Exchange Server的数据存储,所以被称为Extensible Storage Service (ESS).其 ...
- u-boot makefile $$
define filechk_uboot.release echo "$(UBOOTVERSION)$$($(CONFIG_SHELL) $(srctree)/scripts/setl ...