SSD Nodes Learn 🎉 VPS từ $5.50/tháng
Hướng dẫn Matt ConnorBởi Matt Connor

Cách khôi phục khi ufw làm mất kết nối SSH

Bị ufw khóa khỏi VPS? Dùng provider console hoặc rescue mode, tắt firewall, kiểm tra rule thực sự đã áp dụng và tránh lockout sau lần reboot tiếp theo.

Vào lại trước

Nếu ufw đã chặn bạn khỏi VPS, cách vào lại là dùng console của nhà cung cấp hoặc rescue mode, vì khi rule chặn đã có hiệu lực thì không thể sửa bằng SSH. Kernel drop packet của bạn trước khi sshd kịp nhận, nên không còn gì để đăng nhập và cũng không thể sửa qua network. Mở console trong control panel của nhà cung cấp, đăng nhập tại prompt đó rồi chạy một command.

sudo ufw disable

Bạn sẽ thấy Firewall stopped and disabled on system startup. Các kết nối SSH mới sẽ hoạt động lại trong vòng một hoặc hai giây. Không có cấu hình nào bị mất: disable unload các rule khỏi kernel và ghi ENABLED=no vào /etc/ufw/ufw.conf, còn các rule của bạn vẫn nằm trên disk tại /etc/ufw/user.rules, chờ lần ufw enable tiếp theo.

Không reboot rồi hy vọng mọi thứ tự hết. ufw tự khởi động khi boot, nên ENABLED=yes sẽ khiến cùng ruleset được load lại trước khi network hoạt động. Reboot không thay đổi gì đối với tình trạng bị ufw lockout.

Console cần password mà bạn có thể chưa đặt

Web console (VNC hoặc serial) là bàn phím được kết nối trực tiếp với máy. Đây không phải là network path, nên không có firewall rule nào chặn được nó. Tuy nhiên, console vẫn cần local login. Đây là điểm khiến các thiết lập chỉ dùng key bị lỗi: nếu bạn chưa từng đặt password cho sudo user và root login đang bị khóa, console sẽ hiển thị prompt nhưng bạn không thể nhập thông tin hợp lệ. Hãy đặt password ngay bây giờ, khi bạn vẫn còn SSH: sudo passwd yourname. Hầu hết panel cũng có thể reset root password, thao tác này thường buộc máy reboot.

Nếu không thể sử dụng console, hãy boot vào rescue system của nhà cung cấp. Rescue system chạy một hệ điều hành riêng với disk của bạn chưa được mount, nên bạn có thể tắt ufw từ bên ngoài.

lsblk
sudo mount /dev/vda1 /mnt
sudo sed -i 's/^ENABLED=yes/ENABLED=no/' /mnt/etc/ufw/ufw.conf
sudo umount /mnt

Chạy lsblk trước, vì root partition không phải lúc nào cũng là /dev/vda1. Reboot vào hệ thống thông thường; ufw sẽ vẫn tắt cho đến khi bạn tự enable lại.

Trình tự khôi phục tối thiểu

Thực hiện theo thứ tự này. 4 bước đầu tiên an toàn. Bước tiếp theo thì không.

  1. sudo ufw disable để unload các rule và khôi phục quyền truy cập.
  2. sudo ufw show added để in các rule bạn đã thêm, dưới dạng các command đã thêm chúng. Lệnh này hoạt động khi ufw inactive, còn ufw status thì không.
  3. sudo sshd -T | grep -i '^port' để xác nhận cổng mà sshd thực sự listen. Lệnh này in port 22 nếu bạn chưa thay đổi cổng.
  4. sudo ufw allow 22/tcp, dùng port thực tế của bạn, để lần enable tiếp theo không lặp lại việc khóa quyền truy cập.
  5. sudo ufw enable, nhưng phải lên lịch rollback trước. Phần đó ở bên dưới trang này.

ufw reset thực sự làm gì khi reset

ufw reset là biện pháp cuối cùng, không phải bước đầu tiên. Lệnh này tắt firewall, sao lưu mọi file rules và khôi phục mặc định: từ chối kết nối đến và cho phép kết nối đi. Nó in một dòng sao lưu cho mỗi file:

Backing up 'user.rules' to '/etc/ufw/user.rules.20260813_101500'

Sau khi reset, bạn không còn rule allow nào. Vì vậy, hãy chạy lệnh này từ console thay vì qua SSH và thêm rule cho SSH trước khi bật firewall lại. Các bản sao lưu này là file văn bản thuần túy. sudo grep -n dport /etc/ufw/user.rules.20260813_101500 cho biết các rule cũ là gì. Bạn có thể dùng chúng để dựng lại ruleset mà mình không định xóa bỏ.

Nơi ufw lưu các rule

Đọc file luôn chính xác hơn việc đoán theo trí nhớ. Năm đường dẫn chứa toàn bộ trạng thái:

  • /etc/ufw/user.rules/etc/ufw/user6.rules: các rule bạn đã thêm, theo thứ tự chúng được đánh giá.
  • /etc/ufw/before.rules/etc/ufw/after.rules, cùng các biến thể 6: framework mà ufw dùng để bao quanh các rule của bạn, gồm rule cho phép các kết nối đã được thiết lập và các rule loopback.
  • /etc/default/ufw: các policy mặc định và switch IPV6.
  • /etc/ufw/ufw.conf: ENABLED và mức độ log.
  • /var/log/ufw.log: các kết nối đã bị chặn sau khi bật logging.

ufw tạo một bản sao có timestamp của file trước khi ghi lại file đó, vì vậy ls /etc/ufw/ sẽ chứa các tên như user.rules.20260813_101500. Đây là lịch sử để hoàn tác. Bạn nên đọc nó trước khi bắt đầu khôi phục các thay đổi.

Để xem những gì đã được nạp vào kernel thay vì những gì đang nằm trên đĩa, dùng sudo ufw show raw, hoặc sudo iptables -Ssudo ip6tables -S. Trên Ubuntu 22.04 và 24.04, các lệnh đó là phiên bản dùng nft ở phía dưới, nên sudo nft list ruleset sẽ in cùng các rule bằng cú pháp mới hơn.

Tại sao bật ufw lại làm mất phiên SSH?

Chính sách mặc định cho lưu lượng vào là deny. Nếu bật ufw mà không có rule cho cổng SSH, mọi kết nối mới sẽ bị chặn. ufw có cảnh báo việc này: Command may disrupt existing ssh connections. Proceed with operation (y|n)? Trả lời y khi chưa có rule cho phép SSH là nguyên nhân phổ biến nhất của mọi vấn đề trên trang này.

Phần dễ gây nhầm lẫn là độ trễ. /etc/ufw/before.rules cho phép các packet ở trạng thái ESTABLISHED,RELATED đi qua trước khi xử lý các rule của bạn, nên phiên SSH dùng để chạy lệnh vẫn hoạt động bình thường. Việc bị khóa chỉ xuất hiện khi kết nối lần sau, có thể sau vài giờ. Khi đó, thay đổi firewall không còn dễ được liên hệ với sự cố. Luôn mở một phiên SSH thứ hai và xác nhận phiên đó hoạt động trước khi đóng phiên đầu tiên.

Vì sao apt và DNS ngừng hoạt động sau khi thay đổi policy?

sudo ufw default deny outgoing chặn các truy vấn DNS (domain name system) đi ra ngoài và HTTP đi ra ngoài. Vì vậy, việc phân giải tên dừng lại và cập nhật package thất bại. apt update báo cáo Temporary failure resolving 'archive.ubuntu.com'. SSH đến máy vẫn hoạt động vì các gói phản hồi cho kết nối này có trạng thái ESTABLISHED và được các rule của framework cho phép. Điều này khiến firewall có vẻ không liên quan, trong khi nó chính là nguyên nhân.

Nếu bạn muốn dùng policy chặn lưu lượng đi ra, hãy mở những gì máy thực sự cần:

sudo ufw allow out 53
sudo ufw allow out 80/tcp
sudo ufw allow out 443/tcp
sudo ufw allow out 123/udp

Nếu thiếu rule cuối cùng, đồng hồ sẽ bị lệch. Đồng hồ sai làm xác thực chứng chỉ TLS (transport layer security) thất bại. Khi đó, curl bắt đầu lỗi do ngày giờ thay vì do cổng. Triệu chứng này xuất hiện vài ngày sau khi thay đổi. Vì vậy, policy chặn lưu lượng đi ra phù hợp với các máy được bạn monitor, không phù hợp với một máy chỉ được thiết lập một lần.

Vì sao rule ufw của tôi không bao giờ khớp?

ufw đánh giá các user rule theo thứ tự và dừng ở rule khớp đầu tiên. Một deny được thêm sau một allow tổng quát sẽ không bao giờ có hiệu lực, vì rule allow đã quyết định cách xử lý packet. In danh sách kèm số thứ tự, sau đó insert rule vào đúng vị trí cần thiết.

sudo ufw status numbered
sudo ufw insert 1 deny from 203.0.113.10 to any port 22
sudo ufw delete 4

sudo ufw --dry-run allow 8080/tcp in ra các rule sẽ được ghi nhưng không thay đổi gì. Đây là cách an toàn để xem rule trước khi áp dụng.

Một bẫy khác nằm trong application profile. sudo ufw allow OpenSSH sử dụng profile trong /etc/ufw/applications.d/openssh-server, và profile đó chỉ cổng 22. Nếu sshd listen trên 2222, rule sẽ mở một cổng không có dịch vụ nào sử dụng và khiến bạn bị lock out dù ruleset trông có vẻ đúng. Sau khi đổi cổng, hãy dùng số cổng đó. Phần cú pháp còn lại được trình bày trong phần cơ bản về ufw firewall cho VPS.

Vì sao các rule IPv4 không giải thích được những gì tôi thấy?

Vì một nửa lưu lượng không phải IPv4. Ubuntu ship IPV6=yes trong /etc/default/ufw, sau đó ufw duy trì một ruleset v6 song song trong /etc/ufw/user6.rules. Rule được viết bằng địa chỉ IPv4, chẳng hạn ufw allow from 203.0.113.10 to any port 22, hoàn toàn không tạo rule v6. Nếu VPS của bạn có bản ghi AAAA, client sẽ ưu tiên IPv6, và kết nối sẽ timeout trong khi ufw status hiển thị một rule có vẻ đúng. Dùng ssh -4 user@host với ssh -6 user@host để kiểm tra sự khác biệt. Nếu lệnh đầu tiên hoạt động còn lệnh thứ hai không hoạt động, vấn đề nằm ở ruleset v6.

Trường hợp ngược lại nguy hiểm hơn về mặt bảo mật. Với IPV6=no, ufw hoàn toàn không quản lý ip6tables, nên policy v6 vẫn giữ giá trị mặc định ACCEPT của kernel. Một cổng mà bạn nghĩ đã đóng vẫn phản hồi trên địa chỉ IPv6, và không lệnh ufw nào hiển thị cổng đó. Kiểm tra bằng sudo ip6tables -Sss -tlnp, rồi đọc cách ufw xử lý cổng IPv6 để hiểu đầy đủ.

Vì sao cổng Docker vẫn mở khi ufw từ chối cổng đó?

Docker mở một cổng bằng cách ghi các rule DNAT (destination network address translation) vào bảng nat và chèn chain riêng vào FORWARD. Các rule của ufw nằm trong đường xử lý INPUT. Lưu lượng đến container được forward thay vì chuyển đến host, nên không đi qua chain chứa rule deny của bạn. docker run -p 5432:5432 vẫn có thể truy cập từ Internet khi ufw đang hoạt động và từ chối mọi lưu lượng.

sudo iptables -t nat -S DOCKER

Cách đơn giản nhất là publish cổng trên loopback: -p 127.0.0.1:5432:5432 bind phía host vào 127.0.0.1, nên không có kết nối bên ngoài nào truy cập được, bất kể ufw được cấu hình thế nào. Docker publish cổng qua ufw trình bày các trường hợp service cần được public.

Đặt lịch rollback trước khi áp dụng rule

Đây là thói quen giúp việc quản lý firewall vẫn có thể xử lý được khi xảy ra sự cố. Trước mọi thay đổi có rủi ro, hãy đặt lịch undo. Nếu thay đổi làm bạn mất quyền truy cập, máy sẽ tự khôi phục sau năm phút và bạn không cần mở console.

sudo systemd-run --on-active=5m --unit=ufw-rollback /usr/sbin/ufw disable

systemd in Running timer as unit: ufw-rollback.timer. Bây giờ hãy thực hiện thay đổi. Nếu sau đó bạn vẫn mở được một SSH session mới, hãy hủy rollback:

sudo systemctl stop ufw-rollback.timer

Nếu không mở được session đó, hãy chờ. ufw sẽ tự dừng và lần thử kết nối tiếp theo sẽ thành công. Mẹo shutdown -r +5 kinh điển không có tác dụng với ufw, vì ufw sẽ nạp lại cùng ruleset khi boot.

Luôn giữ một phương án truy cập thứ hai

  • Đăng nhập vào console của nhà cung cấp một lần trước khi cần dùng, rồi xác nhận mật khẩu hoạt động. Một console chưa từng được kiểm tra không phải là phương án dự phòng.
  • Tạo một user sudo thứ hai với key riêng, để một file authorized_keys bị hỏng không khiến bạn mất hoàn toàn quyền truy cập.
  • Kiểm tra xem nhà cung cấp có firewall mạng trong panel hay không, tách biệt với ufw. Firewall này chặn cùng các cổng đó, và ufw status sẽ không bao giờ đề cập đến nó.
  • Không đặt ufw allow from <your home address> làm rule SSH duy nhất nếu địa chỉ đó là địa chỉ động. Nhà cung cấp có thể thay đổi địa chỉ qua đêm và bạn sẽ bị mất quyền truy cập.

Thời điểm ít tốn công nhất để làm tất cả việc này là ngay trên server mới, cùng với các bước thiết lập khác trong 10 phút đầu tiên trên một VPS mới.

Refused hoặc timed out cho biết layer nào bị lỗi

Connection refused nghĩa là packet đã đến server và có thành phần gửi TCP reset trở lại. Đường đi của network vẫn hoạt động, vì vậy sshd đã dừng hoặc đang listen trên port khác. Firewall hiếm khi là nguyên nhân, vì ufw mặc định sẽ drop packet thay vì reject.

Connection timed out nghĩa là hoàn toàn không có phản hồi. Đây là dấu hiệu của việc packet bị drop: ufw, firewall của nhà cung cấp hoặc địa chỉ bị sai. Hiểu đúng hai lỗi này giúp bạn tránh mất cả giờ để đoán nguyên nhân, và sự khác nhau giữa connection refused và timed out sẽ xử lý các trường hợp còn lại.

Bật logging trước thay đổi tiếp theo

sudo ufw logging on
sudo tail -f /var/log/ufw.log

Một packet bị chặn sẽ xuất hiện như sau:

[UFW BLOCK] IN=eth0 OUT= SRC=203.0.113.10 DST=192.0.2.5 LEN=60 PROTO=TCP SPT=51234 DPT=22 WINDOW=64240 SYN

DPT=22 với địa chỉ của bạn trong SRC= chứng minh ufw là thành phần đang chặn bạn, không phải network và cũng không phải sshd. Trên image tối giản không có rsyslog, sẽ không có /var/log/ufw.log, và các dòng tương tự sẽ xuất hiện từ sudo journalctl -k | grep UFW. ufw giới hạn tần suất ghi log cho các rule logging của chính nó, vì vậy việc không thấy một dòng log không chứng minh packet đã được cho phép.

Nếu bạn thấy các rule mà mình chưa từng thêm

Một ruleset tự thay đổi không phải là lỗi firewall. Có người đã dùng root để ghi thay đổi đó. Chạy sudo grep ufw /var/log/auth.log để xem những lệnh sudo nào đã được chạy và dưới tài khoản nào, sau đó chạy last để kiểm tra các lần đăng nhập gần thời điểm đó. Nếu các tài khoản này không trùng với bất kỳ ai bạn biết, hãy dừng việc debug firewall và thực hiện checklist xử lý VPS bị xâm nhập thay vào đó. Bật lại firewall trên một máy chủ đang bị người khác kiểm soát chỉ che giấu vấn đề.

Bật lại

Khi đã biết nguyên nhân, hãy bật lại ufw theo cách không thể lặp lại sự cố khóa truy cập. Cho phép cổng SSH thực tế của bạn, lên lịch rollback, bật ufw, sau đó mở một phiên SSH mới hoàn toàn từ terminal khác và xác nhận phiên đó kết nối được. Chỉ đóng phiên đang làm việc sau khi phiên mới đã hoạt động. Bật logging trong một ngày, vì log cho biết bạn quên cho phép gì nhanh hơn nhiều so với việc đọc user.rules.

FAQ

ufw disable có xóa các rule của tôi không?

Không. disable gỡ ruleset khỏi kernel và ghi ENABLED=no vào /etc/ufw/ufw.conf. Các rule vẫn nằm trong /etc/ufw/user.rules/etc/ufw/user6.rules, còn sudo ufw show added liệt kê chúng khi firewall không hoạt động. ufw reset là lệnh xóa các rule này và trước tiên sẽ sao lưu từng file, đồng thời in ra một dòng như Backing up 'user.rules' to '/etc/ufw/user.rules.20260813_101500'.

Reboot VPS có khôi phục trạng thái bị ufw khóa truy cập không?

Không. ufw khởi động cùng hệ thống từ ENABLED=yes trong /etc/ufw/ufw.conf, nên các rule tương tự sẽ được nạp trước khi network hoạt động và bạn lại bị khóa truy cập. Reboot chỉ có tác dụng sau khi bạn đã tắt ufw, hoặc sau khi chỉnh sửa file đó từ rescue mode với disk đã được mount. Dùng console của nhà cung cấp và chạy sudo ufw disable tại đó.

Vì sao container Docker vẫn có thể truy cập được khi ufw deny port?

Docker tự ghi các rule DNAT và FORWARD cho từng port được publish. Lưu lượng đó được forward đến container thay vì chuyển đến host, nên không đi qua INPUT chain, nơi có rule deny của ufw. Dùng -p 127.0.0.1:5432:5432 để publish trên loopback khi port chỉ dành cho host, rồi kiểm tra các rule Docker đã cài bằng sudo iptables -t nat -S DOCKER.

Tôi không có mật khẩu console và cũng không có rescue mode. Tôi còn lựa chọn nào?

Các lựa chọn còn lại phụ thuộc vào nhà cung cấp: reset mật khẩu từ control panel, thao tác này thường sẽ reboot server, hoặc gắn disk vào một instance khác để chỉnh sửa /etc/ufw/ufw.conf từ đó. Hãy hỏi bộ phận support trước khi rebuild server, vì rebuild sẽ xóa dữ liệu trên server. Khi đăng nhập lại được, chạy sudo passwd yourname và thử đăng nhập console một lần, để lần bị khóa tiếp theo chỉ mất 2 phút.

#ufw#firewall#lockout#console#recovery