[英]How to use nginx to direct traffic to two different ports on the same device?
I am currently working on a FPV robotics project that has two servers, flask/werkzeug and streamserver, serving http traffic and streaming video to an external web server, located on a different machine.我目前正在从事一个 FPV 机器人项目,该项目有两台服务器,flask/werkzeug 和 streamserver,为 http 流量和流式视频提供服务,并将视频流式传输到位于另一台机器上的外部 web 服务器。
The way it is currently configured is like this:目前的配置方式是这样的:
I want to place them behind a https reverse proxy so that I can connect to this via https://example.com where "example.com" is set to 1.2.3.4 in my external system's hosts file.我想将它们放在 https 反向代理后面,以便我可以通过https://example.com连接到它,其中“example.com”在我的外部系统主机文件 2 中设置为 1。
I would like to:我想:
. . . . . . such that the "external" connection (to ports 5000 and 5001 are both secure connections as far as the outside world is concerned, such that:这样“外部”连接(就外部世界而言,到端口 5000 和 5001 都是安全连接,例如:
[external system]-https://example.com:5000/5001----nginx----https://example.com:5000
\---http://example.com:5001
http://example.com:5000 or 5001 redirects to https.
All of the literature I have seen so far talks about:到目前为止,我看到的所有文献都在谈论:
My application is just an every-day plain vanilla server type configuration, and the only reason I am even messing with https is because of the really annoying problems with things not working except in a secure context which prevents me from completing my project.我的应用程序只是一个日常普通的普通服务器类型配置,而我什至弄乱 https 的唯一原因是因为除了在安全上下文中无法完成我的项目之外,事情无法正常工作的真正烦人的问题。
I am sure this is possible, but the literature is either hideously confusing or appears to talk to a different use case.我确信这是可能的,但文献要么令人困惑,要么似乎在谈论不同的用例。
A reference to a simple how-to would be the most usefull choice.参考简单的操作方法将是最有用的选择。 Clear and unambiguous steps would also be appreciated.清晰明确的步骤也将受到赞赏。
Thanks in advance for any help you can provide.提前感谢您提供的任何帮助。
This minimal config should provide public endpoints:这个最小配置应该提供公共端点:
http://example.com/* => https://example.com/*
https://example.com/stream => http://1.2.3.4:5001/
https://example.com/* => https://1.2.3.4:5000/
# redirect to HTTPS
server {
listen 80;
listen [::]:80;
server_name example.com
www.example.com;
return 301 https://example.com$request_uri;
}
server {
listen 443 ssl http2;
listen [::]:443 ssl http2;
server_name example.com
www.example.com;
ssl_certificate /etc/nginx/ssl/server.cer;
ssl_certificate_key /etc/nginx/ssl/server.key;
location /stream {
proxy_pass http://1.2.3.4:5001/; # HTTP
}
# fallback location
location / {
proxy_pass https://1.2.3.4:5000/; # HTTPS
}
}
First, credit where credit is due: @AnthumChris's answer is essentially correct.首先,应得的信用:@AnthumChris 的回答基本上是正确的。
After considerable additional research, I discovered the following:经过大量的额外研究,我发现了以下内容:
There is actually too much information online, most of which is contradictory, possibly wrong, and unnecessarily complicated.网上的信息其实太多了,大部分都是自相矛盾的,可能是错误的,不必要的复杂。
Installing nginx:安装 nginx:
Configuring the systems using nginx and connecting to it:使用 nginx 配置系统并连接到它:
Note: This is a special case unique to my use-case as this is running on a stand-alone robot for development purposes and my domain is not a "live" domain on a web-facing server.注意:这是我的用例独有的特殊情况,因为它在独立机器人上运行以用于开发目的,并且我的域不是面向 Web 的服务器上的“实时”域。 It is a "real" domain with a "real" and trusted certificate to avoid browser warnings while development progresses.它是一个“真实”域,具有“真实”和受信任的证书,以避免在开发过程中出现浏览器警告。
Configuring nginx:配置 nginx:
/etc/nginx/sites-enabled
放置配置文件的正确位置(在树莓派上)是/etc/nginx/sites-enabled
nginx -T
is your friend. nginx -T
是你的朋友。 You can use this to "test" your configuration for problems before you try to start it.您可以在尝试启动之前使用它来“测试”您的配置是否存在问题。sudo systemctl restart nginx
will attempt to restart nginx, (which as you begin configuration, will likely fail.) sudo systemctl restart nginx
将尝试重新启动 nginx,(在您开始配置时,可能会失败。)sudo systemctl status nginx.service >./[path]/log.txt 2>&1
is also your friend. sudo systemctl status nginx.service >./[path]/log.txt 2>&1
也是你的朋友。 This allows you to collect error messages at runtime that will prevent the service from starting.这允许您在运行时收集将阻止服务启动的错误消息。 In my case, the majority of the problems were caused by other services using ports I had selected, or silly mis-configurations.就我而言,大多数问题是由使用我选择的端口的其他服务或愚蠢的错误配置引起的。sudo netstat -tulpn | grep nginx
启动 nginx 并且状态返回没有问题后,请尝试sudo netstat -tulpn | grep nginx
sudo netstat -tulpn | grep nginx
to make sure it's listening on the correct ports. sudo netstat -tulpn | grep nginx
以确保它正在侦听正确的端口。Troubleshooting nginx after you have it running: nginx 运行后故障排除:
SSL certificates: SSL 证书:
cat mycert.crt bundle.file > combined.crt
to create it.与其他 SSL 服务器不同,nginx 需要使用cat mycert.crt bundle.file > combined.crt
将站点证书与从证书颁发机构收到的中间证书捆绑包结合起来创建它。Ultimately I ended up with the following configuration file:最终我得到了以下配置文件:
#server {
# listen example.com:80;
# server_name example.com;
# return 301 https://example.com$request_uri;
# }
# This is the "web" server (command and control), running Flask/Werkzeug
# that must be passed through as a secure connection so that the
# joystick/gamepad works.
#
# Note that the internal Flask server must be configured to use a
# secure connection too. (Actually, that may not be true, but that's
# how I set it up. . .)
#
server {
listen example.com:443 ssl;
server_name example.com;
ssl_certificate /usr/local/share/ca-certificates/extra/combined.crt;
ssl_certificate_key /usr/local/share/ca-certificates/extra/example.com.key;
ssl_prefer_server_ciphers on;
location / {
proxy_pass https://example.com:5000;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
}
# This is the video streaming port/server running streamserver
# which is not, and cannot be, secured. However, since most
# modern browsers will not mix insecure and secure content on
# the same page, the outward facing connection must be secure.
#
server {
listen example.com:5001 ssl;
server_name example.com;
ssl_certificate /usr/local/share/ca-certificates/extra/combined.crt;
ssl_certificate_key /usr/local/share/ca-certificates/extra/www.example.com.key;
ssl_prefer_server_ciphers on;
# After securing the outward facing connection, pass it through
# as an insecure connection so streamserver doesn't barf.
location / {
proxy_pass http://example.com:5002;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.