Pages

Monday, 30 December 2019

Linux 的 netstat 指令

Linux 的 netstat 指令可以用來查詢各種網路相關資訊,檢測各種網路相關的問題。
在 Linux 系統中若要檢查網路相關的問題,netstat 是一個很常使用到的指令之一,雖然他只能在本機執行,但是他可以列出非常多很有用的資訊,像 socket、TCP、UDP、IP 與 ethernet 層的各種資訊都可以利用 netstat 來查詢。

一般遇到問題時,第一個檢查步驟就是查閱系統記錄檔(log),必要時可以嘗試提升記錄層級(logging level)來獲得更詳盡的資訊。如果 netstat 所提供的資訊不夠時,亦可使用 Wireshark、tshark、tcpdump 或 nmap 等檢測工具。
在每個 Linux 系統中預設都會有安裝 netstat,而且他不需要使用管理者權限即可執行,也同時支援 IPv4 與 IPv6,不過不同的 UNIX/Linux 系統可能在參數上會有一些差異,所以如果您寫好的指令要在不同的系統上執行時,可能要稍微注意一下。
以下是各種 netstat 指令的使用範例與技巧。

基本用法

列出所有連接埠(Port)

列出所有連接埠,包含 listening 與 non listening:
netstat -a
 
僅列出 TCP 的連接埠:
netstat -at 僅列出 UDP 的連接埠:
netstat -au

列出 Listening 狀態的連接埠

列出所有 listening 狀態的連接埠:
netstat -l 列出所有 listening 狀態的 TCP 連接埠:
netstat -lt 列出所有 listening 狀態的 UDP 連接埠:
netstat -lu

統計數據

列出各種協定的統計數據:
netstat -s 列出 TCP 的統計數據:
netstat -st 列出 UDP 的統計數據:
netstat -su 如果要顯示應詳細的統計數據,可以再加上 -w 參數:
netstat -sw

顯示使用網路的行程

加上 -p 這個參數之後,可以顯示每個網路連接埠是被哪一個程式所使用,例如查看所有使用 TCP 連線的程式:
netstat -pt 如果用一般使用者的權限執行 netstat 時,就只能查看屬於自己的行程,若要查看所有的行程,就要使用管理者權限:
sudo netstat -pt 我們可以配合 grep 找出特定程式所使用的連接埠:
netstat -ap | grep ssh

不要解析 DNS

如果您不想要讓 netstat 自動解析 DNS、連接埠名稱與使用者名稱的話,可以加上 -n 參數,這樣可以加速 netstat 的執行速度:
netstat -an 也可以單獨指定不要解析的項目:
netsat -a --numeric-ports netsat -a --numeric-hosts netsat -a --numeric-users

連續輸出

加上 -c 參數之後,可以讓 netstat 每隔一秒輸出一次最新的資訊:
netstat -ct 我們也可以用 watch 達到類似的功能:
watch -n 1 netstat -t

路由表(Routing Table)

使用 netstat 加上 -r 可以查看目前核心的路由表:
netstat -r 輸出會類似這樣
Kernel IP routing table Destination Gateway Genmask Flags MSS Window irtt Iface default 10.0.2.2 0.0.0.0 UG 0 0 0 eth0 10.0.2.0 * 255.255.255.0 U 0 0 0 eth0 link-local * 255.255.0.0 U 0 0 0 eth0 這個跟 route 的輸出相同。

網路介面資訊

顯示系統中每個網路介面的資訊:
netstat -i Kernel Interface table Iface MTU Met RX-OK RX-ERR RX-DRP RX-OVR TX-OK TX-ERR TX-DRP TX-OVR Flg eth0 1500 0 500 0 0 0 309 0 0 0 BMRU lo 65536 0 283 0 0 0 283 0 0 0 LRU 顯示較詳細的資訊:
netstat -ie Kernel Interface table eth0 Link encap:Ethernet HWaddr 08:00:27:e8:47:48 inet addr:10.0.2.15 Bcast:10.0.2.255 Mask:255.255.255.0 inet6 addr: fe80::a00:27ff:fee8:4748/64 Scope:Link UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1 RX packets:500 errors:0 dropped:0 overruns:0 frame:0 TX packets:309 errors:0 dropped:0 overruns:0 carrier:0 collisions:0 txqueuelen:1000 RX bytes:436569 (436.5 KB) TX bytes:44984 (44.9 KB) lo Link encap:Local Loopback inet addr:127.0.0.1 Mask:255.0.0.0 inet6 addr: ::1/128 Scope:Host UP LOOPBACK RUNNING MTU:65536 Metric:1 RX packets:283 errors:0 dropped:0 overruns:0 frame:0 TX packets:283 errors:0 dropped:0 overruns:0 carrier:0 collisions:0 txqueuelen:0 RX bytes:30501 (30.5 KB) TX bytes:30501 (30.5 KB) 這個跟 ifconfig 的輸出相同。

進階用法

列出使用中的網路連線

的輸出中會將使用中的網路連線標示為 ESTABLISHED,我們可以藉由 grep 找出這些連線的資訊:
netstat -atnp | grep ESTA
(Not all processes could be identified, non-owned process info
 will not be shown, you would have to be root to see it all.)
tcp        0      0 10.0.2.15:33061         173.194.72.113:80       ESTABLISHED 2266/firefox    
tcp        0      0 10.0.2.15:55167         54.194.90.130:443       ESTABLISHED 2266/firefox    
tcp        0      0 10.0.2.15:36853         54.148.186.182:443      ESTABLISHED 2266/firefox    
tcp        0      0 10.0.2.15:43221         54.230.124.50:80        ESTABLISHED 2266/firefox    
tcp        0      0 10.0.2.15:59644         91.189.89.240:80        ESTABLISHED 2266/firefox    
tcp        0      0 10.0.2.15:43378         173.194.72.136:443      ESTABLISHED 2266/firefox    
tcp        0      0 10.0.2.15:60502         64.233.187.100:443      ESTABLISHED 2266/firefox    
tcp        0      0 10.0.2.15:60816         54.230.124.50:443       ESTABLISHED 2266/firefox
若要即時監控使用中的連線資訊,可以使用 watch
watch -d -n0 "netstat -atnp | grep ESTA"

列出完整的 URL 位址

在預設的狀況下,netstat 會將過長的 URL 位址截斷,保持簡潔的輸出格式,而 -W 可以讓 netstat 列出完整的 URL 位址:
netstat -tup -W

用 awk 分析連線

這個指令可以分析 Apache 的連線,列出每個 IP 位址的連線數:
netstat -anpt | grep apache2 | grep ESTABLISHED | awk -F "[ :]*" '{print $4}' | uniq -c
不過這個指令需要管理者權限才能正常使用。
這個指令可以將所有連線的 IP 位址列出來,並依照每個 IP 位址的連線數排序:
netstat -an | grep ESTABLISHED | awk '/^tcp/ {print $5}' | awk -F: '{print $1}' | sort | uniq -c | sort -nr
輸出會像這樣:
      2 119.160.254.215
      1 98.138.250.102
      1 98.138.243.53
      1 23.41.139.27
      1 124.108.101.11
      1 116.214.12.74
      1 106.10.170.120
 
這個指令會用 + 號表示連線數:
netstat -an | grep ESTABLISHED | awk '{print $5}' | awk -F: '{print $1}' | sort | uniq -c | awk '{ printf("%s\t%s\t",$2,$1) ; for (i = 0; i < $1; i++) {printf("+")}; print "" }'
輸出會像這樣:
116.214.12.74 1 +
119.160.254.197 1 +
119.160.254.215 2 ++
119.161.24.16 1 +
124.108.101.11 1 +
203.69.138.155 1 +
23.41.139.27 3 +++
23.41.141.49 1 +
63.250.200.128 1 +
98.138.243.53 3 +++
98.138.250.102 1 +
 
這個指令會計算各種連線狀態的統計:
netstat -ant | awk '{print $6}' | grep -v established\) | grep -v Foreign | sort | uniq -c | sort -n
      3 CLOSE_WAIT
      3 LISTEN
      7 ESTABLISHED

使用者的 Listening 行程

這個指令會列出每個使用者所開啓的 listening 行程數:
netstat -ltpe | awk '{print $7}' | grep -v Address | grep -v "^$" | sort | uniq -c | awk '{print $2 ": " $1}'
輸出會像這樣:
gtwang: 1
root: 3

查看本機服務

-lx 參數可以列出目前 listening 的 UNIX 連接埠:
netstat -lx
我們可以透過這個方式檢查哪一些服務是只開給本機(localhost)使用的。
這個指令可以驗證 MySQL 是否是透過 UNIX domain socket 連線:
netstat -lx | grep -i mysql
輸出會像這樣:
unix  2      [ ACC ]     STREAM     LISTENING     12921    /var/run/mysqld/mysqd.sock

參考資料:The Geek StuffTecmintUnixmen
---------------

netstat -tulpn|grep :port-number查看哪个进程在监听这个port-number。

netstat -tulpn|grep some-process-name 查看这个进程是否在运行中。