我的物聯網設備系統位於 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;
(...)
}
}