Tường lửa ứng dụng web (WAF) cho WordPress: chọn loại nào, bật ra sao

Tường lửa ứng dụng web WAF cho WordPress: so sánh WAF đám mây, WAF trên server và plugin, cách bật ModSecurity với OWASP CRS và tránh chặn nhầm.

Sơ đồ: request độc hại bị tường lửa ứng dụng web chặn trước khi tới WordPress

Ý chính

  • WAF kiểm tra nội dung từng request HTTP và chặn các mẫu tấn công như SQL injection, XSS, chèn file.
  • Có ba vị trí đặt WAF: dịch vụ đám mây phía trước, module trên web server, và plugin bên trong WordPress.
  • Nên chạy WAF ở chế độ chỉ ghi log vài ngày, xử lý chặn nhầm rồi mới chuyển sang chặn.
  • WAF không thay được việc cập nhật plugin, mật khẩu mạnh và sao lưu.

Tường lửa ứng dụng web (WAF) là lớp bảo vệ đọc nội dung từng request HTTP gửi tới website và chặn những request khớp với mẫu tấn công như SQL injection, XSS, chèn file hay thực thi mã từ xa, trước khi chúng tới được WordPress. Khác với tường lửa mạng (UFW, iptables) chỉ nhìn IP và cổng, WAF hiểu URL, tham số, cookie và nội dung form. Với WordPress, WAF đặc biệt hữu ích vì nó chặn được nhiều cuộc tấn công nhắm vào plugin có lỗ hổng trong khoảng thời gian bạn chưa kịp cập nhật.

Bài viết so sánh ba loại WAF cho WordPress, giải thích ModSecurity và bộ luật OWASP CRS (lựa chọn mã nguồn mở phổ biến nhất trên server), cách triển khai mà không làm hỏng website, và những gì WAF không làm được.

Tường lửa ứng dụng web WAF hoạt động thế nào?

Mỗi request tới website đi qua WAF trước. WAF so nội dung request với một bộ luật: chuỗi giống câu lệnh SQL trong tham số, thẻ <script> trong form, đường dẫn kiểu ../../etc/passwd, user-agent của công cụ quét lỗ hổng. Nếu khớp, WAF chặn request (thường trả về 403) hoặc chỉ ghi log, tuỳ chế độ.

Bộ luật mã nguồn mở được dùng rộng rãi nhất là OWASP Core Rule Set (CRS). CRS dùng cách chấm điểm bất thường: mỗi luật khớp cộng điểm cho request, và request chỉ bị chặn khi tổng điểm vượt ngưỡng. CRS có bốn mức paranoia (PL1 đến PL4). PL1 là mức nền dành cho mọi website; mức cao hơn bật thêm luật, bắt được nhiều tấn công hơn nhưng cũng chặn nhầm nhiều request hợp lệ hơn. Tài liệu CRS khuyến nghị hướng tới ngưỡng điểm bất thường là 5.

Có những loại WAF nào cho WordPress?

Loại Chạy ở đâu Ưu điểm Hạn chế
WAF đám mây / CDN Máy chủ của nhà cung cấp, trước website (đổi DNS) Chặn tấn công trước khi tới VPS, giảm tải, thường kèm chống DDoS Bị vượt qua nếu kẻ tấn công biết IP thật của server; dữ liệu đi qua bên thứ ba
WAF trên server (ModSecurity + CRS) Module của nginx hoặc Apache Bảo vệ mọi website trên server, không phụ thuộc bên ngoài, không đổi DNS Tốn RAM và CPU của server; cần tinh chỉnh chặn nhầm
Plugin WordPress (endpoint) Bên trong WordPress, chạy bằng PHP Biết người dùng nào đang đăng nhập, vai trò gì; thường kèm quét mã độc Chỉ chạy sau khi PHP và WordPress đã nạp; mỗi site cài và cập nhật riêng

Không có loại nào "tốt nhất" cho mọi trường hợp. Wordfence, nhà phát triển một plugin firewall phổ biến, lập luận rằng WAF đám mây có thể bị vượt qua nếu lộ IP gốc, còn plugin chạy ngay trong website (bài viết của Wordfence). Đây là góc nhìn của một nhà cung cấp, nhưng điểm kỹ thuật thì đúng: nếu dùng WAF đám mây, hãy cấu hình tường lửa server chỉ nhận cổng 80/443 từ dải IP của nhà cung cấp đó.

Với nhà cung cấp hosting và agency quản lý nhiều website, WAF trên server là lớp hợp lý nhất: một lần cài, bảo vệ mọi website, kể cả những site mà khách quên cài plugin bảo mật. Các lớp còn lại có thể chồng lên trên.

ModSecurity hiện nay ra sao?

ModSecurity là engine WAF mã nguồn mở lâu đời nhất, chạy với Apache, nginx và các web server khác. Trustwave, đơn vị bảo trì nhiều năm, đã kết thúc hỗ trợ ModSecurity ngày 1/7/2024 và chuyển quyền quản lý mã nguồn cho OWASP. Dự án vẫn tiếp tục dưới OWASP.

Một điểm cần chú ý nếu bạn tự cài: trang chủ CRS cho biết nhánh CRS 3.3.x đã hết vòng đời và khuyến nghị chuyển sang 4.x. Trong khi đó, kho chính thức của Ubuntu 24.04 có gói modsecurity-crs bản 3.3.5 (trong universe), Debian 12 có 3.3.4. Nếu dùng gói của bản phân phối, hãy kiểm tra bản vá và cân nhắc dùng CRS 4.x từ dự án gốc.

Cách bật WAF cho WordPress với ZoPanel

ZoPanel tích hợp ModSecurity với OWASP Core Rule Set, bật riêng cho từng website.

Bước 1: Cài tường lửa (quản trị viên)

Vào Bảo mật → Tường lửa ứng dụng web → Cài tường lửa, hoặc chọn thành phần WAF trong Thành phần. Tường lửa chỉ được nạp khi có ít nhất một website dùng, và tốn khoảng 25 MB RAM mỗi worker nginx. Trên server nhỏ 1–2 GB, hãy tính khoản này vào kế hoạch bộ nhớ.

Bước 2: Chạy chế độ chỉ ghi log vài ngày

Trong tab Công cụ của website, thẻ Tường lửa ứng dụng web có ba chế độ: Bật (chặn tấn công), Chỉ phát hiện (ghi log) và Tắt. Bắt đầu bằng Chỉ phát hiện (ghi log). Trong vài ngày, dùng website như bình thường: đăng bài, sửa trang bằng page builder, nhập sản phẩm, thanh toán thử.

Bước 3: Xử lý chặn nhầm

Bảng sự kiện cho biết thời gian, IP, request và lý do; mỗi sự kiện được đánh dấu đã chặn hoặc đã ghi. Nếu một request hợp lệ bị đánh dấu (page builder và chức năng import là thủ phạm thường gặp), bấm Cho phép. Mã luật tương ứng được thêm vào Luật được bỏ qua, chỉ cho website này. Muốn bỏ ngoại lệ, bấm vào luật trong danh sách rồi Bỏ.

Bước 4: Chuyển sang chặn

Khi log chỉ còn tấn công thật, chuyển sang Bật (chặn tấn công). Quản trị viên có thể dùng Áp dụng cho mọi website để đặt một chế độ cho toàn server; thẻ cho biết bao nhiêu website đang chặn, chỉ ghi log hoặc tắt.

File tĩnh như ảnh, CSS, JavaScript không đi qua tường lửa, nên WAF không làm chậm phần lớn request. Chi tiết trong tài liệu công cụ website.

Các lớp bổ sung có sẵn

WAF làm tốt nhất khi đi cùng các lớp khác. Trên ZoPanel:

  • Quy tắc rewrite WordPress (tab PHP & cấu hình) chặn xmlrpc.php, file PHP trong wp-content/uploads và truy cập trực tiếp wp-config.php.
  • Giới hạn tốc độ request chặn bot và flood từ một IP: Nhẹ (20/giây), Vừa (8/giây) hoặc Chặt (2/giây), request vượt mức nhận HTTP 429.
  • Thẻ Bảo mật trong tab WordPress kiểm tra trình sửa file đã tắt, debug đã tắt, wp-config.php chỉ tài khoản đọc được, không có admin tên "admin".
  • Quét mã độc hằng tuần tìm webshell, backdoor và mã bị chèn, có cách ly file.
  • Nếu website đứng sau Cloudflare, bật Website đứng sau Cloudflare để log, giới hạn tốc độ và Fail2ban thấy IP thật của khách.

Xem toàn bộ trong tài liệu bảo mật.

Tự cài ModSecurity cho nginx trên Ubuntu/Debian

Nếu bạn tự quản lý server, Ubuntu 24.04 và Debian 12 đều có gói module nginx và bộ luật:

sudo apt install libnginx-mod-http-modsecurity modsecurity-crs

Gói module kèm file cấu hình mẫu và hướng dẫn trong /usr/share/doc/libnginx-mod-http-modsecurity/README.Debian. Các bước chính: bật modsecurity on; và modsecurity_rules_file trong server block, nạp bộ luật CRS, khởi động lại nginx, theo dõi /var/log/nginx/modsec_audit.log. Cấu hình mẫu để SecRuleEngine DetectionOnly, tức chỉ ghi log; chỉ đổi thành SecRuleEngine On sau khi đã xử lý chặn nhầm. Luôn chạy sudo nginx -t trước khi reload.

Với WordPress, CRS 3.3.x có sẵn bộ luật loại trừ dành cho WordPress (trong thư mục rules của gói, bật bằng biến tx.crs_exclusions_wordpress trong crs-setup.conf), giúp giảm chặn nhầm ở wp-admin; ở CRS 4.x, phần này được tách thành plugin riêng. Như đã nói ở trên, gói của bản phân phối là nhánh 3.3.x; hãy cân nhắc CRS 4.x nếu bạn duy trì cấu hình lâu dài.

WAF không bảo vệ được những gì?

WAF là một lớp, không phải tất cả. Nó không ngăn được:

  • Plugin lỗi thời có lỗ hổng logic. Nếu một plugin cho người dùng quyền subscriber tự nâng lên admin bằng một request trông hoàn toàn bình thường, WAF không có mẫu nào để bắt.
  • Mật khẩu bị lộ. Kẻ tấn công đăng nhập bằng mật khẩu thật thì mọi request đều hợp lệ. Dùng mật khẩu mạnh và xác thực hai lớp cho tài khoản quản trị.
  • Tấn công dò mật khẩu chậm từ nhiều IP khác nhau, mỗi IP chỉ vài lần.
  • Mã độc đã nằm sẵn trên server từ trước khi bật WAF.
  • DDoS lớn làm nghẽn băng thông trước khi request tới server; việc này cần lọc ở phía nhà cung cấp mạng hoặc CDN.

Vì vậy thứ tự ưu tiên vẫn là: cập nhật WordPress, plugin, giao diện; xoá plugin không dùng; mật khẩu mạnh và 2FA; sao lưu ra ngoài server; rồi mới tới WAF. Nếu site đã bị nhiễm, xem bài xử lý WordPress bị nhiễm mã độc.

WAF có làm chậm WordPress không?

Có một chút chi phí, nhưng thường nhỏ so với thời gian PHP và database xử lý một trang WordPress. Phần lớn chi phí nằm ở RAM: trên ZoPanel khoảng 25 MB mỗi worker nginx khi WAF được nạp. Cách giữ chi phí thấp là bỏ qua file tĩnh (ZoPanel làm sẵn), giữ mức paranoia thấp nếu không có lý do nâng, và bật page cache để phần lớn khách nhận trang từ cache. Chúng tôi đo tác động của page cache tới số website trên một VPS trong bài một VPS 4 GB chạy được bao nhiêu website WordPress.

Kết luận

Với WordPress, tường lửa ứng dụng web là lớp bảo vệ đáng có: nó chặn phần lớn công cụ quét tự động và mua thời gian khi một plugin có lỗ hổng mới. Chọn vị trí đặt WAF theo hoàn cảnh: WAF trên server cho nhà cung cấp hosting và agency, WAF đám mây khi cần chặn tấn công trước khi tới VPS, plugin khi bạn chỉ quản lý một site. Dù chọn loại nào, hãy bắt đầu ở chế độ chỉ ghi log và xử lý chặn nhầm trước khi bật chặn.

ZoPanel có sẵn ModSecurity với OWASP CRS cho từng website, cùng giới hạn tốc độ, quét mã độc và kiểm tra bảo mật WordPress, ngay cả trên gói Free (3 tài khoản hosting, 10 website, 10 database, không giới hạn thời gian). Xem bảng giá để biết thêm.

Câu hỏi thường gặp

WAF khác gì tường lửa thông thường như UFW?

Tường lửa mạng như UFW chỉ quyết định dựa trên IP, cổng và giao thức. WAF đọc nội dung request HTTP như URL, tham số, cookie và dữ liệu form để nhận ra mẫu tấn công. Một server nên có cả hai: UFW đóng các cổng không dùng, WAF lọc lưu lượng web đi vào cổng 80 và 443.

Website WordPress nhỏ có cần WAF không?

Có, nếu chi phí thấp. Công cụ quét lỗ hổng tự động không chọn mục tiêu theo quy mô; chúng thử mọi website tìm được. WAF chặn phần lớn lưu lượng này. Nhưng với site nhỏ, cập nhật plugin đều đặn và sao lưu vẫn quan trọng hơn.

Có nên dùng cùng lúc plugin bảo mật và WAF trên server không?

Được, hai lớp bổ sung cho nhau: WAF trên server chặn request trước khi PHP chạy, plugin biết ngữ cảnh người dùng trong WordPress. Hãy để ý chặn nhầm ở cả hai nơi khi có lỗi, và đừng bật trùng các tính năng nặng như quét mã độc ở cả hai lớp cùng giờ.

Vì sao WAF chặn nhầm khi sửa trang bằng page builder?

Page builder gửi HTML, CSS và đôi khi JavaScript trong nội dung form, trông giống tấn công XSS với bộ luật. Hãy chạy chế độ chỉ ghi log trước, tìm mã luật gây chặn nhầm và loại trừ nó cho đúng website đó thay vì tắt WAF hoàn toàn.

OWASP CRS paranoia level nên đặt mức nào?

Mức 1 (PL1) là mức nền phù hợp cho phần lớn website. Chỉ nâng lên PL2 hoặc cao hơn khi website chứa dữ liệu nhạy cảm và bạn sẵn sàng dành thời gian xử lý chặn nhầm, vì mỗi mức cao hơn bật thêm luật khắt khe hơn.