Nginx基於SNI的選擇性TLS透傳反向代理

Nginx基於SNI的選擇性TLS透傳反向代理

我的物聯網設備系統位於 NAT 後面,因此無法從公共互聯網訪問它們(儘管這是需要的)。為了克服這個問題,我將它們綁定到 VPN,其中一個成員暴露在公共互聯網上充當網關。 VPN 設定了一個內部網域,網路的每個成員都有一個基於唯一 ID 的子網域(讓我們使用 MAC 位址),如下所示:12a4f81ead4e.vpn.example.com

我希望在Gatway代理請求上建立一個反向代理,運行 nginx。

該計劃是為網關創建 DNS 記錄,*.gateway.com並將流量路由(咳咳,代理)12a4f81ead4e.gateway.com往返12a4f81ead4e.vpn.example.com。因此,最終用戶只需12a4f81ead4e.gateway.com在瀏覽器中輸入即可存取其裝置。我想使用 nginx,因為網關已經出於其他目的運行 nginx。

我希望 HTTP 請求很簡單,並且可以透過精心設計的 nginxproxy_pass指令來完成。

但是 HTTPS 請求呢?據我了解,基於 SNI 的 TLS 直通現在由 nginx 實現,但到目前為止我看到的所有範例都創建了一個靜態映射......將傳入的 SNI 映射到上游目標:

stream {
  map $ssl_preread_server_name $selected_upstream {
    example.org upstream_1;
    example.net upstream_2;
    example.com upstream_3;
    default upstream_4;
  }
  upstream upstream_1 { server 10.0.0.1:443; }
  upstream upstream_2 { server 10.0.0.2:443; }
  upstream upstream_3 { server 10.0.0.3:443; }
  upstream upstream_4 { server 10.0.0.4:443; }
  server {
    listen 10.0.0.5:443;
    proxy_pass $selected_upstream;
    ssl_preread on;
  }
}

問題是設備是從 VPN 動態新增/刪除的,我不想一直重寫 nginx 設定檔。如果可以從檔案中讀取地圖,那麼這是朝著正確方向邁出的一步,儘管我認為每次更改時都需要重新載入nginx,這會引發權限問題,當然可以使用sudo 規則來規避,但不能使用最佳解決方案。

另外,我只想代理傳入的請求*.gateway.com,並將其他 https 請求正常伺服器到現有的虛擬主機。如果可能的話,我想避免終止 SSL 連線。並不是真正的硬性要求,但如果技術上可行的話,希望以這種方式實現。也只是為了好玩。

我很好地在內部偵聽其他虛擬主機的備用端口,當我想設置“全局”位置時,我對HTTP 做了類似的操作,並將所有HTTP 虛擬主機移動到端口81,並在端口上實現了一個包羅萬象的虛擬主機80 服務於「全球」位置,並將其他所有內容代理到連接埠 81。

所以...我需要這樣的東西(顯然不起作用):

stream {
  map $ssl_preread_server_name $selected_upstream {
    (.*).gateway.com $1.vpn.example.com;
    default normal_serve;
  }

  upstream normal_serve { server 127.0.0.1:8443; }

  server {
    listen 0.0.0.0:443;
    proxy_pass $selected_upstream;
    ssl_preread on;
  }

  server {
    listen 127.0.0.1:8443;
    server_name other.website.com;

    (...)
  }
}

答案1

這可以解決問題:

stream {
  resolver 8.8.8.8;

  map $ssl_preread_server_name $selected_upstream {
    ~(.*).gateway.example.com $1.vpn.example.com:443;
    default 127.0.0.1:8443;
  }

  server {
    listen 0.0.0.0;
    proxy_pass $selected_upstream;
    ssl_preread on;
  }
}

http {
  resolver 8.8.8.8;
  server {
    listen 127.0.0.1:8443 ssl;
    (...)
  }
}

相關內容