Trải nghiệm thực tế: Server sập kết nối dù CPU chỉ 10%
Hôm đó đúng đợt mở bán vé một sự kiện lớn, website bỗng lăn ra chết. Check nhanh trên Grafana, CPU chỉ ăn khoảng 10-12%, RAM còn dư tới hơn 24GB trên tổng số 32GB. Nginx không chết, database vẫn nhàn rỗi. Tuy nhiên, mọi request từ người dùng đều xoay tít rồi báo timeout. Mở terminal gõ dmesg -T, mình thấy log nhảy liên tục:
TCP: Possible SYN flooding on port 443. Sending cookies. Check SNMP counters.
Kiểm tra trạng thái mạng bằng netstat -n -p | grep SYN_RECV | wc -l, con số vọt lên hơn 1.000 socket treo lơ lửng. Lúc này, kernel đã âm thầm từ chối mọi lượt bắt tay mới.
Thực tế khi audit hạ tầng cho nhiều startup, mình thấy mô hình này lặp lại liên tục: dev dựng máy chủ Ubuntu/Debian, cài Nginx, bật tường lửa UFW mở cổng 80 và 443 là coi như xong. Ít ai để ý rằng các giá trị TCP/IP mặc định trong kernel Linux vốn được thiết kế cho mạng nội bộ từ hàng chục năm trước, hoàn toàn không được trang bị sẵn để chống chọi các đợt càn quét từ botnet.
Vì sao cấu hình mặc định lại dễ gục ngã?
Trong quy trình bắt tay 3 bước (3-way handshake) của TCP, khi client gửi gói tin SYN, kernel sẽ lưu trạng thái chờ (half-open connection) vào một bộ đệm gọi là SYN Backlog. Kẻ tấn công lợi dụng điểm yếu này để bắn liên tục hàng chục nghìn gói SYN giả mạo IP nguồn (IP Spoofing) mỗi giây và biến mất, không bao giờ gửi lại gói ACK cuối cùng.
Hệ quả nhãn tiền gồm 3 điểm nghẽn chính:
- Tràn hàng đợi SYN: Giá trị
tcp_max_syn_backlogmặc định trên nhiều distro chỉ dao động từ 128 đến 1024. Botnet chỉ cần bắn vài giây là lấp đầy bộ đệm này, khiến kernel tự động drop toàn bộ kết nối từ khách hàng thật. - Bỏ lọt gói tin giả mạo: Theo mặc định, Linux thường không kiểm tra xem gói tin đến có thể định tuyến ngược về chính card mạng vừa nhận hay không. Lỗ hổng định tuyến này biến server thành nạn nhân của kỹ thuật IP Spoofing.
- Cạn kiệt bảng Connection Tracking: Netfilter (lớp lõi của iptables/UFW) phải duy trì trạng thái cho từng gói tin qua bảng
nf_conntrack. Khi bị dội bom hàng triệu kết nối ảo, bảng này chạm ngưỡng trầnnf_conntrack_max, kéo theo tình trạng rớt gói diện rộng ngay tại tầng mạng.
So sánh các giải pháp phòng thủ phổ biến
Khi gặp vấn đề nghẽn mạng do DoS, chúng ta thường có ba hướng xử lý:
- Dùng CDN / WAF (Cloudflare, Fastly): Rất tốt cho lớp web HTTP/HTTPS. Dù vậy, nó vô tác dụng nếu kẻ tấn công biết được IP gốc (Origin IP), hoặc khi bạn cần bảo vệ các cổng chạy trực tiếp như TCP microservices hay database.
- Viết rule iptables / nftables để rate-limit: Phương án này lọc được IP spam quen thuộc. Tuy nhiên, đối chiếu hàng triệu rule cho từng packet vẫn tiêu tốn CPU đáng kể khi traffic dồn dập.
- Tối ưu tham số Kernel qua sysctl: Đây là tuyến phòng thủ rẻ và hiệu quả nhất. Tinh chỉnh trực tiếp tại tầng nhân giúp máy chủ drop gói tin rác chỉ sau vài nano-giây trước khi chúng kịp ngốn tài nguyên của ứng dụng.
Từng bước tinh chỉnh sysctl để gia cố Linux Kernel
Các cờ cấu hình mạng của Linux nằm trong hệ thống file ảo /proc/sys/. Bạn có thể can thiệp trực tiếp và an toàn thông qua công cụ sysctl.
1. Khắc chế triệt để SYN Flood với SYN Cookies
Bình thường, kernel phải cấp phát bộ nhớ RAM cho mỗi kết nối nửa vời (half-open). Khi bật SYN Cookies, kernel sẽ không lưu trạng thái vào RAM nữa. Thay vào đó, nó mã hóa thông tin kết nối thành một chuỗi toán học nằm ngay trong Sequence Number gửi ngược về client.
Chỉ khi nhận lại gói ACK hợp lệ chứa mã này, server mới thực sự cấp phát tài nguyên. Hàng đợi SYN sẽ không bao giờ bị nghẽn cứng.
# Bật SYN Cookies khi hàng đợi bị đầy
net.ipv4.tcp_syncookies = 1
# Nới rộng kích thước hàng đợi SYN backlog từ mặc định lên 8.192 kết nối
net.ipv4.tcp_max_syn_backlog = 8192
# Giảm số lần thử gửi lại gói SYN-ACK từ 5 lần xuống 2 lần để giải phóng socket rác sau ~9 giây
net.ipv4.tcp_synack_retries = 2
2. Chặn đứng IP Spoofing bằng Reverse Path Filtering
Cơ chế Reverse Path Filtering (rp_filter) buộc kernel đối chiếu địa chỉ IP nguồn của gói tin với bảng định tuyến (routing table). Nếu gói tin đến từ cổng eth0 nhưng đường về hợp lệ lại nằm ở cổng khác hoặc không thể định tuyến, kernel sẽ vứt bỏ ngay lập tức.
# Giá trị 1 kích hoạt chế độ Strict Mode (khuyên dùng cho server độc lập có 1 card mạng chính)
net.ipv4.conf.all.rp_filter = 1
net.ipv4.conf.default.rp_filter = 1
3. Vô hiệu hóa ICMP Redirects và phòng chống Smurf Attack
ICMP là giao thức chẩn đoán mạng, nhưng thường bị hacker lợi dụng để đầu độc bảng định tuyến (ICMP Redirect) hoặc biến server thành công cụ khuếch đại tấn công từ chối dịch vụ (Smurf Attack). Nếu máy chủ của bạn không đóng vai trò làm router, hãy tắt hoàn toàn các tính năng này:
# Không chấp nhận gói tin chuyển hướng tuyến đường ICMP từ bên ngoài
net.ipv4.conf.all.accept_redirects = 0
net.ipv4.conf.default.accept_redirects = 0
net.ipv4.conf.all.secure_redirects = 0
net.ipv4.conf.default.secure_redirects = 0
# Không gửi thông báo ICMP redirect cho host khác
net.ipv4.conf.all.send_redirects = 0
net.ipv4.conf.default.send_redirects = 0
# Phớt lờ mọi yêu cầu ICMP echo gửi tới địa chỉ Broadcast
net.ipv4.icmp_echo_ignore_broadcasts = 1
# Giới hạn tốc độ phản hồi thông điệp lỗi ICMP (tối đa 100ms một lần)
net.ipv4.icmp_ratelimit = 100
4. Thu hồi socket treo và mở rộng bảng Connection Tracking
Khi bị quét cổng hoặc dính DoS, server thường tồn đọng một lượng khổng lồ socket kẹt ở trạng thái TIME_WAIT hoặc FIN_WAIT_2. Tình trạng này làm cạn kiệt dải cổng tạm thời (ephemeral ports). Bạn hãy rút ngắn thời gian giữ các kết nối chết này:
# Rút ngắn thời gian chờ đóng socket từ 60 giây xuống 15 giây
net.ipv4.tcp_fin_timeout = 15
# Cho phép tái sử dụng các socket TIME-WAIT cho kết nối an toàn mới
net.ipv4.tcp_tw_reuse = 1
# Nới rộng bảng theo dõi trạng thái netfilter lên hơn 1 triệu bản ghi (mỗi bản ghi tốn ~300 bytes RAM)
net.netfilter.nf_conntrack_max = 1048576
# Nâng trần hàng đợi lắng nghe (listen backlog) của socket lên 65.535
net.core.somaxconn = 65535
Triển khai an toàn vào môi trường Production
Đừng bao giờ chỉnh sửa trực tiếp vào file /etc/sysctl.conf mặc định. File này dễ bị ghi đè khi nâng cấp hệ điều hành. Thay vào đó, hãy tách cấu hình riêng biệt vào thư mục /etc/sysctl.d/.
Bước 1: Khởi tạo file cấu hình mới:
sudo nano /etc/sysctl.d/99-security-hardening.conf
Bước 2: Lưu các thông số đã tinh chọn vào file:
# 1. Chống giả mạo IP (Strict Reverse Path Filtering)
net.ipv4.conf.all.rp_filter = 1
net.ipv4.conf.default.rp_filter = 1
# 2. Ngăn ngừa tấn công SYN Flood
net.ipv4.tcp_syncookies = 1
net.ipv4.tcp_max_syn_backlog = 8192
net.ipv4.tcp_synack_retries = 2
# 3. Chặn lạm dụng ICMP và Source Routing
net.ipv4.icmp_echo_ignore_broadcasts = 1
net.ipv4.conf.all.accept_redirects = 0
net.ipv4.conf.default.accept_redirects = 0
net.ipv4.conf.all.send_redirects = 0
net.ipv4.conf.default.send_redirects = 0
net.ipv4.conf.all.accept_source_route = 0
net.ipv4.conf.default.accept_source_route = 0
# 4. Tối ưu thu hồi kết nối mạng
net.core.somaxconn = 65535
net.ipv4.tcp_fin_timeout = 15
net.ipv4.tcp_tw_reuse = 1
Bước 3: Kích hoạt thay đổi ngay lập tức mà không cần reboot server:
sudo sysctl --system
Bước 4: Xác thực lại xem giá trị mới đã ăn vào kernel hay chưa:
sysctl net.ipv4.tcp_syncookies net.ipv4.conf.all.rp_filter
Output hiển thị = 1 tức là thiết lập đã hoạt động thành công. Chỉ với vài phút tinh chỉnh, bạn đã dựng xong một tấm khiên vững chắc ở tầng nhân, giúp server sống sót êm đẹp qua những đợt quét botnet tự động mà không tiêu tốn thêm một đồng chi phí phần cứng.

