UFW được nghĩ ra để có thể cấu hình tường lửa trong ba lệnh, và ở điểm đó nó thành công. Vấn đề nằm ở chỗ khác: ufw status hiển thị ý định chứ không phải kết quả. Một quy tắc có thể nằm trong danh sách mà chẳng đóng được gì cả — vì ba nguyên nhân khác nhau, và cả ba đều gặp thường xuyên trên các máy chủ thật.
Khởi đầu không khóa bạn ra ngoài
Thứ tự các lệnh là quan trọng. Cho phép SSH trước, rồi mới bật:
sudo ufw default deny incoming
sudo ufw default allow outgoing
sudo ufw allow OpenSSH
sudo ufw enable
ufw enable trước khi cho phép SSH sẽ cắt chính phiên của bạn, và sau đó chỉ còn console của nhà cung cấp. Nếu máy chủ đã được cấu hình sẵn và bạn không chắc, hãy giữ một kết nối thứ hai mở — nó sống sót qua một lần sửa hỏng.
Hãy xem trạng thái chi tiết; bản ngắn giấu đi chính sách mặc định:
sudo ufw status verbose
Sai lầm thứ nhất: quy tắc có mà cổng mở cho cả thế giới
Dòng phổ biến nhất trong cấu hình của người khác:
sudo ufw allow 3306
Đó là cách MySQL được mở «để tôi kết nối được từ nhà» — và mở cho toàn bộ Internet. Có hai biến thể đúng, và cả hai đều tốt hơn:
sudo ufw allow from 203.0.113.25 to any port 3306
hoặc, đáng tin cậy hơn, đừng để dịch vụ ra ngoài chút nào: bind-address = 127.0.0.1 trong cấu hình MySQL, còn truy cập từ bên ngoài qua đường hầm SSH. Tường lửa là tuyến thứ hai; tuyến thứ nhất là dịch vụ không lắng nghe trên địa chỉ công khai. Một quy tắc trong UFW có thể bị xóa nhầm, trong khi bind-address không tự thay đổi.
Sai lầm thứ hai: IPv6
Một quy tắc kiểu ufw allow from 203.0.113.25 chỉ áp dụng cho IPv4. Nếu máy chủ có địa chỉ IPv6 — và đa số VPS đều có và đang bật — thì dịch vụ vẫn với tới được qua nó. Nhà cung cấp đã cấp địa chỉ, bạn không nhớ nó, còn trình quét thì nhớ.
Hãy kiểm tra xem lọc v6 có bật không (IPV6=yes trong /etc/default/ufw) và dịch vụ có đang lắng nghe trên :: mà không cần thiết không:
ss -tulpn | grep ':::'
Các quy tắc nêu địa chỉ tường minh phải được viết riêng cho từng phiên bản giao thức.
Sai lầm thứ ba: Docker
Cái bực mình nhất. Docker xuất bản cổng bằng cách thêm quy tắc của mình vào các chuỗi iptables trước những quy tắc mà UFW ghi. Kết quả là một container chạy với -p 5432:5432 vẫn với tới được từ Internet dù UFW báo Status: active và chính sách deny incoming. Tường lửa không hỏng — nó đơn giản là không bao giờ đến lượt.
Cách chữa không nằm ở UFW mà ở cách cổng được xuất bản:
ports:
- "127.0.0.1:5432:5432"
Gắn vào địa chỉ cục bộ là giải pháp đơn giản và đáng tin cậy nhất. Chỉ những gì thực sự phục vụ khách truy cập mới nên hướng ra ngoài: thường là cổng 80 và 443 của một reverse proxy.
Thứ tự quy tắc
UFW áp dụng quy tắc khớp đầu tiên rồi dừng lại ở đó. Nên một lệnh từ chối thêm sau lệnh cho phép sẽ không hoạt động: nó không bao giờ đến lượt. Hãy xem đánh số và chèn vào đúng chỗ cần:
sudo ufw status numbered
sudo ufw insert 1 deny from 198.51.100.0/24
sudo ufw delete 7
Quy tắc được xóa theo số, nhưng số sẽ dịch chuyển sau mỗi lần xóa — hãy xóa từng cái một và đọc lại danh sách.
Kiểm tra từ bên ngoài
Các lệnh cục bộ cho thấy những gì đã được cấu hình. Kết quả thực sự chỉ thấy được từ một máy khác:
nmap -Pn -p- 203.0.113.25
nc -zv 203.0.113.25 3306
Bất kỳ máy chủ nào khác hoặc máy tính ở nhà của bạn đều dùng được. Đây là phép kiểm tra duy nhất không nói dối, và đáng chạy sau mỗi lần cấu hình lại đáng kể — đặc biệt sau khi cài thứ gì đó «tự cấu hình mạng»: Docker, các bảng điều khiển, VPN.
Nhật ký
Mặc định UFW gần như không ghi gì. Hãy bật bằng:
sudo ufw logging low
Các bản ghi đi vào /var/log/ufw.log — nhưng chỉ khi trong hệ thống có rsyslog. Trên Debian 12 và Ubuntu 24.04 có thể không có, và khi đó mọi thứ đi vào nhật ký của systemd:
sudo journalctl -k | grep -i '\[UFW'
Một /var/log/ufw.log rỗng tự nó chẳng nói lên điều gì — hãy xem trong nhật ký trước.
Nên mong đợi gì ở một tường lửa
UFW đóng những gì không nên với tới được. Nó không xem xét nội dung các yêu cầu đến những gì đang mở: cổng 443 mở cho tất cả, và bất cứ thứ gì tới trang web đều tới không bị cản. Đó là việc của các công cụ khác — WAF ở mức ứng dụng, IDS ở mức lưu lượng. Công việc của tường lửa khiêm tốn hơn và quan trọng hơn: để danh sách cổng mở khớp với những gì bạn tin về nó. Danh sách đó cùng các quy tắc đang hoạt động trên một trang trông ra sao — xem ở demo bên dưới.