本篇文章在于淺嘗輒止的分析TCP的SYNCookie機(jī)制
一個連接的建立需要進(jìn)行TCP三次握手踢步,如下圖所示
簡單來說侮攀,服務(wù)端收到客戶端的SYN包之后未巫,將連接放到半連接隊列中扫尺, 當(dāng)服務(wù)端再次收到客戶端的ACK包之后约急,會將連接從半連接隊列移到全連接隊列中零远, 這樣服務(wù)端的程序調(diào)用accept()方法的時候,就可以從全連接隊列中獲取到連接了.
這里要提到SYN Flood厌蔽, 如果一個客戶端在短時間內(nèi)發(fā)送大量的SYN包給服務(wù)端牵辣,而且不發(fā)送ACK包給服務(wù)端, 這樣會導(dǎo)致服務(wù)端的半連接隊列很快就被填滿了奴饮, 間接導(dǎo)致其他客戶端無法與服務(wù)端完成三次握手.
接下來纬向,通過實(shí)驗?zāi)M這樣的場景,以及如何解決它.
【實(shí)驗】
一臺ubuntu-20.04機(jī)器作為服務(wù)端(IP=192.168.0.103)戴卜, 一臺Kali機(jī)器作為客戶端(IP=192.168.0.102)
首先逾条,需要修改一個服務(wù)端的配置文件(/etc/sysctl.conf),修改的文件內(nèi)容如下
如果sysctl.conf文件中沒有對應(yīng)的屬性值則自己手動添加
屬性值的含義如下
net.ipv4.tcp_syncookies = 0 表示不開啟SYNCookie機(jī)制
net.ipv4.tcp_max_syn_backlog = 5 設(shè)置半連接隊列大小
net.core.somaxconn = 5 設(shè)置全連接隊列大小
這里只是將半連接隊列和全連接隊列設(shè)置的小了一些, 除此之外沒有其他特殊原因
接下來投剥,在服務(wù)端师脂,使用Python語言搭建一個簡單的Server程序,代碼如下
import socket
server=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
server.bind(('192.168.0.103',8082))
server.listen(5)
程序監(jiān)聽在8082端口
然后在客戶端機(jī)器上江锨,通過netwox命令吃警,向服務(wù)端持續(xù)發(fā)送SYN包,模擬SYN Flood
以上命令會向192.168.0.103機(jī)器的8082端口發(fā)送SYN包
通過 apt install netwox 安裝netwox命令
接下來泳桦, 我們看一下服務(wù)端的一些現(xiàn)象
在服務(wù)端執(zhí)行 netstat -s | grep LISTEN 命令汤徽,可以查看半連接隊列的情況
可以發(fā)現(xiàn),被丟棄的SYN包的數(shù)量一直在增長. 因為客戶端一直在向服務(wù)端發(fā)送SYN包灸撰, 當(dāng)半連接隊列滿了之后谒府,后面的SYN包只能被丟棄
在服務(wù)端執(zhí)行 sudo tcpdump -nn -i enp0s8 port 8082 命令,如下圖
192.168.0.103屬于enp0s8網(wǎng)卡
可以發(fā)現(xiàn)浮毯, 客戶端一直發(fā)送SYN包給服務(wù)端
而且通過查看系統(tǒng)日志完疫,比如使用dmesg命令或者查看 /var/log/kern.log文件,能夠發(fā)現(xiàn)如下一行信息
TCP: request_sock_TCP: Possible SYN flooding on port 8082. Dropping request.
大概意思是债蓝,在8082端口可能發(fā)生了SYN Flood攻擊壳鹤, 請求被丟棄了.
假如我們有另外一個客戶端,向服務(wù)端正常的發(fā)送三次握手饰迹,比如執(zhí)行 telnet 192.168.0.103 8082 命令
它會一直處于連接中芳誓,直到超時失敗.
【總結(jié)】 由于半連接隊列滿了余舶,導(dǎo)致客戶端無法與服務(wù)端建立連接
針對上面的情況,TCP給出了一個解決思路锹淌,修改服務(wù)端的配置文件(/etc/sysctl.conf)匿值,將 net.ipv4.tcp_syncookies = 1 ,表示開啟SYNCookie機(jī)制赂摆, 其他的無需修改挟憔, 繼續(xù)上面的實(shí)驗
通過 netstat -s | grep LISTEN 命令,可以發(fā)現(xiàn)SYN包沒有再被丟棄 (被丟棄的數(shù)量沒有發(fā)生變化)
再次通過dmesg命令查看系統(tǒng)日志烟号,發(fā)現(xiàn)如下一行信息
TCP: request_sock_TCP: Possible SYN flooding on port 8082. Sending cookies.
大概意思是绊谭,在8082端口可能發(fā)生了SYN Flood攻擊, 發(fā)送了cookies.
是因為在服務(wù)端開啟了SYNCookie機(jī)制汪拥, 即便半連接隊列滿了达传, 通過Cookie機(jī)制,依然可以保證讓客戶端連接到服務(wù)端.
這個時候通過另外一個客戶端執(zhí)行 telnet 192.168.0.103 8082 命令喷楣,是可以正常連接到服務(wù)端的趟大,如下圖
【總結(jié)】開啟TCP的SYN Cookie機(jī)制,即便半連接隊列滿了铣焊,客戶端也可以成功與服務(wù)端建立連接