ale*_*ini 19 http nginx https lighttpd
我想知道 nginx 是否能够在同一个端口上处理 http 和 https 请求。[*]
这就是我想要做的。我正在运行处理 http 请求的 Web 服务器 (lighttpd),以及通过 https 为文档树的特定部分提供服务的 C 程序。这两个进程运行在同一台服务器上。
在防火墙级别,我只能有一个端口将流量转发到此服务器。所以我想做的是在这台服务器上设置 nginx 以便它侦听单个端口上的请求,然后:
A) 重定向所有http://myhost.com/*请求,以便它们转到 localhost:8080(lighttpd 正在侦听的位置)
B) 如果用户请求以 https://myhost.com/app 开头的 URL,它会将该请求发送到 localhost:8008(C 程序)。请注意,在这种情况下,远程浏览器和 nginx 之间的流量必须加密。
你认为这可能吗?如果是,怎么做?
我知道如何使用两个不同的端口来做到这一点。我面临的挑战是仅使用一个端口来完成此操作(不幸的是,我无法控制此特定环境中的防火墙配置,因此这是我无法避免的限制)。使用诸如通过 ssh 进行反向端口转发来绕过防火墙的技术也不起作用,因为这应该适用于只有 Web 浏览器和 Internet 链接的远程用户。
如果这超出了 nginx 的能力,您知道还有其他产品可以满足此要求吗?(到目前为止,我在使用 lighttpd 和 pound 进行设置时没有成功)。我也更喜欢避免使用 Apache(尽管如果这是唯一可能的选择,我愿意使用它)。
提前致谢,亚历克斯
[*] 为了清楚起见,我说的是通过同一端口处理加密和未加密的 HTTP 连接。加密是通过 SSL 还是 TLS 完成都没有关系。
小智 21
根据维基百科关于状态代码的文章,当 http 流量发送到 https 端口时,Nginx 有一个自定义错误代码(错误代码 497)
根据error_page上的nginx 文档,您可以定义一个 URI,该 URI 将针对特定错误显示。
因此,我们可以创建一个 uri,当出现错误代码 497 时,客户端将被发送到该 uri。
#lets assume your IP address is 89.89.89.89 and also that you want nginx to listen on port 7000 and your app is running on port 3000
server {
listen 7000 ssl;
ssl_certificate /path/to/ssl_certificate.cer;
ssl_certificate_key /path/to/ssl_certificate_key.key;
ssl_client_certificate /path/to/ssl_client_certificate.cer;
error_page 497 301 =307 https://89.89.89.89:7000$request_uri;
location / {
proxy_pass http://89.89.89.89:3000/;
proxy_pass_header Server;
proxy_set_header Host $http_host;
proxy_redirect off;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-Protocol $scheme;
}
}
Run Code Online (Sandbox Code Playgroud)
但是,如果客户端通过 GET 以外的任何其他方法发出请求,则该请求将转换为 GET。从而保留客户端通过的请求方法;我们使用错误处理重定向,如error_page 上的 nginx 文档中所示
这就是我们使用301 =307
重定向的原因。
使用此处显示的 nginx.conf 文件,我们可以让 http 和 https 侦听同一端口
小智 18
对于那些可能正在搜索的人:
添加ssl on;
和error_page 497 $request_uri;
到您的服务器定义。
从 1.15.2 开始,这终于可以正确执行了。请参阅此处的信息。
在你的 nginx.conf 中添加一个这样的块(在 http 块之外):
stream {
upstream http {
server localhost:8000;
}
upstream https {
server localhost:8001;
}
map $ssl_preread_protocol $upstream {
default https;
"" http;
}
server {
listen 8080;
listen [::]:8080;
proxy_pass $upstream;
ssl_preread on;
}
}
Run Code Online (Sandbox Code Playgroud)
然后你可以创建你的普通服务器块,但是监听这些不同的端口:
server {
listen 8000;
listen [::]:8000;
listen 8001 ssl;
listen [::]:8001 ssl;
...
Run Code Online (Sandbox Code Playgroud)
这样,流块能够预读并检测它是否是 TLS(在本例中在端口 8080 上),然后代理将其传递到本地正确的服务器端口。
我认为没有任何东西可以在单个端口上处理两种不同的协议......
我很好奇为什么你只能转发一个端口,但除此之外......这并不理想,但如果我处于你的位置,我会通过 https 提供所有服务。
归档时间: |
|
查看次数: |
27325 次 |
最近记录: |