查看 tcp 的網絡鏈接狀況nginx
netstat -anp |grep tcp
複製代碼
TCP快速打開(TCP Fast Open,TFO)是對TCP的一種簡化握手手續的拓展,用於提升兩端點間鏈接的打開速度。簡而言之,就是在TCP的三次握手過程當中傳輸實際有用的數據安全
三次握手的過程當中,當用戶首次訪問server時,發送syn包,server根據用戶IP生成cookie,並與syn+ack一同發回client;client再次訪問server時,在syn包攜帶TCP cookie;若是server校驗合法,則在用戶回覆ack前就能夠直接發送數據;不然按照正常三次握手進行。bash
TFO提升性能的關鍵是省去了熱請求的三次握手,這在充斥着小對象的移動應用場景中可以極大提高性能。服務器
sysctl -w net.ipv4.tcp_fastopen=1
其中數字包含含義以下:
0: 關閉
1: 做爲客戶端時使用 TFO
2: 做爲服務端時使用 TFO
3. 所有使用TFO
複製代碼
因須要相關代碼支持開啓 TCP_FASTOPEN 選項, 因此沒法正常抓nginx請求包, 此圖來源於網絡.cookie
從上面的示例中能夠看到 TFO 的其中一個優勢就是能夠提升網絡的利用率,尤爲是有頻繁網絡創建的情景,TFO 的優點尤爲明顯。可是,除此以外,TFO 還有一個很大的優勢就是能夠防止 SYN泛洪攻擊。網絡
Message Flow:tcp
Requesting Fast Open Cookie in connection 1:
TCP A (Client) TCP B (Server)
______________ ______________
CLOSED LISTEN
#1 SYN-SENT ----- <SYN,CookieOpt=NIL> ----------> SYN-RCVD
#2 ESTABLISHED <---- <SYN,ACK,CookieOpt=C> ---------- SYN-RCVD
(caches cookie C)
Performing TCP Fast Open in connection 2:
TCP A (Client) TCP B (Server)
______________ ______________
CLOSED LISTEN
#1 SYN-SENT ----- <SYN=x,CookieOpt=C,DATA_A> ----> SYN-RCVD
#2 ESTABLISHED <---- <SYN=y,ACK=x+len(DATA_A)+1> ---- SYN-RCVD
#3 ESTABLISHED <---- <ACK=x+len(DATA_A)+1,DATA_B>---- SYN-RCVD
#4 ESTABLISHED ----- <ACK=y+1>--------------------> ESTABLISHED
#5 ESTABLISHED --- <ACK=y+len(DATA_B)+1>----------> ESTABLISHED
複製代碼
TCP SYN泛洪發生在OSI第四層,這種方式利用TCP協議的特性,就是三次握手。攻擊者發送TCP SYN,SYN是TCP三次握手中的第一個數據包,而當服務器返回ACK後,該攻擊者就不對其進行再確認,那這個TCP鏈接就處於掛起狀態,也就是所謂的半鏈接狀態,服務器收不到再確認的話,還會重複發送ACK給攻擊者。這樣更加會浪費服務器的資源。攻擊者就對服務器發送很是大量的這種TCP鏈接,因爲每個都無法完成三次握手,因此在服務器上,這些TCP鏈接會由於掛起狀態而消耗CPU和內存,最後服務器可能死機,就沒法爲正經常使用戶提供服務了。(來源:百度百科)性能
經過上圖流程, 咱們發如今 SYN 中間實際上是維護了一個隊列, SYN 攻擊就是短期內僞造不一樣 IP 地址的 SYN 報文, 快速佔滿 backlog 隊列, 使服務不能提供正常服務.優化
咱們觀察圖中, 在 server 端維護着兩個隊列, 分別是 syns queue 和 accept queue, 這兩個隊列的大小可使用 tcp_max_syn_backlog 和 somaxconn 兩個內核配置.spa
tcp_max_syn_backlog 是指定所能接受SYN同步包的最大客戶端數量,即半鏈接上限
somaxconn 是指服務端所能accept即處理數據的最大客戶端數量,即完成鏈接上限
複製代碼
其中還有兩個內核參數咱們常常接觸:
tcp_abort_on_overflow
當 tcp 創建鏈接的 3 路握手完成後,將鏈接置入 ESTABLISHED 狀態並交付給應用程序的 backlog 隊列時,會檢查 backlog 隊列是否已滿。若已滿,一般行爲是將鏈接還原至 SYN_ACK 狀態,以形成 3 路握手最後的 ACK 包意外丟失假象 —— 這樣在客戶端等待超時後可重發 ACK —— 以再次嘗試進入 ESTABLISHED 狀態 —— 做爲一種修復/重試機制。若是啓用 tcp_abort_on_overflow 則在檢查到 backlog 隊列已滿時,直接發 RST 包給客戶端終止此鏈接 —— 此時客戶端程序會收到 104 Connection reset by peer 錯誤。
tcp_syncookies
在 tcp 創建鏈接的 3 次握手過程當中,當服務端收到最初的 SYN 請求時,會檢查應用程序的 syn_backlog 隊列是否已滿。若已滿,一般行爲是丟棄此 SYN 包。若未滿,會再檢查應用程序的 backlog 隊列是否已滿。若已滿而且系統根據歷史記錄判斷該應用程序不會較快消耗鏈接時,則丟棄此 SYN 包。若是啓用 tcp_syncookies 則在檢查到 syn_backlog 隊列已滿時,不丟棄該 SYN 包,而改用 syncookie 技術進行 3 次握手。 (當隊列未滿時, 不會使用此方式).
文中部分圖片和知識來源於網絡.
部分 TCP 內核參數完全瞭解(blog.csdn.net/rain_qingti…)
更多精彩內容關注公衆號 (呆呆熊的技術路) :