繁体   English   中英

如何使用 nginx 将流量引导到同一设备上的两个不同端口?

[英]How to use nginx to direct traffic to two different ports on the same device?

我目前正在从事一个 FPV 机器人项目,该项目有两台服务器,flask/werkzeug 和 streamserver,为 http 流量和流式视频提供服务,并将视频流式传输到位于另一台机器上的外部 web 服务器。

目前的配置方式是这样的:

我想将它们放在 https 反向代理后面,以便我可以通过https://example.com连接到它,其中“example.com”在我的外部系统主机文件 2 中设置为 1。

我想:

  • 将流量传递到 1.2.3.4:5000 的内部连接作为安全连接。 (某些服务,如游戏手柄,除非是安全连接,否则将无法工作。)
  • 将流量作为内部纯文本连接传递到 1.2.3.4:5001,因为“streamserver”不支持 HTTPS 连接。

. . . 这样“外部”连接(就外部世界而言,到端口 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.

到目前为止,我看到的所有文献都在谈论:

  • 路由/负载平衡到不同的物理服务器。
  • 在 Kubernates 和/或 Docker 容器中做所有事情。

我的应用程序只是一个日常普通的普通服务器类型配置,而我什至弄乱 https 的唯一原因是因为除了在安全上下文中无法完成我的项目之外,事情无法正常工作的真正烦人的问题。

我确信这是可能的,但文献要么令人困惑,要么似乎在谈论不同的用例。

参考简单的操作方法将是最有用的选择。 清晰明确的步骤也将受到赞赏。

提前感谢您提供的任何帮助。

这个最小配置应该提供公共端点:

  1. http://example.com/* => https://example.com/*
  2. https://example.com/stream => http://1.2.3.4:5001/
  3. 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
  }
}

首先,应得的信用:@AnthumChris 的回答基本上是正确的。

经过大量的额外研究,我发现了以下内容:

  1. 网上的信息其实太多了,大部分都是自相矛盾的,可能是错误的,不必要的复杂。

    • 无需编辑 nginx.conf 文件。 事实上,这可能是个坏主意。
    • nginx 的当前开源版本可以用作反向代理,尽管 nginx 网站上的评论说您需要 Pro 版本。&nbsp 截至目前,Raspberry Pi 的当前版本是 1.14。
    • 在整理大量信息后,我发现为多个后端设备/服务器实例设置反向代理非常简单 比您相信的在线文档要简单得多。

  2. 安装 nginx:

    • 第一次安装nginx时会报安装失败 这是一个虚假的警告 您收到此警告是因为安装过程尝试启动 nginx 服务并且还没有有效的配置 - 因此服务启动失败,但安装(可能)正确且正确。

  3. 使用 nginx 配置系统并连接到它:

    注意:这是我的用例独有的特殊情况,因为它在独立机器人上运行以用于开发目的,并且我的域不是面向 Web 的服务器上的“实时”域 它是一个“真实”域,具有“真实”和受信任的证书,以避免在开发过程中出现浏览器警告。

    • 我必须在机器人和远程系统的 HOSTS 文件中输入条目,以自动将对我的域的引用重定向到正确的设备(机器人的固定 IP 地址),而不是停放域的 directnic 服务器。

  4. 配置 nginx:

    • 放置配置文件的正确位置(在树莓派上)是/etc/nginx/sites-enabled
    • 将其命名为 nginx.conf 并不重要,它会盲目地导入该目录中的任何内容。 另一方面,如果该目录中已有任何内容,则应将其删除或用前导点重命名。
    • nginx -T是你的朋友。 您可以在尝试启动之前使用它来“测试”您的配置是否存在问题。
    • sudo systemctl restart nginx将尝试重新启动 nginx,(在您开始配置时,可能会失败。)
    • sudo systemctl status nginx.service >./[path]/log.txt 2>&1也是你的朋友。 这允许您在运行时收集将阻止服务启动的错误消息。 就我而言,大多数问题是由使用我选择的端口的其他服务或愚蠢的错误配置引起的。
    • 启动 nginx 并且状态返回没有问题后,请尝试sudo netstat -tulpn | grep nginx sudo netstat -tulpn | grep nginx以确保它正在侦听正确的端口。

  5. nginx 运行后故障排除:

    • 大多数浏览器(至少是 Firefox 和 Chrome)都支持您通过按 F-12 进入的“开发者模式”。 控制台消息非常有用。

  6. SSL 证书:

    • 与其他 SSL 服务器不同,nginx 需要使用cat mycert.crt bundle.file > combined.crt将站点证书与从证书颁发机构收到的中间证书捆绑包结合起来创建它。

  7. 最终我得到了以下配置文件:

    • 请注意,我注释掉了 HTTP 重定向,因为在我的设备上有使用端口 80 的服务。 在正常情况下,您需要自动将端口 80 重定向到安全连接。
    • 另请注意,我没有在配置文件中使用硬编码的 IP 地址 这允许您在必要时重新配置目标 IP 地址。
    • 一个推论是 - 如果您要重定向到配置有相同证书的内部安全设备,则必须将其作为域而不是 IP 地址传递,否则安全连接将失败。

#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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM