iT邦幫忙

2024 iThome 鐵人賽

DAY 6
0

心跳機制

首先我們要先了解到,關閉瀏覽器正常會終止所有活躍的 WebSocket 連接並向伺服器發送關閉信號。然而,在某些情況下(如網絡中斷、客戶端崩潰、網絡不穩定等),close 事件可能不會立即觸發。

不過測了一些方法但可能因為本地端的關係,除非找到本地與本地間要發生這種不主動通知close的觸發方式,所以我只能盡量實作看看

重新連接是基於client端與server端斷掉,所以client與server重新交握,而心跳則是因client端因各種原因導致斷開但卻沒有通知到server端,要讓server端主動去斷開

如果這個不修別人就很容易可以搞甚麼DDOS了,一直給你的server塞死掉的client最終附載不住癱瘓掉,當然簡單給他設個連接上限也可以防止伺服器炸掉,不過你的伺服器就會卡死或是禁止新的連接近來

ping/pong

下面大致展現一下心跳機制是如何運作的吧
server.js

wss.on("connection", (ws) => {
    // 設置心跳機制
    ws.isAlive = true; // 初始設置連接為活躍狀態
    ws.on("pong", () => {
        console.log("還活著唷");
        ws.isAlive = true;
    }); // 客戶端回應 pong 時,設置連接為活躍狀態

    const interval = setInterval(() => {
        console.log(wss.clients);
        wss.clients.forEach((client) => {
            if (client.isAlive === false) {
                console.log("終止連接");
                return client.terminate(); // 如果連接不活躍,終止連接
            }
            client.isAlive = false; // 暫時設置連接為不活躍
            client.ping(); // 發送 ping 幀以檢查連接狀態
            console.log("發送 ping 幀");
        });
    }, 3000); // 每 3 秒檢查一次連接狀態

    ws.on("close", () => {
        clearInterval(interval); // 連接關閉時,清除定時器
        console.log("關掉囉");
    });
});

解釋:
wss.clients可以看出你有多少個連接,如果有10個人向你連接則有10筆,而在每個交握中添加了isAlive的變數,然後對前端發送ping消息,如果前端沒給予回應則會關閉。

ping/pong
後端server發送ping訊號後,前端瀏覽器會自動用pong訊號接收並自動返回ping訊號,使得後端server的pong訊號可以觸發,從而控制isAlive這樣就可得知是否斷開連線了

client端

ws.onopen = () => {
    console.log("Connected to server");

    // 客戶端定期發送心跳訊息
    setInterval(() => {
        // 確保 WebSocket 連線仍然是 OPEN 狀態
        if (ws.readyState === WebSocket.OPEN) {
            ws.send(JSON.stringify({ type: "heartbeat" }));
            console.log("還活著");
        }
    }, 3000); // 每 3 秒發送一次心跳訊息
};

既然瀏覽器會自動幫我們回應pong訊息,那client幹嘛還要寫呢?
所以client也可不寫,但如果只靠瀏覽器的流程,可能就會少很多的訊息,如果你希望的是收到client的詳細訊息則可直接用計時器固定發些資訊給後端,後端再用message去接收判斷

不過也因為瀏覽器會自動去觸發因此js並無onping/onpong的指令,如果遇到client端需要自己寫,大概就是這樣運作的

小小廢話

原以為心跳只是單純刪除多餘的連結,後面想了想好像有資安問題就是塞一堆突然覺得挺有趣的,畢竟因為websocket會一直交握只要有一台電腦就可以輕鬆讓伺服器過載,但一般的fetch就需要大量的電腦一同攻擊才可能

不過應該也有檢查server負荷的方法就是了,避免使用有效連結讓伺服器卡死,但是比起沒有心跳能用殭屍方式塞爆,與用有效連結塞爆的server兩者的成本也會有導致攻擊方會不會扁你

不過我也非專業資安人士,只不過在寫的時候感覺websocket的持續連接好像會有這些問題,有問題請見諒哈哈

但也可從這些部分看出,Websocket雖然有者持續連接的好處在,但要做的各種防禦排錯處理等等都會很複雜,比起以往的單向傳輸還來的須注意更多就是了

下面內容轉自網站:https://valuementor.com/managed-security/understanding-web-sockets-attacks/

保護 WebSocket 連線的安全

為了最大限度地降低 WebSocket 出現安全漏洞的風險,請遵循以下準則:

  • 實施適當的輸入驗證和輸出編碼以防止 XSS 攻擊。
  • 使用安全、加密的連線 (SSL/TLS) 來保護 WebSocket 通訊。
  • 實施強大的身份驗證和授權機制。
  • 保護WebSocket握手訊息免受CSRF攻擊,避免跨站WebSockets劫持漏洞。
  • 監控 WebSocket 連線並對其進行速率限制,以偵測和減輕 DoS/DDoS 攻擊。
  • 定期更新和修補 WebSocket 伺服器軟體以解決漏洞。

資安真的挺多的,至於WebSocket的DDoS是否有我想的那麼簡單也不好說,有機會在試試他的其他問題例如CSRF

今天就這樣囉


上一篇
[day5]觀察WebSocket運作流程
下一篇
[day7]前端框架React SPA?介紹
系列文
雙向奔赴的websocket與冰冷的react30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言