39 | 案例篇:怎么缓解 DDoS 攻击带来的性能下降问题?
生活随笔
收集整理的這篇文章主要介紹了
39 | 案例篇:怎么缓解 DDoS 攻击带来的性能下降问题?
小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.
上一節(jié),學(xué)習(xí)了 tcpdump 和 Wireshark 的使用方法,并通過(guò)幾個(gè)案例,帶你用這兩個(gè)工具實(shí)際分析了網(wǎng)絡(luò)的收發(fā)過(guò)程。碰到網(wǎng)絡(luò)性能問題,不要忘記可以用 tcpdump 和 Wireshark 這兩個(gè)大殺器,抓取實(shí)際傳輸?shù)木W(wǎng)絡(luò)包,排查潛在的性能問題。今天,來(lái)看另外一個(gè)問題,怎么緩解 DDoS(Distributed Denial of Service)帶來(lái)的性能下降問題。
DDoS 簡(jiǎn)介
DDoS 的前身是 DoS(Denail of Service),即拒絕服務(wù)攻擊,指利用大量的合理請(qǐng)求,來(lái)占用過(guò)多的目標(biāo)資源,從而使目標(biāo)服務(wù)無(wú)法響應(yīng)正常請(qǐng)求。DDoS(Distributed Denial of Service) 則是在 DoS 的基礎(chǔ)上,采用了分布式架構(gòu),利用多臺(tái)主機(jī)同時(shí)攻擊目標(biāo)主機(jī)。這樣,即使目標(biāo)服務(wù)部署了網(wǎng)絡(luò)防御設(shè)備,面對(duì)大量網(wǎng)絡(luò)請(qǐng)求時(shí),還是無(wú)力應(yīng)對(duì)。比如,目前已知的最大流量攻擊,正是去年 Github 遭受的 DDoS 攻擊,其峰值流量已經(jīng)達(dá)到了 1.35Tbps,PPS 更是超過(guò)了 1.2 億(126.9 million)。從攻擊的原理上來(lái)看,DDoS 可以分為下面幾種類型。- 第一種,耗盡帶寬。無(wú)論是服務(wù)器還是路由器、交換機(jī)等網(wǎng)絡(luò)設(shè)備,帶寬都有固定的上限。帶寬耗盡后,就會(huì)發(fā)生網(wǎng)絡(luò)擁堵,從而無(wú)法傳輸其他正常的網(wǎng)絡(luò)報(bào)文。
- 第二種,耗盡操作系統(tǒng)的資源。網(wǎng)絡(luò)服務(wù)的正常運(yùn)行,都需要一定的系統(tǒng)資源,像是 CPU、內(nèi)存等物理資源,以及連接表等軟件資源。一旦資源耗盡,系統(tǒng)就不能處理其他正常的網(wǎng)絡(luò)連接。
- 第三種,消耗應(yīng)用程序的運(yùn)行資源。應(yīng)用程序的運(yùn)行,通常還需要跟其他的資源或系統(tǒng)交互。如果應(yīng)用程序一直忙于處理無(wú)效請(qǐng)求,也會(huì)導(dǎo)致正常請(qǐng)求的處理變慢,甚至得不到響應(yīng)。
案例準(zhǔn)備
下面的案例仍然基于 Ubuntu 18.04,同樣適用于其他的 Linux 系統(tǒng)。我使用的案例環(huán)境是這樣的:機(jī)器配置:2 CPU,8GB 內(nèi)存。預(yù)先安裝 docker、sar 、hping3、tcpdump、curl 等工具,比如 apt-get install docker.io hping3 tcpdump curl這些工具你應(yīng)該都比較熟悉了。其中,hping3 在 系統(tǒng)的軟中斷 CPU 使用率升高案例 中曾經(jīng)介紹過(guò),它可以構(gòu)造 TCP/IP 協(xié)議數(shù)據(jù)包,對(duì)系統(tǒng)進(jìn)行安全審計(jì)、防火墻測(cè)試、DoS 攻擊測(cè)試等。本次案例用到三臺(tái)虛擬機(jī),我畫了一張圖來(lái)表示它們之間的關(guān)系。你可以看到,其中一臺(tái)虛擬機(jī)運(yùn)行 Nginx ,用來(lái)模擬待分析的 Web 服務(wù)器;而另外兩臺(tái)作為 Web 服務(wù)器的客戶端,其中一臺(tái)用作 DoS 攻擊,而另一臺(tái)則是正常的客戶端。使用多臺(tái)虛擬機(jī)的目的,自然還是為了相互隔離,避免“交叉感染”。由于案例只使用了一臺(tái)機(jī)器作為攻擊源,所以這里的攻擊,實(shí)際上還是傳統(tǒng)的 DoS ,而非 DDoS。接下來(lái),我們打開三個(gè)終端,分別 SSH 登錄到三臺(tái)機(jī)器上(下面的步驟,都假設(shè)終端編號(hào)與圖示 VM 編號(hào)一致),并安裝上面提到的這些工具。同以前的案例一樣,下面的所有命令,都默認(rèn)以 root 用戶運(yùn)行。如果你是用普通用戶身份登陸系統(tǒng),請(qǐng)運(yùn)行 sudo su root 命令切換到 root 用戶。接下來(lái),我們就進(jìn)入到案例操作環(huán)節(jié)。案例分析
首先,在終端一中,執(zhí)行下面的命令運(yùn)行案例,也就是啟動(dòng)一個(gè)最基本的 Nginx 應(yīng)用:# 運(yùn)行 Nginx 服務(wù)并對(duì)外開放 80 端口 # --network=host 表示使用主機(jī)網(wǎng)絡(luò)(這是為了方便后面排查問題) $ docker run -itd --name=nginx --network=host nginx然后,在終端二和終端三中,使用 curl 訪問 Nginx 監(jiān)聽的端口,確認(rèn) Nginx 正常啟動(dòng)。假設(shè) 192.168.0.30 是 Nginx 所在虛擬機(jī)的 IP 地址,那么運(yùn)行 curl 命令后,你應(yīng)該會(huì)看到下面這個(gè)輸出界面:# -w 表示只輸出 HTTP 狀態(tài)碼及總時(shí)間,-o 表示將響應(yīng)重定向到 /dev/null $ curl -s -w 'Http code: %{http_code}\nTotal time:%{time_total}s\n' -o /dev/null http://192.168.0.30/ ... Http code: 200 Total time:0.002s從這里可以看到,正常情況下,我們?cè)L問 Nginx 只需要 2ms(0.002s)。接著,在終端二中,運(yùn)行 hping3 命令,來(lái)模擬 DoS 攻擊:# -S 參數(shù)表示設(shè)置 TCP 協(xié)議的 SYN(同步序列號(hào)),-p 表示目的端口為 80 # -i u10 表示每隔 10 微秒發(fā)送一個(gè)網(wǎng)絡(luò)幀 $ hping3 -S -p 80 -i u10 192.168.0.30現(xiàn)在,再回到終端一,你就會(huì)發(fā)現(xiàn),現(xiàn)在不管執(zhí)行什么命令,都慢了很多。不過(guò),在實(shí)踐時(shí)要注意:- 如果你的現(xiàn)象不那么明顯,那么請(qǐng)嘗試把參數(shù)里面的 u10 調(diào)小(比如調(diào)成 u1),或者加上–flood 選項(xiàng);
- 如果你的終端一完全沒有響應(yīng)了,那么請(qǐng)適當(dāng)調(diào)大 u10(比如調(diào)成 u30),否則后面就不能通過(guò) SSH 操作 VM1。
- 即客戶端構(gòu)造大量的 SYN 包,請(qǐng)求建立 TCP 連接;
- 而服務(wù)器收到包后,會(huì)向源 IP 發(fā)送 SYN+ACK 報(bào)文,并等待三次握手的最后一次 ACK 報(bào)文,直到超時(shí)。
攻擊源IP不固定解決的方法
不過(guò),一般來(lái)說(shuō),SYN Flood 攻擊中的源 IP 并不是固定的。比如,你可以在 hping3 命令中,加入 --rand-source 選項(xiàng),來(lái)隨機(jī)化源 IP。不過(guò),這時(shí),剛才的方法就不適用了。幸好,我們還有很多其他方法,實(shí)現(xiàn)類似的目標(biāo)。比如,你可以用以下兩種方法,來(lái)限制 syn 包的速率:# 限制 syn 并發(fā)數(shù)為每秒 1 次 $ iptables -A INPUT -p tcp --syn -m limit --limit 1/s -j ACCEPT# 限制單個(gè) IP 在 60 秒新建立的連接數(shù)為 10 $ iptables -I INPUT -p tcp --dport 80 --syn -m recent --name SYN_FLOOD --update --seconds 60 --hitcount 10 -j REJECT到這里,我們已經(jīng)初步限制了 SYN Flood 攻擊。不過(guò)這還不夠,因?yàn)槲覀兊陌咐€只是單個(gè)的攻擊源。如果是多臺(tái)機(jī)器同時(shí)發(fā)送 SYN Flood,這種方法可能就直接無(wú)效了。因?yàn)槟愫芸赡軣o(wú)法 SSH 登錄(SSH 也是基于 TCP 的)到機(jī)器上去,更別提執(zhí)行上述所有的排查命令。系統(tǒng) TCP 優(yōu)化
所以,這還需要你事先對(duì)系統(tǒng)做一些 TCP 優(yōu)化。比如,SYN Flood 會(huì)導(dǎo)致 SYN_RECV 狀態(tài)的連接急劇增大。在上面的 netstat 命令中,你也可以看到 190 多個(gè)處于半開狀態(tài)的連接。不過(guò),半開狀態(tài)的連接數(shù)是有限制的,執(zhí)行下面的命令,你就可以看到,默認(rèn)的半連接容量只有 256:$ sysctl net.ipv4.tcp_max_syn_backlog net.ipv4.tcp_max_syn_backlog = 256換句話說(shuō), SYN 包數(shù)再稍微增大一些,就不能 SSH 登錄機(jī)器了。 所以,你還應(yīng)該增大半連接的容量,比如,你可以用下面的命令,將其增大為 1024:$ sysctl -w net.ipv4.tcp_max_syn_backlog=1024 net.ipv4.tcp_max_syn_backlog = 1024另外,連接每個(gè) SYN_RECV 時(shí),如果失敗的話,內(nèi)核還會(huì)自動(dòng)重試,并且默認(rèn)的重試次數(shù)是 5 次。你可以執(zhí)行下面的命令,將其減小為 1 次:$ sysctl -w net.ipv4.tcp_synack_retries=1 net.ipv4.tcp_synack_retries = 1開啟 SYN Cookies
除此之外,TCP SYN Cookies 也是一種專門防御 SYN Flood 攻擊的方法。SYN Cookies 基于連接信息(包括源地址、源端口、目的地址、目的端口等)以及一個(gè)加密種子(如系統(tǒng)啟動(dòng)時(shí)間),計(jì)算出一個(gè)哈希值(SHA1),這個(gè)哈希值稱為 cookie。然后,這個(gè) cookie 就被用作序列號(hào),來(lái)應(yīng)答 SYN+ACK 包,并釋放連接狀態(tài)。當(dāng)客戶端發(fā)送完三次握手的最后一次 ACK 后,服務(wù)器就會(huì)再次計(jì)算這個(gè)哈希值,確認(rèn)是上次返回的 SYN+ACK 的返回包,才會(huì)進(jìn)入 TCP 的連接狀態(tài)。因而,開啟 SYN Cookies 后,就不需要維護(hù)半開連接狀態(tài)了,進(jìn)而也就沒有了半連接數(shù)的限制。注意,開啟 TCP syncookies 后,內(nèi)核選項(xiàng) net.ipv4.tcp_max_syn_backlog 也就無(wú)效了。你可以通過(guò)下面的命令,開啟 TCP SYN Cookies:$ sysctl -w net.ipv4.tcp_syncookies=1 net.ipv4.tcp_syncookies = 1注意,上述 sysctl 命令修改的配置都是臨時(shí)的,重啟后這些配置就會(huì)丟失。所以,為了保證配置持久化,你還應(yīng)該把這些配置,寫入 /etc/sysctl.conf 文件中。比如:$ cat /etc/sysctl.conf net.ipv4.tcp_syncookies = 1 net.ipv4.tcp_synack_retries = 1 net.ipv4.tcp_max_syn_backlog = 1024不過(guò)要記得,寫入 /etc/sysctl.conf 的配置,需要執(zhí)行 sysctl -p 命令后,才會(huì)動(dòng)態(tài)生效。當(dāng)然案例結(jié)束后,別忘了執(zhí)行 docker rm -f nginx 命令,清理案例開始時(shí)啟動(dòng)的 Nginx 應(yīng)用。DDoS 到底該怎么防御
到這里,今天的案例就結(jié)束了。不過(guò),你肯定還有疑問。你應(yīng)該注意到了,今天的主題是“緩解”,而不是“解決” DDoS 問題。為什么不是解決 DDoS ,而只是緩解呢?而且今天案例中的方法,也只是讓 Nginx 服務(wù)訪問不再超時(shí),但訪問延遲還是比一開始時(shí)的 2ms 大得多。內(nèi)核參數(shù)
實(shí)際上,當(dāng) DDoS 報(bào)文到達(dá)服務(wù)器后,Linux 提供的機(jī)制只能緩解,而無(wú)法徹底解決。即使像是 SYN Flood 這樣的小包攻擊,其巨大的 PPS ,也會(huì)導(dǎo)致 Linux 內(nèi)核消耗大量資源,進(jìn)而導(dǎo)致其他網(wǎng)絡(luò)報(bào)文的處理緩慢。雖然你可以調(diào)整內(nèi)核參數(shù),緩解 DDoS 帶來(lái)的性能問題,卻也會(huì)像案例這樣,無(wú)法徹底解決它。跳過(guò)內(nèi)核協(xié)議棧
在之前的 C10K、C100K 文章 中,我也提到過(guò),Linux 內(nèi)核中冗長(zhǎng)的協(xié)議棧,在 PPS 很大時(shí),就是一個(gè)巨大的負(fù)擔(dān)。對(duì) DDoS 攻擊來(lái)說(shuō),也是一樣的道理。所以,當(dāng)時(shí)提到的 C10M 的方法,用到這里同樣適合。比如,你可以基于 XDP 或者 DPDK,構(gòu)建 DDoS 方案,在內(nèi)核網(wǎng)絡(luò)協(xié)議棧前,或者跳過(guò)內(nèi)核協(xié)議棧,來(lái)識(shí)別并丟棄 DDoS 報(bào)文,避免 DDoS 對(duì)系統(tǒng)其他資源的消耗。阻斷流量
不過(guò),對(duì)于流量型的 DDoS 來(lái)說(shuō),當(dāng)服務(wù)器的帶寬被耗盡后,在服務(wù)器內(nèi)部處理就無(wú)能為力了。這時(shí),只能在服務(wù)器外部的網(wǎng)絡(luò)設(shè)備中,設(shè)法識(shí)別并阻斷流量(當(dāng)然前提是網(wǎng)絡(luò)設(shè)備要能扛住流量攻擊)。比如,購(gòu)置專業(yè)的入侵檢測(cè)和防御設(shè)備,配置流量清洗設(shè)備阻斷惡意流量等。既然 DDoS 這么難防御,這是不是說(shuō)明, Linux 服務(wù)器內(nèi)部壓根兒就不關(guān)注這一點(diǎn),而是全部交給專業(yè)的網(wǎng)絡(luò)設(shè)備來(lái)處理呢?應(yīng)用層面
當(dāng)然不是,因?yàn)?DDoS 并不一定是因?yàn)榇罅髁炕蛘叽?PPS,有時(shí)候,慢速的請(qǐng)求也會(huì)帶來(lái)巨大的性能下降(這種情況稱為慢速 DDoS)。比如,很多針對(duì)應(yīng)用程序的攻擊,都會(huì)偽裝成正常用戶來(lái)請(qǐng)求資源。這種情況下,請(qǐng)求流量可能本身并不大,但響應(yīng)流量卻可能很大,并且應(yīng)用程序內(nèi)部也很可能要耗費(fèi)大量資源處理。這時(shí),就需要應(yīng)用程序考慮識(shí)別,并盡早拒絕掉這些惡意流量,比如合理利用緩存、增加 WAF(Web Application Firewall)、使用 CDN 等等。小結(jié)
今天,我們學(xué)習(xí)了分布式拒絕服務(wù)(DDoS)時(shí)的緩解方法。DDoS 利用大量的偽造請(qǐng)求,使目標(biāo)服務(wù)耗費(fèi)大量資源,來(lái)處理這些無(wú)效請(qǐng)求,進(jìn)而無(wú)法正常響應(yīng)正常的用戶請(qǐng)求。由于 DDoS 的分布式、大流量、難追蹤等特點(diǎn),目前還沒有方法可以完全防御 DDoS 帶來(lái)的問題,只能設(shè)法緩解這個(gè)影響。比如,你可以購(gòu)買專業(yè)的流量清洗設(shè)備和網(wǎng)絡(luò)防火墻,在網(wǎng)絡(luò)入口處阻斷惡意流量,只保留正常流量進(jìn)入數(shù)據(jù)中心的服務(wù)器中。在 Linux 服務(wù)器中,你可以通過(guò)內(nèi)核調(diào)優(yōu)、DPDK、XDP 等多種方法,來(lái)增大服務(wù)器的抗攻擊能力,降低 DDoS 對(duì)正常服務(wù)的影響。而在應(yīng)用程序中,你可以利用各級(jí)緩存、 WAF、CDN 等方式,緩解 DDoS 對(duì)應(yīng)用程序的影響。思考最后給你留一個(gè)思考題??吹浇裉斓陌咐?#xff0c;你可能會(huì)覺得眼熟。實(shí)際上,它正是在 系統(tǒng)的軟中斷 CPU 使用率升高案例 基礎(chǔ)上擴(kuò)展而來(lái)的。當(dāng)時(shí),我們是從軟中斷 CPU 使用率的角度來(lái)分析的,也就是說(shuō),DDoS 會(huì)導(dǎo)致軟中斷 CPU 使用率(softirq)升高?;叵胍幌庐?dāng)時(shí)的案例和分析思路,再結(jié)合今天的案例,你覺得還有沒有更好的方法,來(lái)檢測(cè) DDoS 攻擊呢?除了 tcpdump,還有哪些方法查找這些攻擊的源地址?1 增大隊(duì)列SYN最大半連接數(shù) sysctl -w et.ipv4.tcp_max_syn_backlog=30002 減少超時(shí)值:通過(guò)減少超時(shí)重傳次數(shù),sysctl -w net.ipv4.tcp_synack_retries=13 SYN_COOKIE : 開啟cookie echo "1" > / proc/sys/net/ipv4/tcp_syncookies?4 過(guò)濾可疑IP地址: iptables -I INPUT -s 192.168.0.2 -p tcp -j REJECT 禁止 0.2訪問阿里云的高防總結(jié)
以上是生活随笔為你收集整理的39 | 案例篇:怎么缓解 DDoS 攻击带来的性能下降问题?的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 38 | 案例篇:怎么使用 tcpdum
- 下一篇: 40 | 案例篇:网络请求延迟变大了,我