Toàn Bộ Thông Báo Lỗi
Bạn thử SSH vào một server đã kết nối trước đó và bị chặn với thông báo này:
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@ WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED! @
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
IT IS POSSIBLE THAT SOMEONE IS DOING SOMETHING NASTY!
Someone could be eavesdropping on you right now (man-in-the-middle attack)!
It is also possible that a host key has just been changed.
The fingerprint for the ED25519 key sent by the remote host is
SHA256:abc123xyz...
Please contact your system administrator.
Add correct host key in /home/user/.ssh/known_hosts to get rid of this message.
Offending ECDSA key in /home/user/.ssh/known_hosts:42
ED25519 host key for 192.168.1.100 has changed and you have requested strict checking.
Host key verification failed.
Kết nối bị chặn. Bạn bị khóa ngoài cho đến khi giải quyết xong vấn đề này.
Chuyện Gì Đang Xảy Ra
SSH lưu fingerprint của mỗi server bạn đã kết nối vào file ~/.ssh/known_hosts. Trên máy của một sysadmin bận rộn, file đó có thể chứa hàng trăm entry. Mỗi lần kết nối, SSH so sánh key hiện tại của server với key đã lưu. Không khớp? Bị chặn.
Những lý do hợp lệ phổ biến nhất khiến điều này xảy ra:
- Server được rebuild hoặc cài lại hệ điều hành — một bản cài OS mới sẽ tạo SSH host key hoàn toàn mới
- IP của server được gán lại cho một máy khác
- Admin tự tay tạo lại SSH host key
- Bạn đang kết nối qua load balancer và rơi vào backend node khác với lần trước
- Server được chuyển sang cloud instance mới (thay thế AWS EC2, rebuild GCP, v.v.)
Và đúng vậy — trong một số trường hợp hiếm gặp — đây có thể là tấn công man-in-the-middle thật sự. Nếu bạn không chắc điều gì đã thay đổi trên server, hãy xác nhận với team trước khi tiếp tục.
Cách 1: Xóa Key Cũ (Nhanh)
Thông báo lỗi cho bạn biết chính xác dòng nào trong known_hosts đang gây ra vấn đề. Trong ví dụ trên là dòng 42. Xóa nó bằng ssh-keygen -R:
# Xóa theo hostname
ssh-keygen -R hostname
# Xóa theo địa chỉ IP
ssh-keygen -R 192.168.1.100
# Xóa theo hostname:port (cổng không chuẩn)
ssh-keygen -R [hostname]:2222
Entry cũ sẽ bị xóa. Một bản backup được lưu tại ~/.ssh/known_hosts.old. Giờ kết nối lại — SSH sẽ hỏi bạn có chấp nhận fingerprint mới không:
ssh user@192.168.1.100
The authenticity of host '192.168.1.100 (192.168.1.100)' can't be established.
ED25519 key fingerprint is SHA256:newfingerprint...
Are you sure you want to continue connecting (yes/no/[fingerprint])? yes
Warning: Permanently added '192.168.1.100' (ED25519) to the list of hosts.
Cách 2: Chỉnh Sửa known_hosts Thủ Công
Không dùng được ssh-keygen -R, hoặc cần kiểm soát chính xác hơn? Thông báo lỗi cho bạn biết số dòng — chẳng hạn dòng 42. Xóa trực tiếp bằng lệnh:
sed -i '42d' ~/.ssh/known_hosts
Hoặc mở file trong trình soạn thảo và xóa dòng bắt đầu bằng hostname hoặc IP của server. Kết quả như nhau.
Cách 3: Kết Nối Một Lần Mà Không Cập Nhật known_hosts
Cần vào ngay bây giờ mà không muốn đụng vào known_hosts? Hai flag này sẽ xử lý:
ssh -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null user@192.168.1.100
Lệnh này bỏ qua hoàn toàn việc kiểm tra host key — chỉ cho phiên làm việc này mà thôi. Đừng đặt nó thành mặc định vĩnh viễn. Làm vậy sẽ vô hiệu hóa toàn bộ mục đích của việc kiểm tra host key. Chỉ dùng khi bạn chắc chắn mình đang kết nối đúng máy và cần xử lý nhanh.
Cách 4: Scripts Tự Động và Ansible
Đang chạy Ansible playbook hoặc script trên nhiều server với key thay đổi liên tục? Tắt strict host checking theo từng host trong ~/.ssh/config:
Host 192.168.1.*
StrictHostKeyChecking no
UserKnownHostsFile /dev/null
Tốt hơn nữa, giới hạn phạm vi cho một môi trường cụ thể với cài đặt an toàn hơn:
Host staging-*.example.com
StrictHostKeyChecking accept-new
UserKnownHostsFile ~/.ssh/known_hosts_staging
StrictHostKeyChecking accept-new tự động chấp nhận key của những host chưa từng kết nối, nhưng vẫn chặn nếu key đã biết bị thay đổi. Đây là lựa chọn lý tưởng cho môi trường staging.
Xác Nhận Đã Sửa Xong
Sau khi xóa key cũ và chấp nhận key mới, chạy kiểm tra nhanh:
ssh user@192.168.1.100 'hostname && uptime'
Xác nhận key mới đã được lưu đúng:
ssh-keygen -F 192.168.1.100
# Host 192.168.1.100 found: line 42
192.168.1.100 ED25519 AAAAC3NzaC1lZDI1NTE5AAAA...
Muốn xác minh fingerprint thủ công? Truy cập console vào server (không qua SSH) và chạy:
ssh-keygen -lf /etc/ssh/ssh_host_ed25519_key.pub
Fingerprint đó phải khớp từng byte với những gì SSH hiển thị trong lúc kết nối.
Nếu Lỗi Cứ Lặp Lại
Bị lỗi này mỗi lần kết nối lại? Đó là dấu hiệu của vấn đề cấu trúc, không phải thay đổi key đơn lẻ:
- Load balancer với nhiều backend — mỗi backend có host key riêng. Cách khắc phục: cấu hình tất cả backend dùng chung một host key, hoặc dùng floating IP gắn cố định với một backend.
- Docker container khởi động lại — mỗi container mới tạo ra SSH host key mới. Cách khắc phục: mount
/etc/sshnhư một persistent volume để key tồn tại qua các lần khởi động lại. - Cloud autoscaling — AWS Auto Scaling, GCP managed instance groups và các dịch vụ tương tự tạo ra instance mới với key mới. Cách khắc phục: đưa SSH host key vào AMI hoặc machine image, hoặc khôi phục chúng từ secrets manager (AWS Secrets Manager, HashiCorp Vault) lúc khởi động.
Phòng Tránh
Có server tự quản lý? Hãy backup host key ngay sau khi cài đặt lần đầu:
sudo tar czf /root/ssh-host-keys-backup.tar.gz /etc/ssh/ssh_host_*
Lần sau khi rebuild server đó, hãy khôi phục key trước khi khởi động sshd. Các entry known_hosts của client vẫn hợp lệ. Không ai thấy cảnh báo đáng sợ kia nữa.

