TCP 連線管理是網路程式設計和系統管理的根本。理解 TCP 的三次握手流程、連線狀態以及如何使用相關工具進行診斷,對於開發可靠的網路應用和維護穩定的網路環境至關重要。本文除了介紹 TCP 的核心概念外,也示範瞭如何使用 netstat、ss 和 lsof 等 Linux 工具來監控和分析網路連線,並提供了一些實用的技巧,例如使用 tr 和 cut 命令格式化輸出結果,以便更有效地進行網路診斷和問題排查。這些工具和技巧可以幫助開發者和系統管理員更好地理解網路連線狀態,進而提升網路應用程式的效能和穩定性。
TCP三次握手流程圖示
sequenceDiagram; participant Client as 使用者端; participant Server as 伺服器; Client-»Server: SYN; Server-»Client: SYN-ACK; Client-»Server: ACK;
此圖示展示了TCP三次握手的流程。
#### 圖示內容解密:
1. 使用者端發起連線請求,傳送SYN包。
2. 伺服器回應SYN-ACK包,確認收到使用者端的請求並準備建立連線。
3. 使用者端傳送ACK包,確認連線建立。
## TCP 連線建立與終止的深入解析
在網路診斷與通訊的領域中,TCP(Transmission Control Protocol)扮演著重要的角色。不同於 UDP(User Datagram Protocol),TCP 提供可靠的、導向連線的通訊服務。本篇文章將探討 TCP 的連線建立過程、三次握手、連線狀態以及如何使用 Linux 工具進行網路診斷。
### TCP 三次握手:建立可靠的連線
TCP 連線的建立始於所謂的「三次握手」(three-way handshake)。這個過程確保了雙方都準備好進行資料傳輸,並且能夠追蹤遺失或損壞的封包。以下是三次握手的步驟:
1. **客戶端發起連線請求**:客戶端從一個臨時埠(ephemeral port)向伺服器的固定埠(通常是已知的服務埠,如 HTTP 的 80 埠)傳送一個 SYN(synchronize)封包,並附帶一個初始序列號(SEQ)。
2. **伺服器回應連線請求**:伺服器收到 SYN 封包後,回應一個 SYN-ACK 封包,其中包含對客戶端 SEQ 的確認(ACK),以及伺服器自己的初始 SEQ。
3. **客戶端確認連線建立**:客戶端收到 SYN-ACK 後,傳送一個 ACK 封包確認伺服器的 SEQ,從此連線正式建立。
```plantuml
@startuml
note
無法自動轉換的 Plantuml 圖表
請手動檢查和調整
@enduml
內容解密:
- 客戶端發起 SYN 封包:客戶端選擇一個初始序列號
x,並將 SYN 位置為 1,表示請求建立連線。 - 伺服器回應 SYN-ACK 封包:伺服器確認客戶端的序列號
x,並回應x+1作為 ACK。同時,伺服器選擇自己的初始序列號y,並將 SYN 位置為 1。 - 客戶端確認連線:客戶端收到伺服器的 SYN-ACK 後,將 ACK 設定為
y+1,確認伺服器的初始序列號。
連線狀態與 netstat 命令
在 Linux 系統中,netstat 命令是一個非常有用的工具,用於檢視目前系統的網路連線狀態、路由表以及網路介面統計資訊。以下是如何使用 netstat 命令來列出所有監聽中的埠和連線:
$ netstat -tuan
輸出範例:
Active Internet connections (servers and established)
Proto Recv-Q Send-Q Local Address Foreign Address State
tcp 0 0 127.0.0.53:53 0.0.0.0:* LISTEN
tcp 0 0 0.0.0.0:22 0.0.0.0:* LISTEN
tcp 0 0 192.168.122.22:34586 13.33.160.88:443 TIME_WAIT
...
內容解密:
Proto列:顯示使用的協定,如 TCP 或 UDP。Local Address列:顯示本地主機的 IP 位址和埠號。Foreign Address列:顯示遠端主機的 IP 位址和埠號。State列:顯示目前的連線狀態,如 LISTEN、ESTABLISHED 或 TIME_WAIT。
常見的 TCP 狀態包括:
LISTEN:伺服器正在監聽特定埠,等待客戶端的連線請求。ESTABLISHED:連線已建立,雙方可以進行資料傳輸。TIME_WAIT:連線已關閉,但仍在等待一段時間,以確保所有封包都已處理完畢。
圖解 TCP 連線狀態
下圖展示了 TCP 連線在不同階段的狀態變化:
@startuml
skinparam backgroundColor #FEFEFE
skinparam defaultTextAlignment center
skinparam rectangleBackgroundColor #F5F5F5
skinparam rectangleBorderColor #333333
skinparam arrowColor #333333
title 圖解 TCP 連線狀態
rectangle "SYN_SENT" as node1
rectangle "SYN+ACK" as node2
rectangle "ACK" as node3
rectangle "FIN" as node4
rectangle "Timeout" as node5
node1 --> node2
node2 --> node3
node3 --> node4
node4 --> node5
@enduml
內容解密:
- 初始狀態:連線開始於
Closed狀態。 - SYN_SENT 狀態:客戶端傳送 SYN 後進入此狀態,等待伺服器的回應。
- SYN_RECV 狀態:伺服器收到 SYN 後進入此狀態,並回應 SYN-ACK。
- ESTABLISHED 狀態:客戶端收到 SYN-ACK 後傳送 ACK,連線正式建立。
- 連線終止過程:當一方傳送 FIN 後進入
FIN_WAIT1狀態,收到對方的 ACK 後進入FIN_WAIT2狀態,最終進入TIME_WAIT狀態後關閉連線。
網路診斷中的本地埠列舉:瞭解連線與監聽狀態
在進行網路診斷時,瞭解系統的連線狀態和監聽埠是至關重要的。這不僅能幫助我們識別系統上正在執行的服務,還能檢測潛在的安全問題和效能瓶頸。本文將探討如何使用Linux工具來進行本地埠列舉,並深入瞭解系統的連線狀態。
使用 netstat 命令進行埠列舉
netstat 是一個強大的命令列工具,用於顯示系統的網路連線狀態、路由表和介面統計等資訊。透過使用不同的選項,我們可以過濾出特定的資訊,例如正在監聽的埠和已建立的連線。
顯示監聽埠與對應服務
要檢視系統上正在監聽的TCP和UDP埠,以及對應的服務程式,可以使用以下命令:
$ sudo netstat -tulpn
輸出結果中會顯示協定型別(Proto)、本地地址(Local Address)、外部地址(Foreign Address)、狀態(State)以及對應的程式名稱(PID/Program name)。
程式碼解析:
$ sudo netstat -tulpn
-t選項表示顯示TCP協定相關的連線。-u選項表示顯示UDP協定相關的連線。-l選項表示僅顯示正在監聽的埠。-p選項表示顯示與連線相關的程式名稱和PID。-n選項表示以數字形式顯示地址和埠號,而不是使用網域名稱和服務名稱。
內容解密:
此命令用於列出所有正在監聽的TCP和UDP埠,並顯示對應的程式名稱和PID。這對於系統管理員來說是非常有用的,因為它可以幫助識別哪些服務正在執行,以及是否有未經授權的服務在監聽埠。
使用 ss 命令作為 netstat 的替代方案
ss 命令是 netstat 的一個現代替代品,它提供了更多的功能和更快的執行速度。使用 ss 命令可以獲得類別似於 netstat 的輸出結果。
顯示TCP和UDP連線狀態
要檢視系統上的TCP和UDP連線狀態,可以使用以下命令:
$ sudo ss -tuap
程式碼解析:
$ sudo ss -tuap
-t選項表示顯示TCP協定相關的連線。-u選項表示顯示UDP協定相關的連線。-a選項表示顯示所有連線(包括監聽和非監聽狀態)。-p選項表示顯示與連線相關的程式名稱和PID。
內容解密:
此命令用於列出所有TCP和UDP連線的詳細資訊,包括本地地址、遠端地址、連線狀態以及對應的程式名稱和PID。這對於深入瞭解系統的網路活動非常有幫助。
處理輸出結果:使用 tr 和 cut 命令進行格式化
當使用 ss 或 netstat 命令時,輸出的結果可能比較雜亂。為了更好地格式化輸出結果,我們可以使用 tr 和 cut 命令來處理。
使用 tr 和 cut 命令格式化輸出
要格式化 ss 命令的輸出結果,可以使用以下命令:
$ sudo ss -tuap | tr -s ' ' | cut -d ' ' -f 1,2,5,6 --output-delimiter=$'\t'
程式碼解析:
$ sudo ss -tuap | tr -s ' ' | cut -d ' ' -f 1,2,5,6 --output-delimiter=$'\t'
sudo ss -tuap用於取得TCP和UDP連線的詳細資訊。tr -s ' '用於將多個連續的空格字元壓縮為一個空格字元,以方便後續處理。cut -d ' ' -f 1,2,5,6用於選擇特定的欄位(在本例中為第1、2、5和6欄位)。--output-delimiter=$'\t'用於指定輸出結果的欄位分隔符為Tab字元。
內容解密:
此命令組合用於對 ss 命令的輸出結果進行格式化處理,使得輸出結果更加清晰易讀。透過選擇特定的欄位和使用Tab字元作為分隔符,可以使輸出結果更加整潔,便於進一步分析和處理。
本地連線埠列舉:我連線到什麼?我正在監聽什麼?
在 Linux 系統中,瞭解本地的網路連線和監聽的連線埠對於系統管理員和網路工程師來說非常重要。這不僅有助於監控系統的網路活動,還能夠協助排查網路問題和最佳化網路組態。本篇文章將介紹如何使用 Linux 工具來進行本地連線埠列舉。
使用 ss 命令進行網路連線列舉
ss 命令是一個強大的工具,用於調查系統的網路連線。它能夠顯示比 netstat 更詳細的資訊。
$ sudo ss -tuap
這個命令會列出所有 TCP 和 UDP 連線,包括監聽中的連線埠。其中:
-t引數指定顯示 TCP 連線。-u引數指定顯示 UDP 連線。-a引數表示顯示所有連線(包括監聽中的和已建立的)。-p引數用於顯示使用每個連線的程式。
內容解密:
sudo ss -tuap:使用ss命令列出所有 TCP 和 UDP 連線,並顯示相關的程式資訊。sudo:以系統管理員許可權執行命令,必要時輸入密碼。ss:用於顯示 socket 資訊的命令。-tuap:引陣列合,-t表示 TCP,-u表示 UDP,-a表示所有,-p表示顯示程式資訊。
處理 ss 命令的輸出
預設情況下,ss 命令輸出的欄位之間使用空格分隔,這可能會導致欄位對齊問題。我們可以使用 tr 和 cut 命令來格式化輸出。
$ sudo ss -tuap | tr -s ' ' | cut -d ' ' -f 1,2,5,6 --output-delimiter=$'\t'
內容解密:
tr -s ' ':將多個連續的空格壓縮成一個,以方便後續處理。tr:用於字元轉換的命令。-s ' ':將多個空格壓縮成一個。
cut -d ' ' -f 1,2,5,6 --output-delimiter=$'\t':選擇特定的欄位並使用 Tab 字元作為輸出分隔符。cut:用於從輸入中選取特定欄位的命令。-d ' ':指定輸入欄位的分隔符為空格。-f 1,2,5,6:選擇第1、2、5、6欄位。--output-delimiter=$'\t':指定輸出時使用 Tab 作為分隔符。
將輸出重新導向到檔案
我們可以使用重新導向運算元 > 將輸出儲存到檔案中。
$ sudo ss -tuap | tr -s ' ' | cut -d ' ' -f 1,2,5,6 --output-delimiter=$'\t' > ports.tsv
$ cat ports.tsv
內容解密:
> ports.tsv:將輸出重新導向到名為ports.tsv的檔案中。>:輸出重新導向運算元,將前一個命令的輸出儲存到指定的檔案中。
cat ports.tsv:顯示ports.tsv檔案的內容。cat:用於顯示檔案內容的命令。
使用 tee 命令同時輸出到檔案和終端
tee 命令允許我們將輸出同時儲存到檔案和顯示在終端上。
$ sudo ss -tuap | tr -s ' ' | cut -d ' ' -f 1,2,5,6 --output-delimiter=$'\t' | grep "EST" | tee ports.out
內容解密:
grep "EST":過濾出包含 “EST” 的行,通常用於找出已建立的連線。grep:用於文字搜尋的命令。"EST":搜尋包含 “EST” 的行,通常對應於已建立的 TCP 連線。
tee ports.out:將輸入同時寫入ports.out檔案和輸出到終端。tee:用於將輸入複製到多個輸出的命令。
使用 netstat 命令
另一個經典的命令是 netstat,它也能夠提供網路連線資訊。
$ sudo netstat -tulpn
內容解密:
sudo netstat -tulpn:列出所有監聽中的 TCP 和 UDP 連線埠,並顯示相關程式資訊。-t:顯示 TCP 連線。-u:顯示 UDP 連線。-l:僅顯示監聽中的連線埠。-p:顯示使用每個連線的程式。-n:以數字形式顯示地址和連線埠號。
使用 lsof 命令列舉網路連線
lsof 命令可以用來列舉開啟的檔案和網路連線。
$ lsof -i :443
$ lsof -i :22
內容解密:
lsof -i :443和lsof -i :22:列出使用特定連線埠(例如443和22)的網路連線。lsof:用於列舉開啟檔案和網路連線的命令。-i :443和-i :22:指定要查詢的連線埠號。