如何在 Nginx 反向代理后面设置 MongoDB
How to setup MongoDB behind Nginx Reverse Proxy
我正在尝试将 Nginx 设置为访问 MongoDB 数据库的反向代理。默认情况下 Mongo 监听 27017 端口。我想要做的是通过 nginx 重定向一个主机名,例如 mongodb.mysite.com 并将其传递给 mongodb 服务器。通过这种方式,我将从外部网络关闭已知的 27017 端口,并从隐藏的 url 访问我的数据库,就像我给出的示例一样。
所以我正在尝试使用此配置设置 Nginx :
server {
listen 80;
server_name mongo.mysite.com;
gzip off;
location / {
proxy_pass http://127.0.0.1:27017;
proxy_redirect off;
proxy_buffering off;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
}
}
因此,在完成此操作后,我尝试使用命令 mongo mongo.mysite.com:80
从我的 cmd 连接 mongo shell,然后返回以下错误:
2015-08-06T13:44:32.670+0300 I NETWORK recv(): message len 1347703880 is invalid. Min 16 Max: 48000000
2015-08-06T13:44:32.670+0300 I NETWORK DBClientCursor::init call() failed
2015-08-06T13:44:32.674+0300 E QUERY Error: DBClientBase::findN: transport error: mongo.therminate.com:80 ns: admin.$cmd query: { whatsmyuri: 1 }
at connect (src/mongo/shell/mongo.js:181:14)
at (connect):1:6 at src/mongo/shell/mongo.js:181
exception: connect failed
同样在 Nginx 访问日志中我得到了这个:
94.66.184.128 - - [06/Aug/2015:10:44:32 +0000] "<\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xD4\x07\x00\x00\x00\x00\x00\x00admin.$cmd\x00\x00\x00\x00\x00\x01\x00\x00\x00\x15\x00\x00\x00\x10whatsmyuri\x00\x01\x00\x00\x00\x00" 400 172 "-" "-"
有没有人知道这里出了什么问题?谢谢!
如果您通过通常的默认 ip 值连接到 mongodb 的本地实例,它应该连接:mongo 10.8.8.10
问题在于通过 mongodb shell 解析地址,但这并没有发生。
我把它抛在脑后,但在完成一些工作后,我不得不再次面对这个问题,这次我想到了解决方案!
NGINX 基本上是一个 HTTP 服务器,所以通过上述方式设置重定向和代理,它将所有通信包装在 HTTP 协议中。所以发生的错误是,虽然 Mongo 期待原始 TCP 流量,但它正在获取 HTTP 流量。
因此解决方案是使用 NGINX 的新 stream module
用于处理原始 TCP 流量并将上游服务器设置为指向 mongodb 实例。
更多信息:NGINX stream module
你说得对,你需要通过在 .conf 文件中添加一个流部分来使用 NGINX 的流模块:
stream {
server {
listen <your incoming Mongo TCP port>;
proxy_connect_timeout 1s;
proxy_timeout 3s;
proxy_pass stream_mongo_backend;
}
upstream stream_mongo_backend {
server <localhost:your local Mongo TCP port>;
}
}
添加到@Néstor 的回答中,此配置应写入 /etc/nginx/nginx.conf
正上方 http
部分,如下所示:
stream {
server {
listen <your incoming Mongo TCP port>;
proxy_connect_timeout 1s;
proxy_timeout 3s;
proxy_pass stream_mongo_backend;
}
upstream stream_mongo_backend {
server <localhost:your local Mongo TCP port>;
}
}
http {
...
}
您应该永远将其写入.conf
文件并将文件放入/etc/nginx/sites-available
文件夹。因为 /etc/nginx/sites-available
文件夹中的任何配置信息都属于 http
部分。
我想再分享一个小贴士。我只是配置了 mongodb 的 nginx ssl 支持。它应该更安全。您可以看到如下配置:
stream {
server {
listen <your incoming port> ssl so_keepalive=on;
ssl_certificate <your path to certificate>;
ssl_certificate_key <your path to private key>;
proxy_connect_timeout 2s;
proxy_pass stream_mongo_backend;
proxy_timeout 10m;
}
upstream stream_mongo_backend {
server 127.0.0.1:<your mongodb port>;
}
}
我用 python 代码测试了访问 mongodb 的方法:
mng_client = pymongo.MongoClient('mongodb://<your username>:<your password>@<ipaddress or domain name>:<your incoming port as defined above>/?tls=true')
我正在尝试将 Nginx 设置为访问 MongoDB 数据库的反向代理。默认情况下 Mongo 监听 27017 端口。我想要做的是通过 nginx 重定向一个主机名,例如 mongodb.mysite.com 并将其传递给 mongodb 服务器。通过这种方式,我将从外部网络关闭已知的 27017 端口,并从隐藏的 url 访问我的数据库,就像我给出的示例一样。
所以我正在尝试使用此配置设置 Nginx :
server {
listen 80;
server_name mongo.mysite.com;
gzip off;
location / {
proxy_pass http://127.0.0.1:27017;
proxy_redirect off;
proxy_buffering off;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
}
}
因此,在完成此操作后,我尝试使用命令 mongo mongo.mysite.com:80
从我的 cmd 连接 mongo shell,然后返回以下错误:
2015-08-06T13:44:32.670+0300 I NETWORK recv(): message len 1347703880 is invalid. Min 16 Max: 48000000
2015-08-06T13:44:32.670+0300 I NETWORK DBClientCursor::init call() failed
2015-08-06T13:44:32.674+0300 E QUERY Error: DBClientBase::findN: transport error: mongo.therminate.com:80 ns: admin.$cmd query: { whatsmyuri: 1 }
at connect (src/mongo/shell/mongo.js:181:14)
at (connect):1:6 at src/mongo/shell/mongo.js:181
exception: connect failed
同样在 Nginx 访问日志中我得到了这个:
94.66.184.128 - - [06/Aug/2015:10:44:32 +0000] "<\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xD4\x07\x00\x00\x00\x00\x00\x00admin.$cmd\x00\x00\x00\x00\x00\x01\x00\x00\x00\x15\x00\x00\x00\x10whatsmyuri\x00\x01\x00\x00\x00\x00" 400 172 "-" "-"
有没有人知道这里出了什么问题?谢谢!
如果您通过通常的默认 ip 值连接到 mongodb 的本地实例,它应该连接:mongo 10.8.8.10
问题在于通过 mongodb shell 解析地址,但这并没有发生。
我把它抛在脑后,但在完成一些工作后,我不得不再次面对这个问题,这次我想到了解决方案!
NGINX 基本上是一个 HTTP 服务器,所以通过上述方式设置重定向和代理,它将所有通信包装在 HTTP 协议中。所以发生的错误是,虽然 Mongo 期待原始 TCP 流量,但它正在获取 HTTP 流量。
因此解决方案是使用 NGINX 的新 stream module
用于处理原始 TCP 流量并将上游服务器设置为指向 mongodb 实例。
更多信息:NGINX stream module
你说得对,你需要通过在 .conf 文件中添加一个流部分来使用 NGINX 的流模块:
stream {
server {
listen <your incoming Mongo TCP port>;
proxy_connect_timeout 1s;
proxy_timeout 3s;
proxy_pass stream_mongo_backend;
}
upstream stream_mongo_backend {
server <localhost:your local Mongo TCP port>;
}
}
添加到@Néstor 的回答中,此配置应写入 /etc/nginx/nginx.conf
正上方 http
部分,如下所示:
stream {
server {
listen <your incoming Mongo TCP port>;
proxy_connect_timeout 1s;
proxy_timeout 3s;
proxy_pass stream_mongo_backend;
}
upstream stream_mongo_backend {
server <localhost:your local Mongo TCP port>;
}
}
http {
...
}
您应该永远将其写入.conf
文件并将文件放入/etc/nginx/sites-available
文件夹。因为 /etc/nginx/sites-available
文件夹中的任何配置信息都属于 http
部分。
我想再分享一个小贴士。我只是配置了 mongodb 的 nginx ssl 支持。它应该更安全。您可以看到如下配置:
stream {
server {
listen <your incoming port> ssl so_keepalive=on;
ssl_certificate <your path to certificate>;
ssl_certificate_key <your path to private key>;
proxy_connect_timeout 2s;
proxy_pass stream_mongo_backend;
proxy_timeout 10m;
}
upstream stream_mongo_backend {
server 127.0.0.1:<your mongodb port>;
}
}
我用 python 代码测试了访问 mongodb 的方法:
mng_client = pymongo.MongoClient('mongodb://<your username>:<your password>@<ipaddress or domain name>:<your incoming port as defined above>/?tls=true')