我目前正在努力解決一個 Web 應用程式的問題,該應用程式使用 SignalR over WebSockets,其中流量透過 Barracuda Web 應用程式防火牆 (WAF) 進行引導。每次使用 Websocket 連線到signalr/connect
端點的嘗試都會失敗,並顯示 400 錯誤請求。然後連線恢復為 WebServer 輪詢,這可以工作,但不是我們想要的。
發出的請求將發送到我們的 Barracuda Web 應用程式防火牆,然後發送到我們的負載平衡 IIS Web 伺服器。我們在 Windows Server 2012R2 上使用 IIS 8.5,該應用程式是 .Net 4.6.2 Web 應用程式。
相同的設定(不使用 Barracuda WAF)可以正常工作。
到目前為止我有
按照本文在 WAF 中啟用 Websocketshttps://campus.barracuda.com/product/webapplicationfirewall/doc/49054741/how-to-enable-websocket。我仍然遇到同樣的 400 錯誤。
檢查以確保我的 IIS 伺服器WebSocket
啟用了該功能。
在 Web.Config 中開啟 SignalR 偵錯/跟踪https://docs.microsoft.com/en-us/aspnet/signalr/overview/testing-and-debugging/enabling-signalr-tracing。這會產生日誌文件,但沒有指示錯誤。
我不確定還需要檢查什麼?
答案1
所以我發現了我的問題。我發現我們實際上首先透過 Azure 負載平衡器將流量傳送到 WAF。當我登出 WAF 存取日誌中的標頭時,我可以看到標Connection
頭沒有值,我知道我的客戶端正在將其發送為Upgrade
.
使用 Azure 負載平衡器似乎會出現問題。因此,我正在研究使用 Azure 應用程式網關。
不過,目前我可以透過讓 WAFConnection
為我添加標頭、配置重寫標頭規則以將此標頭髮送到我的 IIS 伺服器來使其正常工作。
WebSocket 所需的標頭
Connection: Upgrade Upgrade: websockets
- 開啟Barracuda WAF管理網站。
- 前往網站 -> 網站翻譯
在 HTTP 請求重寫,新增新的重寫規則...
- 指定規則名稱。
- 設定序號。
- 選擇重寫標頭作為操作。
- 輸入 Connection 作為標頭名稱。
- 使用 * 作為舊值,它將替換任何值。
- 輸入升級作為重寫值,以便改為發送。
- 用作
Header Upgrade eq websocket
重寫條件。現在,僅當Upgrade
標頭包含 value時才套用規則websocket
。 - 單擊新增。
現在,當我嘗試再次載入應用程式時,成功連接到 /signalr/connect 並使用 webSockets 傳輸!
更多資訊可以在我的部落格文章