淺談SYNPROXY

小米運維發表於2019-03-21
本文主要介紹了SYNPROXY的相關原理、DDoS簡述、LVS相關應用等內容。
上篇文章回顧:容器程式Core Dump處理

SYNPROXY簡述

SYNPROXY是防禦DDoS攻擊的有力手段。

SYNPROXY是一個TCP握手代理,原生支援是從Linux核心3.13開始的。當一個TCP請求從客戶端發出時,首先與該握手代理進行三次握手,其採用SYNCookie技術,只有該請求通過cookie合法性校驗,代理伺服器才會與伺服器進行真正的TCP三次握手,此時客戶端和服務端之間的連線才真正建立,進入資料傳輸階段。

DDoS簡述

DDoS(Distributed Denial of Service,分散式拒絕服務)攻擊源於DoS(Denial of Service,拒絕服務)攻擊。DoS攻擊又稱洪水攻擊,其攻擊目的主要是使計算機的網路或系統資源耗盡,無法為正常請求建立連線,導致客戶端無法正常訪問。而當攻擊者為兩個及兩個以上的被攻陷的計算機組成的“殭屍團”時,則為DDoS攻擊,相比於DoS的“單挑”,顯然“群毆”來得殺傷力和破壞力更大。

DDoS的攻擊形式多樣,按照攻擊形式分為頻寬消耗型攻擊和資源消耗型攻擊,按照攻擊層級分為網路層DDoS攻擊和應用層DDoS攻擊。網路層DDoS攻擊最為常見和殺傷力較大的攻擊為SYNFlood攻擊。

SYNFlood攻擊利用TCP協議缺陷,傳送大量偽造的TCP連線請求(SYN報文),使被攻擊方的記憶體資源不足或者CPU超負載。即,建立TCP連線需要三次握手,被攻擊方在收到攻擊方SYN報文回覆SYN-ACK報文,但是偽造的SYN報文一般源IP地址不存在或不可達,導致被攻擊方為維護數以萬計的SYN_RCVD狀態(半開放狀態)連線而消耗巨大的資源,產生頻繁的超時重傳動作,使得正常的連線請求無法建立,甚至於被攻擊方的CPU資源被耗盡,伺服器處於癱瘓狀態。

DDoS讓人頭疼的地方在於,它就像普通感冒一樣,只能防禦,難以根治,並且攻擊手段在不斷進化。而SYNPROXY作為最為經濟實惠的防禦手段,成為眾多防禦手段中較為常用的一種。

SYNPROXY原理

前文說過,SYNPROXY基於SYNCookie技術實現防禦DDoS功能,而SYNCookie技術又是基於TCP三次握手做的修改,所以我們需要回顧下TCP三次握手,進而學習SYNCookie技術和SYNPROXY原理。

1、TCP三次握手

我們知道,TCP是一種可靠的、面向連線的、基於位元組流的四層傳輸層協議,連線建立需要TCP三次握手。

淺談SYNPROXY

第一次握手:客戶端say hello,傳送SYN報文,進入SYN_SEND狀態,服務端收到客戶 端的“問候”(SYN報文)後回以SYN-ACK報文表示友好,進入SYN_RCVD狀態;
第二次握手:客戶端收到服務端的SYN-ACK報文後,傳送ACK報文,進入ESTABLISED狀態;
第三次握手:服務端在收到客戶端的ACK報文後,進入ESTABLISED狀態,兩方正式“建交”。

SYNCookie技術

SYNCookie由Daniel J. Bernstein發明,主要用於防禦SYNFlood攻擊。它的原理是,在伺服器接收到SYN報文並返回SYN-ACK報文時,不分配一個專門的資料區,而是根據這個SYN報文計算出一個cookie值。這個cookie值作為將要返回的SYN ACK報文的初始序列號。當客戶端返回一個ACK報文時,伺服器根據報文頭資訊計算cookie,與客戶端返回的確認序列號(初始序列號 + 1)進行對比,如果相同,則是一個正常連線,然後,分配資源,建立連線。實現的關鍵在於cookie的計算,cookie的計算應該包含本次連線的狀態資訊,使攻擊者不能偽造。關於cookie如何計算和校驗參見SYN cookies。

SYNPROXY原理

淺談SYNPROXY

工作流程(圖中紅色部分就是由握手代理模擬發出的,對於客戶端而言是透明的),簡要分為以下三個階段:

  • 第一階段:客戶端與握手代理進行三次握手,第二步握手代理回覆客戶端的ACK-ACK報文攜帶的初始序列號(ISN1)由SYNCookie演算法生成,與SYNCookie工作流程相似;

  • 第二階段:當cookie驗證通過後,握手代理充當客戶端和服務端進行三次握手,並負責校正初始序列號(ISN2)和視窗大小;

  • 第三階段:在連線建立之後握手代理負責調整客戶端和服務端之間資料傳輸過程中的序列號和確認號。

那麼問題來了,為什麼第二步握手代理回覆給客戶端的SYN-ACK報文的接收視窗大小為0,又何時何法將服務端真正的視窗大小透傳給客戶端?握手代理又如何協調客戶端和服務端之間的初始序列號(ISN)以保證真正的連線建立?

關於視窗的問題

  • 為什麼第二步握手代理回覆的SYN-ACK報文的接收視窗大小為0?在客戶端和伺服器端真正建立連線前,首先,握手代理和客戶端要進行三次握手,其次才是握手代理和服務端的三次握手,若是在此時,客戶端傳送資料過來,無疑不會被服務端正確接收。為了避免這種情況的發生,握手代理回覆給客戶端一個大小為0的視窗,告訴客戶端“我還沒有準備好接收資料”,因為此時僅僅是握手代理和客戶端之間的三次握手,真正的連線尚未建立,無法傳輸資料。

  • 那麼,何時何法將服務端真正的視窗大小透傳給客戶端?當握手代理和伺服器完成了三次握手,握手代理再將服務端回覆的SYN-ACK報文中真正的視窗大小(圖中第五步)透傳給客戶端,告訴客戶端“我準備好了,可以開始傳輸資料了”。

關於序列號的問題

  • 第二步握手代理回覆的SYN-ACK報文中所攜帶的初始序列號是如何產生的?這個序列號是握手代理採用SYNCookie技術計算得出的cookie值,這個cookie值根據客戶端的SYN報文中的源地址、目的地址、源埠、目的埠等資訊計算出來的,準確性很高,使得客戶端第三次握手發來的ACK報文幾乎無法被偽造。

  • 第五步服務端回覆的SYN-ACK報文中所攜帶的初始序列號,握手代理又如何透傳給客戶端?可以看出,兩個ISN(ISN1、ISN2)是獨立生成的,由於客戶端並不知道握手代理的存在,會將握手代理髮送的SYN-ACK記錄在TCP連線中,在握手代理透傳服務端的ACK-SYN時,攜帶的是服務端生成的ISN2,與之前的ISN1不一樣,因此這個透傳的SYN-ACK應當是不會被客戶端正確接收的。那麼,SYNPROXY是如何解決這個問題呢

    1.握手代理將服務端的SYN-ACK報文去掉SYN標記,僅保留ACK標記,作為一個視窗更新動作傳送給客戶端;

    2.對於從服務端收到的任何資料包文,在發往客戶端前,調整其序列號使得與客戶端握手時的ISN相適應;
    3.對於從客戶端收到的任何資料包文,在發往服務端前,調整其ACK使得與服務端握手時的ISN相適應。

如此,所有問題都解決了,SYNPQOXY就像一個智慧傳話筒,全程參與著客戶端和服務端的資料傳輸過程。

結論

需要說明,由於SYNPROXY自身導致的效能缺陷,再加上DDoS攻擊的無法完全防禦性,依靠SYNPROXY完全抵禦DDoS攻擊幾乎不可能。只要攻擊者發起規模足夠大的攻擊,SYNPROXY便有可能抵擋不住攻勢。實踐證明,SYNPROXY對SYNFlood攻擊具有有效且有限的防禦作用。

LVS應用

LVS為什麼要使用SYNPROXY

Linux核心原生的ip_vs模組主要實現負載均衡功能,對DDoS攻擊幾乎沒有防護作用,後端真實伺服器一般也不具備這種攻擊防禦,或者防禦作用不高,一旦這種攻擊包被轉發到後端真實伺服器上,會造成後端真實伺服器崩潰,LVS機器也會因此產生資源消耗,影響LVS轉發效能。

LVS支援SYNPROXY

"A distribution of Linux Virtual Server with some advanced features. It introduces a new packet forwarding method - FULLNAT other than NAT/Tunneling/DirectRouting, and defense mechanism against synflooding attack - SYNPROXY."

"This FullNAT and SYNPROXY code for IPVS in Linux kernel 2.6.32 was written by Jiaming Wu,Jiajun Chen,Ziang Chen,Shunmin Zhu at taobao.com, Jian Chen at 360.cn, with some advising from Wensong Zhang at taobao.com. The code was affected by ideas of the source NAT and SYNPROXY version that was hard coded to IPVS in Linux kernel 2.6.9 by Wen Li, Yan Tian, Jian Chen, Yang Yi, Yaoguang Sun, Fang Han, Ying liu and Jiaming Wu at baidu.com in 2009.

The FullNAT and SYNPROXY support were added to keepalived/ipvsadm by Jiajun Chen and Ziang Chen at taobao.com."

淘寶開發的LVS支援SYNPROXY功能,基於TCP的SYNCookie技術,適用於LVS/FULLNAT模式。原始碼請移步官方地址alibaba-LVS/FULLNAT

小結

本文淺談DDoS攻擊、SYNCookie技術和SYNPROXY原理,更多關於SYNPROXY和SYNCookie的具體實現以及LVS/FULLNAT模式是如何實現SYNPROXY,需要深入研究原始碼,希望此文對大家有所幫助。

參考資料

文章首發於公眾號“小米運維”,點選檢視原文