看着 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), ports3469
...
netstat
屬於net-tools
工具集,而ss
屬於iproute
。其命令對應如下,是時候和 net-tools 説 Bye 了。
基本使用
我們按照使用場景來看下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 的所有連接
ssdst 10.66.224.130
ssdst 10.66.224.130:http
ssdst 10.66.224.130:smtp
ssdst 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
注意ss的執行結果,我們説明一下Recv-Q和Send-Q。
這兩個值,在LISTEN和ESTAB狀態分別代表不同意義。一般,正常的應用程序這兩個值都應該為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
即可每秒刷新一次網絡流量。
watch cat /proc/net/dev
有時候我們發現網絡帶寬佔用非常高,但我們無法判斷到底流量來自哪裏。這時候,iftop就可以幫上忙了。如圖,可以很容易的找出流量來自哪台主機。
當你不確定內網的流量來源,比如有人在壓測,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-ieth0host 10.10.1.1
tcpdump-ieth0dst 10.10.1.20
3)-w
參數將抓取的包寫入到某個文件中
tcpdump-ieth0-s0-wtest.pcap
4)tcpdump支持表達式,還有更加複雜的例子,比如抓取系統中的get,post請求(非https)
tcpdump -s 0 -v -n -l | egrep -i "POST /|GET /|Host:"
更多參見https://hackertarget.com/tcpdump-examples/
抓取的數據,使用 wireshark 查看即可。
HTTP 抓包抓包工具將自身當作代理,能夠抓取你的瀏覽器到服務器之間的通訊,並提供修改、重放、批量執行的功能。是發現問題,分析協議,攻擊站點的利器。常用的有以下三款:
Burpsuite (跨平台)
Fiddle2 (Win)
Charles (Mac)
你可能需要使你的生產環境HTTP真實流量在開發環境或者預演環境重現,這樣就用到了流量複製功能。
有三個工具可供選擇,個人傾向於Gor。
Gor
TCPReplay
TCPCopy
根據TCP/IP介紹,socket大概包含10個連接狀態。我們平常工作中遇到的,除了針對SYN的拒絕服務攻擊,如果有異常,大概率是TIME_WAIT和CLOSE_WAIT的問題。
TIME_WAIT一般通過優化內核參數能夠解決;CLOSE_WAIT一般是由於程序編寫不合理造成的,更應該引起開發者注意。
TIME_WAITTIME_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(kernel199)
TCP:20047(estab32,closed20000,orphaned4,synrecv0,timewait20000/0),ports10785
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_WAITCLOSE_WAIT一般是由於對端主動關閉,而我方沒有正確處理的原因引起的。説白了,就是程序寫的有問題,屬於危害比較大的一種。
我們拿”csdn 諧音太郎”遇到的一個典型案例來説明。
代碼是使用HttpClient的一個使用片段。在這段代碼裏,通過調用in.close來進行連接資源的清理。但可惜的是,代碼中有一個判斷:非200狀態的連接直接返回。在這種情況下,in連賦值的機會都沒有,當然也就無法關閉,然後就發生了連接泄漏。
所以,HttpClient的正確關閉方式是使用其api:abort
。
# 斷點續傳下載文件
wget -c $url
# 下載整站
wget -r -p -np -k $url
# 發送網絡連接(常用)
curl -XGET $url
# 傳輸文件
scp
sftp
# 數據鏡像備份
rsync
# 連通性檢測
pinggoogle.com
# 到對端路由檢測
tracepathgoogle.com
# 域名檢測
diggoogle.com
nslookupgoogle.com
# 網絡掃描工具
nmap
# 壓力測試
iperf
# 全方位監控工具(好東西)
nmon
# 停止某個網卡
ifdown
# 開啓某個網卡
ifup
# 多功能管理工具
ethtool
wrk
ab
webbench
http_load
# 遠程登錄
telnet
ssh
nc
# 防火牆
iptables -L
除了基本的工具,本文提到的很多網絡命令,都不是預裝的,需要使用yum自行安裝。網絡編程方面的學習,我覺得,讀一下《TCP/IP詳解 卷1:協議》這本書,然後寫幾個Netty應用就可以了。
NIO我們已經在I/O篇提起了,在此不再做詳細介紹。等你碰到所謂的拆包粘包問題,遇到心跳和限流問題,甚至遇到了流量整形問題,那麼證明你離一個專業的網絡編程程序員越來越近了。