Sau bài này bạn làm được: SSH vào server và trong 5 phút biết: IP nào đang gắn, service nào đang listen, connection nào đang mở; giải thích tại sao refused và timeout có nghĩa khác nhau ở tầng firewall.
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 table, conntrack, netfilter (iptables/nftables)
▼
[Network interface: eth0, ens5, bond0…]
│
▼
[Vật lý / cloud NIC / overlay network]
Mọ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:
Firewall DROP: client gửi SYN → (im lặng) → client timeout sau vài giây/phút
Firewall REJECT: client gửi SYN → RST/ICMP ngay lập tức → client báo "refused"
Hầ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 # backlog tối đa cho accept queue
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)
Khi nào cần tune:
somaxconnthấp: server đang nhận burst connection → SYN DROP, client timeout.ip_local_port_rangenhỏ: khi một server mở ra rất nhiều kết nối outbound (proxy, crawler) → port exhaustion, connection failed.
Đổ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
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.