Bức tranh mạng trên một Linux host
Ứng dụng / container
│ (socket API: bind, connect, send…)
▼
Kernel: TCP/IP stack (routing, conntrack, netfilter)
│
▼
Network interface (eth0, ens5, bond0…)
│
▼
Vật lý / cloud NIC / overlayMọi traffic đi qua kernel, hiểu kernel networking là hiểu hành vi thực sự của hệ thống.
Interface và địa chỉ IP: lệnh ip
# Liệt kê interface và địa chỉ IP
ip -4 addr show
# Output mẫu:
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP>
inet 10.0.1.50/24 brd 10.0.1.255 scope global eth0
# Liệt kê link layer (MAC, trạng thái UP/DOWN)
ip link show
# Xem routing table
ip route show
# Output:
default via 10.0.1.1 dev eth0
10.0.1.0/24 dev eth0 proto kernel scope link src 10.0.1.50
172.17.0.0/16 dev docker0 proto kernel # Docker bridge
# Trace packet tới đích sẽ đi đường nào
ip route get 8.8.8.8
# 8.8.8.8 via 10.0.1.1 dev eth0 src 10.0.1.50
Ghi nhớ: ip addr và ip route thay thế ifconfig và route (deprecated).
Socket và process: lệnh ss
# Tất cả TCP đang LISTEN
ss -lntp
# Tất cả TCP ESTABLISHED
ss -tnp state established
# Tất cả UDP đang LISTEN
ss -lnup
# Lọc theo cổng
ss -lntp sport = :443
# Đếm theo trạng thái
ss -tan | awk '{print $1}' | sort | uniq -c | sort -rn
Đọc output:
State Recv-Q Send-Q Local Addr:Port Peer Addr:Port Process
LISTEN 0 128 0.0.0.0:80 0.0.0.0:* ("nginx",pid=123)
LISTEN 0 128 127.0.0.1:5432 0.0.0.0:* ("postgres",pid=456)
ESTAB 0 0 10.0.1.50:443 1.2.3.4:55123 ("nginx",pid=123)
Recv-Qcao: dữ liệu đang chờ application đọc, app bị block?Send-Qcao: dữ liệu chờ gửi, network bị tắc nghẽn?- Postgres chỉ bind
127.0.0.1→ không truy cập được từ ngoài (đúng hay sai tùy thiết kế).
Firewall: iptables / nftables khái niệm
Linux kernel dùng netfilter để lọc gói tin. iptables (cũ) và nftables (mới) là front-end để cấu hình netfilter.
Ghi chú 2025: nhiều distro hiện đại (Debian 11+, RHEL 9+, Ubuntu 22.04+) đã mặc định nftables backend; lệnh iptables thực chất là wrapper (iptables-nft). Kubernetes từ 1.29+ hỗ trợ kube-proxy nftables mode; CNI hiện đại (Cilium, Calico eBPF) có thể bỏ qua netfilter hoàn toàn bằng eBPF, xem bài 10.
Hiểu action, quan trọng hơn cú pháp:
ACCEPT → cho gói qua
DROP → im lặng bỏ gói (client thấy timeout)
REJECT → bỏ gói + gửi ICMP/RST về (client thấy refused hoặc unreachable nhanh hơn)
DROP vs REJECT trong debug:
Client
│ (SYN (Firewall DROP))
▼
FirewallHầu hết cloud SG dùng DROP (stateful). Khi “không vào được” và timeout dài → nghĩ ngay tới DROP rule.
Xem rule hiện tại:
# iptables (cần root)
iptables -L -n -v --line-numbers
# nftables
nft list ruleset
# Kiểm tra chain INPUT / FORWARD / OUTPUT
iptables -L INPUT -n -v
sysctl, tham số kernel ảnh hưởng mạng
# Xem tất cả tham số mạng
sysctl -a | grep net.core
# Các tham số quan trọng:
sysctl net.core.somaxconn # accept queue tối đa (connection đã handshake, chờ app accept())
sysctl net.ipv4.tcp_max_syn_backlog # SYN queue tối đa (connection đang handshake)
sysctl net.ipv4.ip_local_port_range # dải ephemeral port (VD: 32768 60999)
sysctl net.ipv4.tcp_max_tw_buckets # số socket TIME_WAIT tối đa trên hệ thống
sysctl net.ipv4.tcp_fin_timeout # thời gian chờ FIN trước khi đóng (s)
sysctl net.ipv4.tcp_tw_reuse # bật tái dùng TIME_WAIT cho outbound (cẩn trọng)
SYN queue vs accept queue
Hai hàng chờ khác nhau khi server nhận connection:
[1] Client gửi SYN
│
▼
[2] SYN queue (tcp_max_syn_backlog)\nđang thực hiện 3-way handshake
│
▼
[3] Accept queue (somaxconn)\nđể app gọi accept()
│
▼
[4] Application xử lý kết nối- SYN queue đầy (
tcp_max_syn_backlog): kernel bắt đầu gửi SYN cookies (nếu bật) hoặc DROP SYN mới. Kiểm tra:nstat -az | grep SyncookiesSent. - Accept queue đầy (
somaxconn): kernel DROP hoặc gửi RST cho connection đã hoàn thành handshake. Kiểm tra:nstat -az | grep ListenOverflows. ss -lntpcộtRecv-Qtrên LISTEN socket = số connection trong accept queue hiện tại;Send-Q= giá trị somaxconn.
Lưu ý:
somaxconnlà giới hạn kernel; app còn truyềnbacklogparameter tronglisten()syscall. Giá trị thực tế =min(app_backlog, somaxconn). NGINX dùnglisten 80 backlog=4096;, nếu somaxconn = 128 thì chỉ được 128.
Khi nào cần tune:
- Accept queue đầy (
ListenOverflowstăng): server đang nhận burst connection → tăngsomaxconn+ backlog app. - SYN queue đầy (SYN cookie active): có thể là SYN flood (DDoS) hoặc burst hợp lệ → tăng
tcp_max_syn_backlog.
Đổi tạm thời (mất sau reboot):
sysctl -w net.core.somaxconn=65535
Đổi vĩnh viễn:
echo "net.core.somaxconn = 65535" >> /etc/sysctl.d/99-custom.conf
sysctl -p /etc/sysctl.d/99-custom.conf
Kiểm tra connectivity từ server
# Ping (ICMP, có thể bị chặn, không phải TCP)
ping -c 4 8.8.8.8
# Trace route tới đích
mtr --report 8.8.8.8 # realtime, tốt hơn traceroute
traceroute 8.8.8.8
# Test TCP connect (không cần curl)
nc -vz api.example.com 443
# Kiểm tra DNS từ server
dig +short A api.example.com
conntrack, bảng theo dõi connection
Kernel dùng conntrack (connection tracking) để SG/iptables stateful hoạt động. Bảng conntrack có giới hạn:
# Số entry hiện tại vs tối đa
sysctl net.netfilter.nf_conntrack_count
sysctl net.netfilter.nf_conntrack_max
# Nếu count ẩp max → connection mới bị DROP!
# Tăng max (cẩn thận với RAM: ~300 bytes/entry)
sysctl -w net.netfilter.nf_conntrack_max=262144
# Xem conntrack entries (cần conntrack-tools)
conntrack -L | head
conntrack -C # count
Trên node K8s chạy nhiều Service, conntrack table dễ đầy → packet drop khó debug. Cilium eBPF mode không dùng conntrack kernel (tự track trong eBPF map) nên tránh được vấn đề này.
Tóm tắt
ip addr+ip route= bức tranh routing trên host.ss -lntp= biết ai đang nghe cổng nào.- DROP → timeout; REJECT → refused, quan trọng khi phân biệt firewall rule.
- Tune
sysctlcẩn thận: ghi lại giá trị cũ trước khi thay đổi.
Câu hỏi hay gặp
Service chỉ listen 127.0.0.1:8080, gọi từ máy khác vào 8080 thì sao? Expose an toàn ra sao?
Trả lời: Không kết nối được từ IP khác vì chỉ lắng nghe loopback. Muốn public: bind 0.0.0.0 hoặc IP máy và dùng reverse proxy + TLS + firewall (chỉ mở 443), không nên mở thẳng app port ra internet nếu không cần.
Recv-Q trên LISTEN tăng mãi, nghĩa là gì?
Trả lời: Hàng chờ accept đầy: kernel đã hoàn tất handshake nhưng tiến trình accept() chậm (app bị block, single-thread, hoặc quá tải). Cần tăng capacity app hoặc somaxconn/tune phù hợp.
iptables DROP cổng 5432, client thấy refused hay timeout?
Trả lời: Thường là timeout (gói SYN bị drop, không có RST). Refused là khi có RST (không có process listen hoặc REJECT).
Bài tiếp theo (Giai đoạn III): Mạng trong Docker, khi workload chạy trong container, mạng có thêm một lớp abstraction.