2011-09-03 203 views
6

我有兩臺Linux服務器(讓我們將它們命名爲A和B),連接到同一臺(非託管)交換機。我在兩臺服務器上都禁用了防火牆(所有表中都沒有規則,所有默認策略都設置爲ACCEPT)。所以,沒有什麼應該阻止一臺服務器發送任何TCP/IP數據包和另一臺服務器來接收它們。什麼可能導致TCP/IP重置(RST)標誌不被髮送?

現在,在一個我們運行TCP服務器應用程序,這聽/接受傳入的連接,然後發送大量的數據要在環連接的客戶端(S)。它不會嘗試從客戶端讀取數據,並且在客戶端斷開連接時執行write()套接字操作時會出現EPIPE錯誤。

接着,在B I運行NC(netcat的)作爲客戶端應用程序,連接到上的一個服務器應用程序,開始接收數據,和幾秒鐘後我按下Ctrl-C中斷這個連接。

我看到的,是服務器應用上的一個剛剛在寫()掛起,它並沒有得到EPIPE或其他任何錯誤。

我使用tcpdump的跟蹤TCP/IP數據包,這裏是我所看到的:

  • 中斷第B的netcat後,B發送一個翅片到,它正確地ACK回覆該FIN - 所以,現在我們要公平半開TCP連接,這是確定
  • 接下來,嘗試下一個數據發送到客戶端與常規ACK和PSH,ACK數據包,這也有望和正確
  • BUT,B沒有按不會以任何方式回覆這些數據包(雖然我期望它回覆RST數據包,因爲它將數據包接收到已經關閉/不存在的TCP連接)
  • A沒有得到ACK,所以它停止發送新數據,並開始重新發送數據包老(在這一點上一次調用write()方法掛起)

我也想跑上的一個netcat的(因此客戶端和服務器應用程序都在相同的物理服務器上運行),這樣一切都按預期運行 - 服務器應用程序在用Ctrl-C中斷netcat後立即獲得了EPIPE。並且tcpdump顯示按預期發送了RST數據包。

那麼,什麼可能會導致在此情況下,不發送RST?

我使用硬化的Gentoo Linux,跟上時代的,內核2.6.39硬化-R8,沒有任何特定的sysctl網絡相關的配置。

注意到這些服務器上存在重要的網絡活動或大約5000個tcp連接(在任何時候由netstat -alnp列出)​​,我認爲大約1000個連接平均每秒打開和關閉可能會也可能不重要。它通常在內核日誌是這樣看(但是從使用上面所討論的服務器應用程序的端口號是不同的):

TCP: Possible SYN flooding on port XXXXX. Sending cookies. 
    net_ratelimit: 19 callbacks suppressed 

下面是TCP會話通常是這樣的:http://i54.tinypic.com/1zz10mx.jpg

+0

從對其他網站的討論:** 1)**的netcat後退出了netstat不會再列出它連接上服務器B(雖然我認爲它應該在FIN_WAIT_2狀態中列出),在服務器A上的netstat仍然顯示此按照預期,處於CLOSE_WAIT狀態的連接; ** 2)**有人認爲這可能是因爲SO_LINGER而發生的,但我不同意,因爲netcat不會手動激活SO_LINGER並在exit()之前執行close(),因此不應該自動激活,並且SO_LINGER不應該影響ACK/RST無論如何都會對_incoming_包進行回覆。 – Powerman

+0

看起來像舊內核(2.6.28-hardened-r9)按預期工作 - 發送RST數據包。 – Powerman

回答

3

此行爲是結果啓用功能在我硬化內核:

Security options ---> 
    Grsecurity ---> 
     Network Protections ---> 
     [*] TCP/UDP blackhole and LAST_ACK DoS prevention 

CONFIG_GRKERNSEC_BLACKHOLE:

如果你比如Y在這裏,無論是TCP資源ets也不會發送ICMP目標不可達數據包以響應發送到不存在關聯偵聽進程的端口的數據包。此功能同時支持IPV4和IPV6,並免除了blackholing的環回接口。啓用此功能可使主機更容易抵禦DoS攻擊,並降低掃描器的網絡可見性。實現的黑洞功能等同於FreeBSD的黑洞功能,因爲它阻止RST響應所有數據包,而不僅僅是SYN。

相關問題