nodejs app可以在nginx反向代理后面的端口3000上访问

时间:2016-02-18 11:07:34

标签: node.js ssl nginx proxy

我正在运行一个nodejs应用程序,其中nodejs app是一个侦听端口3000的服务器。我使用nginx作为反向代理,它也处理ssl。下面列出了配置(在阅读几篇教程和论坛帖子之后,我觉得这很标准)。一切都按预期工作,除了我仍然能够访问“http://example.com:3000”下的应用程序。这是否意味着我需要添加另一台服务器侦听端口3000以重定向到https?这可能意味着我到目前为止阅读的教程有点不完整或者我忽略了一些基本的东西。任何人都可以帮我弄清楚它是什么吗?

 # app server upstream

upstream app {
    server 127.0.0.1:3000;
}

# default http server. Redirect to https server

server {
    listen 80;
    server_name www.example.com example.com;
    return 301 https://example.com$request_uri;  
}

# https server

server {
    listen 443;
    server_name www.example.com example.com;

    ssl on;
    ssl_certificate ssl.crt;
    ssl_certificate_key ssl.key;

    ssl_session_timeout 5m;

    ssl_protocols SSLv3 TLSv1 TLSv1.1 TLSv1.2;
    ssl_ciphers "HIGH:!aNULL:!MD5 or HIGH:!aNULL:!MD5:!3DES";
    ssl_prefer_server_ciphers on;

    location / {
        proxy_pass http://app;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection 'upgrade';
        proxy_set_header Host $host;
        proxy_cache_bypass $http_upgrade;   
    }
}   

2 个答案:

答案 0 :(得分:1)

如果您可以从计算机外部访问端口3000,则意味着您以HTTP服务器正在侦听所有接口的方式对Node.js应用程序进行编程。这本身并不错,默认情况下,您应该以这种方式编写应用程序,因为您无法预测最终部署拓扑的未来变化。按照Oxi的建议,将端口从外部世界隐藏到防火墙(这里有iptables)。

这样,您就不需要在将来更改代码,以使其适应不同的部署拓扑。

例如,我有一个类似的案例。我使用Haproxy作为负载均衡器和SSL终止。但在我的情况下,Haproxy实例在不同的主机上运行以考虑性能。如果在开发阶段我限制我的应用程序只监听本地连接,那么我将不得不在开发时更新我的​​代码,以适应新的拓扑。

我希望这会对你有所帮助。

答案 1 :(得分:0)

配置Nginx绑定到运行Node的端口将引发错误:

$ nginx: [emerg] bind() to 0.0.0.0:3000 failed (98: Address already in use)

这是因为多个服务无法绑定同一端口。哪个负责处理该请求?

您可以改为绑定您的节点脚本来侦听特定的IP地址。如果将节点脚本绑定到本地接口IP(127.0.0.1)而不是所有IP,则可以有效地阻止Node在Node端口(例如3000)上接受外部连接。

您可能已经在做类似的事情,

const server = app.listen(port)

改为尝试

const server = app.listen(port, '127.0.0.1')

我正在将此解决方案与Nginx作为代理在端口443上运行一起使用。Nginx仍然可以连接到Node服务,同时阻止它接受来自外部请求的连接;有效地阻止了http://example.com:3000

上的请求

您还可以使用iptables解决此问题。

使用iptables,您有两种方法:阻止所有内容,然后仅打开内部接口。您也可以重定向请求,例如。从3000到443(或80),这是一个有趣的想法。

我还没有亲自测试过这些,所以请考虑一下理论上的例子。也许有人有一个可靠的例子?

iptables -A INPUT -p tcp --dport 3000 -j DROP
iptables -A INPUT -s 127.0.0.1 -p tcp --dport 3000 -j ACCEPT

OR

iptables -A OUTPUT -o lo -p tcp -m tcp --dport 3000 -j REDIRECT --to-ports 443