最近我按照这些教程创建了一个预装了 MongoDB 的服务器
这是我第一次这样做。今天我收到了来自 DigitalOcean 的邮件:
最近的网络安全扫描表明您的 Droplet
是 运行一个 MongoDB 实例并且它可能无意中暴露 数据,或配置错误以允许未经授权的访问。 MongoDB 监听 对于端口 27107 上来自任何地方的流量,您可以验证这一点 通过尝试连接到您的 MongoDB 实例来报告 简单的 telnet 命令:droplet-name
如果连接成功,您将收到如下输出,这将确认您的服务对公共 Internet 可见telnet xxx.xxx.xx.xx 27107
Trying xxx.xxx.xx.xx... Connected to xxx.xxx.xx.xx.
修复此问题仅需几分钟,并且 相对简单。您将需要打开 mongodb 实例并 运行以下命令添加您要连接的 IP:
sudo mongod --bind_ip localhost, ip-or-Associated-Hostname-you-connect-from
连接到我的服务器后,我尝试了
sudo mongod --bind_ip localhost
和sudo mongod --bind_ip xxx.xxx.xx.xx
命令(xxx.xxx.xx.xx是我的服务器IP,我必须输入ssh [email protected]
命令才能连接到我的服务器),但是他们没用,他们把我扔了
I CONTROL [main] Automatically disabling TLS 1.0, to force-enable TLS 1.0 specify --sslDisabledProtocols 'none'
I CONTROL [initandlisten] MongoDB starting : pid=16339 port=27017 dbpath=/data/db 64-bit host=host-name
I CONTROL [initandlisten] db version v4.0.3
I CONTROL [initandlisten] git version: xxxxxxxxxxxxxxxxxxxxx
I CONTROL [initandlisten] OpenSSL version: OpenSSL 1.1.1 11 Sep 2018
I CONTROL [initandlisten] allocator: tcmalloc
I CONTROL [initandlisten] modules: none
I CONTROL [initandlisten] build environment:
I CONTROL [initandlisten] distmod: ubuntu1804
I CONTROL [initandlisten] distarch: x86_64
I CONTROL [initandlisten] target_arch: x86_64
I CONTROL [initandlisten] options: { net: { bindIp: "localhost" } }
E STORAGE [initandlisten] Failed to set up listener: SocketException: Address already in use
I CONTROL [initandlisten] now exiting
I CONTROL [initandlisten] shutting down with code:48
所以我记得我的
mongod.conf
是:
net:
port: 27017
bindIp: 0.0.0.0
security:
authorization: enabled
我将
0.0.0.0
更改为 localhost,xxx.xxx.xx.xx
,现在当我尝试连接 telnet xxx.xxx.xx.xx 27017
时(我之前没有尝试使用此命令来检查连接是否成功,我的错)我收到了
Connecting To xxx.xxx.xx.xx...Could not open connection to the host, on port 27017: Connect failed
我猜我的服务对公共互联网不可见(如果我再次设置
bindIp: 0.0.0.0
我得到相同的输出)
但我注意到 DigitalOcean 电子邮件 telnet 命令说
27107
,我的所有设置(和 DigitalOcean 文档)都基于端口27017
。邮箱端口错误?如果我输入 telnet xxx.xxx.xx.xx 27017
,输出为 Trying xxx.xxx.xx.xx...
,然后控制台被完全清理(甚至提示),标题栏变为 Telnet xxx.xxx.xx.xx
。如果我按下一个键,什么也没有发生,但是在多次按下任意键后,控制台会恢复到开始时的状态。不知道连接成功没有。
如果我以 root 身份检查
ufw status
,输出是
To Action From
-- ------ ----
22/tcp LIMIT Anywhere
80/tcp ALLOW Anywhere
443/tcp ALLOW Anywhere
27017 ALLOW Anywhere
OpenSSH ALLOW Anywhere
22/tcp (v6) LIMIT Anywhere (v6)
80/tcp (v6) ALLOW Anywhere (v6)
443/tcp (v6) ALLOW Anywhere (v6)
27017 (v6) ALLOW Anywhere (v6)
OpenSSH (v6) ALLOW Anywhere (v6)
我觉得这样不好。 如果我尝试使用
mongoose
和 mongodb://xxx.xxx.xx.xx:27017
在我的机器上运行的 Nodejs 应用程序上连接到 mongo,则连接成功,但是当我尝试创建一个新文档时,它会抛出 MongoServerError: command insert requires authentication
看起来不错但我不确定。
我做错了什么?我只想允许从我的电脑和我的 Nodejs 应用程序连接到 Mongo,通过 App Platform 部署在 DigitalOcean 上(App Platform 应用程序没有静态 IP 地址)
提前致谢
DigitalOcean 的建议不是很聪明。没有理由以
root身份运行
mongod
。通过运行 sudo mongod ...
,您将忽略 mongod.conf
中的设置,这可能很糟糕。从日志消息来看,您似乎在 mongod
服务已在运行时尝试启动 mongod
。您只能运行一次mongod
(使用相同的端口和/或dbPath
)。
现在,关于你的实际问题:
当您设置
net.bindIp: localhost
(或--bind_ip localhost
)时,mongod
服务只暴露给本地机器,即您不能从任何外部机器连接到MongoDB。此设置通常用于维护工作或仅从本地安装的应用程序访问您的 MongoDB 时 - 这似乎是您的情况。
当您设置
net.bindIpAll: true
或net.bindIp: 0.0.0.0
(或根据命令行选项)时,mongod
服务将暴露给外部网络,即您可以从外部机器连接到您的MongoDB——前提是防火墙设置允许访问.
设置
net.bindIp: xxx.xxx.xx.xx
或多或少相同,实际上只有当您的计算机有多个网络接口时才有用。
您启用了身份验证,这很好。但是,则还必须使用用户名/密码 *),在连接字符串中或使用db.auth().
注意,您可以(几乎)always connect 到 MongoDB 而无需用户名/密码。但是,除非您经过身份验证,否则您只能执行无害的命令,如
db.help()
、db.version()
、db.listCommands()
等。对于其他命令,您会看到错误command ... requires authentication
。
*) MongoDB 还通过 x.509 证书、LDAP 或 Kerberos 提供身份验证。