# 網路相關 command


## 簡介

最早 net-tools 起源於 BSD（在 1980 年代，BSD 開發了現代網際網路的雛形——BSD TCP/IP 堆疊。為了管理這個堆疊，開發者編寫了一系列工具），他提供了自己的一些 command 包含：

1. `ifconfig`: 網卡設定
2. `route`: 路由管理
3. `arp`: arp 快取
4. `ipmaddr`: 多播成員
5. `netstat`: 連線統計

但在 Linux 2.2 之後，推出自己的 `iproute2` 使用者工作集。

主要因為通訊機制的落後 (ioctl vs. Netlink)，net-tools 依賴的是 ioctl 系統調用和讀取 /proc/net 檔案。這種方式效率低，且難以擴充。當 Linux 核心引入了高級路由、多路由表、策略路由時，ioctl 已經無法負荷這些複雜的資訊交換。

| **功能目的 (Purpose)** | **現代工具 (iproute2)** | **傳統工具 (net-tools)** | **核心觀察/設定重點** |
| --- | --- | --- | --- |
| **網卡位址與狀態** | `ip addr` | `ifconfig` | IP 位址、子網遮罩、網卡狀態 (UP/DOWN)。 |
| **連結層 (L2) 資訊** | `ip link` | `ifconfig` | MAC 位址、MTU 設定、虛擬介面管理。 |
| **路由表管理** | `ip route` | `route` / `netstat -r` | 靜態路由、預設閘道 (Gateway)、策略路由。 |
| **ARP / 鄰居快取** | `ip neigh` | `arp` | L2 與 L3 位址映射表 (ARP Table)。 |
| **多播成員資格** | `ip maddr` | `ipmaddr` | 網卡加入的多播組 (Multicast Group)。 |
| **Socket 連線狀態** | `ss` | `netstat` | 監聽埠、建立的 TCP/UDP 連線、PID 關聯。 |
| **通訊協定統計** | `nstat` | `netstat -s` | 核心 SNMP 計數器 (如 SYN Cookies)。 |
| **網路隧道 (Tunnel)** | `ip tunnel` | `iptunnel` | GRE、IPIP 等隧道封裝設定。 |
| **網橋 / 交換機** | `bridge` | `brctl` | Linux Bridge 設定 (舊工具屬於 `bridge-utils`)。 |
| **流量控制 / QoS** | `tc` | (無對等) | 頻寬限制、延遲模擬 (Linux 流量控制核心)。 |

但還是有些工具像是 `ping` or `traceroute` 還在用，這類工具屬於 `iputils` 或單獨的套件，它們的核心是發送 ICMP 封包，與管理介面或路由表的 iproute2 是不同維度的功能。

Ubuntu 為了簡化伺服器與桌面的網路配置，又多了一層管理指令：

* `nmcli` (Network Manager CLI)：這是桌機版或具有 NetworkManager 的 Server 最強大的工具。它可以管理 WiFi、VPN 與乙太網路切換
* `nmtui`：nmcli 的文字圖形化版本（TUI），如果你不想背指令，這個很好用
* `netplan`：這是 Ubuntu 18.04 之後的標準網路設定工具。你修改 /etc/netplan/*.yaml 後，需要執行 sudo netplan apply 才會生效

### ifconfig

```bash
adl@adl-D630MT:~$ ifconfig
enp0s31f6: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 192.168.169.90  netmask 255.255.255.0  broadcast 0.0.0.0
        ether 88:d7:f6:56:6f:64  txqueuelen 1000  (Ethernet)
        RX packets 33336364  bytes 35531193350 (35.5 GB)
        RX errors 1133360  dropped 8696  overruns 0  frame 566680
        TX packets 12031595  bytes 4914630505 (4.9 GB)
        TX errors 0  dropped 4 overruns 0  carrier 0  collisions 0
        device interrupt 16  memory 0xdf100000-df120000
```

基本上如上當例子：

1. 介面
   * `enp0s31f6`: 這是介面名稱。在現代 Ubuntu 中採用「可預測網路介面名稱」，這代表這張網卡插在 PCI 匯流排的特定位置
   * `flags=4163<UP,BROADCAST,RUNNING,MULTICAST>`:
       * UP: 網卡已啟動
       * BROADCAST: 支援廣播
       * RUNNING: 網卡已連接線路且正在運作（通常代表有偵測到物理載波）
       * MULTICAST: 支援多播
   * `mtu 1500`: 最大傳輸單元。乙太網路標準通常是 1500 bytes，超過此大小的封包會被切分（Fragmentation）
2. 位址資訊 (Layer 2 & 3)
   * `inet 192.168.169.90`: 網卡的 IPv4 位址
   * `netmask 255.255.255.0`: 子網路遮罩
   * `broadcast 0.0.0.0`: (注意) 這裡顯示 `0.0.0.0` 通常代表該介面沒有正確設定廣播位址，標準 `/24` 網段通常應為 `192.168.169.255`
   * `ether 88:d7:f6:56:6f:64`: 網卡的物理 MAC 位址
   * `txqueuelen 1000`: 傳送隊列長度
3. 流量統計 (Traffic Stats)
    * RX/TX info，包含
    * errors 封包損壞或格式錯誤
    * dropped: 核心緩衝區滿了或是因為防火牆規則被丟棄的封包
    * overruns: 硬體接收速度跟不上軟體處理速度，導致資料溢位
    * frame: 底层物理層出現幀錯誤（常見於線路老化或電磁干擾）
    * collisions: 網路衝突次數。在全雙工（Full-duplex）切換式網路中，這通常應為 0
4. `device interrupt / memory`: 該網卡在硬體層級使用的中斷號與記憶體映射位址

其他常見 command 像是

1. `sudo ifconfig XXX down/up`: 開關網卡
2. `sudo ifconfig <interface> 192.168.1.100 netmask 255.255.255.0 broadcast 192.168.1.255`: 手動設定 IP
3. `sudo ifconfig <interface> hw ether AA:BB:CC:DD:EE:FF`: 甚至可以修改 MAC
4. `sudo ifconfig <interface> mtu 1400`: 調整 MTU
5. `sudo ifconfig <interface> promisc (關閉則加個負號：-promisc)`: 如果你要用 tcpdump 或 Wireshark 抓取所有經過網卡的封包（不論目的地是否為自己）
6. `ifconfig -a`: 列出所有網卡，預設只顯示啟用的

### ethtool

`ethtool` 用於查詢與控制網路介面卡的控制器（Controller）與實體層（PHY）參數（L1/L2）。它直接與網卡驅動程式溝通，獲取硬體級別的統計數據。

基礎包含查看硬體基本狀態

```bash
adl@adl-D630MT:~$ sudo ethtool enp0s31f6
Settings for enp0s31f6:
 Supported ports: [ TP ]
 Supported link modes:   10baseT/Half 10baseT/Full
                         100baseT/Half 100baseT/Full
                         1000baseT/Full
 Supported pause frame use: Symmetric Receive-only
 Supports auto-negotiation: Yes
 Supported FEC modes: Not reported
 Advertised link modes:  10baseT/Half 10baseT/Full
                         100baseT/Half 100baseT/Full
                         1000baseT/Full
 Advertised pause frame use: Symmetric Receive-only
 Advertised auto-negotiation: Yes
 Advertised FEC modes: Not reported
 Link partner advertised link modes:  10baseT/Half 10baseT/Full
                                      100baseT/Half 100baseT/Full
                                      1000baseT/Full
 Link partner advertised pause frame use: Symmetric
 Link partner advertised auto-negotiation: Yes
 Link partner advertised FEC modes: Not reported
 Speed: 1000Mb/s
 Duplex: Full
 Auto-negotiation: on
 Port: Twisted Pair
 PHYAD: 1
 Transceiver: internal
 MDI-X: off (auto)
 Supports Wake-on: pumbg
 Wake-on: d
        Current message level: 0x00000007 (7)
                               drv probe link
 Link detected: yes
```

* Supported ports: TP 代表 Twisted Pair（雙絞線），也就是我們常見的 RJ45 網孔。如果支援光纖，這裡會出現 FIBRE
* Supported link modes：這張網卡原生支援的所有速率
* Supported pause frame use：流量控制 (Flow Control) 能力。當網路塞車時，網卡是否支援暫停傳送。Symmetric 是對等傳收，Receive-only 是只收暫停指令
* Supports auto-negotiation: Yes：硬體是否支援「自動協商」。這能讓兩台設備見面時自動討論出最高共識速率
* Supported FEC modes：前向錯誤更正 (Forward Error Correction)。通常在 25G/100G 高速網路或光纖才有用，1G 網卡通常顯示 Not reported
* 宣傳規格區 (Advertised)： ...
* 對端（隊友）狀態區 (Link partner)： ...
* 當前連線狀態 (Current Status)
  * `Speed: 1000Mb/s`：
    * 目前的實際傳輸速率。
  * `Duplex: Full`：
    * 目前是全雙工（可同時收發）。如果是 `Half`，代表收發會互撞，效能會減半。
  * `Auto-negotiation: on`：
    * 目前的自動協商功能是開啟的。
  * `Port: Twisted Pair`：
    * 目前使用的物理介面是雙絞線。
  * `PHYAD: 1`：
    * 實體層位址。這是主機板 CPU 用來跟網卡晶片（PHY）通訊的內部編號，一般維運不太需要理它。
  * `Transceiver: internal`：
    * 收發器類型。`internal` 代表收發功能整合在網卡主晶片內。
  * `MDI-X: off (auto)`：
    * 線路自動跳線。早期接電腦對電腦要用跳線（Crossover），現在網卡會自動偵測並切換邏輯電路。`off` 通常指目前是正常直連模式。
  * `Supports Wake-on: pumbg / Wake-on: d`：
    * 遠端喚醒 (WoL)。`d` (disabled) 代表目前關閉中；`g` (magic packet) 代表支援用魔術封包喚醒。
  * `Current message level`：
    * 驅動程式的除錯訊息等級。一般預設是 7 (drv probe link)，代表只記錄基本的偵測資訊。
  * `Link detected: yes`：
    * 物理連線偵測。最直觀的欄位，`yes` 代表物理電訊號有接通。

或者我們可以查詢硬體統計數據，例如可以看 L1 實體層的錯誤：

```bash
adl@Twinkle:~$ sudo ethtool -S enp6s0f1 | grep -E "crc_errors|symbol_errors|length_errors|align_errors"
     rx_crc_errors: 0
     rx_length_errors: 0
     rx_long_length_errors: 0
     rx_short_length_errors: 0
```

* `rx_crc_errors` (最常見)：
  * 意義：封包內容在傳輸過程中變形，導致校驗碼不符。
  * 原因：網路線品質太差（如 Cat 5 硬跑 1G）、接頭氧化、環境電磁干擾、或是網卡電路老化。
* `rx_symbol_errors`：
  * 意義：實體層編碼錯誤。
  * 原因：通常是線路極度不穩定或兩端時鐘同步（Clocking）出問題。
* `rx_missed_errors`：
  * 意義：封包抵達了但網卡緩衝區已滿，來不及收。
  * 原因：通常是系統處理速度太慢或 CPU 負載過高

除了查詢，ethtool 還能強制更改硬體行為：

1. 降低速度
2. 調整 Ring Buffer
3. 管理硬體加速 (Offload)
4. ...

### ss

`ss` 看的是「軟體層（Socket）」的狀態，而 `ethtool` 看的是「硬體/驅動層（NIC）」的表現。`ss` 取代了舊的 `netstat`，它直接從核心（Kernel）的 TCP/UDP 協定棧中抓取資訊 (L4)。

| **選項** | **名稱** | **說明** |
| --- | --- | --- |
| **`-t`** | **TCP** | 只看 TCP 連線。 |
| **`-u`** | **UDP** | 只看 UDP 連線。 |
| **`-l`** | **Listening** | 只看「正在監聽」的埠號（預設不顯示監聽中的）。 |
| **`-a`** | **All** | 顯示所有連線（包含建立中、監聽中、已關閉的）。 |
| **`-n`** | **Numeric** | 不解析服務名稱（顯示 80 而不是 http），**實驗時必加，速度更快**。 |
| **`-p`** | **Process** | 顯示是哪個 **PID / 程式名稱** 在使用這個 Socket。 |
| **`-e`** | **Extended** | 顯示更詳細的資訊（例如 inode, uid）。 |
| **`-i`** | **Internal** | 顯示核心內部的 TCP 參數（RTT, CWND, MSS 等）。 |

### nstat

它直接讀取核心的 SNMP 計數器，速度極快，且支援「增量顯示」，他是 `netstat -s` 的代替品，他可以看的比 `netstat` 的訊息還多，是因為會從 `/proc` 底下的文件拿資訊。

{{< image
    src="image.png"
    alt="[nstat](https://linux-audit.com/system-administration/commands/nstat/)"
    caption="[nstat](https://linux-audit.com/system-administration/commands/nstat/)"
>}}

`nstat` 預設會讀取上次執行後的「增量」，並將歷史紀錄存在 `/etc/nstat.history`，基本 Option 包含：

```bash
kola:~$ nstat -h
Usage: nstat [OPTION] [ PATTERN [ PATTERN ] ]
   -h, --help          this message
   -a, --ignore        ignore history
   -d, --scan=SECS     sample every statistics every SECS
   -j, --json          format output in JSON
   -n, --nooutput      do history only
   -p, --pretty        pretty print
   -r, --reset         reset history
   -s, --noupdate      don't update history
   -t, --interval=SECS report average over the last SECS
   -V, --version       output version information
   -z, --zeros         show entries with zero activit
```

1. `-a`: `nstat` 預設看上次執行 `nstat` 中間增加多少，`-a` 可以看開機到現在所有累計數值
2. `-z`: 看所有指標，因為預設不顯示為 0 的數值
3. `-s`: 顯示增量，但不更新歷史紀錄

最後面 PATTERN 可以接一些不同的指標名稱，像是：

1. `TcpExtSyncookiesSent`: 送出的 SYN Cookies 數量，如果這個數字在跳動，代表系統偵測到 SYN Flood 並開始抵抗
2. `TcpExtTCPBacklogDrop`: 因為 TCP 隊列滿了而丟棄的封包
3. `TcpExtListenDrops`: 核心無法為新連線建立 Socket。通常代表 `accept()` 隊列已滿
4. ...

`nstat` man page 沒寫有哪些指標可以用，因為 `nstat` 只是搬運工，他不定義數據，這些指標是來自核心 Network Stack Counter，每個版本核心可能不一樣，核心主要用 `NET_INC_STATS` 等 Macro 紀錄指標。

核心的 `/proc` 檔案系統介面（如 `/proc/net/netstat`）會定期將這些內部變數轉換為文字，供使用者空間（User Space）讀取。

