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.
- Giữ session SSH đang mở.
- Xác minh port SSH thực tế và source IP/network quản trị.
- Tạo allow rule cho SSH từ source cần thiết.
- Review rule bằng
ufw statushoặcufw --dry-runkhi phù hợp. - Chỉ sau đó mới enable UFW.
- 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à:
- Inventory intended inbound flows.
- Inventory current listening sockets.
- Map owner/purpose.
- Allow flow cần thiết.
- Áp default deny.
- 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:
- Ruleset hiện tại.
- Listening socket.
- SSH từ source quản trị.
- HTTP/HTTPS từ user path.
- Health check/CDN/WAF path nếu có.
- Database/internal service từ source hợp lệ.
- Monitoring/backup agent.
- 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
- Inventory listening socket trước change.
- Map intended inbound flows.
- Giữ active SSH session và console/rescue path.
- Allow management source trước default deny.
- Chỉ public HTTP/HTTPS khi architecture cần.
- Database/internal service không public ngoài nhu cầu.
- Review IPv4 và IPv6.
- Không quản cùng một ruleset bằng nhiều source of truth không phối hợp.
- Review UFW/nftables/cloud rules cùng nhau.
- Dùng dry-run/syntax check khi tooling hỗ trợ.
- Read-back ruleset sau write.
- Test SSH/web/monitoring/backup dependency.
- Log ở mức có ích, tránh noise không quản lý.
- Ghi rollback point và owner.
- 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.
