如何将端口80上的非HTTP请求转发到另一个端口?

有一个监听80和443端口的nginx web服务器。 我想像往常一样处理所有的http请求,并将所有非http请求转发到另一个端口(比如1234)。

我的问题是非常相似的已经在stackoverflow上回答: 是否有可能转发NON-http连接请求到Nginx的其他端口? 。 也许,我误解了最广泛的答案,但是当我在nginx.conf中添加这样的内容时:

stream { upstream backend { server example.com:1234; } server { listen 80; proxy_pass backend; } } 

我得到(预期) bind() to 0.0.0.0:80 failed (98: Address already in use)错误。

nginx只能同时向一个端口提供一种服务。

所以,这个configuration将工作:

 http { server { listen 80; server_name example.com; ... } } stream { server { listen 81; proxy_pass backend; } upstream backend { server 127.0.0.1:12345; } } 

您不能在streamhttp块上使用相同的端口,因为nginx无法区分stream量types。

正如@AlexeyTen在他的评论中提到的那样, sslh是达到这个目的的正确工具。 它内置了对HTTP,SSL,SSH,OpenVPN,tinc和XMPP协议的支持,还支持定制的正则expression式testing。

例如,要使sslh将http请求转发给nginx,而将非http请求转发给ejabberd,则足以replace所有nginx的虚拟主机

  listen 80; 

  listen 127.0.0.1:88; 

也可以使用listen 127.0.0.1:80如果sslh仅在特定ip上侦听端口80,或者使用例如listen 88 ),则安装sslh并编辑其默认选项:

 RUN=yes DAEMON_OPTS="--numeric --user sslh --listen 0.0.0.0:80 --http 127.0.0.1:88 --xmpp 127.0.0.1:5222 --pidfile /var/run/sslh/sslh.pid" 

(debian中的/etc/default/sslh )。 最后,(重新)启动服务:

 systemctl restart nginx systemctl start sslh 

如果需要--transparent选项,那么会有一些额外的步骤 – 它们在github上有很好的logging。