乙個NAT引發的血案

2022-08-25 19:15:19 字數 2181 閱讀 2282

背景:

內網有一台nginx伺服器提供外網服務,時常出現訪問異常或者重連現象,此故障出現均在外網不在內網,內網訪問一切正常,未出現此類故障:

當開啟nat時丟棄資料報增加。

客戶端顯示:

nginx伺服器顯示

分析處理過程:

1、內網和外網訪問的區別在於內網訪問使用私網位址直接訪問nginx伺服器,外網和內網之間使用一台防火牆進行連線,nginx和公網位址在防火牆上做了位址對映。

2、懷疑是出口防火牆的問題,經過防火牆的廠家進行了檢查,分三部分:

> 內到外的位址對映是正常的,沒出現任何異常。

> 同為對映的郵件,dns等伺服器沒出現此類問題。

> 異常的就集中在和nginx之間的tcp連線異常,經常丟包造成。

在中間進行抓包分析情況如下:

抓包顯示中間的異常資料報只有去往nginx的資料報卻沒有會回來的資料報。

3、後聯合廠家和nginx管理人員溝通提出可能是由於防火牆的nat時間戳造成的,nginx伺服器端修改tcp_tw_recycle狀態為down後恢復正常。

4、通過參考網上的資料,我們定位到問題發生的原因:我們的web server的

linux

內做過調整,開啟了

net.ipv4.tcp_tw_recycle

,在防火牆只做

nat的情況下,觸發了大量的

tcp建連失敗。

啟用time-wait狀態

sockets

的快速**,這個選項不推薦啟用。在

nat(network address translation)

網路下,會導致大量的

tcp連線建立錯誤。

下面我們來具體說下,首先解釋下tcp的

time_wait

狀態:

開啟net.ipv4.tcp_tw_recycle的目的,就是希望能夠加快

time_wait

狀態的**,當然這個選項的生效也依賴於

net.ipv4.tcp_timestamps

的開啟(預設就是開啟的)。

當開啟了tcp_tw_recycle選項後,當連線進入

time_wait

狀態後,會記錄對應遠端主機最後到達分節的時間戳。如果同樣的主機有新的分節到達,且時間戳小於之前記錄的時間戳,即視為無效,相應的資料報會被丟棄

當防火牆啟用nat模式時,客戶端

tcp請求到達防火牆,修改目的位址(

ip+埠號)後便**給後端伺服器,而客戶端時間戳資料沒有變化。對於後端

web server

,請求的源位址是防火牆,所以從後端伺服器的角度看,原本不同客戶端的請求經過

lvs的**,就可能會被認為是同乙個連線,加之不同客戶端的時間可能不一致,所以就會出現時間戳錯亂的現象,於是後面的資料報就被丟棄了。

5、問題解決。

解決辦法是linux核心引入tcp_tw_timeout開關,該開關可以動態設定time_wait 時間,加速**time_wait 狀態,從而可以關閉tcp_tw_recycle,避免上述問題。

乙個memset引發的血案

前幾天做了一道bst題,提交了幾次都是wa,今天抽空拿了出來仔細瞧瞧總算被我發現禍頭根源.總結原因還在於自己對memset不太了解,以前用對估計也是瞎貓撞見死耗子 memset的介紹 void memset void buffer,int ch,size t count buffer 指向某段記憶體...

乙個分號引發的「血案」

再多的表情也無法詮釋我現在的心情!a b for matrices 這是很水的一道題,然而卻整整折騰了我2個多小時。從晚上6點多開始,花了沒幾分鐘就把 敲好了,可是資料一測,竟然不對,然後就開始找問題,找了很久,我竟然都還沒看出問題在哪,越找心裡越不爽,這麼做明明對的呀,一執行怎麼就錯了呢?一直到了...

乙個strlen引發的血案

部分測試 原來是這樣的 int decryptrelation aesdecryptfromfiletobytes const std string in file path,unsigned char out data,const char aes encrypt key,int in data ...