基于 WebAssembly + Coraza 相結(jié)合的 Traefik v3.0 高效解決方案解析
Hello folks,我是 Luga,今天我們來(lái)聊一下云原生網(wǎng)關(guān) Traefik 最新技術(shù) - WebAssembly 和 Coraza。
作為領(lǐng)先的云原生入口控制器和網(wǎng)關(guān)代理,Traefik 憑借其出色的可擴(kuò)展性、簡(jiǎn)單性和性能,在現(xiàn)代應(yīng)用架構(gòu)中扮演著關(guān)鍵角色。而在最新發(fā)布的 Traefik v3.0 版本中,引入了 WebAssembly 和 Coraza Web 應(yīng)用程序防火墻(WAF) Plugin 的強(qiáng)強(qiáng)聯(lián)手,為網(wǎng)絡(luò)代理的功能和安全性帶來(lái)了前所未有的增強(qiáng)。
Traefik 自定義 Plugin 開發(fā)的前世恩怨
作為 Traefik 項(xiàng)目早期最受歡迎的功能之一,“自定義 Plugin ”的概念自 2017 年開始由用戶提出,并源于以下背景和需求:
https://github.com/traefik/traefik/issues/1336?ref=traefik.io
其實(shí),回顧 Traefik 的發(fā)展史,在 2016 年正式對(duì)外發(fā)布后,Traefik 已經(jīng)成為了一個(gè)備受歡迎的邊緣代理解決方案,然而,基于各自業(yè)務(wù)的實(shí)際情況,一些用戶希望能夠更進(jìn)一步地定制和擴(kuò)展其功能。希望能夠有一種靈活的方式來(lái)添加特定的功能或自定義請(qǐng)求處理邏輯,以滿足他們特定應(yīng)用程序的需求。這種需求的提出促使了 Traefik 團(tuán)隊(duì)開始構(gòu)思如何為用戶提供一種可擴(kuò)展的機(jī)制來(lái)滿足這些需求。
于是,自定義 Plugin 的概念應(yīng)運(yùn)而生。它允許開發(fā)人員編寫自己的 Plugin,并將其與 Traefik 集成,從而實(shí)現(xiàn)對(duì)代理服務(wù)的個(gè)性化定制。這種機(jī)制為用戶提供了靈活性和可擴(kuò)展性,使他們能夠根據(jù)自己的需求添加特定的功能或修改請(qǐng)求處理流程。
隨著時(shí)間的推移,自定義 Plugin 成為了 Traefik 項(xiàng)目中最受歡迎的功能之一,為用戶提供了無(wú)限的可能性,使他們能夠根據(jù)自己的應(yīng)用程序需求進(jìn)行定制,無(wú)論是添加新的協(xié)議支持、實(shí)現(xiàn)高級(jí)的路由邏輯還是集成其他的服務(wù)和工具。
因此,如何基于 Golang 自定義實(shí)現(xiàn)這些 Plugin ,并使其能夠絲滑運(yùn)行便是當(dāng)前所要解決的問題。比如,嘗試將 Go 代碼編譯成動(dòng)態(tài)庫(kù),以使得這些庫(kù)可以在運(yùn)行時(shí)加載和執(zhí)行。然而,基于當(dāng)時(shí) Go 語(yǔ)言的生態(tài)不是特別完善不足以支撐自定義 Plugin 的需求,于是在 Traefik 團(tuán)隊(duì)的共同努力下實(shí)現(xiàn)了一種優(yōu)雅的 Go 解釋器,也就是當(dāng)前主流的 Yaegi 項(xiàng)目,隨著眾多技術(shù)人員的參與,基于 Yaegi 所開發(fā)的中間件 Plugin 在Traefik 生態(tài)中成為現(xiàn)實(shí)。Yaegi 使許多人能夠?yàn)樗麄兊纳舷挛拈_發(fā)中間件或提供商。時(shí)至今日,我們可以看到通過目錄提供的中間件 Plugin 達(dá)到一百多個(gè),以及更多私有的 Plugin。
盡管采用了 Yaegi 解釋器,使得用 Go 語(yǔ)言編寫 Plugin 成為可能,但這種做法對(duì)于非 Go 開發(fā)人員來(lái)說(shuō)仍有一定門檻。正因如此,一部分社區(qū)開發(fā)者在 2023 年開始著手探索構(gòu)建一種全新的 Plugin 引擎,以突破現(xiàn)有 Plugin 體系的語(yǔ)言束縛,進(jìn)一步擴(kuò)展 Traefik 的靈活性和可擴(kuò)展性。
因此,一種與語(yǔ)言無(wú)關(guān)、安全可靠、高性能等特性,成為了構(gòu)建 Traefik 新一代 Plugin 體系的不二之選,那便是——WebAssembly 技術(shù)。
WebAssembly:Traefik v3.0 邊緣計(jì)算能力的基石
WebAssembly,即 縮寫為 “WASM” 作為一種革命性的低級(jí)編程模型,以其緊湊的二進(jìn)制指令格式和接近原生的運(yùn)行性能,引起了廣泛關(guān)注。不同于傳統(tǒng)的高級(jí)編程語(yǔ)言,WebAssembly 而是類似于硬件指令集的底層抽象,為 Web 帶來(lái)了全新的執(zhí)行環(huán)境。
除了在 Web 瀏覽器中運(yùn)行外,WebAssembly 同樣可以借助 WebAssembly 系統(tǒng)接口(WASI)規(guī)范在操作系統(tǒng)級(jí)別的運(yùn)行時(shí)運(yùn)行,實(shí)現(xiàn)對(duì)底層系統(tǒng)資源如文件、網(wǎng)絡(luò)等的訪問,從而使得 WASM 成為一種通用的可移植二進(jìn)制指令格式,促進(jìn)了云原生、邊緣計(jì)算、AI 推理等諸多領(lǐng)域的應(yīng)用實(shí)踐。
接下來(lái),我們主要了解一下在實(shí)際的業(yè)務(wù)場(chǎng)景中, WebAssembly 如何為 Traefik Plugin 開發(fā)助力。
對(duì) Traefik 了解的人應(yīng)該都知道,作為云原生時(shí)代領(lǐng)先的反向代理和負(fù)載均衡器, Traefik 采用了模塊化架構(gòu)設(shè)計(jì),其請(qǐng)求路由管道由 Entrypoint(入口點(diǎn))、Router (路由器)以及Service(服務(wù))三大核心組件構(gòu)成。
入口點(diǎn)作為流量的入口,定義了網(wǎng)絡(luò)層面上進(jìn)入 Traefik 的監(jiān)聽端點(diǎn),可以是基于 HTTP、HTTPS、TCP 等多種協(xié)議類型。傳入的請(qǐng)求經(jīng)過入口點(diǎn)后,會(huì)被路由器所接管并進(jìn)行智能分發(fā)。路由器是整個(gè)路由管道的大腦,負(fù)責(zé)根據(jù)配置的規(guī)則和策略,將請(qǐng)求精準(zhǔn)地轉(zhuǎn)發(fā)至能夠處理該請(qǐng)求的服務(wù)節(jié)點(diǎn)。
在請(qǐng)求的路由轉(zhuǎn)發(fā)過程中,Traefik 提供了中間件(Middleware)機(jī)制,使得請(qǐng)求在被最終定向至服務(wù)節(jié)點(diǎn)前,可以經(jīng)過一系列預(yù)處理或后處理操作。這些操作涉及訪問控制、請(qǐng)求轉(zhuǎn)換、身份驗(yàn)證、速率限制等多種功能,為路由管道添加了極大的靈活性和可擴(kuò)展性。
接下來(lái),讓我們來(lái)看看如何為 Traefik 編寫 WASM Plugin,這里,我們基于 WebAssembly 編寫一個(gè)自定義 Plugin。
為了實(shí)現(xiàn)該 Plugin,Traefik 提供了多種開發(fā)語(yǔ)言選擇,包括 Go、C 以及 Rust 等,只要最終代碼能夠?qū)崿F(xiàn)統(tǒng)一的 HTTP-Wasm 接口規(guī)范即可。在當(dāng)前示例中,我們使用 Go 語(yǔ)言進(jìn)行開發(fā),目標(biāo)主要實(shí)現(xiàn)兩個(gè)核心功能:handleRequest 和 handleResponse,分別負(fù)責(zé)請(qǐng)求預(yù)處理和響應(yīng)后處理的自定義邏輯。
具體可參考如下:
package main
import (
"encoding/json"
"fmt"
"os"
"github.com/http-wasm/http-wasm-guest-tinygo/handler"
"github.com/http-wasm/http-wasm-guest-tinygo/handler/api"
)
// Config the plugin configuration.
type Config struct {
Headers map[string]string `json:"headers,omitempty"`
}
func main() {
var config Config
err := json.Unmarshal(handler.Host.GetConfig(), &config)
if err != nil {
handler.Host.Log(api.LogLevelError, fmt.Sprintf("Could not load config %v", err))
os.Exit(1)
}
mw, err := New(config)
if err != nil {
handler.Host.Log(api.LogLevelError, fmt.Sprintf("Could not load config %v", err))
os.Exit(1)
}
handler.HandleRequestFn = mw.handleRequest
}
// Demo a Demo plugin.
type Demo struct{}
// New created a new Demo plugin.
func New(config Config) (*Demo, error) {
return &Demo{}, nil
}
func (d Demo) handleRequest(req api.Request, resp api.Response) (next bool, reqCtx uint32) {
return true, 0
}
然后,將編譯的 Plugin 加載到靜態(tài)配置中,具體可參考如下:
# Static configuration
experimental:
localPlugins:
example:
moduleName: github.com/traefik/plugindemowasm
```
最后,使用我們所構(gòu)建的新 Plugin 定制一個(gè)路由器,具體如下所示:
# Dynamic configuration
http:
routers:
my-router:
rule: host(`demo.localhost`)
service: service-foo
entryPoints:
- web
middlewares:
- my-plugin
services:
service-foo:
loadBalancer:
servers:
- url: http://127.0.0.1:5000
middlewares:
my-plugin:
plugin:
example:
headers:
Foo: Bar
是不是看起來(lái)跟其他的差不多一樣簡(jiǎn)單?
Coraza:增強(qiáng)Traefik v3.0 安全性的堡壘
什么是 Coraza ?
在應(yīng)用程序安全防護(hù)領(lǐng)域,Coraza 作為一款全新的開源 Web 應(yīng)用程序防火墻(WAF)項(xiàng)目,憑借其卓越的性能表現(xiàn)和靈活的防護(hù)能力,正嶄露頭角。
作為 OWASP (開放Web應(yīng)用程序安全項(xiàng)目) 旗下的一員,Coraza 從底層開始采用 Go 語(yǔ)言精心構(gòu)建,摒棄了傳統(tǒng) WAF 產(chǎn)品臃腫笨重的代碼基因,擁有極致的性能優(yōu)化和資源占用效率。在多項(xiàng)基準(zhǔn)測(cè)試中,Coraza 展現(xiàn)出遠(yuǎn)超同類產(chǎn)品的高吞吐量和低延遲特性,可以毫無(wú)懼色地應(yīng)對(duì)現(xiàn)代云原生應(yīng)用程序的高流量挑戰(zhàn)。
除了性能之外,Coraza 還以其出色的擴(kuò)展性和規(guī)則定制能力而備受推崇,天生支持 OWASP 核心規(guī)則集(Core Rule Set),可以高效阻擋 SQL 注入、XSS、代碼執(zhí)行等多種Web攻擊威脅。同時(shí),Coraza 也提供了一套功能強(qiáng)大的域特定語(yǔ)言 SecLang,允許用戶根據(jù)業(yè)務(wù)需求,自由定制和擴(kuò)展安全規(guī)則,實(shí)現(xiàn)個(gè)性化的防護(hù)策略。因此,無(wú)論是基于標(biāo)準(zhǔn)防護(hù)還是定制防護(hù),Coraza 都能游刃有余。
現(xiàn)在,Coraza 項(xiàng)目已作為 Traefik Plugin 生態(tài)的一部分,具體可參考如下:
接下來(lái),我們來(lái)看一下 Coraza plugin 在Traefik 中的應(yīng)用,具體如下:
# This config was generated by "mage updateVersion". DO NOT EDIT.
entryPoints:
web:
address: :80
providers:
file:
filename: /etc/traefik/config-dynamic.yaml
experimental:
plugins:
coraza:
moduleName: github.com/jcchavezs/coraza-http-wasm-traefik
version: v0.2.1
然后,我們需要更新動(dòng)態(tài)配置中路由器的中間件部分,具體可參考如下所示:
http:
# ...
middlewares:
waf:
plugin:
coraza:
directives:
- SecRuleEngine On
- SecDebugLog /dev/stdout
- SecDebugLogLevel 9
- SecRule REQUEST_URI "@streq /admin" "id:101,phase:1,log,deny,status:403"
為了驗(yàn)證 Coraza WAF 防火墻的配置規(guī)則生效情況,我們可以通過發(fā)起簡(jiǎn)單的測(cè)試請(qǐng)求,直觀地觀測(cè)到不同請(qǐng)求模式下的響應(yīng)結(jié)果。
首先,我們使用 curl 命令行工具向本地運(yùn)行的 Traefik 反向代理發(fā)起一個(gè) HEAD 請(qǐng)求,嘗試訪問/admin路徑,具體可參考如下:
curl -I 'http://localhost:8080/admin'
由于之前我們?cè)?Coraza 的規(guī)則配置中,專門為 /admin 路徑設(shè)置了攔截策略,因此,這條請(qǐng)求將觸發(fā) WAF 的防護(hù)規(guī)則生效。我們預(yù)期會(huì)看到 “HTTP 403 Forbidden” 的響應(yīng)狀態(tài)碼被返回,表明該請(qǐng)求已被視為惡意訪問而被 WAF 成功攔截。
相反,如果我們嘗試訪問另一個(gè)未被防護(hù)規(guī)則覆蓋的普通路徑,例如:
curl -I 'http://localhost:8080/anything'
由于該請(qǐng)求路徑?jīng)]有匹配任何 WAF 防護(hù)規(guī)則,因此預(yù)計(jì)會(huì)得到 “HTTP 200 OK” 的正常響應(yīng)狀態(tài)碼,請(qǐng)求將被成功代理至后端服務(wù)處理。
通過這一對(duì)反例的測(cè)試,我們可以直觀地感受到 Coraza WAF 防護(hù)規(guī)則的生效情況。當(dāng)請(qǐng)求匹配特定規(guī)則時(shí),將被實(shí)時(shí)攔截并返回對(duì)應(yīng)的狀態(tài)碼或拒絕訪問提示;而對(duì)于未匹配規(guī)則的普通請(qǐng)求則會(huì)放行,確保合法業(yè)務(wù)流量不受影響。
綜上所述,WebAssembly 作為一種革命性的技術(shù),使得在沙箱環(huán)境中運(yùn)行各種編程語(yǔ)言編寫的代碼成為可能,從而大幅提升了可移植性和安全性。通過與 Coraza 結(jié)合使用,Traefik v3.0 可以利用 WASM 的優(yōu)勢(shì),在不影響核心代理性能的前提下,動(dòng)態(tài)加載和卸載安全策略,實(shí)現(xiàn)高度定制化和靈活的 WAF 防護(hù)。
這一創(chuàng)新組合不僅賦予了 Traefik 更出色的模塊化架構(gòu)和可擴(kuò)展性,還顯著增強(qiáng)了其應(yīng)對(duì)各種Web攻擊的能力,從 SQL 注入、跨站腳本攻擊到機(jī)器行為檢測(cè),全面守護(hù)應(yīng)用程序的安全。而 Coraza 作為一款全功能 WAF,其高效、低延遲的特性有助于確保 Traefik 的高性能表現(xiàn)。
憑借 WASM 和 Coraza 兩大利器的加持,Traefik v3.0 正努力成為云原生時(shí)代下最值得信賴的網(wǎng)絡(luò)代理和安全防護(hù)者,為現(xiàn)代應(yīng)用程序架構(gòu)提供無(wú)縫整合、動(dòng)態(tài)擴(kuò)展和全方位保駕護(hù)航,助力企業(yè)安全可靠地向云原生時(shí)代轉(zhuǎn)型。
Reference :
- [1] https://github.com/traefik/traefik/issues/1336?ref=traefik.io
- [2] https://github.com/corazawaf/coraza
- [3] https://traefik.io/blog/traefik-3-deep-dive-into-wasm