Home/Blog/Nhật ký chống DDoS trên VPS: Từ sự cố 502 đến hướng dẫn cấu hình phòng thủ 5 lớp & chịu tải tối ưu
Security

Nhật ký chống DDoS trên VPS: Từ sự cố 502 đến hướng dẫn cấu hình phòng thủ 5 lớp & chịu tải tối ưu

N
Nam
·15 phút đọc·61 lượt xem
Nhật ký chống DDoS trên VPS: Từ sự cố 502 đến hướng dẫn cấu hình phòng thủ 5 lớp & chịu tải tối ưu

Nhật ký chống DDoS trên VPS: Từ sự cố 502 đến kiến trúc phòng thủ 5 lớp & báo cáo thực nghiệm Locust

Tấn công từ chối dịch vụ (DoS/DDoS) luôn là nỗi ác mộng đối với các quản trị viên hệ thống VPS vừa và nhỏ. Khi bị vắt cạn tài nguyên, web server thường trả về lỗi 502 Bad Gateway hoặc hoàn toàn đơ cứng.

Trong bài viết này, tôi chia sẻ chi tiết trải nghiệm thực tế từ lúc hệ thống keoquy.com bị sập do quá tải Event Loop của Next.js, cho đến quá trình xây dựng hệ thống phòng thủ 5 lớp 100% Self-Hosted (không phụ thuộc Cloudflare) và phân tích báo cáo kiểm thử chịu tải thực tế với 2,000 user giả lập (Locust).

Kiến trúc phòng thủ 5 lớp Self-Hosted trên VPS


1. Nguyên nhân gốc rễ: Tại sao Web Server dính lỗi 502 Bad Gateway?

Trong đợt thử nghiệm đầu tiên bằng script Python đơn giản (python-requests), lượng kết nối TCP tạo ra đồng thời vượt quá 5,000 kết nối.

Sơ đồ luồng gây nghẽn:

  1. Event Loop Single-Thread: Next.js mặc định chạy trên 1 tiến trình Node.js (1 CPU core). Với lượng request dồn dập, Event Loop bị nghẽn (Block Event Loop).
  2. Backlog Queue tràn ngập: Hàng đợi kết nối TCP socket bị đầy. Caddy Web Server (Reverse Proxy) gửi request tới port 3000 nhưng Node.js không phản hồi kịp.
  3. Caddy 502 Bad Gateway: Caddy nhận phản hồi connection reset by peer hoặc connection refused từ upstream 127.0.0.1:3000, lập tức trả lỗi 502 về cho người dùng.

2. Chi tiết 5 lớp phòng thủ Self-Hosted tối ưu

Để bảo vệ VPS chống lại các đợt DoS/DDoS lớp 4 (L4) và lớp 7 (L7) mà không cần đến proxy trung gian, chúng tôi thiết lập kiến trúc 5 tầng chuyên sâu:

Ảnh chụp Terminal thực tế: iptables firewall status, Fail2ban ban list và PM2 6-Worker Cluster

Lớp 1: Linux Kernel sysctl (Tối ưu Socket & Anti-SYN Flood)

Cấu hình tại /etc/sysctl.d/99-anti-ddos.conf:

  • net.ipv4.tcp_syncookies = 1: Kích hoạt SYN Cookies bảo vệ khỏi SYN flood.
  • net.core.somaxconn = 65535: Mở rộng hàng đợi kết nối TCP.
  • net.ipv4.tcp_max_syn_backlog = 65535: Tăng dung lượng hàng đợi SYN.
  • net.ipv4.tcp_fin_timeout = 15: Rút ngắn thời gian thu hồi socket FIN-WAIT-2.

Lớp 2: iptables Connlimit Firewall (Chặn đứng tại Tầng Kernel)

Giới hạn mỗi IP chỉ được phép mở tối đa 40 kết nối TCP đồng thời tới port 80/443:

sudo iptables -A INPUT -p tcp --syn --dport 443 -m connlimit --connlimit-above 40 -j DROP
sudo iptables -A INPUT -p tcp --syn --dport 80 -m connlimit --connlimit-above 40 -j DROP

Kết quả: Khi botnet tạo quá 40 kết nối, Kernel lập tức DROP gói tin SYN mà không tốn tài nguyên xử lý ở các tầng trên.

Lớp 3: Caddy Web Server (Bot Filtering & JSON Access Logs)

Chặn các User-Agent công cụ cào dữ liệu / script bot phổ biến và ghi nhận log JSON:

@blocked_bots {
    header_regexp User-Agent "(?i)(python-requests|httpx|Go-http-client|Scrapy|libwww-perl)"
}
respond @blocked_bots 403

Ảnh chụp Nhật ký Caddy Access Log JSON và log Fail2ban Ban IP tự động

Lớp 4: Fail2ban (Tự động khóa IP vi phạm)

Cấu hình Jail caddy-ddos tự động chặn IP phát sinh quá 15 lỗi (403, 429, 502) trong 60 giây. IP vi phạm bị DROP ở firewall trong 3,600 giây (1 giờ).

Lớp 5: Application Scaling với PM2 Cluster Mode (100% CPU Cores)

Chuyển Next.js từ đơn luồng sang chạy Cluster trên toàn bộ 6 nhân CPU (ecosystem.config.js):

module.exports = {
  apps: [{
    name: 'keoquy-frontend',
    script: 'node_modules/next/dist/bin/next',
    args: 'start -p 3000',
    instances: 'max', // Tận dụng 6/6 CPU Cores
    exec_mode: 'cluster'
  }]
};

3. Báo cáo thực nghiệm chịu tải với Locust (2,000 Users)

Sau khi hoàn tất cấu hình 5 lớp, chúng tôi tiến hành đợt Load Test thực tế lớn nhất sử dụng framework Locust với 2,000 user giả lập truy cập liên tục.

Báo cáo chi tiết kết quả thử nghiệm chịu tải Locust DDoS Load Test Report

Thông số kiểm thử & Kết quả chi tiết từ Báo cáo Locust:

Thông số / Chỉ số Giá trị thực tế ghi nhận Phân tích kỹ thuật
Target Host https://keoquy.com Server VPS 6 Cores, RAM 16GB
Simulated Users 2,000 Users Spawn rate 50 user/s
Tổng số Requests 84,809 Request Diễn ra trong 4 phút
Lưu lượng trung bình (RPS) 353.0 Req/s Tải xử lý trực tiếp
Số Request bị chặn (Dropped) 58,542 (69.0%) Chặn bởi iptables connlimit
Số Request thành công (200 OK) 26,267 (31.0%) Phản hồi mượt mà 5-7ms
Lỗi 502 Bad Gateway 0 lỗi (0%) Node.js Cluster tải mượt

Phân tích lỗi ConnectTimeoutError trong Locust Report:

Trong báo cáo Locust, 58,542 failures ghi nhận dưới dạng ConnectTimeoutError (Connection to keoquy.com timed out). Đây không phải lỗi sập server, mà chính là bằng chứng cho thấy Lớp 2 (iptables connlimit) hoạt động hoàn hảo: Khi IP test vượt quá 40 kết nối TCP, Kernel thực hiện DROP gói tin SYN. Phía client test không nhận được ACK nên bị timeout, giúp CPU và RAM của VPS hoàn toàn bình tĩnh ở mức < 20%!


4. Tổng kết & Bài học kinh nghiệm

  1. Self-Hosted Anti-DDoS hoàn toàn khả thi đối với các đợt tấn công từ số lượng IP hạn chế hoặc script bot tự động.
  2. Quy tắc vàng: Giữ kết nối tấn công càng xa ứng dụng (Application Layer) càng tốt. Chặn ở iptables DROP tiêu tốn gần như 0% CPU so với việc để request đi vào Node.js / Python / Go.
  3. PM2 Cluster Mode là bắt buộc đối với Next.js khi triển khai trên VPS đa nhân để tránh nghẽn Event Loop.

Hy vọng bài chia sẻ cùng báo cáo thực nghiệm này mang lại nhiều giá trị hữu ích cho các bạn đang quản trị VPS!

Chia sẻ bài viết này:
FacebookTelegram

Bình luận

Đăng nhập để tham gia bình luận

Đang tải bình luận...

Bài viết tương tự