Khi mình mới bắt đầu quản lý server, cứ thấy ai dùng netstat là mình làm theo. Thói quen từ các tutorial cũ, và mình không đặt câu hỏi gì cả. Cho đến khi cần debug kết nối chậm trên production server với vài nghìn socket đang mở — netstat chạy mất hơn 30 giây mới ra kết quả. Hôm đó mình mới thực sự tìm hiểu về ss.
Mình quản lý network cho office 50 người và một datacenter nhỏ — bài này tổng hợp từ thực tế sau khoảng 6 tháng chuyển dần từ netstat sang ss, và học cách kết hợp cả hai cho từng tình huống khác nhau.
netstat vs ss: Hai công cụ, một mục tiêu
Cả hai đều cho bạn thấy trạng thái kết nối mạng, port đang lắng nghe, và socket đang hoạt động. Nhưng cách chúng hoạt động bên dưới hoàn toàn khác nhau.
netstat thuộc gói net-tools, đọc thông tin từ /proc/net/ theo cách truyền thống. Trên Ubuntu 20.04+ và Debian 11+, nó không được cài sẵn nữa — bạn phải cài thủ công nếu cần.
ss (socket statistics) thuộc gói iproute2, giao tiếp trực tiếp với kernel qua netlink socket. Đây là lý do nó nhanh hơn rõ rệt khi có nhiều kết nối đang mở — thay vì parse file text trong /proc, nó lấy dữ liệu thẳng từ kernel.
Phân tích ưu nhược của từng công cụ
netstat: Quen thuộc nhưng đã lỗi thời
Ưu điểm:
- Syntax mình nhớ mà không cần Google; tutorial StackOverflow từ 2012 vẫn chạy đúng
- Output dễ đọc với người mới — cột rõ ràng, không cần giải thích nhiều
- Xem routing table và interface statistics trong cùng một tool (dù
ip routelàm tốt hơn)
Nhược điểm:
- Chậm khi có nhiều kết nối — parse
/proc/net/tcpdạng text, không scale được - Gói
net-toolsgần như không còn được cập nhật; nhiều distro đã bỏ khỏi default install - Filter options ít và kém linh hoạt hơn
ssnhiều
ss: Nhanh, hiện đại, nhưng cần làm quen syntax
Ưu điểm:
- Trên server với 5.000+ socket,
sstrả kết quả dưới 1 giây;netstatcó thể mất cả phút - Filter expression language rất mạnh — lọc theo IP, subnet, port, state, process trong một lệnh
- Hiển thị thêm thông tin TCP timer, congestion window — thứ
netstatkhông có - Đang được phát triển tích cực, là công cụ chuẩn trên mọi distro Linux hiện đại
Nhược điểm:
- Syntax filter khác hoàn toàn với
netstat, mất vài buổi để nhớ - Output lần đầu nhìn vào hơi lạ, đặc biệt cột Process với format
users:(("nginx",pid=5678,fd=7))
Chọn công cụ nào cho tình huống nào?
Sau 6 tháng dùng cả hai, mình rút ra được quy tắc khá đơn giản:
- Server production, nhiều kết nối: Dùng
ss— không bàn cãi. Trên server có vài nghìn connection đang mở, ss trả kết quả trong vài giây trong khi netstat có thể mất cả phút. - Debug nhanh trên máy dev hoặc workstation: Cả hai đều được, nhưng mình vẫn dần chuyển về
ssđể giữ thói quen nhất quán. - Cần routing table hoặc interface statistics: Dùng
ip routevàip -s linktừ iproute2 thay vìnetstat -r— cùng gói vớiss, nhất quán hơn.
Hướng dẫn sử dụng thực tế
Kiểm tra port đang lắng nghe
Tác vụ mình làm nhiều nhất — xem service nào đang chiếm port nào:
# Dùng ss (khuyến nghị)
ss -tlnp
# Giải thích flags:
# -t : TCP only
# -l : listening sockets
# -n : hiển thị số port thay vì tên service (nhanh hơn)
# -p : hiển thị process name và PID
# Dùng netstat tương đương
netstat -tlnp
Output của ss -tlnp trông như sau:
State Recv-Q Send-Q Local Address:Port Peer Address:Port Process
LISTEN 0 128 0.0.0.0:22 0.0.0.0:* users:(("sshd",pid=1234,fd=3))
LISTEN 0 511 0.0.0.0:80 0.0.0.0:* users:(("nginx",pid=5678,fd=6))
LISTEN 0 511 0.0.0.0:443 0.0.0.0:* users:(("nginx",pid=5678,fd=7))
Tìm process nào đang chiếm một port cụ thể
Tình huống hay gặp nhất: service không start được, báo port đã bị chiếm:
# Kiểm tra port 8080 đang bị chiếm bởi ai
ss -tlnp | grep :8080
# Hoặc dùng filter expression của ss
ss -tlnp 'sport = :8080'
# Output sẽ có dạng: users:(("node",pid=12345,fd=10))
# Kill process đó bằng:
kill -9 12345
Xem tất cả kết nối đang hoạt động
# Tất cả TCP connections đang ESTABLISHED
ss -tn state established
# Đếm số kết nối theo trạng thái
ss -tan | awk 'NR>1 {print $1}' | sort | uniq -c | sort -rn
# Tổng quan nhanh bằng ss -s
ss -s
Output ss -s rất hữu ích để đánh giá nhanh tình trạng server:
Total: 234 (kernel 312)
TCP: 45 (estab 23, closed 5, orphaned 0, timewait 17)
UDP: 8
Filter kết nối theo IP hoặc subnet
Tính năng này mình dùng nhiều khi quản lý office — cần xem máy nào đang kết nối đến server nội bộ, hoặc kiểm tra xem traffic từ một IP cụ thể đang đổ vào port nào:
# Xem tất cả kết nối từ subnet 192.168.1.0/24
ss -tn 'dst 192.168.1.0/24'
# Kết nối đến một IP cụ thể
ss -tn 'dst 192.168.1.100'
# Kết nối từ một IP cụ thể
ss -tn 'src 10.0.0.5'
# Kết hợp: kết nối từ subnet đến port 443
ss -tn 'src 192.168.1.0/24 and dport = :443'
Xem TCP timer — tính năng chỉ có trên ss
# Xem TCP timer (keepalive, retransmit timeout...)
ss -tn -o
# Output sẽ có thêm cột timer:
# timer:(keepalive,1min3sec,0)
# Nghĩa: keepalive timer còn 1 phút 3 giây, 0 lần retransmit
Theo dõi realtime
# Cập nhật mỗi 2 giây
watch -n 2 'ss -s'
# Hoặc theo dõi số kết nối theo trạng thái
watch -n 2 'ss -tan | awk "NR>1 {print \$1}" | sort | uniq -c | sort -rn'
Debugging workflow khi phát hiện kết nối bất thường
Hồi mình phát hiện một server trong datacenter đang bị scan port từ IP lạ, quy trình debug như sau:
# Bước 1: Xem có SYN flood không
ss -tn state syn-recv
# Bước 2: Đếm kết nối theo IP nguồn — phát hiện IP đang flood
ss -tn | awk 'NR>1 {print $5}' | grep -oP '^[\d.]+' | sort | uniq -c | sort -rn | head -20
# Bước 3: Xem toàn bộ kết nối từ IP đáng ngờ
ss -tn 'src 203.0.113.50'
# Bước 4: Kiểm tra TIME_WAIT có bất thường không
ss -tan state time-wait | wc -l
Với netstat, bước 2 mất cả phút khi server có nhiều kết nối mở. Đây chính là lý do thực tế mình chuyển sang ss — không phải vì đọc blog kêu hay, mà vì ngồi chờ output trong lúc đang debug incident thật sự rất ức chế.
Alias tiện dụng để dùng nhanh hàng ngày
Ba alias này mình thêm vào ~/.bashrc trên tất cả server, tiết kiệm được khá nhiều lần gõ:
# Thêm vào ~/.bashrc
alias ports='ss -tlnp' # Xem port đang listen
alias conns='ss -tn state established' # Kết nối đang active
alias socksum='ss -s' # Tổng quan socket statistics
# Reload
source ~/.bashrc
Cài đặt nếu chưa có
# Debian/Ubuntu
sudo apt install iproute2 # ss (thường đã có sẵn)
sudo apt install net-tools # netstat (nếu cần)
# CentOS/RHEL/Rocky Linux
sudo dnf install iproute # ss
sudo dnf install net-tools # netstat
# Kiểm tra version
ss -V
netstat --version
Trên Ubuntu 22.04 và Debian 12, ss đã được cài sẵn. netstat thì không — bạn phải cài thêm nếu cần.
Tổng kết
Học từ đầu? Học ss luôn, bỏ qua netstat. Syntax hơi khác một chút nhưng đáng bỏ thời gian làm quen. Đã quen netstat và muốn chuyển? Nhớ vài lệnh core của ss là đủ cho 90% tác vụ hàng ngày.
Với mình, sau nửa năm dùng ss trên production, mình không quay lại netstat nữa. Không phải vì ai bảo — mà vì nó nhanh hơn và filter mạnh hơn đúng lúc thực sự cần.

