Web 服務
依網域提供反向代理、重新導向、靜態檔案與固定文字,是 Gately 的統一 Web 入口。選單位置:側邊欄「Web → Web 服務」。
結構:監聽、站台與預設站台
設定分三層:
- 監聽:一個監聽連接埠。欄位包括網路(
tcp雙堆疊、tcp4、tcp6)、監聽位址(留空為所有位址)、連接埠、HTTPS 開關、最低 TLS 版本(1.0 / 1.1 / 1.2 / 1.3)、是否接收 PROXY 協定。 - 站台:監聽下依網域比對的一個站台。網域支援精確網域、
*.example.com(比對任意層級子網域)與*(比對全部);比對優先順序為精確網域、萬用字元、*。 - 預設站台:沒有站台符合時使用,未啟用時回傳 404。
修改站台或預設站台並儲存時,站台清單會原地替換:監聽保持執行,已建立的連線(含 WebSocket)不會中斷,各站台的統計資料也會保留。新設定無效時繼續使用原來的站台。修改監聽自身的設定(網路、位址、連接埠、HTTPS、最低 TLS、HTTP/3、PROXY 協定)會重新啟動該監聽。
站台類型
| 類型 | 說明 |
|---|---|
| 反向代理 | 轉發到一個或多個後端,後端位址格式為 http(s)://主機:連接埠,支援 WebSocket |
| 重新導向 | 跳轉到完整 URL,狀態碼 301 / 302 / 307 / 308(預設 302),可選保留原路徑與查詢字串。URL 中可以寫 {host},會替換為訪客使用的網域:https://{host} 加上「保留路徑」,就能把所有 HTTP 請求跳轉到同一網域的 HTTPS |
| 靜態檔案 | 目錄需為絕對路徑;關閉「目錄列表」時,目錄請求只在存在 index.html 時回傳。「無副檔名網址」在檔案不存在時再嘗試 路徑.html 與 路徑/index.html(適用於 VitePress 等產生器,相當於 nginx 的 try_files $uri $uri.html $uri/index.html);「404 頁面」填寫目錄內的路徑,如 404.html,以 404 狀態回傳 |
| 固定文字 | 自訂內容、Content-Type(預設 text/plain; charset=utf-8)與狀態碼(100-599,預設 200) |
反向代理站台的其他選項:
- 使用後端 Host:Host 標頭改為後端位址,關閉時保留用戶端請求的 Host;
- 略過後端憑證驗證、關閉 Keep-Alive;
- 向後端送出 PROXY 協定(v2 標頭,傳遞真實用戶端 IP,需要後端支援);
- 加入
X-Forwarded-For/X-Forwarded-Proto/X-Forwarded-Host/X-Forwarded-Port與X-Real-IP; - 使用造訪網域作為 SNI(僅 HTTPS 後端):握手時傳送訪客使用的網域,並依它驗證憑證,相當於 nginx 的
proxy_ssl_server_name on; proxy_ssl_name $host。後端依 SNI 分流時(例如 frp 的vhost_https)需要開啟。每個後端使用獨立的連線池,不同網域的連線不會互相重用。
所有類型的站台都可設定存取日誌、跨來源(CORS)、自訂請求標頭與回應標頭(每行 Key: Value,Value 留空表示刪除該標頭),並可引用一個 WAF 防火牆 實例(實例不存在或停用時放行)。
傳輸與協定
- HTTPS:使用 SSL 憑證 模組中涵蓋該網域的憑證;
- HTTP/3(QUIC):在開啟 HTTPS 的監聽中啟用,相同埠號的 UDP 上同時提供 HTTP/3,並透過
Alt-Svc回應標頭通告瀏覽器;需要在防火牆與連接埠映射中放行該 UDP 埠; - WebSocket:反向代理自動支援;
- PROXY 協定:監聽可接收上游(如 haproxy、frp)送出的 PROXY 標頭,僅信任「全域設定 → 可信 PROXY 來源」中列出的 IP 或網段,留空表示不信任任何來源;反向代理可向後端送出 PROXY 標頭。
驗證
在站台編輯視窗的「安全」頁設定:
- 網頁驗證:瀏覽器顯示登入頁;
- 基本驗證:HTTP Basic;
- 使用者:每行
使用者名稱:密碼,密碼可填 bcrypt 雜湊。啟用基本驗證時至少需要一位使用者;啟用網頁驗證時至少需要一位使用者或第三方登入身分; - 第三方登入:支援 GitHub、Google、QQ、OIDC,使用自己的 OAuth 應用程式。允許的身分每行一條,格式
提供方識別碼:帳號,例如github:octocat、google:me@gmail.com,行尾可用#加備註,github:*表示該提供方的任意帳號。
第三方登入的提供方在「全域設定」中設定:填寫自己的 Client ID / Secret 並啟用,同時設定回呼位址(需由 Gately 的某個監聽提供,例如 https://auth.example.com)。登錄到 GitHub / Google / QQ 的回呼 URL 為:
https://auth.example.com/__gately_auth/oauth/callback管理後台自身的第三方登入在「設定 → 帳號與安全」中單獨設定。
轉發認證(Authelia 等)
把認證交給外部服務,相當於 nginx 的 auth_request 或 Traefik 的 forwardAuth。在「安全」頁勾選「轉發認證」;同一站台不能同時啟用基本驗證或網頁驗證。
| 欄位 | 說明 |
|---|---|
url | 驗證介面,例如 Authelia 的 http://127.0.0.1:9091/api/authz/auth-request |
loginUrl | 介面回傳 401 時把訪客跳轉到的位址,例如 https://auth.example.com/?rd={url}&rm={method};{url} 為原始位址(已編碼),{method} 為請求方法。留空時原樣回傳介面的回應 |
copyHeaders | 驗證通過後從介面回應複製到後端請求的身分標頭,預設 Remote-User、Remote-Groups、Remote-Email、Remote-Name |
運作方式:
- 每個請求先以不帶請求本文的 GET 送到
url,帶上訪客的請求標頭(Cookie、Authorization等),以及X-Original-Method、X-Original-URL、X-Forwarded-Method、X-Forwarded-Proto、X-Forwarded-Host、X-Forwarded-Uri、X-Forwarded-For與X-Real-Ip,逾時 10 秒; - 回傳 2xx 即放行,並帶上身分標頭;回傳 401 時跳轉到
loginUrl(狀態碼 302);其他結果(如 403 或跳轉)原樣回傳給訪客;介面無法連線時回傳 502; - 訪客自帶的身分標頭一律刪除,無法偽造;
- 可與路徑規則和「驗證範圍」搭配,只讓部分路徑(如
/admin)需要登入,也可與臨時分享連結搭配。
共用使用者:TOTP 與單一登入
帳號只需定義一次,就能用於多個站台,並可選擇啟用 TOTP 二次驗證,涵蓋了很多人使用 Authelia 的主要目的。
在「全域設定 → 共用使用者」中:
- 新增使用者名稱與密碼;密碼以 bcrypt 雜湊儲存,API 不會回傳。要啟用 TOTP,點「啟用 TOTP」,用驗證器 App(Google Authenticator、1Password 等)掃描 QR Code 並儲存;重新產生會使舊金鑰失效;
- 單一登入網域,例如
example.com:在該網域或其子網域下的任一站台登入後,其他站台無需再登入。它使用父網域 Cookie(gately_sso,有效期 7 天),不會轉發給後端。留空則每個站台單獨登入。
在站台的「安全」頁,於網頁驗證或基本驗證旁勾選「使用共用使用者」;站台自有的使用者仍然可用。
行為說明:
- 只要有共用使用者啟用了 TOTP,登入頁就會顯示驗證碼輸入框,每個驗證碼只能使用一次;
- 修改使用者的密碼或 TOTP 金鑰後,該使用者既有的工作階段立即失效;
- 基本驗證只接受未啟用 TOTP 的共用使用者,因為瀏覽器的密碼彈出視窗沒有地方輸入驗證碼;
- 失敗次數與其他登入共用同一套限流與自動封鎖。
存取控制
IP 黑白名單
站台「安全」頁的「IP 存取控制」可選關閉、白名單、黑名單,清單每行一個 IP 或網段(如 192.168.1.0/24),還可以同時引用訂閱的 IP 清單。
訂閱 IP 清單
在「全域設定 → 訂閱 IP 清單」新增清單:填寫下載網址與重新整理間隔(預設 24 小時),Gately 會定時下載並快取到設定目錄,重新啟動後無需連網即可使用。內容每行一個 IP、CIDR 或 起始-結束 範圍,#、;、// 之後為註解。例如省市 IP 段可使用 metowolf/iplist 的 https://metowolf.github.io/iplist/data/cncity/440000.txt(廣東省)。
- 站台與路徑規則的白名單、黑名單可以引用多個清單,與手動填寫的 IP 段一起判斷,符合任一項即視為在名單中;
- 下載內容無法辨識(例如回傳了錯誤頁面)時保留上次的清單,並在清單上顯示原因,一小時後重試;
- 清單下載成功前視為空清單:白名單因此拒絕存取,黑名單不額外攔截;
- 仍被站台引用的清單無法刪除。
路徑規則
在「安全」頁的「路徑規則」中,依路徑前綴覆寫站台的驗證與 IP 設定:
| 欄位 | 取值 |
|---|---|
prefix | 以 / 開頭的路徑前綴,如 /admin |
auth | 沿用站台(空)、off(無需驗證)、on(必須驗證) |
ipMode / ipList | 沿用站台(空)、whitelist、blacklist,並附 IP 或網段清單 |
比對規則:
- 最長前綴優先;
- 依路徑段邊界比對,
/admin符合/admin與/admin/x,/administrator不符合; - 請求路徑先正規化(消除
.、..與重複斜線)再比對,/public/../admin以/admin處理; - 同一前綴只能設定一條規則。
「驗證範圍」選項(authOptional):勾選後,驗證只作用於規則中標記為「必須驗證」的路徑,其餘路徑公開。此選項需要先啟用基本驗證或網頁驗證。
臨時分享連結
啟用基本驗證或網頁驗證後,可為站台建立分享連結,讓訪客免帳號存取:
| 欄位 | 說明 |
|---|---|
| 名稱 | 備註名,如「給小明」 |
| 到期時間 | 留空為不過期 |
可用次數 maxUses | 最多可被兌換的次數,0 為不限;重新啟動後計數歸零 |
路徑限制 pathPrefix | 非空時,連結只能存取該前綴下的路徑,需以 / 開頭 |
訪客造訪 https://網域/任意路徑?_gs=權杖 即可兌換工作階段。兌換成功後伺服器端設定免登入 Cookie 並跳轉到去掉 _gs 參數的位址,工作階段最長 24 小時,且不超過連結的到期時間。權杖無效時按一般存取處理,不透露失敗原因。刪除連結後已發出的工作階段立即失效。權杖在儲存後產生(至少 16 位),可在介面複製完整連結。
驗證失敗限流與自動封鎖
- 同一來源 IP 在 15 分鐘內驗證失敗累計 10 次後,暫時拒絕繼續嘗試;
- 「全域設定 → 自動封鎖 → 驗證失敗封鎖」填寫分鐘數(0 至 43200),達到 10 次失敗時封鎖來源 IP;填 0 表示不封鎖,僅限流;
- 自動封鎖觸發時發布
AuthBanned事件,可經 通知中心 推送; - IPv6 位址依 /64 網段彙整計數與封鎖。
封鎖清單
「全域設定」中的封鎖清單顯示目前被封鎖的 IP、原因(驗證連續失敗或手動封鎖)和到期時間,可點擊「解除」。也可手動封鎖:填寫 IP 與小時數(1 至 720,即最長 30 天),介面預設時長為 24 小時。
封鎖清單與入侵防護共用同一份:開啟入侵防護模組時,這裡只顯示封鎖數量,並連到入侵防護頁面管理。封鎖同樣對連接埠轉發、STUN 等服務生效,開啟防火牆同步後會在系統防火牆中丟棄;開啟「忽略內網位址」時,內網位址不會被自動封鎖。
GeoIP 國家過濾
站台「國家過濾」有三種模式:關閉、僅允許、拒絕,並填寫兩位 ISO 國家代碼(以逗號分隔,如 CN, HK, US)。啟用時至少填寫一個國家。
- 過濾依賴 GeoIP 資料庫,需先在「全域設定 → GeoIP 資料庫」匯入:上傳
.mmdb檔案,或填寫下載位址。支援 MaxMind GeoLite2、DB-IP 等國家庫或城市庫;上傳限制 129 MB; - 資料庫未載入時過濾不生效(放行所有訪客),介面會提示;
- 內網位址一律放行;
- 「拒絕」模式下,庫中查不到國家的位址放行。
依路徑分流後端
為反向代理站台把某個路徑前綴下的請求送到其他後端,相當於 nginx 的 location /api/ { proxy_pass ...; }。在站台編輯視窗「基本」頁的「分路徑後端」中新增。
| 欄位 | 說明 |
|---|---|
prefix | 路徑前綴,如 /api/。依路徑段邊界比對:/api 與 /api/ 都符合 /api 和 /api/x,不符合 /apix |
targets | 該路徑的後端,寫法與站台後端相同;留空時使用站台後端,只追加下面的請求標頭 |
requestHeaders | 該路徑追加的請求標頭,每行 Key: Value;在站台請求標頭之後套用,同名時以路徑的為準 |
- 最長前綴優先,路徑原樣轉發(不會去掉前綴);
- 站台的其他設定,如 Host 選項、憑證驗證、轉發標頭、PROXY 協定、負載平衡策略與健康檢查,對每個路徑後端同樣生效;
- 壓縮、限流、快取與改寫作用於整個站台。
反向代理進階
這些選項位於站台編輯視窗的「流量」頁。
後端、權重與備用
後端清單每行一個位址,位址後可附參數:
http://10.0.0.2:8080 weight=3
http://10.0.0.3:8080 backupweight=N:權重,1 至 100 的整數,預設 1;backup:備用後端,僅在所有非備用後端都無法使用時啟用;全部後端都無法使用時回退到所有非備用後端繼續嘗試。
負載平衡策略
| 介面選項 | lbPolicy | 說明 |
|---|---|---|
| 輪詢(依權重) | 空 | 預設 |
| 隨機(依權重) | random | |
| IP 雜湊(工作階段保持) | ip_hash | 同一用戶端 IP 落到同一後端 |
| 最少連線 | least_conn | 依「連線數 / 權重」選擇最小者 |
健康檢查
主動檢查開關預設關閉。啟用後的欄位與預設值:
| 欄位 | 預設值 | 範圍 |
|---|---|---|
方式 mode | http | http(請求檢查路徑,狀態碼小於 400 視為健康)或 tcp(只測試連線) |
路徑 path | / | 以 / 開頭,僅 http 方式 |
間隔 interval | 10 秒 | 1 至 3600 |
逾時 timeout | 3 秒 | 1 至 60 |
連續失敗 fails | 3 次判定無法使用 | 1 至 20 |
連續成功 passes | 2 次恢復 | 1 至 20 |
啟用向後端送出 PROXY 協定時,HTTP 檢查自動改用 TCP。
被動檢查一律生效:多個後端中,連續 3 次連線失敗的後端暫停 30 秒後再試探(只有一個後端且未啟用主動檢查時不摘除)。啟用主動檢查後,恢復完全由檢查結果決定。後端狀態變動時發布上游無法使用 / 已恢復事件,可經 通知中心 推送。
壓縮
對反向代理、靜態檔案、固定文字站台可啟用壓縮(重新導向站台除外)。依 Accept-Encoding 優先選擇 br,其次 gzip。
- 僅壓縮文字類內容:
text/*、JSON、JavaScript、XML、XHTML、RSS / Atom、WebAssembly、SVG;text/event-stream排除在外; - 宣告的
Content-Length小於 256 位元組的回應保持原樣; - 已有
Content-Encoding的回應保持原樣;WebSocket 升級請求直接放行; - 壓縮後強驗證 ETag 改為弱驗證。
依 IP 限流
依用戶端 IP 的權杖桶限流,欄位:
| 欄位 | 說明 |
|---|---|
rate | 每秒允許的請求數 |
burst | 突發容量;設定了 rate 而 burst 為 0 時自動取 rate 取整後加 1 |
maxConns | 單一 IP 的並行請求上限,0 為不限 |
啟用限流時 rate 與 maxConns 至少設定一項。
記憶體回應快取
僅對反向代理站台生效,快取存放在記憶體中,以 LRU 淘汰。
| 欄位 | 預設值 | 範圍 |
|---|---|---|
ttl 預設時長 | 0 | 0 至 30 天(秒)。上游未宣告快取指令時,200 回應快取這麼久;0 表示只快取上游明確允許的回應 |
maxMb 快取容量 | 64 | 1 至 4096 MB |
快取規則:
- 僅快取 GET 請求,且請求不含
Authorization、Cookie、Range標頭,也不含Cache-Control: no-cache; - 僅快取狀態碼 200 的回應;回應含
Set-Cookie、Vary: *,或Cache-Control為no-store/private/no-cache時略過; - 遵循
s-maxage,其次max-age; - 單一項目上限為 4 MB,同時不超過總容量的四分之一;
- 命中時回傳標頭
X-Cache: HIT與Age,未命中為X-Cache: MISS; - 快取鍵包含 Host、完整請求 URI 與
Accept-Encoding。
路徑改寫與重新導向
規則依順序比對,命中第一條即停止。
| 欄位 | 說明 |
|---|---|
pattern | 比對請求路徑的正規表示式,如 ^/old/(.*)$ |
to | 取代結果,可用 $1 引用群組 |
redirect | 關閉為內部改寫(改寫後的路徑送往後端,目標需以 / 開頭);開啟為重新導向 |
code | 重新導向狀態碼 301 / 302 / 307 / 308,預設 302 |
重新導向會保留原查詢參數。重新導向目標中可以寫 {host},表示訪客使用的網域。重新導向規則先於驗證執行,相當於 nginx 的 location = / { return 302 ...; },所以 / 這類路徑可以直接把訪客送走,不要求先登入。
存取統計與監控
站台統計
執行中的監聽,在站台列點擊「統計」開啟統計視窗,可選最近 1 小時、6 小時、24 小時:
- 分鐘級存取統計:每分鐘一個點,保留最近 24 小時,包含請求數曲線與 4xx / 5xx 錯誤曲線;
- 狀態碼分布 2xx / 3xx / 4xx / 5xx,累計回應流量;
- 來源 IP Top 10 與國家 Top 10(國家統計需要已匯入 GeoIP 資料庫);
- 反向代理站台顯示每個後端的健康狀態、權重、是否備用與目前連線數。
統計保存在記憶體中,重新啟動或修改該監聽自身的設定後重新計數;修改站台會保留其計數。排行榜最多統計 5000 個不同來源。
Prometheus 指標
全域指標端點 GET /api/metrics 彙總了全部模組的指標,見 監控指標。下面的模組端點只包含 Web 服務的指標。
指標端點為 GET /api/webservice/metrics,Prometheus 文字格式,需攜帶登入憑據或 API 權杖。
curl -H "Authorization: Bearer gtl_xxxx" http://localhost:16680/api/webservice/metrics| 指標 | 類型 | 說明 |
|---|---|---|
gately_site_requests_total | counter | 站台累計請求數 |
gately_site_errors_total | counter | 站台後端錯誤數 |
gately_site_active_requests | gauge | 進行中的請求數 |
gately_site_response_bytes_total | counter | 累計回應位元組數 |
gately_site_responses_total | counter | 依狀態類別(標籤 class:2xx 至 5xx)統計的回應數 |
gately_upstream_up | gauge | 後端是否健康,1 健康、0 無法使用(附標籤 upstream) |
所有指標帶有標籤 listener(監聽名稱#監聽 key)與 site(站台名稱,未命名時取第一個網域)。
匯入 nginx 設定
頁面頂端的「匯入 nginx」可以把現有的 nginx 站台轉換為 Gately 的監聽與站台。建議在 nginx 所在主機執行 nginx -T,把完整輸出貼上:輸出中包含 include 的所有檔案,Gately 會像 nginx 一樣展開 include。
- 先預覽:依監聽連接埠分組列出每個站台的類型、後端或目錄、來源檔案與行號,以及需要留意的地方(使用了變數的指令、正規表示式 location、缺少憑證的網域等),無法轉換的站台會說明原因;
- 相同連接埠的站台合併到既有監聽,否則新增監聽;已存在的網域會略過,可以重複匯入;
- 預設匯入為停用狀態,方便與 nginx 並行逐一核對後再啟用;勾選「匯入後立即啟用」則立即生效(nginx 仍佔用相同連接埠時,新增的監聽會啟動失敗);
- 可轉換的內容:
proxy_pass(含 upstream 的權重、備用與負載平衡策略)、root/alias靜態目錄(autoindex、try_files $uri.html、error_page 404)、return跳轉與固定內容、整站rewrite跳轉、add_header、proxy_set_header、gzip、allow/deny、location 層級的分路徑後端、存取控制與跳轉、listen ... proxy_protocol與quic; auth_request會轉換為轉發認證:驗證位址取自驗證子請求 location 的proxy_pass(支援set變數),登入跳轉取自error_page 401 =302,Authelia 的常見寫法可以直接轉換;只在部分 location 啟用時,轉換為只對指定路徑驗證(「驗證範圍」);auth_basic轉換為使用共用使用者的基本驗證,nginx 的使用者檔案不會被讀取,補齊使用者之前任何人都無法通過;stream中的 TCP/UDP 轉發請在 連接埠轉發 中設定;憑證不會匯入,HTTPS 站台缺少憑證時,預覽會列出 nginx 使用的憑證檔案,可在 憑證 頁依檔案路徑新增。
取代 haproxy 與 nginx
連接埠轉發加上 Web 服務可以取代 haproxy + nginx 的組合。常見配置是:在 443 上放一條 SNI 分流 規則,把 VPN 等 TLS 服務直接送到各自的後端,其餘網域送到一個接收 PROXY 協定的 Web 服務監聽;再在 80 連接埠放一個 Web 服務監聽,用重新導向站台(https://{host})跳轉到 HTTPS。
nginx 設定的對應關係:
| nginx | Gately |
|---|---|
帶 server_name 的 server | 使用這些網域的站台 |
proxy_pass 不同的 location | 分路徑後端 |
auth_request(Authelia) | 轉發認證,或帶 TOTP 的共用使用者 |
proxy_ssl_name $host | 使用造訪網域作為 SNI |
return 301 https://$host$request_uri | 重新導向站台,https://{host} 並勾選「保留路徑」 |
location = / 裡的 return 302 /admin | 改寫規則,開啟「重新導向」,pattern 為 ^/$ |
try_files $uri $uri.html $uri/index.html 與 error_page 404 | 靜態檔案的無副檔名網址與 404 頁面 |
add_header | 回應標頭 |
部署提示
Web 服務需要監聽主機的 80 / 443 等連接埠,Docker 部署建議使用 --network host。