1. 程式人生 > >TCP三次握手和四次揮手過程原理及擴充套件(二)

TCP三次握手和四次揮手過程原理及擴充套件(二)

【1】TCP如何保證可靠性傳輸?

  1. 在傳遞資料之前,會有三次握手來建立連線
  2. 應用資料被分割成TCP認為最合適的資料庫(按位元組編號,合理分片),這和UDP完全不同,應用程式產生的資料報長度保持不變。(將資料截斷為合理的長度)
  3. 當TCP發出一個段後,它啟動一個定時器,等待目的端確認收到這個報文段。如果不能及時收到一個確認,將重發這個報文段。(超時重發)
  4. 當RCPU收到發自TCP連線的另一端的資料,它將傳送一個確認。這個確認不是立即傳送,通常將推遲幾分之一秒。(對於收到的請求,給出確認響應)(之所以推遲,可能是要對包做完整校驗)
  5. TCP將保持它首部和資料的校驗和。這是一個端到端的校驗和,目的是檢測資料在傳輸過程中的任何變化。如果收到段的檢驗和有差錯,TCP將丟棄這個報文段和不確認收到此報文段。(校驗出包有錯,丟棄報文段,不給出響應,TCP傳送資料端,超時會重發資料)
  6. 既然TCP報文段作為IP資料報來傳輸,而IP資料報的到達可能會失序,因此TCP報文段的到達也可能會失序。如果必要,TCP將對收到的資料進行重新排序,將收到的資料以正確的順序交給應用層。(對失序資料進行重新排序,然後才交給應用層)
  7. 既然IP資料報會發生重複,TCP的接收端必須丟棄重複的資料。(對於重複資料,能夠丟棄重複資料)
  8. TCP還能提供流量控制。TCP連線的每一方都有固定大小的緩衝空間。TCP的接收端只允許另一端傳送接收端緩衝區所能接納的資料。這將防止較快主機致使較慢主機的快取區溢位。TCP使用的流量控制協議是可變大小的滑動視窗協議。
  9. TCP還能提供擁塞控制。當網路擁塞時,減少資料的傳送。

【2】TCP建立連線之後怎麼保持連線(檢測連線斷沒斷)?

         兩種技術可以運用。一種是由TCP協議層實現的Keepalive機制另一種是由應用層自己實現的HeartBeat心跳包

               1.在TCP中有一個Keep-alive的機制可以檢測死連線,原理很簡單:當連線閒置一定的時間(引數可以設定,預設是兩小時)之後,TCP協議會向對方傳送一個keepalive探針包(包內沒有資料),對方再收到包以後,如果連線一切正常,應該回復一個ACK;如果連接出現錯誤了(例如對方重啟了,連線狀態丟失),則應當回覆一個RST;如果對方沒有回覆,那麼,伺服器每隔一定的時間(引數可以設定)再發送keepalive探針包。如果連續多個包(引數值可以設定)都被無視了,說明連線斷開了。

              2.心跳包之所以叫心跳包是因為:它向心跳一樣每隔固定時間發一次,以此來告訴伺服器,這個客戶端好活著。事實上這是為了表示長連線,至於這個包的內容,是沒有什麼特殊規定的,不過一般都是很小的包,或者只包含包頭的一個空包。由應用程式自己傳送心跳包來檢測連線的健康性。客戶端可以在一個Timer中或者低級別的執行緒中定時向伺服器傳送一個短小精悍的包,並等待伺服器的迴應,客戶端程式在一定時間內沒有收到伺服器迴應即認為連線不可用,同樣,伺服器在一定時間內沒有收到客戶端的心跳包則認為客戶端已經掉線。

【3】TCP三次握手有哪些漏洞?

  1.      SYN Flood攻擊   : 

            SYN Flood是DDOS攻擊的方式之一,這是一種利用TCP協議缺陷,傳送大量偽造的TCP連線請求,從而使得被攻擊方資源耗盡(CPU滿負荷或記憶體不足)的攻擊方式。

            要明白這種攻擊的基本原理,還是要從TCP連線建立的過程開始說起(上篇文章已經詳細說明過,這裡再概述一下):

            首先,請求端(客戶端)傳送一個包含SYN標誌的TCP報文,SYN即同步(Synchronize),同步報文會指明客戶端所使用的埠號以及TCP連線的初始化序列號。

           第二步:伺服器在收到客戶端的SYN報文後,將返回一個SYN+ACK的報文,表示客戶端的請求被接受,同時TCP序列號加一,ACK即確認(Acknowledgment)。

          第三步:客戶端也返回一個確認報文ACK給伺服器端,同時TCP序列號被加一,到此一個TCP連線完成。

          以上的連線過程在TCP協議中被稱為三次握手。

          問題就出現在TCp連線的三次握手中,假設一個使用者向伺服器傳送了SYN報文後突然宕機或者掉線,那麼伺服器在發出SYN+ACK應答報文後是無法收到客戶端的ACK報文的(第三次握手無法完成),這種情況下伺服器一般會不停的重試(再次傳送SYN+ACK給客戶端)並等待一段時間後丟失這個未完成的連線,這段時間的長度我們成為SYN Timeout(大約為30秒~2分鐘);一個使用者出現異常導致伺服器的一個執行緒等待1分鐘並不是什麼很大的問題,但是如果有一個惡意的攻擊者傳送大量偽造原IP地址的攻擊報文,傳送到伺服器端,伺服器端將為了維護一個非常大的半連線佇列而消耗非常多的CPU時間和記憶體。伺服器端也將忙於處理攻擊者偽造的TCP連線請求而無暇顧及客戶端的正常請求(畢竟在這種時候客戶端的正常請求比例非常之小),此時從正常客戶的角度來看,伺服器失去響應,這種情況我們稱作:伺服器端受到了SYN Flood攻擊(SYN洪水攻擊)。

       原理:攻擊者首先偽造地址對伺服器發起SYN請求,伺服器迴應(AYN+ACK)包,而真實的IP會認為,我沒有發請求,不作迴應。伺服器沒有收到迴應,這樣的話,伺服器不知道(SYN+ACK)是否傳送成功,預設情況下會重試5此(tcp_syn_retries)。這樣的話,對於伺服器的記憶體、頻寬都有很大的消耗。攻擊者如果處於公網,可以偽造IP的話,對於伺服器就很難根據IP來判斷攻擊者,給防護帶來很大的困難。

    解決辦法: 

     第一種是縮短SYN Timeout時間:由於SYN Flood攻擊的效果取決於伺服器上保持的SYN半連線數,這個值=SYN攻擊的頻度*SYN Timeout,所以通過縮短從接收到SYN報文到確定這個報文無效並丟棄該連線的時間,例如設定為20秒以下(過低的SYN  Timeout設定可能會影響客戶的正常訪問),可以成倍的降低伺服器的負荷。

    第二種方式是設定SYN Cookie:就是給每一個請求連線的IP地址分配一個Cookie,如果短時間內連續受到某個IP的重複SYN報文,就認定是受到了攻擊,以後這個IP地址來的包會被丟棄。

上述兩種方法只能對付比較原始的SYN Flood攻擊,縮短SYN Timeout時間僅在對方攻擊頻度不高的情況下生效,SYN Cookie更依賴於對方使用真實的IP地址,如果攻擊者以數萬/秒的速度傳送SYN報文,同時利用隨機改寫IP報文中的源地址,以上的方法將毫無用武之地。例如SOCK_RAW返回的套接字通過適量的設定可以自己完全控制IP頭的內容從而實現IP欺騙。

  第三種方法是SYN Cache技術:此種技術在收到SYN時不急著去分配系統資源,而是先回應一個ACK報文,並在一個專用的Hash表中(Cache)中儲存這種半開連線,直到收到正確的ACK報文再去分配資源。

  第四種方法是使用硬體防火牆:SYN Flood攻擊很容易就被防火牆攔截

  【擴充套件】DDOS攻擊的原理,如何防止DDOS攻擊?

    DDOS是英文Distributed Dential of Service的縮寫,意為“分散式拒絕服務”。

      當前主要有兩種流行的DDOS攻擊:

      1.SYN Flood攻擊:上文已經介紹過。

      2.TCP全連線攻擊:這種攻擊是為了繞過常規防火牆的檢查而設計的,一般情況下,常規防火牆大多具備過濾Land等DOS攻擊的能力,但是對於正常的TCP連線時放過的,很多網路服務程式(如:IIS、Apache等Web伺服器)能接受的TCP連線數是有限的,一旦有大量的TCP連線,則會導致網站訪問非常緩慢甚至無法訪問。TCP全連線攻擊就是通過許多殭屍主機不斷的與受害伺服器建立大量的TCP連線,直到伺服器的記憶體等資源耗盡而被拖垮,從而造成拒絕服務。這種攻擊的特點是可繞過一般防火牆的防護而達到攻擊目的。缺點是需要找很多殭屍主機,並且由於殭屍主機的IP是暴露的,因此容易被跟蹤。

    解決辦法:

  1.   限制SYN流量: 使用者在路由器上分配SYN的最大流量來限制SYN封包所能佔有的最高頻寬,這樣,當出現大量的超過所限定的SYN流量時,說明不是正常的網路訪問,而是有黑客入侵。
  2. 定期掃描:定期掃描現有的網路主節點,清查可能存在的安全漏洞,對新出現的漏洞及時進行清理。
  3. 在骨幹節點配置防火牆:防火牆本身能抵禦DDOS攻擊和其他一些攻擊。在發現受到攻擊的時候,可以將攻擊導向一些犧牲主機,這樣可以保護真正的主機不被攻擊。
  4. 用足夠的機器承受黑客攻擊:這是一種較為理想的應對策略。如果使用者擁有足夠的容量和足夠的資源給黑客攻擊,在它不斷訪問使用者、奪取使用者資源時,自己的資源也在逐漸耗失,或許未等使用者被攻擊死,黑客已經無力支招了。不過此方法需要投入的資金比較多,平時大多數裝置處於空閒狀態。
  5. 過濾不必要的服務和埠:可以使用Inexpress、Express、Forwarding等工具來過濾不必要的服務和埠,即在路由器上過濾假IP。

3.Land攻擊:Land攻擊利用了TCP連線建立的三次握手過程,通過向一個目標主機發送一個用於建立請求連線的TCP SYN報文而是按對目標主機的攻擊。與正常的TCP SYN報文不同的是:Land攻擊報文的源IP地址和目的IP地址是相同的,都是目標主機的IP地址。這樣目標主機在接收到這個SYN報文後,就會向該報文的源地址傳送一個ACK報文,並建立一個TCP連線控制結構,而該報文的源地址就是自己。由於目的IP地址和源IP地址是相同的,都是目標主機的IP地址,因此這個ACK報文就發給了目標主機本身。這樣如果攻擊者傳送了足夠多的SYN報文,則目標計算機的TCB可能會耗盡,最終不能正常服務。

 【4】如果客戶端發起握手請求,服務端無法立刻建立連線應該回應什麼?

             RST報文,表示重置,重新建立連線。

【5】TCP與UDP的區別(或各自的優缺點),以及各自的用途和使用領域。

        1.基於連線VS無連線

TCP是面向連線的協議,而UDP是無連線的協議。這意味著當一個客戶端和一個伺服器通過TCP傳送資料之前,必須先建立連線,建立連線的過程即TCP三次握手。

      2.可靠性

         TCP提供交付保證,這意味著一個使用TCP協議傳送的訊息是保證交付給客戶端的,如果訊息再傳輸過程中丟失,那麼它將重發。UDP是不可靠的,它不提供任何交付的保證,一個數據包在運輸過程中可能會丟失。

     3.有序性

訊息到達網路的另一端可能是無序的,TCP協議將會為你排好序,UDP不提供任何有序性的保證。

  4.速度

TCP速度比較慢,UDP速度比較快。因為TCP必須建立連線,以保證訊息的可靠交付和和有序性,它需要做比UDP更多的事。這就是為什麼UDP更適合對速度比較敏感的引用。TCP適合傳輸大量資料,UDP適合傳輸少量資料。

    5.重量級VS輕量級

TCP是重量級的協議,UDP則是輕量級的協議。一個TCP資料報的報頭大小最少是20位元組,UDP資料報的報頭固定是8個位元組。TCP報頭好包含序列號,ACK號,資料偏移量,保留,控制位,視窗,緊急指標,可選項,填充項,校驗位,源埠和目的埠:

     而UDP報頭只包含長度、源埠號、目的埠金和校驗和:

     6.流量控制和擁塞控制

TCP有流量控制和擁塞控制。UDP沒有流量控制和擁塞控制。

    7.TCP面向位元組流,UDP面向報文的

TCP是位元組流的協議,無記錄邊界。

        UDP傳送的乜咯資料報是記錄型的資料報,所謂的記錄型資料報就是接收程序可以識別接收到的資料報的記錄邊界。

   8.TCP只能單播,不能傳送廣播和組播;UDP可以組播

         TCP應用場景:效率要求相對低,但是對準確性要求相對高的場景,因為傳輸中需要對資料確認、重發、排序等操作,相比之下效率沒有UDP高。如:檔案傳輸、郵件傳輸、遠端登入。

        UDP應用場景:效率要求相對高,對準確性要求相對較低的場景。例如:QQ聊天等即時通訊,廣播通訊。

【6】為什麼TCP比UDP安全,但還有很多用UDP?

  1. 無需建立連線(減少延遲)
  2. 無需維護連線狀態
  3. 頭部開銷小,一個TCP資料報的報頭大小最少是20位元組,UDP資料報的報頭固定是8個位元組。
  4. 應用層能更好的控制要傳送的資料和傳送時間。UDP沒有擁塞控制,因此網路中的擁塞不會影響主機的傳送頻率。某些實時應用要求以穩定的速度傳送資料,可以容忍一些資料的丟失,但不允許有較大的延遲,而UDP正好滿足這些應用的需求。

【7】TCP如何實現流量控制和擁塞控制的?TCP是怎麼做錯誤處理的?

流量控制就是讓傳送方的傳送速率不要太快,要讓接收方來得及接收。利用滑動視窗機制可以很方便的在TCP連線上實現對傳送方的流量控制。原理就是運用TCP報文段中的視窗大小欄位來控制,傳送方的傳送視窗大小不可以大於接收發回的視窗大小。

        所謂滑動視窗協議主要有兩點:

              1.“視窗”對應的是一段可以被髮送者傳送的位元組序列,其連續的範圍稱之為“視窗”;

              2.“滑動”則是指這段“允許傳送的範圍”是可以隨著傳送的過程而變化的,方式就是按順序“滑動”。

             例子:1.TCP協議的兩端分別為傳送者A和接收者B,由於是全雙工協議,因此A和B應該分別維護著一個獨立的傳送緩衝區和接收緩衝區,由於對等性(A發B收和B發A收),我們以A傳送B接收的情況作為例子;

                       2.傳送視窗是傳送快取中的一部分,是可以被TCP協議傳送的那部分,其實應用層需要傳送的所有資料都被放進了傳送者的資料緩衝區;

                      3.傳送視窗中相關的有四個概念:已傳送並收到確認的資料(不再發送視窗和傳送緩衝區之內)、已傳送但未收到確認的資料(位於傳送視窗之中)、允許傳送但尚未傳送的資料以及傳送視窗外發送緩衝區內暫時不允許傳送的資料。

                      4.每次成功傳送資料之後,傳送視窗就會在傳送緩衝區中按順序移動,將新的資料包含到視窗中準備傳送。

        幾種擁塞控制方法: 慢開始和擁塞避免、快重傳和快恢復

【8】TCP滑動視窗協議,視窗過大或過小有什麼影響?

滑動視窗的大小對網路效能有很大的影響。

         如果滑動視窗過小,極端的情況下就是停止等待協議,發一個報文等一個ACK,會造成通訊效率下降。

         如果滑動視窗過大,網路容易擁塞,容易造成接收端的快取不夠而溢位,容易產生丟包現象,則需要多次發生重複非資料,消耗了網路頻寬。

【9】在流量控制的過程中,必須考慮傳輸效率

         1.Nagle演算法:

                   Nagle演算法是為了避免網路中存在太多的小包(協議頭比例非常大)造成擁塞。Nagle演算法就是為了儘可能傳送大塊資料,避免網路中充斥著許多小資料塊。

                  Nagle演算法要求一個TCP連線上最多隻能有一個未被確認的小分組,在該分組的確認到達之前不能傳送其他小分組,因此它事實上是一個擴充套件的停-等協議,只不過它是基於包停-等的,而不是基於位元組停-等的。

                  在TCP的實現中廣泛使用Nagle演算法。演算法如下:若傳送應用程序把要傳送的資料逐個位元組的送到TCP的傳送快取,則傳送方就把第一個資料位元組先發送出去,把後面到達的資料位元組都快取起來。當傳送方收到第一個資料字元的確認後,再把傳送快取中的所有資料組裝成一個報文段傳送出去,同時繼續對隨後到達的資料進行快取。只有在收到對前一個報文段的確認後才能繼續傳送下一個報文段。當資料到達較快而網路速率較慢時,用這樣的方法可以明顯的減少所用的網路頻寬。Nagle演算法還規定,當到達的資料已達到傳送視窗大小的一半或已達到報文段的最大長度時,就立即傳送一個報文段。

                它主要的職責就是資料的累積,實際上有三個門檻:

                           1.緩衝區中的位元組數達到了一定量(超過閾值MSS)

                           2.等待了一定的時間(一般的Nagle演算法都是等待200ms)

                           3.緊急資料傳送

     2.糊塗視窗綜合症:

另一個問題叫做糊塗視窗綜合症,有時也會使TCP的效能變壞。設想一種情況:TCP接收方的快取已滿,而互動式的應用程序一次只從接收快取中讀取1個位元組(這樣就使接受快取空間僅騰出1個位元組),然後向傳送方傳送確認,並把視窗設定為1個位元組(但傳送的資料報是40位元組長)。接著,傳送方又發來1個位元組的資料(這裡,傳送方傳送的IP資料報是41位元組長)。接收方發回確認,仍然將視窗設定為1個位元組。這樣進行下去,使網路的效率很低。

             要解決這個問題,可以讓接收方等待一段時間,使得或接收快取已有足夠空間容納一個最長的報文段,或者等到接收快取已有一半空閒的空間。只要出現這兩種情況之一,接收方就發出確認報文,並向傳送方通知當前的視窗大小。此外,傳送方也不要傳送太小的報文段,而是把資料積累成足夠大的報文段,或達到接收方快取的空間的一半大小。這兩種方法可以配合使用。使得在傳送方不傳送很小的報文段的同時,接收方也不要在快取剛剛有了一點小的空間就急忙把這個很小的視窗大小資訊通知給傳送方。

【10】TCP黏包

           TCP報文粘連就是:本來發送的是多個TCP報文,但是在接收端收到的卻是一個報文,把多個報文合成了一個報文。

           TCP報文粘連的原因:“粘包”可能發生在傳送端,也可能發生在接收端。在流傳輸中出現。UDP不會出現粘包,因為它有訊息邊界(兩段資料間是有界限的)

          1.由Nagle演算法造成的傳送端的粘包

Nagle演算法在上文已經介紹過了,這裡就不在贅述。

         2.接收端接收不及時造成的接收端粘包

TCP會把接收到的資料存在自己的緩衝區中,然後通知應用層取資料,當應用層由於某些原因不能及時把TCP的資料取出來,就會造成TCP緩衝區中存放了幾段資料,產生報文粘連的現象。

      TCP報文粘連的解決辦法:               1.關閉Nagle演算法。在socket選項中,TCP_NODELAY表示是否使用Nagle演算法。

              2.接收端儘可能快速的從緩衝區取資料。

              3.可以在傳送的資料中,新增一個表示資料的開頭和結尾的字元,在收到訊息後,通過這些字元來處理報文粘連。