查看網絡丟包
$ sudo tcpdump -i eth0 port 22 and "tcp[tcpflags] & (tcp-syn)
!= 0"html
$ sudo iptables-save -t filtercentos
$ dmesg |grep nf_conntrack
若是輸出值中有「nf_conntrack: table full, dropping packet」,說
明服務器nf_conntrack表已經被打滿。緩存
經過/proc文件系統查看nf_conntrack表實時狀態:服務器
# 查看nf_conntrack表最大鏈接數
$ cat /proc/sys/net/netfilter/nf_conntrack_max
65536
# 查看nf_conntrack表當前鏈接數
$ cat /proc/sys/net/netfilter/nf_conntrack_count
7611cookie
如何解決網絡
若是確認服務器因鏈接跟蹤表溢出而開始丟包,首先須要查看具體鏈接判斷是否正遭受DOS攻擊,若是是正常的業務流量形成,能夠考慮調整nf_conntrack的參數:app
nf_conntrack_max決定鏈接跟蹤表的大小,默認值是65535,能夠根據系統內存大小計算一個合理值:CONNTRACK_MAX = RAMSIZE(in bytes)/16384/(ARCH/32),如32G內存能夠設置1048576;tcp
nf_conntrack_buckets決定存儲conntrack條目的哈希表大小,默認值是nf_conntrack_max的1/4,延續這種計算方式:BUCKETS = CONNTRACK_MAX/4,如32G內存能夠設置262144;函數
nf_conntrack_tcp_timeout_established決定ESTABLISHED狀態鏈接的超時時間,默認值是5天,能夠縮短到1小時,即3600。工具
修改鏈接數 :
$ sysctl -w net.netfilter.nf_conntrack_max=1048576 $ sysctl -w net.netfilter.nf_conntrack_buckets=262144 $ sysctl -w net.netfilter.nf_conntrack_tcp_timeout_established=3600
物理介質上的數據幀到達後首先由NIC(網絡適配器)讀取,寫入設備內部緩衝區Ring Buffer中,再由中斷處理程序觸發Softirq從中消費,Ring Buffer的大小因網卡設備而異。當網絡數據包到達(生產)的速率快於內核處理(消費)的速率時,Ring Buffer很快會被填滿,新來的數據包將被丟棄。
如何確認
經過ethtool或/proc/net/dev能夠查看因Ring Buffer滿而丟棄的包統計
,在統計項中以fifo標識:
$ ethtool -S eth0|grep rx_fifo rx_fifo_errors: 0 $ cat /proc/net/dev
能夠看到服務器的接收方向的fifo丟包數並無增長,這裏天然也排除這個緣由。
如何解決
若是發現服務器上某個網卡的fifo數持續增大,能夠去確認CPU中斷是否
分配均勻,也能夠嘗試增長Ring Buffer的大小,經過ethtool能夠查看
網卡設備Ring Buffer最大值,修改Ring Buffer當前設置:
# 查看eth0網卡Ring Buffersize狀況最大值和當前設置
$ ethtool -g eth0
# 修改網卡eth0接收與發送硬件緩存區大小
$ ethtool -G eth0 rx 4096 tx 4096
netdev_max_backlog是內核從NIC收到包後,交由協議棧(如IP、TCP)處理以前的緩衝隊列。每一個CPU核都有一個backlog隊列,與Ring Buffer同理,當接收包的速率大於內核協議棧處理的速率時,CPU的backlog隊列不斷增加,當達到設定的netdev_max_backlog值時,數據包將被丟棄。
如何確認
經過查看/proc/net/softnet_stat能夠肯定是否發生了netdev backlog隊列溢出:
$ cat /proc/net/softnet_stat 01a7b464 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 01d4d71f 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 0349e798 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 017e0826 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
其中:
每一行表明每一個CPU核的狀態統計,從CPU0依次往下;
每一列表明一個CPU核的各項統計:第一列表明中斷處理程序收到的包總數;第二列即表明因爲netdev_max_backlog隊列溢出而被丟棄的包總數。
從上面的輸出能夠看出,這臺服務器統計中,並沒有由於netdev_max_backlog致使的丟包。
如何解決
netdev_max_backlog的默認值是1000,在高速鏈路上,可能會出現上述第二列統計不爲0的狀況,能夠經過修改內核參數net.core.netdev_max_backlog來解決:
$ sysctl -w net.core.netdev_max_backlog=2000
反向路由過濾機制是Linux經過反向路由查詢,檢查收到的數據包源IP是否可路由(Loose mode)、是否最佳路由(Strict mode),若是沒有經過驗證,則丟棄數據包,設計的目的是防範IP地址欺騙攻擊。rp_filter提供了三種模式供配置:
如何確認
查看當前rp_filter策略配置:
$ cat /proc/sys/net/ipv4/conf/eth0/rp_filter
若是這裏設置爲1,就須要查看主機的網絡環境和路由策略是否可能會致使客戶端的入包沒法經過反向路由驗證了。
從原理來看這個機制工做在網絡層,所以,若是客戶端可以Ping通服務器,就可以排除這個因素了。
如何解決
根據實際網絡環境將rp_filter設置爲0或2:
$ sysctl -w net.ipv4.conf.all.rp_filter=2 或 $ sysctl -w net.ipv4.conf.eth0.rp_filter=2
半鏈接隊列指的是TCP傳輸中服務器收到SYN包但還未完成三次握手的鏈接隊列,隊列大小由內核參數tcp_max_syn_backlog定義。
當服務器保持的半鏈接數量達到tcp_max_syn_backlog後,內核將會丟棄新來的SYN包。
如何確認
經過dmesg能夠確認是否有該狀況發生:
$ dmesg | grep "TCP: drop open request from"
半鏈接隊列的鏈接數量能夠經過netstat統計SYN_RECV狀態的鏈接得知
$ netstat -ant|grep SYN_RECV|wc -l 0
大多數狀況下這個值應該是0或很小,由於半鏈接狀態從第一次握手完成時進入,第三次握手完成後退出,正常的網絡環境中這個過程發生很快,若是這個值較大,服務器極有可能受到了SYN Flood攻擊。
如何解決
tcp_max_syn_backlog的默認值是256,一般推薦內存大於128MB的服務器能夠將該值調高至1024,內存小於32MB的服務器調低到128,一樣,該參數經過sysctl修改:
$ sysctl -w net.ipv4.tcp_max_syn_backlog=1024
上述行爲受到內核參數tcp_syncookies的影響,若啓用syncookie機制,當半鏈接隊列溢出時,並不會直接丟棄SYN包,而是回覆帶有syncookie的SYC+ACK包,設計的目的是防範SYN Flood形成正常請求服務不可用。
$ sysctl -w net.ipv4.tcp_syncookies=1 net.ipv4.tcp_syncookies = 1
PAWS全名Protect Againest Wrapped Sequence numbers,目的是解決在高帶寬下,TCP序列號在一次會話中可能被重複使用而帶來的問題。
TIME_WAIT狀態的鏈接須要佔用服務器內存資源維持,Linux內核提供了一個參數來控制TIME_WAIT狀態的快速回收:tcp_tw_recycle,它的理論依據是:
如何確認
經過netstat能夠獲得因PAWS機制timestamp驗證被丟棄的數據包統計:
$ netstat -s |grep -e "passive connections rejected because of time stamp" -e "packets rejects in established connections because of timestamp」 387158 passive connections rejected because of time stamp 825313 packets rejects in established connections because of timestamp
經過sysctl查看是否啓用了tcp_tw_recycle及tcp_timestamp :
$ sysctl net.ipv4.tcp_tw_recycle net.ipv4.tcp_tw_recycle = 1 $ sysctl net.ipv4.tcp_timestamps net.ipv4.tcp_timestamps = 1
此次問題正是由於服務器同時開啓了tcp_tw_recycle和timestamps,而客戶端正是使用NAT來訪問服務器,形成啓動時間相對較短的客戶端得不到服務器的正常響應。
如何解決
若是服務器做爲服務端提供服務,且明確客戶端會經過NAT網絡訪問,或服務器以前有7層轉發設備會替換客戶端源IP時,是不該該開啓tcp_tw_recycle的,而timestamps除了支持tcp_tw_recycle外還被其餘機制依賴,推薦繼續開啓:
$ sysctl -w net.ipv4.tcp_tw_recycle=0 $ sysctl -w net.ipv4.tcp_timestamps=1
ropwatch使用前提:
一、首先內核必須大於等於2.6.30;
二、編譯內核時應該加上「NET_DROP_MONITOR=y」;
三、因爲dropwatch是依賴Kernel Tracepoint API的,其原理是各個協議層釋放skb時收集信息來判斷有無丟包,用的很少,不免存在一些BUG致使內核crash,所以具有必定危險性,建議troubleshooting時,最好先切走業務;
使用方法:
一、筆者使用的系統是CentOS 6.3,首先須要經過yum安裝dropwatch:"yum install dropwatch -y」
二、帶參數運行dropwatch:"dropwatch -l kas」,不帶參數運行,默認輸出的是各個函數的地址信息,不便於觀察;
補充一下,使用 -l kas後,會經過「/proc/kallsysms」去映射地址和符號表的對應關係,實測會出各類問題甚至死機,建議不要這麼作;能夠本身經過/boot/System.Map去查詢。
三、開始抓取內核丟包數據:」start」:
[root@localhost ~]$sudo dropwatch -l kas Initalizing kallsyms db dropwatch>start Enabling monitoring... Kernel monitoring activated. Issue Ctrl-C to stop monitoring 1 drops at netlink_unicast+251 (0xffffffff814639c1) 1 drops at init_dummy_netdev+50 (0xffffffff81438a10) 2 drops at init_dummy_netdev+50 (0xffffffff81438a10) 2 drops at init_dummy_netdev+50 (0xffffffff81438a10) 1 drops at udp_queue_rcv_skb+953 (0xffffffff8149b113) 2 drops at init_dummy_netdev+50 (0xffffffff81438a10) 1 drops at init_dummy_netdev+50 (0xffffffff81438a10) 1 drops at icmp_sk_init+317 (0xffffffff8149e557) ^CGot a stop messagedropwatch>
網卡的驅動程序
ethtool -i eth0 //找到驅動driver: pcnet32
lsmod //找到使用的驅動模塊,在裏面結果裏面找。ps:lsmod | grep pcnet32
網絡測試工具
mtr 默認發送 ICMP 數據包進行鏈路探測,經過 -u 參數來指定 UDP 數據包用於探測。相對於 traceroute 只做一次鏈路跟蹤測試,mtr 會對鏈路上的相關節點作持續探測並給出相應的統計信息。mtr 能避免節點波動對測試結果的影響,因此其測試結果更正確,建議優先使用。
[root@centos ~]# mtr 223.5.5.5
二、My traceroute [v0.75]
三、mycentos6.6 (0.0.0.0) Wed Jun 15 23:16:27 2016
四、Keys: Help Display mode Restart statistics Order of fields quit
五、Packets Pings
六、Host Loss% Snt Last Avg Best Wrst StDev
七、1. ???
八、2. 192.168.17.20 0.0% 7 13.1 5.6 2.1 14.7 5.7
默認配置下,返回結果中各數據列的說明以下:
第一列(Host):節點 IP 地址和域名。如前面所示,按 n 鍵能夠切換顯示。
第二列(Loss%):節點丟包率。
第三列(Snt):每秒發送數據包數。默認值是 10,能夠經過參數 -c 指定。
第四列(Last):最近一次的探測延遲值。
第5、6、七列(Avg、Best、Wrst):分別是探測延遲的平均值、最小值和最大值。
第八列(StDev):標準誤差。越大說明相應節點越不穩定。
轉載於:https://www.cnblogs.com/276815076/p/5736272.html