Zoraxy v3 – 適合新手的反向代理伺服器
最近我一直在進行相當多的 Zoraxy 更新。對於從未聽過 Zoraxy 的人來說,它是我的開源反向代理伺服器 (Reverse Proxy Server)。可以部署在你的 homelab 或server / NAS 裡面。 如果你對 Zoraxy 如何運作沒有興趣,單純是來找一個可以在 Windows 和 Linux 上運行的 Reverse Proxy Server,請按這裡。 v3 的新功能? 嗯,如果你之前使用過 Zoraxy v2,每次打開 Web 管理界面,你都會感到一陣沮喪的感覺。這是因為在開發 v2 的過程中,我沒有多餘的時間仔細考慮配色方案或設計一個具吸引力的界面配色(然而作為開源項目來說,這界面已經算是到達夠好 + 能用的設計)。 v2 homepage v2 的代理清單 現在 v3 長這個樣子 除了界面更新之外,Zoraxy 還添加了大量新功能,以 optimize proxy core 的功能(或者我可以說,因為有太多 user 是從 Nginx Proxy Manager(NPM)轉過來用 Zoraxy,所以有一些部分如果盡量接近 NPM 的設計會省下我很多處理 issue 的麻煩)。一般來說,這不是 NPM 的替代品,而更像是一個讓你更容易在測試和debug 時切換 endpoint 的 Reverse Proxy。但無論如何,我不介意人們提出感覺像 NPM 的 enhancement issues。 Default Site 在 Zoraxy v3 中,我們新增了對 Default Site 和多個 host name 的支援。 Zoraxy 的前身(名為“Web Proxy”,是 ArozOS 系統的一個子服務)設計僅用於處理單一域名的反向代理,v2 版本添加了對子域和其他主機名的支援,但由於是沒經過設計加進去的,所以對 user 來說有夠混亂( 使用者對 “Proxy ”、“Subdomain” 和 “Proxy Root” 的設定感到困惑然後又跑來開 issue。這就是為什麼在 v3 的設計中,我設計一個新的界面和設置邏輯。有了Default Site 的選項(對,就是 NPM 那個),那習慣用 NPM 的人可以輕鬆地切換到 Zoraxy 了。(順帶省下了我很多解釋東西怎樣用的時間) Default Site 提供 4 個選項供選擇。對於新手來說,你可能想要使用內部靜態網頁伺服器,在使用 "Static Web Server" 功能時將一個 "index.html" 文件作為你的網站首頁。這更像是傳統的 Apache 的用法,如果在 apache.conf 中沒有對應的 Virtual Host,所有的路由都會進入內置的靜態網頁伺服器,並從你的 /var/www/html 資料夾抓檔案來回應 request。 Redirection 和 404 Not Found 用起來也相對直接。對於 Redirection (重定向),你可以輸入要重定向的目標域名/IP 地址。在要將舊的(子)域名指向新域名,或者直接阻止那些未知/過時子域名的請求時滿有用的。 Wildcard 域名證書與 SNI 在 v3 中,我們 implement 了 TLS/SSL 證書查找邏輯中的 SNI。Zoraxy SNI 與其他 implementation 的區別在於,它不需要用戶輸入來將證書與特定主機名“鏈接”起來,而是會自動掃描並 serve 出對應的 TLS certificate。 在 v2 中,用戶需要手動為每個證書設置與匹配的域名。例如,如果你有一個證書可以涵蓋 a.example.com 和 b.example.com,你需要手動將其匹配關鍵字設置為 "example.com",才能使這個域名的 TLS 加密正常工作(不然會出現 self sign certificate error)。現在有了 Zoraxy v3 的自動證書查找邏輯,你不需要設定任何東西。只需上傳你的證書(或使用內置的 ACME 工具從你選擇的 CA 生成一個),Zoraxy 將自動解析並選擇正確的 certificate。唯一的限制是對於包含多個主機名的證書(例如 domain.com 和 anotherdomain.com),速度會稍微慢一些(可能需要 O(n)…
在 Zoraxy 加入 TLS SNI 功能
最近我在開發的 Zoraxy v3 在我開發 Zoraxy 之前我也不知道 https 證書這東西對於 reverse proxy 伺服器來說到底有多複雜。一開始的時候因為我都是用一個域名(domain name),所以 reverse proxy 裡面也是只需要處理一個主機名稱(host name)。而初代的 Zoraxy 則是直接用 TLS hello info 裡面的 server name 作為 certificate 的 key 來找到合適的 certificate 並回傳給客戶端,所以時間複雜度(time complexity)而言是 O(1) 的速度。換成程式碼大概長這樣: http.ListenAndServeTLS(":443", "server.crt", "server.key", nil) 到後來發現 virtual directory 帶來的麻煩後,Zoraxy v2 加入了 sub-domain 的支援。為了解決找 certificate 的問題, v2 的做法是讓使用者把每個 sub-domain 都 map 到一張 certificate 上面,所以結果就是同一個域名下會有很多張證書(例如說 a.example.com 會有 a.example.com 的證書、b.example.com 會有 b.example.com 的證書)。這樣設計的好處是一來找 certificate 的演算法比較簡單,二來我們可以根據 hello info 的 server name 進行也是 O(1) 時間複雜度的 certificate lookup,不用任何存取 file system 的 loop 便可以直接找到證書。 if fileExists(helloInfo.ServerName+".pem") && fileExists( helloInfo.ServerName+".key") { //Direct hit pubKey = helloInfo.ServerName+".pem" priKey = helloInfo.ServerName+".key" } 然後在 Zoraxy v2 用了這一年多之後就又出現問題了。coauthor 的其中一張證書裡面包含了幾個不同的 domain 跟 subdomain,也有使用者的證書是含 wildcard 的,也有是舊版用 Common Name 來定義(而不是 DNS entry)來標記 host name 的,結果就是一大堆 issue 就出現在 repo 上面。 SNI 的基本概念 SNI 的原理大概就是由伺服器端跟據 TLS Hello Info 的 Server Name 來自動回傳合適的 certificate 給 Client (這裡因為 Zoraxy 是一個 http proxy,那我就以瀏覽器為 client 的例子)。對於很直接的域名例如說 v1 跟 v2 裡面出現的,基本上就是只要把 certificate map 到一個 string 轉 certificate 的資料結構裡面就可以了。但是對於 v3 之後的複雜案例,則是需要一些更複雜的邏輯來處理。 相信來得我部落格的人不是工程師應該都是技術大佬,所以我就直接把 code 拿出來講好了。這裡是 Zoraxy v3 TLS 解釋器裡面最重要的 function func(m * Manager) CertMatchExists(serverName string) bool { for _, certCacheEntry: = range m.LoadedCerts { if certCacheEntry.Cert.VerifyHostname(serverName) == nil || certCacheEntry.Cert.Issuer.CommonName ==…
Zoraxy – 新手向 Reverse Proxy Server( 反向代理服務器)
我猜很多 web devs(網頁開發者)都知道什麼是反向代理伺服器 (Reverse Proxy Server)。當您在 homelab 或 cluster 上部署多個 service 並希望使用單一gateway server 和不同 subdomain 將它們 expose 在網際網路上時,反向代理伺服器尤其有用。在這篇部落格文章中,我就來分享一下我為什麼要用 Go 開發自己的反向代理伺服器來取代Apache / Nginx 和把它部署到我的分散式 homelab 中的經驗。 甚麼是 Reverse Proxy? 想像一下,你正在音樂節上隨著你最喜愛的表演,突然你想要一杯 冰涼的飲料。由於你不想錯過任何的表演環節,所以你派你的好朋友(即反向代理伺服器),去替你把飲料拿來(網頁內容)。你的朋友穿過人群,排隊等候,完全不會打擾你觀賞表演,最後在不知甚麼時候帶回了那杯冰涼的飲料。在這種情況下,反向代理伺服器扮演著你和音樂節混亂背後的幕後伺服器之間的中間人角色,隔離你(用戶)和後面混亂的內部網絡 routing,直接由中間人向你提供所需的內容。 不僅僅是為你轉發和中繼網頁內容 ,現代的反向代理可做到比中繼代理之外更多的事情。例如說負載平衡、故障切換(failover)等。像Nginx Proxy Manager(NPM,不是那個黑洞 npm)這樣的管理工具甚至具有內置的自動 SSL證書更新等功能。這就是為什麼反向代理通常被認為是 homelab(或任何類型的網站系統)的“核心”的原因。 那為甚麼我要重新寫一個屬於自己的 Reverse Proxy 伺服器? 如果你是一名資深的 devops 工程師,那你一定有親身體驗過寫 Apache 或 Nginx 配置文件的痛苦,那必定是一個難以忘懷的經歷。當你試圖從 Stack Overflow上 Copy & Paste 一些看不懂的東西到你的 config 檔,並試著根據自己的了解進行修改,卻發現怎樣 route 都是怪怪的。再加上很多開源專案都很依賴於 Rewrite Rules 和 Headers 中某些特殊設置的 Setting,要讓所有 service 都能正常運行真是一件讓人痛苦的事情。更多別提到你想加入一個臨時的 routing rules 做 testing 都要進入 ssh 到後台設置的麻煩( 在開源世界中,有一些替代方案或解決方案可解決這些問題。像 NPM 是 r/selfhost 上 Reddit 用戶最推薦的方案之一。然而,它已經快兩年沒更新了,而且聽說最新版本會弄壞很多東西。這就是為什麼我決定自己開發一個 Reverse Proxy 伺服器以解決自己未來可預見的「所有」問題。 這就是 Zoraxy 誕生的原因 Zoraxy 是一個以 Go 開發的 Reverse Proxy 伺服器。除了基本的功能外,還附了很多不同的工具和機能讓你輕易管理你的伺服器集群(當然也能用於 docker 了)。以下是一些簡單易懂的系統截圖: 登入後的主頁 一些 overview status Subdomain 設定 建立新的 Proxy Rules Proxy root (預設路由路徑) Certificates 重導向設置 存取管理 Uptime Monitor MDNS 與 IP scanner Web SSH 功能 用戶統計 登入界面 TCP Proxy (主要用來當遊戲伺服器路由,如 Minecraft Server) ZeroTier controller 有興趣了解更多或下載試用可以到 https://zoraxy.arozos.com/ 看看喔