Code phòng chống DDOS Website hiệu quả

DDoS (Distributed Denial of Service) là một trong những hình thức tấn công phổ biến nhất trên Internet. Thay vì khai thác lỗ hổng để chiếm quyền điều khiển website, kẻ tấn công sử dụng một lượng lớn máy tính hoặc thiết bị bị nhiễm mã độc để gửi hàng triệu yêu cầu đến máy chủ trong cùng một thời điểm. Khi tài nguyên máy chủ bị sử dụng hết, website sẽ phản hồi chậm, ngừng hoạt động hoặc không thể truy cập.

Nhiều quản trị viên thường tìm kiếm các đoạn code chống DDoS với mong muốn chỉ cần thêm vài dòng mã là có thể bảo vệ toàn bộ hệ thống. Trên thực tế, không có đoạn code nào có thể ngăn chặn hoàn toàn một cuộc tấn công DDoS quy mô lớn. Tuy nhiên, việc kết hợp các kỹ thuật kiểm soát truy cập, giới hạn tần suất gửi yêu cầu, xác thực người dùng và tối ưu cấu hình máy chủ sẽ giúp giảm đáng kể tác động của các cuộc tấn công nhỏ và trung bình.

Bài viết dưới đây sẽ hướng dẫn những phương pháp chống DDoS bằng code và cấu hình máy chủ phù hợp cho website sử dụng PHP, Apache, Nginx cũng như các hệ thống phổ biến hiện nay.

Code phòng chống DDOS Website hiệu quả

Hiểu đúng về cơ chế tấn công DDoS

Trước khi triển khai bất kỳ đoạn code nào, cần hiểu rõ website đang đối mặt với loại tấn công nào. Mỗi hình thức DDoS sẽ cần phương án xử lý khác nhau.

Loại tấn công Đặc điểm Khả năng xử lý bằng code
HTTP Flood Gửi rất nhiều request đến website Cao
Slow HTTP Giữ kết nối lâu để chiếm tài nguyên Trung bình
SYN Flood Tấn công tầng mạng Không
UDP Flood Làm nghẽn băng thông Không
DNS Amplification Khuếch đại lưu lượng Không

Những đoạn code trong bài viết này chủ yếu giúp hạn chế các cuộc tấn công HTTP Flood, Bot Spam và Request Flood.

Nguyên tắc xây dựng lớp bảo vệ website

Một hệ thống chống DDoS hiệu quả nên hoạt động theo nhiều lớp thay vì chỉ phụ thuộc vào một giải pháp duy nhất.

  • Giới hạn số lượng request.
  • Kiểm tra địa chỉ IP.
  • Phát hiện hành vi bất thường.
  • Từ chối bot độc hại.
  • Sử dụng Cache.
  • Kết hợp Firewall.
  • Kết hợp CDN.
  • Giảm tải truy vấn cơ sở dữ liệu.

Khi triển khai đồng thời nhiều lớp bảo vệ, máy chủ sẽ xử lý lưu lượng hiệu quả hơn và giảm nguy cơ bị quá tải.

Giới hạn số lượng request từ mỗi địa chỉ IP bằng PHP

Một trong những cách đơn giản nhất để giảm bot spam là theo dõi số lượng request từ từng IP trong một khoảng thời gian.

Ví dụ dưới đây sử dụng Session để minh họa nguyên lý hoạt động.

<?php
session_start();

$timeLimit = 10;
$maxRequest = 30;

if (!isset($_SESSION['request_time'])) {
    $_SESSION['request_time'] = time();
    $_SESSION['request_count'] = 1;
} else {

    if ((time() - $_SESSION['request_time']) > $timeLimit) {
        $_SESSION['request_time'] = time();
        $_SESSION['request_count'] = 1;
    } else {
        $_SESSION['request_count']++;

        if ($_SESSION['request_count'] > $maxRequest) {
            http_response_code(429);
            exit("Too Many Requests");
        }
    }
}
?>

Trong thực tế nên lưu dữ liệu bằng Redis hoặc Memcached thay vì Session để đạt hiệu suất cao hơn.

Sử dụng Redis để kiểm soát lưu lượng truy cập

Redis có tốc độ xử lý rất nhanh và phù hợp để ghi nhận số lượng request theo từng IP.

Quy trình hoạt động:

  1. Lấy địa chỉ IP.
  2. Tạo khóa Redis.
  3. Tăng bộ đếm.
  4. Thiết lập thời gian hết hạn.
  5. Chặn khi vượt ngưỡng.

Ưu điểm của Redis là không tạo áp lực lên MySQL khi có lượng truy cập lớn.

Chặn IP truy cập quá nhanh bằng Apache .htaccess

Apache hỗ trợ giới hạn lưu lượng thông qua module mod_evasive hoặc mod_security. Ngoài ra có thể sử dụng RewriteRule để chặn các User-Agent hoặc IP bất thường.

RewriteEngine On

RewriteCond %{REMOTE_ADDR} ^123.123.123.123$
RewriteRule .* - [F,L]

Đây chỉ là ví dụ minh họa việc chặn một địa chỉ IP cụ thể.

Hạn chế bot bằng cách kiểm tra User-Agent

Nhiều bot gửi request mà không khai báo User-Agent hoặc sử dụng chuỗi nhận dạng bất thường.

Ví dụ xử lý bằng PHP.

<?php

$userAgent = $_SERVER['HTTP_USER_AGENT'] ?? '';

if (empty($userAgent)) {
    http_response_code(403);
    exit("Forbidden");
}

?>

Không nên chỉ dựa vào User-Agent vì bot hoàn toàn có thể giả mạo trình duyệt phổ biến.

Giới hạn truy cập vào trang đăng nhập

Trang đăng nhập luôn là mục tiêu của bot vì thường xuyên bị gửi hàng nghìn yêu cầu mỗi phút.

Có thể áp dụng các biện pháp sau.

  • Giới hạn số lần đăng nhập.
  • Thêm CAPTCHA.
  • Khóa tạm thời địa chỉ IP.
  • Xác thực hai lớp.
  • Đổi đường dẫn đăng nhập nếu phù hợp.

Những phương pháp này không chỉ giảm nguy cơ DDoS mà còn giúp chống brute force hiệu quả.

Kiểm tra Referer để giảm lưu lượng giả mạo

Một số website yêu cầu request phải đến từ chính tên miền của mình.

Ví dụ:

<?php

$referer = $_SERVER['HTTP_REFERER'] ?? '';

if (!empty($referer) && strpos($referer, 'webmoi.vn') === false) {
    http_response_code(403);
    exit("Access Denied");
}

?>

Không nên sử dụng riêng phương pháp này vì Referer có thể bị giả mạo hoặc bị trình duyệt ẩn.

Giảm tải truy vấn cơ sở dữ liệu

Trong nhiều trường hợp, website bị chậm không phải vì băng thông mà do MySQL xử lý quá nhiều truy vấn.

Các giải pháp nên áp dụng:

  • Cache dữ liệu.
  • Cache HTML.
  • Sử dụng Redis.
  • Sử dụng Memcached.
  • Tối ưu Index.
  • Giảm Query lặp.
  • Phân trang dữ liệu.

Sử dụng bộ nhớ đệm để giảm tải máy chủ

Khi website phải tạo nội dung động cho mỗi lượt truy cập, CPU và bộ nhớ sẽ nhanh chóng bị tiêu tốn nếu xuất hiện lượng lớn request cùng lúc. Việc triển khai bộ nhớ đệm (Cache) giúp giảm số lần thực thi PHP và truy vấn cơ sở dữ liệu, từ đó cải thiện khả năng chịu tải đáng kể.

Tùy vào kiến trúc website, có thể áp dụng nhiều lớp Cache khác nhau.

Loại Cache Mục đích Hiệu quả
Browser Cache Lưu tài nguyên trên trình duyệt Giảm request lặp lại
Page Cache Lưu sẵn nội dung HTML Giảm tải PHP
Object Cache Lưu kết quả truy vấn Giảm tải MySQL
Opcode Cache Lưu mã PHP đã biên dịch Tăng tốc xử lý

Ngay cả khi website chưa bị DDoS, Cache vẫn là một trong những giải pháp giúp tăng hiệu năng và giảm chi phí vận hành máy chủ.

Thiết lập giới hạn kết nối trên Nginx

Nếu sử dụng Nginx, nên cấu hình giới hạn số lượng kết nối và tốc độ gửi request từ mỗi địa chỉ IP. Đây là một trong những lớp bảo vệ hiệu quả trước các cuộc tấn công HTTP Flood.

limit_req_zone $binary_remote_addr zone=webmoi:10m rate=5r/s;

server {

    location / {
        limit_req zone=webmoi burst=20 nodelay;
    }

}

Trong ví dụ trên, mỗi IP chỉ được phép gửi trung bình 5 request mỗi giây. Nếu vượt quá giới hạn, Nginx sẽ trì hoãn hoặc từ chối yêu cầu tùy theo cấu hình.

Chặn các User-Agent độc hại

Nhiều công cụ quét lỗ hổng hoặc bot tự động sử dụng User-Agent cố định. Có thể chủ động từ chối các chuỗi nhận dạng đã biết để giảm lượng request không cần thiết.

<?php

$denyAgent = array(
    "curl",
    "python",
    "wget",
    "sqlmap"
);

$userAgent = strtolower($_SERVER['HTTP_USER_AGENT'] ?? '');

foreach ($denyAgent as $agent) {

    if (strpos($userAgent, $agent) !== false) {

        http_response_code(403);
        exit("Forbidden");

    }

}

?>

Không nên chặn quá nhiều User-Agent vì có thể ảnh hưởng đến các công cụ kiểm tra hợp lệ hoặc dịch vụ giám sát website.

Chặn truy cập từ những IP đã nằm trong danh sách đen

Đối với các website thường xuyên bị tấn công, nên xây dựng danh sách IP bị cấm và kiểm tra ngay khi request được gửi đến.

<?php

$blackList = array(
    "111.111.111.111",
    "222.222.222.222"
);

$ip = $_SERVER['REMOTE_ADDR'];

if (in_array($ip, $blackList)) {

    http_response_code(403);
    exit("Forbidden");

}

?>

Trong hệ thống thực tế, danh sách này thường được lưu trong Redis hoặc Firewall thay vì khai báo trực tiếp trong mã nguồn.

Kiểm tra tần suất truy cập vào cùng một URL

Bot DDoS thường liên tục truy cập vào một đường dẫn nhất định như trang chủ, trang tìm kiếm hoặc API. Nếu phát hiện cùng một IP gửi quá nhiều request đến một URL trong thời gian ngắn, website có thể chủ động từ chối.

Việc theo dõi theo từng URL giúp hạn chế các cuộc tấn công nhắm vào một chức năng cụ thể thay vì toàn bộ website.

Bảo vệ API khỏi Request Flood

API thường trả dữ liệu JSON và có tốc độ phản hồi nhanh, vì vậy rất dễ trở thành mục tiêu của bot. Nếu không giới hạn truy cập, máy chủ sẽ phải xử lý hàng nghìn request mỗi giây.

Một số biện pháp nên triển khai:

  • Sử dụng API Key.
  • Giới hạn số request theo IP.
  • Giới hạn theo Access Token.
  • Thiết lập thời gian hết hạn cho Token.
  • Ghi nhật ký truy cập bất thường.

Phát hiện truy cập bất thường theo thời gian thực

Ngoài việc chặn request, website cũng nên ghi nhận các dấu hiệu bất thường để quản trị viên có thể xử lý kịp thời.

Một số thông tin nên lưu lại gồm:

  • Địa chỉ IP.
  • Thời gian truy cập.
  • User-Agent.
  • URL được truy cập.
  • Mã phản hồi HTTP.
  • Số lượng request trong một khoảng thời gian.

Dữ liệu này rất hữu ích khi phân tích nguyên nhân website bị quá tải hoặc xây dựng quy tắc Firewall.

Ẩn thông tin máy chủ để giảm nguy cơ bị khai thác

Nhiều máy chủ mặc định sẽ gửi thông tin phiên bản Apache, Nginx hoặc PHP trong tiêu đề phản hồi HTTP. Điều này giúp kẻ tấn công dễ dàng xác định môi trường hoạt động và tìm kiếm lỗ hổng tương ứng.

Nên tắt hoặc ẩn các thông tin không cần thiết để giảm khả năng bị dò quét tự động.

Không nên lưu Session trên ổ cứng khi lượng truy cập lớn

Mỗi Session được ghi xuống ổ cứng đều phát sinh thao tác đọc và ghi dữ liệu. Khi có hàng nghìn request đồng thời, tốc độ truy xuất đĩa sẽ trở thành điểm nghẽn.

Đối với website có lượng truy cập cao, nên lưu Session trên Redis để giảm độ trễ và tăng khả năng mở rộng.

Kết hợp Firewall ở cấp hệ điều hành

Các đoạn code PHP chỉ được thực thi sau khi request đã đến máy chủ web. Trong khi đó, Firewall hoạt động ở lớp thấp hơn và có thể loại bỏ nhiều kết nối trước khi chúng tiêu tốn tài nguyên của Apache hoặc Nginx.

Một số giải pháp phổ biến gồm:

  • iptables.
  • nftables.
  • CSF Firewall.
  • Fail2Ban.
  • UFW.

Firewall nên được cấu hình kết hợp với giới hạn kết nối để đạt hiệu quả bảo vệ cao hơn.

Những sai lầm thường gặp khi chống DDoS bằng code

Nhiều quản trị viên cho rằng chỉ cần thêm một đoạn mã PHP là có thể ngăn chặn mọi cuộc tấn công. Đây là quan điểm chưa chính xác vì DDoS có thể diễn ra ở nhiều tầng khác nhau của hệ thống.

  • Chỉ sử dụng Session để giới hạn request.
  • Lưu toàn bộ nhật ký vào MySQL.
  • Không sử dụng Cache.
  • Không cấu hình Firewall.
  • Để API công khai không giới hạn truy cập.
  • Không theo dõi nhật ký hệ thống.
  • Không cập nhật máy chủ và phần mềm.

Câu hỏi thường gặp khi triển khai code chống DDoS

Chỉ sử dụng code PHP có chống được DDoS hoàn toàn không?

Không. Code PHP chỉ được thực thi sau khi yêu cầu đã đến máy chủ web, vì vậy chỉ có thể hạn chế các cuộc tấn công ở tầng ứng dụng như HTTP Flood hoặc bot gửi request liên tục. Đối với các cuộc tấn công DDoS quy mô lớn ở tầng mạng hoặc tầng vận chuyển, cần kết hợp thêm Firewall, CDN, WAF và các dịch vụ chống DDoS chuyên dụng để lọc lưu lượng trước khi đến máy chủ.

Có nên chặn toàn bộ bot truy cập website?

Không nên. Website vẫn cần cho phép các bot hợp lệ như Googlebot, Bingbot hoặc các trình kiểm tra uptime hoạt động bình thường. Thay vì chặn tất cả, nên xây dựng danh sách bot đáng tin cậy và chỉ từ chối các bot có hành vi bất thường hoặc User-Agent không hợp lệ.

Website có lượng truy cập thấp có cần triển khai chống DDoS không?

Có. Ngay cả những website mới hoặc có ít lượt truy cập cũng có thể trở thành mục tiêu của các bot tự động hoặc các cuộc tấn công thử nghiệm. Việc triển khai các biện pháp cơ bản như giới hạn request, sử dụng Cache, cấu hình Firewall và ghi nhật ký truy cập sẽ giúp tăng tính ổn định và giảm nguy cơ gián đoạn dịch vụ trong tương lai.

Tổng kết

Code chống DDoS chỉ là một phần trong chiến lược bảo vệ website. Các đoạn mã giới hạn request, kiểm tra IP, phát hiện hành vi bất thường hay chặn bot sẽ giúp giảm đáng kể các cuộc tấn công HTTP Flood và hạn chế việc tiêu tốn tài nguyên máy chủ. Tuy nhiên, với những cuộc tấn công quy mô lớn, cần kết hợp thêm Cache, Redis, Firewall, cấu hình Apache hoặc Nginx, CDN và các dịch vụ chống DDoS chuyên dụng để tạo thành nhiều lớp phòng vệ.

Đối với hầu hết website doanh nghiệp, việc xây dựng hệ thống bảo vệ nhiều tầng ngay từ đầu sẽ tiết kiệm chi phí và giảm thiểu nguy cơ gián đoạn dịch vụ hơn rất nhiều so với xử lý sau khi website đã bị tấn công.

  • 2 Bình luận
Trần Thị Vân | Content Creator Web Mới
Trần Thị Vân
Trần Thị Vân là Content Creator tại Web Mới, phụ trách nghiên cứu, biên soạn nội dung và chia sẻ kiến thức về website, SEO, lập trình cùng các xu hướng công nghệ
người đánh giá
Trần Văn Linh - 07/08/2023
(5 Sao)
Bài viết hữu ích
Chia sẻ nội dung đánh giá của bạn về Code phòng chống DDOS Website hiệu quả
Email, Điện thoại của bạn sẽ không được hiển thị công khai. Các trường bắt buộc được đánh dấu *
Đánh giá của bạn
Tên *
Email
Số điện thoại *
Bình luận, Hỏi đáp
A
Anh Nguyễn Văn Cường
08/08/2023 10 giờ 52
Còn giải pháp thêm nào hay nữa không ad
Công Ty Tnhh Thương Mại Dịch Vụ Web Mới
Web Mới Admin
Bài viết luôn được cập nhật, mọi người chờ nhé
08/08/2023 15 giờ 07 phút
Trả lời
Đăng ký tư vấn thiết kế website
Tìm hiểu 1 năm không bằng lắng nghe 1 câu tư vấn