Linux Firewall cho Web Server: thiết kế inbound policy với UFW và nftables

Linux Firewall cho Web Server: thiết kế inbound policy với UFW và nftables, default deny, hạn chế SSH, IPv6, cloud firewall, validation và rollback.

Linux Firewall cho Web Server - inbound policy với UFW và nftables

Linux Firewall cho Web Server là lớp kiểm soát network exposure ngay trên host. Mục tiêu không phải “chặn càng nhiều càng tốt”, mà là chỉ cho phép inbound traffic đúng với kiến trúc: HTTP/HTTPS cho user, SSH từ nguồn quản trị nếu cần, và các service nội bộ chỉ từ network được phép. Firewall tốt phải khớp với observed listening sockets, có rollback và được read-back sau thay đổi.

Ubuntu Server dùng ufw như frontend firewall mặc định và tài liệu chính thức mô tả UFW là công cụ đơn giản để quản host-based firewall. Bên dưới, Linux netfilter là subsystem xử lý packet; nftables là một interface hiện đại để xây ruleset trực tiếp. Vì vậy UFW và nftables không phải hai “lớp bảo mật cộng dồn” mặc định; trước khi thiết kế policy cần biết hệ thống hiện dùng frontend/backend nào và ai là source of truth.

Thiết kế inbound policy và rollout an toàn

Firewall không thay thế việc giảm attack surface

Một port không cần thiết nên được tắt service hoặc bind về interface phù hợp trước khi chỉ dựa vào firewall để che nó. Firewall giúp giới hạn reachability, nhưng service vẫn tồn tại, vẫn cần patch, vẫn có thể bị truy cập từ source được phép và vẫn có thể bị mở lại khi rule drift.

Trước khi chỉnh firewall, nên kiểm kê attack surface bằng Attack Surface của Web Server để biết socket nào đang LISTEN, service nào có owner và exposure nào thực sự intended. Nếu finding cho thấy service/port không còn business purpose hoặc đang bind quá rộng, phần restrict/stop/disable/remove nên được xử lý trong Giảm Server Attack Surface thay vì biến firewall thành nơi che mọi service thừa.

Inbound policy nên bắt đầu từ kiến trúc nào?

Đừng bắt đầu bằng việc copy rule từ một bài hướng dẫn khác. Hãy viết trước bảng “ai cần kết nối tới đâu”.

Traffic Source Destination Expected action
HTTP Internet hoặc CDN/WAF TCP 80 nếu cần redirect/ACME ALLOW theo architecture
HTTPS Internet hoặc CDN/WAF TCP 443 ALLOW theo architecture
SSH VPN/bastion/admin IP TCP 22 hoặc port quản trị thực tế ALLOW hạn chế source
Database App host/private network 3306/5432 hoặc port thực tế Không public nếu không cần
Monitoring Monitoring network Agent/exporter port ALLOW source cụ thể
Other inbound Any Any DENY/DROP theo policy

Policy chỉ đúng khi phản ánh đúng traffic path thực tế. Nếu origin chỉ nhận traffic từ CDN/WAF, có thể restrict 80/443 về published IP ranges của provider khi operational model cho phép; nhưng điều này tạo dependency vào IP list của provider và cần automation/read-back.

Trước khi bật UFW: chống tự khóa SSH

UFW trên Ubuntu ban đầu thường ở trạng thái disabled. Nếu bạn SSH vào server từ xa, không nên bật default-deny trước khi tạo rule cho đường quản trị hiện tại. SSH policy bản thân cũng cần được harden độc lập; xem SSH Hardening để khóa authentication, allowed users/groups và source access thay vì chỉ dựa vào firewall.

  1. Giữ session SSH đang mở.
  2. Xác minh port SSH thực tế và source IP/network quản trị.
  3. Tạo allow rule cho SSH từ source cần thiết.
  4. Review rule bằng ufw status hoặc ufw --dry-run khi phù hợp.
  5. Chỉ sau đó mới enable UFW.
  6. Mở session SSH mới để test trước khi đóng session cũ.

Thiết kế policy UFW cơ bản cho Web Server

Ví dụ minh họa, cần điều chỉnh theo kiến trúc thực tế:

sudo ufw default deny incoming
sudo ufw default allow outgoing
sudo ufw allow from 203.0.113.10 to any port 22 proto tcp
sudo ufw allow 80/tcp
sudo ufw allow 443/tcp
sudo ufw status verbose

Không copy IP ví dụ vào production. 203.0.113.10 là địa chỉ tài liệu, không phải IP quản trị của bạn.

Dùng application profile khi phù hợp

Ubuntu lưu UFW application profiles trong /etc/ufw/applications.d. Có thể kiểm tra:

sudo ufw app list
sudo ufw app info 'Nginx Full'

Không assume tên profile tồn tại trên mọi server. Profile chỉ hữu ích khi port/protocol bên trong đúng với deployment hiện tại.

UFW dry-run và rule ordering

Tài liệu Ubuntu hỗ trợ --dry-run cho một số thao tác UFW để xem rule sẽ được sinh mà chưa áp dụng. Ví dụ:

sudo ufw --dry-run allow 443/tcp

Dry-run giúp giảm lỗi cú pháp nhưng không chứng minh rule cuối cùng sẽ không gây lockout, vì outcome còn phụ thuộc ruleset hiện tại, route và source traffic. Sau write vẫn phải read-back và test.

Rule order cũng quan trọng khi policy có deny/allow cụ thể. Dùng:

sudo ufw status numbered

và khi cần thay đổi thứ tự, thực hiện trong change window có rollback.

IPv6 phải được review riêng

Một server có thể bị restrict trên IPv4 nhưng vẫn reachable qua IPv6 nếu host/network có IPv6 active và firewall policy không tương đương. Baseline nên kiểm tra:

ip -6 addr
sudo ss -lntup
sudo ufw status verbose

Không nên tắt IPv6 như một “hardening trick” chung nếu hạ tầng hoặc ứng dụng cần nó. Mục tiêu là policy nhất quán giữa address families đang được sử dụng.

nftables, default-deny và source of truth

nftables là gì?

nftables là framework/firewall userspace cho netfilter. Khái niệm cốt lõi gồm table, chain và rule. Family inet có thể dùng để quản rule áp dụng cho cả IPv4 và IPv6 trong cùng ruleset.

Để đọc ruleset hiện tại:

sudo nft list ruleset

Đây là bước read-only quan trọng trước khi sửa. Nếu server đang được quản bằng UFW, firewalld hoặc automation khác, sửa nftables trực tiếp có thể gây drift hoặc bị công cụ kia ghi đè.

Mẫu nftables inbound policy tối thiểu

Ví dụ dưới đây chỉ minh họa cấu trúc, không nên copy thẳng vào server remote:

table inet filter {
  chain input {
    type filter hook input priority 0; policy drop;

    ct state established,related accept
    iif lo accept

    ip saddr 203.0.113.10 tcp dport 22 accept
    tcp dport { 80, 443 } accept
  }
}

Trước khi áp ruleset có policy drop, phải bảo đảm đường SSH/recovery được cho phép và syntax được kiểm tra. Tùy distro, persistence và service unit của nftables có thể khác; cần dùng cơ chế chính thức của distro.

Default deny có phải lúc nào cũng đúng?

Default deny là nguyên tắc mạnh cho inbound host firewall, nhưng rollout thiếu inventory có thể làm hỏng monitoring, backup, health check, cluster traffic hoặc management plane. Cách đúng là:

  1. Inventory intended inbound flows.
  2. Inventory current listening sockets.
  3. Map owner/purpose.
  4. Allow flow cần thiết.
  5. Áp default deny.
  6. Functional test từng dependency.

“Deny all trước rồi sửa dần” trên production remote server là thay đổi rủi ro cao nếu không có out-of-band console.

Firewall và cloud security group nên phối hợp thế nào?

Nếu server chạy trên cloud/VPS có security group/network firewall, host firewall vẫn có giá trị defense-in-depth. Nhưng hai lớp phải có cùng intended policy. Một rule bị mở ở cloud nhưng host chặn có thể gây khó debug; ngược lại host mở nhưng cloud chặn có thể tạo cảm giác sai rằng service không exposed.

Evidence nên ghi cả hai lớp:

  • Cloud/VPS network rule.
  • Host firewall rule.
  • Listening socket.
  • Observed reachability từ source hợp lệ và source không hợp lệ khi test được phép.

Firewall không nên làm nhiệm vụ của WAF

Host firewall xử lý IP/port/protocol/state. Nó không hiểu application logic ở mức HTTP request như SQL injection, XSS hay bot behavior phức tạp. WAF là lớp khác và không thay host firewall. Ngược lại WAF cũng không thay việc khóa SSH/database exposure.

Logging và validation

Logging firewall nên dùng ra sao?

Firewall logging hữu ích để điều tra drop/deny, nhưng bật log quá chi tiết trên Internet-facing server có thể tạo volume lớn. UFW hỗ trợ logging levels; nftables cũng có rule log. Chỉ log event phục vụ detection/troubleshooting và có retention/owner rõ. Nếu cần thiết kế event, retention và alerting ở cấp server thay vì chỉ riêng firewall, xem Server Audit Logging.

Không nên dùng số lượng packet bị drop như security KPI duy nhất. Bot noise cao không nhất thiết đồng nghĩa server đang bị compromise.

Validation sau thay đổi firewall

API/CLI báo rule đã lưu chưa đủ. Sau change cần kiểm tra:

  1. Ruleset hiện tại.
  2. Listening socket.
  3. SSH từ source quản trị.
  4. HTTP/HTTPS từ user path.
  5. Health check/CDN/WAF path nếu có.
  6. Database/internal service từ source hợp lệ.
  7. Monitoring/backup agent.
  8. Không còn unexpected public exposure.
sudo ufw status verbose
sudo nft list ruleset
sudo ss -lntup
systemctl --failed

Không cần chạy cả UFW và nftables command như hai hệ quản trị song song; dùng chúng để hiểu state phù hợp với stack đang quản lý server.

Mẫu Inbound Firewall Policy Register

Đây là template evidence, không phải firewall state thực tế của SecureWebOps.

Service Port/Proto Allowed source Business purpose Owner Evidence Decision
HTTPS 443/TCP Internet/CDN theo architecture Web traffic Web/Ops Socket + firewall KEEP
SSH 22/TCP hoặc actual VPN/bastion/admin CIDR Administration Platform Firewall + login test RESTRICT
Database 3306/5432 App/private network Application data App/DB Bind + firewall PRIVATE ONLY
Unknown Observed Observed Unknown Unknown Socket/process INVESTIGATE

Checklist Linux Firewall cho Web Server

  1. Inventory listening socket trước change.
  2. Map intended inbound flows.
  3. Giữ active SSH session và console/rescue path.
  4. Allow management source trước default deny.
  5. Chỉ public HTTP/HTTPS khi architecture cần.
  6. Database/internal service không public ngoài nhu cầu.
  7. Review IPv4 và IPv6.
  8. Không quản cùng một ruleset bằng nhiều source of truth không phối hợp.
  9. Review UFW/nftables/cloud rules cùng nhau.
  10. Dùng dry-run/syntax check khi tooling hỗ trợ.
  11. Read-back ruleset sau write.
  12. Test SSH/web/monitoring/backup dependency.
  13. Log ở mức có ích, tránh noise không quản lý.
  14. Ghi rollback point và owner.
  15. Review drift sau deploy hoặc hạ tầng thay đổi.

Nguồn kỹ thuật tham khảo

Kết luận

Linux firewall hiệu quả khi nó phản ánh đúng intended architecture và được quản như code/config có owner. UFW phù hợp với host-based policy đơn giản; nftables cho phép ruleset chi tiết hơn. Dù dùng công cụ nào, nguyên tắc không đổi: inventory trước, allow đúng flow, default-deny có kiểm soát, read-back và functional test.

Đừng dùng firewall để che một service không cần thiết. Nếu port không có business purpose, xử lý service lifecycle trước; firewall chỉ là lớp giảm reachability, không phải lý do để giữ attack surface thừa.

◇
Cần hỗ trợ kiểm tra và xử lý website?Đội ngũ SecureWebOps sẵn sàng hỗ trợ theo phạm vi phù hợp.
Liên hệ ngay →
Đoàn Trình Dục
Về tác giả Đoàn Trình Dục TD Digital · Website Operations & Security

Đoàn Trình Dục là tác giả nội dung trên SecureWebOps. Các bài viết tập trung vào bảo mật WordPress, giám sát an ninh website, malware/backdoor, hardening, backup/recovery và Incident Response theo hướng thực hành, có bước kiểm tra, bằng chứng, validation và rollback khi phù hợp.

Xem hồ sơ tác giả →