MongoDB 是最常用的文档型数据库,很多项目用它存日志、存半结构化数据、存配置,或者干脆拿它当主库。但它的部署和权限配置跟 MySQL 很不一样:默认装完是不需要认证的,绑定地址是 127.0.0.1,一旦为了远程访问随手改成 0.0.0.0 又不设密码,就等于把整个数据库敞开在公网上——这几年被拖库、被勒索的 MongoDB 案例,绝大多数都是这么来的。
这篇文章按"装得上、连得进、管得住、防得住"的顺序,把 MongoDB 在一台 Linux 服务器上的完整部署过程讲清楚:官方仓库安装与发行版包安装的选择、mongod.conf 关键项、开启认证并建用户、远程访问的正确做法与安全红线、以及副本集的简单说明。
一、先搞清楚版本与安装方式
MongoDB 官方版本号采用偶数版本为稳定版(如 6.0、7.0)、奇数版本为开发版的历史约定,现在主流是 6.0 和 7.0 两个系列。选版本时优先选官方仍在维护的稳定版,别用发行版仓库里过旧或被标记 EOL 的版本。
安装有两条路:
一是官方仓库安装,版本新、可控,适合生产环境;二是发行版自带仓库安装,方便但版本通常偏旧。生产环境建议走官方仓库,这样升级和版本选择更自由。
需要注意的是,较新的 MongoDB 对 CPU 有要求:5.0 及以后版本要求 CPU 支持 AVX 指令集。老旧的虚拟机或某些云主机如果 CPU 不支持 AVX,装完会启动失败并报 Illegal instruction。遇到这种情况要么换机型,要么降到 4.4 系列。
检查 CPU 是否支持 AVX:
grep -o 'avx[^ ]*' /proc/cpuinfo | sort -u
# 输出里有 avx 或 avx2 就满足;没有任何输出说明不支持,需要换机型或降版本
二、安装 MongoDB
RHEL / CentOS / Rocky / AlmaLinux
官方仓库通过 yum/dnf 源配置。以 7.0 为例:
# 1. 添加官方仓库(RHEL 8/9、Rocky 8/9)
cat > /etc/yum.repos.d/mongodb-org-7.0.repo <<'EOF'
[mongodb-org-7.0]
name=MongoDB Repository
baseurl=https://repo.mongodb.org/yum/redhat/$releasever/mongodb-org/7.0/x86_64/
gpgcheck=1
enabled=1
gpgkey=https://pgp.mongodb.com/server-7.0.asc
EOF
# 2. 安装
dnf install -y mongodb-org
# CentOS 7 用 yum:yum install -y mongodb-org
# 3. 启动并设置开机自启
systemctl enable --now mongod
systemctl status mongod
Debian / Ubuntu
# 1. 导入官方 GPG key
curl -fsSL https://pgp.mongodb.com/server-7.0.asc | \
gpg -o /usr/share/keyrings/mongodb-server-7.0.gpg --dearmor
# 2. 添加源(Ubuntu 22.04 示例,其他版本替换 codename)
echo "deb [ arch=amd64 signed-by=/usr/share/keyrings/mongodb-server-7.0.gpg ] \
https://repo.mongodb.org/apt/ubuntu jammy/mongodb-org/7.0 multiverse" \
> /etc/apt/sources.list.d/mongodb-org-7.0.list
# 3. 安装
apt-get update
apt-get install -y mongodb-org
# 4. 启动
systemctl enable --now mongod
安装完成后,配置文件默认在 /etc/mongod.conf,数据目录默认是 /var/lib/mongo(RHEL 系)或 /var/lib/mongodb(Debian 系),日志在 /var/log/mongodb/mongod.log。这三个路径后面配置时都会用到。
验证是否起来了:
ss -tlnp | grep 27017 # 默认监听 27017
mongod --version # 查看版本
mongosh # 新版命令行客户端,连本机默认实例
# 老版本用 mongo 命令,MongoDB 6.0 起官方客户端叫 mongosh
三、mongod.conf 关键配置
/etc/mongod.conf 是 YAML 格式,缩进用空格,不要用 Tab,否则会启动失败。下面是最常改的几个块:
# 网络配置
net:
port: 27017
bindIp: 127.0.0.1 # 默认只监听本机,安全首选
# 存储配置
storage:
dbPath: /var/lib/mongo
journal:
enabled: true # 生产务必开启,保证崩溃后可恢复
# 日志
systemLog:
destination: file
logAppend: true
path: /var/log/mongodb/mongod.log
# 进程管理
processManagement:
fork: true # 用 systemd 管理时一般不需要,交给 systemd
timeZoneInfo: /usr/share/zoneinfo
# 安全(先别急着开,等建好用户再开,见下一节)
security:
authorization: disabled
几个必须讲清楚的项:
第一,bindIp 决定谁能连。默认 127.0.0.1 只允许本机,最安全。要提供内网服务可以写内网网卡 IP,比如 bindIp: 127.0.0.1,10.0.0.5,逗号分隔。不要为了方便直接写 0.0.0.0 暴露到公网,这是最典型的被入侵入口。
第二,dbPath 指向数据目录。如果单独挂了一块数据盘,把它改到数据盘上,例如 /data/mongodb。改之前要确保目录存在且属主是 mongod 用户:
mkdir -p /data/mongodb
chown -R mongod:mongod /data/mongodb
# 改完 dbPath 后重启,注意:改目录不会自动搬数据,新目录必须是空的或已放好旧数据
systemctl restart mongod
第三,journal 是预写日志,保证数据在崩溃后能恢复。生产环境一定要 enabled: true。关掉它也许能提升一点写入性能,但代价是断电后可能丢数据、甚至数据文件损坏——不要为了这点性能冒险。
改完配置后,重启前先验证语法:
mongod --config /etc/mongod.conf --configExpand none --fork=false 2>&1 | head
# 或直接重启并看日志
systemctl restart mongod
journalctl -u mongod -n 50 --no-pager
四、启用认证与创建用户
MongoDB 默认没有认证,"先建管理员、再开认证"是关键顺序,顺序错了会把自己锁在门外。
第一步,连上实例(此时还没开认证),创建管理员账号:
// 在 mongosh 中执行
use admin
db.createUser({
user: "admin",
pwd: passwordPrompt(), // 交互式输入密码,避免明文进 shell 历史
roles: [ { role: "userAdminAnyDatabase", db: "admin" },
{ role: "readWriteAnyDatabase", db: "admin" } ]
})
角色别乱给。userAdminAnyDatabase 能管理所有库的用户,readWriteAnyDatabase 能读写所有库。真正生产应该最小权限:管理员先只给 userAdminAnyDatabase 和 clusterAdmin 之类管理角色,业务账号按库、按读写范围单独建。
第二步,启用认证。编辑配置:
security:
authorization: enabled
然后重启:
systemctl restart mongod
重启后再连接就需要带账号了:
# 命令行方式
mongosh -u admin -p --authenticationDatabase admin
# 或连接字符串方式
mongosh "mongodb://admin@127.0.0.1:27017/?authSource=admin"
第三步,为业务库建专用用户和角色。MongoDB 的权限是"库 + 角色"模型,内置角色里常用的有 read、readWrite、dbAdmin、dbOwner:
use myapp
db.createUser({
user: "appuser",
pwd: passwordPrompt(),
roles: [ { role: "readWrite", db: "myapp" } ]
})
// 查看已有用户
db.getUsers()
// 查看某用户权限
db.getUser("appuser")
如果内置角色不够细,可以自定义角色:
use myapp
db.createRole({
role: "appReadOnly",
privileges: [{
resource: { db: "myapp", collection: "" },
actions: ["find"]
}],
roles: []
})
删除用户用 db.dropUser("appuser")。改了密码或权限后,已建立的连接不会自动生效,需要重连。
风险提示:在开启认证的实例上,如果你修改了某个用户、又把它的权限收窄了,务必确认还有一个具备管理权限的账号可用,否则一旦需要恢复会很麻烦。管理员密码务必离线保存一份。
五、远程访问与安全红线
很多人部署 MongoDB 就是为了让应用服务器远程连它。正确做法不是把 bindIp 改成 0.0.0.0 了事,而是分情况处理。
情况一:应用服务器与数据库在同一内网
这是最推荐的方式。把 bindIp 改成内网 IP 或同时监听本机和内网卡:
net:
bindIp: 127.0.0.1,10.0.0.5
然后在防火墙上只放行应用服务器的内网 IP 到 27017 端口。RHEL 系和 Debian 系的防火墙命令不同:
# RHEL / CentOS / Rocky:用 firewalld
firewall-cmd --permanent --add-rich-rule='rule family="ipv4" source address="10.0.0.20/32" port protocol="tcp" port="27017" accept'
firewall-cmd --reload
firewall-cmd --list-all
# Debian / Ubuntu:用 ufw
ufw allow from 10.0.0.20 to any port 27017 proto tcp
ufw status verbose
如果不用 firewalld/ufw,也可以用 iptables 直接限制来源:
iptables -A INPUT -p tcp -s 10.0.0.20 --dport 27017 -j ACCEPT
iptables -A INPUT -p tcp --dport 27017 -j DROP
情况二:必须跨公网连接
这是高风险场景,强烈建议先评估有没有替代方案。 如果实在避不开,底线是:
- 认证必须开(
authorization: enabled),并且用强密码,业务账号最小权限。 - 不要直接暴露 27017 到公网,优先走 VPN、专线、或者 SSH 隧道。
- 如果一定要开放,在云安全组/防火墙层面把来源限制到具体 IP,不要写
0.0.0.0/0。 - 定期检查用户列表和连接日志,发现陌生来源及时封禁。
SSH 隧道是跨公网相对安全的折中:数据在 SSH 加密通道里传,公网只暴露 22 端口。
# 在应用服务器上建立隧道:把本地 27018 转发到数据库服务器的 127.0.0.1:27017
ssh -N -L 27018:127.0.0.1:27017 user@dbserver-ip
# 应用连接 mongodb://appuser@127.0.0.1:27018/myapp?authSource=myapp
严重风险提示:把 MongoDB 的
bindIp设为0.0.0.0且未启用认证,等同于把数据库完全公开。公网上有大量自动化扫描程序,会在数小时内发现并清空你的数据、留下勒索信息。绝不要在公网 IP 上运行无认证、全监听的 MongoDB。 如果已经这样运行过,立即开启认证、限制来源、检查数据完整性,并检查是否有异常用户或可疑连接。
再补充两个安全项:一是禁用或限制 HTTP 接口(老版本有,新版本默认关闭);二是开启审计或至少保留日志,便于事后追查。云厂商的托管 MongoDB 通常提供了免运维的认证和网络隔离,如果团队运维能力有限,托管是值得考虑的选项。
六、副本集简述
单节点 MongoDB 没有冗余,机器一挂数据就不可用,也谈不上高可用。生产环境通常部署副本集(replica set):至少三个节点,一个主节点(primary)负责写,其余从节点(secondary)复制数据。
最小可用配置是三个节点(或者两个数据节点加一个仲裁节点 arbiter)。启动时每个节点带 --replSet 参数:
# 每个节点的 mongod.conf 增加
replication:
replSetName: rs0
然后连到其中一个节点初始化:
rs.initiate({
_id: "rs0",
members: [
{ _id: 0, host: "10.0.0.5:27017" },
{ _id: 1, host: "10.0.0.6:27017" },
{ _id: 2, host: "10.0.0.7:27017" }
]
})
// 查看状态
rs.status()
副本集带来两个额外好处:一是自动故障切换(主节点挂了,从节点选举出新主),二是读写分离(从节点可以承担读流量)。连接字符串也要相应调整:
mongosh "mongodb://appuser@10.0.0.5:27017,10.0.0.6:27017,10.0.0.7:27017/myapp?replicaSet=rs0&authSource=myapp"
副本集里每个节点都要单独建用户吗?不用——用户在副本集内是同步的,在主节点建一次即可。但要注意副本集内部的认证密钥(keyfile 或 x.509),用于节点之间互相验证身份,否则内部通信不安全。
七、日常运维与备份
几条日常命令:
# 看服务状态和日志
systemctl status mongod
tail -f /var/log/mongodb/mongod.log
# 查看数据库和占用
mongosh -u admin -p --authenticationDatabase admin --eval \
'db.adminCommand({listDatabases:1})'
# 逻辑备份(小数据量)
mongodump --uri="mongodb://appuser@127.0.0.1:27017/myapp?authSource=myapp" \
--out=/backup/mongo-$(date +%F)
# 恢复
mongorestore --uri="mongodb://appuser@127.0.0.1:27017/myapp?authSource=myapp" \
--dir=/backup/mongo-2026-10-12/myapp
# 副本集生产环境更推荐物理备份(文件系统快照或 mongodump 结合 oplog)
mongodump 适合中小数据量,数据量大时它会造成明显负载,且不是一致性快照(除非结合 --oplog)。生产环境更推荐基于存储快照的物理备份,或者使用云厂商的自动备份。无论哪种方式,必须定期做恢复演练,没验证过的备份等于没有备份。
常见问题
Q:装完启动失败,日志报 Illegal instruction,怎么办?
基本可以确定是 CPU 不支持 AVX。grep avx /proc/cpuinfo 确认后,换一台支持 AVX 的机器,或改用 4.4 系列版本。
Q:开了认证之后连不上了,怎么办?
先确认连接时带了 authSource(管理账号通常是 admin)。如果管理员密码也忘了,需要以 --noauth(旧版)或临时改回 authorization: disabled 启动来重置,操作前务必备份数据目录。
Q:bindIp 改了 0.0.0.0 但还是连不上?
检查三层:MongoDB 是否监听成功(ss -tlnp | grep 27017)、服务器防火墙是否放行(firewalld/ufw/iptables)、云厂商安全组是否放行。很多"连不上"其实是安全组没开。
Q:改 dbPath 后启动报权限错误?
新目录属主必须是 mongod:mongod,且 SELinux 开启时还需要正确的安全上下文。可以用 chcon -R -t mongod_var_lib_t /data/mongodb 或 semanage fcontext 处理,RHEL 系尤其常见。
Q:单节点够用吗?
开发和测试够用。生产要可用性和数据安全,副本集是基本要求,单节点只能靠频繁备份兜底,恢复期间业务是中断的。
总结
- 生产环境用官方仓库安装,注意 5.0+ 需要 CPU 支持 AVX,否则启动会失败。
mongod.conf里bindIp默认只监听本机最安全,务必开journal,改dbPath要处理目录属主和 SELinux。- 正确顺序是"先建管理员用户,再开
authorization: enabled",业务账号按库按最小权限创建。 - 远程访问优先走内网 + 防火墙白名单,跨公网优先用 SSH 隧道/VPN,绝不要在公网跑无认证、0.0.0.0 监听的实例。
- 生产必须有副本集和经过演练的备份,单节点只适合开发测试。
企业QQ咨询




