Linux之《荒島餘生》(五)網路篇

小姐姐味道發表於2018-12-29

你想通過執行ping google.com來判斷網路連通性麼?我想你這是在侮辱方教授。本篇是《荒島餘生》系列第五篇,網路篇,但不會教你fq。其餘參見:

Linux之《荒島餘生》(一)準備篇

Linux之《荒島餘生》(二)CPU篇

Linux之《荒島餘生》(三)記憶體篇

Linux之《荒島餘生》(四)I/O篇

看著kali linux上百個網路命令,我陷入了沉思。專業的網路命令實在是太多了,如果要羅列,上千個也是有的。個人不是滲透測試工作者,大部分功能只知皮毛。所以本文是非常淺顯的技術總結,僅聚焦工作中常用到的一些Linux命令。

由於nio的普及,ck10k的問題已經成為過去式。現在隨便一臺伺服器,就可以支援數十萬級別的連線了。那麼我們來算一下,100萬的連線需要多少資源。

首先,每一個連線都是檔案控制程式碼,所以需要檔案描述符數量支援才行,每一個socket記憶體佔用15k-20k之間,這樣,僅維護相應socket,就需要20G記憶體;而廣播一個1KB的訊息需要佔用的頻寬為1000M

檢視當前系統的連線

如何看當前系統有多少連線呢?可以使用netstat結合awk進行統計。如下指令碼,統計了每一種狀態的tcp連線數量

# netstat -antp | awk '{a[$6]++}END{ for(x in a)print x,a[x]}'
LISTEN 41
CLOSE_WAIT 24
ESTABLISHED 150
Foreign 1
TIME_WAIT 92
複製程式碼

但如果你在一臺有上萬連線的伺服器上執行這個命令,你可能會等上很長時間。所以,我們有了第二代網路狀態統計工具:netstat => ss(可別和那個越獄工具搞混了)。

# ss -s
Total: 191 (kernel 220)
TCP:   5056 (estab 42, closed 5000, orphaned 3, synrecv 0, timewait 5000/0), ports 3469
...
複製程式碼

netstat屬於net-tools工具集,而ss屬於iproute。其命令對應如下,是時候和net-tools說Bye了。

用途 net-tools iproute
統計 ifconfig ss
地址 netstat ip addr
路由 route ip route
鄰居 arp ip neigh
VPN iptunnel ip tunnel
VLAN vconfig ip link
組播 ipmaddr ip maddr

ss命令

基本使用

我們按照使用場景來看下ss的用法。

檢視系統正在監聽的tcp連線

ss -atr 
ss -atn #僅ip
複製程式碼

檢視系統中所有連線

ss -alt
複製程式碼

檢視監聽444埠的程式pid

ss -ltp | grep 444
複製程式碼

檢視程式555佔用了哪些埠

ss -ltp | grep 555
複製程式碼

顯示所有udp連線

ss -u -a
複製程式碼

檢視TCP sockets,使用-ta選項 檢視UDP sockets,使用-ua選項 檢視RAW sockets,使用-wa選項 檢視UNIX sockets,使用-xa選項

和某個ip的所有連線

ss dst 10.66.224.130
ss dst 10.66.224.130:http
ss dst 10.66.224.130:smtp
ss dst 10.66.224.130:443
複製程式碼

顯示所有的http連線

ss  dport = :http
複製程式碼

檢視連線本機最多的前10個ip地址

netstat -antp | awk '{print $4}' | cut -d ':' -f1 | sort | uniq -c  | sort -n -k1 -r | head -n 10
複製程式碼

Recv-Q和Send-Q

注意ss的執行結果,我們說明一下Recv-Q和Send-Q。

Linux之《荒島餘生》(五)網路篇
這兩個值,在LISTENESTAB狀態分別代表不同意義。一般,正常的應用程式這兩個值都應該為0(backlog除外)。數值越大,說明問題越嚴重。

LISTEN狀態

  • Recv-Q:代表建立的連線還有多少沒有被accept,比如Nginx接受新連線變的很慢

  • Send-Q:代表listen backlog值

ESTAB狀態

  • Recv-Q:核心中的資料還有多少(bytes)沒有被應用程式讀取,發生了一定程度的阻塞

  • Send-Q:代表核心中傳送佇列裡還有多少(bytes)資料沒有收到ack,對端的接收處理能力不強

檢視網路流量

檢視流量

有很多工具可以看網路流量,但我最喜歡sar。sar是linux上功能最全的監控軟體。如圖,使用sar -n DEV 1即可每秒重新整理一次網路流量。

Linux之《荒島餘生》(五)網路篇

當然,你也可以使用ifstat、nload、iptraf等命令檢視。然而資料來源,還是來自我們的/proc目錄

watch cat /proc/net/dev
複製程式碼

檢視佔流量最大的IP

有時候我們發現網路頻寬佔用非常高,但我們無法判斷到底流量來自哪裡。這時候,iftop就可以幫上忙了。如圖,可以很容易的找出流量來自哪臺主機。

Linux之《荒島餘生》(五)網路篇
當你不確定內網的流量來源,比如有人在壓測,api呼叫不合理等,都可以通過這種方法找到他。

抓包

tcpdump

當我們需要判斷是否有流量,或者除錯一個難纏的netty應用問題,則可以通過抓包的方式去進行進一步的判斷。在Linux上,可以通過tcpdump命令抓取資料,然後使用Wireshark進行分析。

tcpdump -i eth0 -nn -s0 -v port 80
複製程式碼
  • -i 指定網路卡進行抓包
  • -n 和ss一樣,表示不解析域名
  • -nn 兩個n表示埠也是數字,否則解析成服務名
  • -s 設定抓包長度,0表示不限制
  • -v 抓包時顯示詳細輸出,-vv、-vvv依次更加詳細

1)加入-A選項將列印ascii ,-X列印hex碼。

tcpdump -A -s0 port 80
複製程式碼

2)抓取特定ip的相關包

tcpdump -i eth0 host 10.10.1.1
tcpdump -i eth0 dst 10.10.1.20
複製程式碼

3)-w引數將抓取的包寫入到某個檔案中

tcpdump -i eth0 -s0 -w test.pcap
複製程式碼

4)tcpdump支援表示式,還有更加複雜的例子,比如抓取系統中的get,post請求(非https)

tcpdump -s 0 -v -n -l | egrep -i "POST /|GET /|Host:"
複製程式碼

更多參見 hackertarget.com/tcpdump-exa…

抓取的資料,使用wireshark檢視即可。

Linux之《荒島餘生》(五)網路篇

http抓包

抓包工具將自身當作代理,能夠抓取你的瀏覽器到伺服器之間的通訊,並提供修改、重放、批量執行的功能。是發現問題,分析協議,攻擊站點的利器。常用的有以下三款:

  • Burpsuite (跨平臺)
  • Fiddle2 (Win)
  • Charles (Mac)

壞事要偷偷的幹哦。

流量複製

你可能需要使你的生產環境HTTP真實流量在開發環境或者預演環境重現,這樣就用到了流量複製功能。 有三個工具可供選擇,個人傾向於Gor。

  • Gor
  • TCPReplay
  • TCPCopy

連線數過多問題

Linux之《荒島餘生》(五)網路篇

根據TCP/IP介紹,socket大概包含10個連線狀態。我們平常工作中遇到的,除了針對SYN的拒絕服務攻擊,如果有異常,大概率是TIME_WAIT和CLOSE_WAIT的問題。 TIME_WAIT一般通過優化核心引數能夠解決;CLOSE_WAIT一般是由於程式編寫不合理造成的,更應該引起開發者注意。

TIME_WAIT

TIME_WAIT是主動關閉連線的一方保持的狀態,像nginx、爬蟲伺服器,經常發生大量處於time_wait狀態的連線。TCP一般在主動關閉連線後,會等待2MS,然後徹底關閉連線。由於HTTP使用了TCP協議,所以在這些頻繁開關連線的伺服器上,就積壓了非常多的TIME_WAIT狀態連線。

某些系統通過dmesg可以看到以下資訊。

__ratelimit: 2170 callbacks suppressed
TCP: time wait bucket table overflow
TCP: time wait bucket table overflow
TCP: time wait bucket table overflow
TCP: time wait bucket table overflow
複製程式碼

通過ss -s命令檢視,可以看到timewait已經有2w個了。

ss -s
Total: 174 (kernel 199)
TCP:   20047 (estab 32, closed 20000, orphaned 4, synrecv 0, timewait 20000/0), ports 10785
複製程式碼

sysctl命令可以設定這些引數,如果想要重啟生效的話,加入/etc/sysctl.conf檔案中。

# 修改閾值
net.ipv4.tcp_max_tw_buckets = 50000 
# 表示開啟TCP連線中TIME-WAIT sockets的快速回收
net.ipv4.tcp_tw_reuse = 1
#啟用timewait 快速回收。這個一定要開啟,預設是關閉的。
net.ipv4.tcp_tw_recycle= 1   
# 修改系統預設的TIMEOUT時間,預設是60s
net.ipv4.tcp_fin_timeout = 10
複製程式碼

測試引數的話,可以使用 sysctl -w net.ipv4.tcp_tw_reuse = 1 這樣的命令。如果是寫入進檔案的,則使用sysctl -p生效。

CLOSE_WAIT

CLOSE_WAIT一般是由於對端主動關閉,而我方沒有正確處理的原因引起的。說白了,就是程式寫的有問題,屬於危害比較大的一種。

我們拿"csdn 諧音太郎"遇到的一個典型案例來說明。

Linux之《荒島餘生》(五)網路篇
程式碼是使用HttpClient的一個使用片段。在這段程式碼裡,通過呼叫in.close()來進行連線資源的清理。但可惜的是,程式碼中有一個判斷:非200狀態的連線直接返回null。在這種情況下,in連賦值的機會都沒有,當然也就無法關閉,然後就發生了連線洩漏。

所以,HttpClient的正確關閉方式是使用其api:abort()

其他常用命令

應用軟體

# 斷點續傳下載檔案
wget -c $url
# 下載整站
wget -r -p -np -k $url
# 傳送網路連線(常用)
curl -XGET $url
# 傳輸檔案
scp
sftp
# 資料映象備份
rsync
複製程式碼

檢測工具

# 連通性檢測
ping google.com
# 到對端路由檢測
tracepath google.com
# 域名檢測
dig google.com
nslookup google.com
# 網路掃描工具
nmap
# 壓力測試
iperf
# 全方位監控工具(好東西)
nmon
複製程式碼

配置工具

# 停止某個網路卡
ifdown
# 開啟某個網路卡
ifup
# 多功能管理工具 
ethtool
複製程式碼

壓力測試

wrk
ab
webbench
http_load
複製程式碼

多功能工具

# 遠端登入
telnet
ssh
nc
# 防火牆
iptables -L
複製程式碼

結尾

除了基本的工具,本文提到的很多網路命令,都不是預裝的,需要使用yum自行安裝。網路程式設計方面的學習,我覺得,讀一下《TCP/IP詳解 卷1:協議》這本書,然後寫幾個Netty應用就可以了。我這裡找到了一本線上的,不用花錢買了。 www.52im.net/topic-tcpip…

如果想要更加深入,可以選擇:

  • 《TCP/IP詳解 卷1:協議》
  • 《UNIX網路程式設計》
  • 《Netty權威指南》

NIO我們已經在I/O篇提起了,在此不再做詳細介紹。等你碰到所謂的拆包粘包問題,遇到心跳和限流問題,甚至遇到了流量整形問題,那麼證明你離一個專業的網路程式設計程式設計師越來越近了。

Linux之《荒島餘生》(五)網路篇

相關文章