簡體   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