記一次Linux服務器curl方式訪問另一臺Linux服務器失敗的處理方法

問題現象

內網的Linux服務器A日常需要通過curl命令連接公網的Linux服務器B,傳輸數據並執行腳本。A連接B的時候過了一個SNAT轉換。
某日突然發現服務器A curl連接服務器B失敗,但ping服務器B可通,telnet 443端口也正常,檢查服務器A和B的配置情況,沒有修改痕跡。
curl -v https://<服務器B的域名>
發現走到client hello之後就不往下走了

苦惱了許久,最後在google上找到了解決辦法。特此記錄

問題原因&解決方法

問題原因:
當客戶端發出的syn包帶有時間戳的情況下,經過NAT轉換後,如果使用的端口被之前使用過,而且時間戳大於本次syn包中的時間戳。系統將會直接丟棄。造成本次鏈接無法正常完成TCP/IP的3次握手。
net.ipv4.tcp_timestamps這個參數默認是開啓的,它會複用鏈接,並去檢查這個IP包裏面的時間是不是比當前的時間大,如果大,那麼就丟棄該包(見rfc1323,TCP相關的,網上查到的),從而造成SYN-SENT發送後,沒有迴應。

然後檢查LinuxA服務器的時間,發現Linux服務器A的時間比B快了5分鐘,基本可以確認就是這個問題了

解決方法:
在Linux服務器A上 修改/etc/sysctl.conf文件,在最後增加如下內容

# Controls the timestamps check in syn-send
# 0 --> do not check
# 1 --> check
net.ipv4.tcp_timestamps = 0

配置完成後,重載sysctl規則

sysctl -p

隨後查看生效情況

sysctl -a |grep timestamp
net.ipv4.tcp_timestamps = 0

再在Linux服務器A上curl服務器B,發現問題解決了。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章