02:10 sáng, một lần deploy chết trên dòng lệnh tôi đã gõ nghìn lần: ssh deploy@staging → Permission denied (publickey). Key thì ổn. Lời đề nghị thì không.
TL;DR: Permission denied (publickey) nghĩa là mọi key client đưa ra đều bị server từ chối — một phán quyết thương lượng, không phải gõ sai mật khẩu. Chẩn đoán bằng ssh -vvv (những key nào đã được đưa ra) và log server journalctl -u ssh (những key nào bị từ chối, và vì sao). Rồi sửa một trong bốn nguyên nhân: sai user, key thiếu trong authorized_keys, quyền quá mở, hoặc key ssh-rsa bị OpenSSH 8.8+ chê. ssh-copy-id ngăn được phần lớn tái phát.
$ ssh -T [email protected]
[email protected]: Permission denied (publickey). Lỗi là một phán quyết, không phải gợi ý: toàn bộ những gì được đề nghị đều bị từ chối.
Vì sao SSH báo “Permission denied (publickey)“?
Xác thực public-key là một cuộc thương lượng đề-nghị-và-từ-chối. Client đưa ra mọi key nó tìm thấy được — identity từ agent, từ ~/.ssh/config, tên file mặc định (id_ed25519, id_rsa) và bất cứ gì truyền qua -i. Server đối chiếu từng lời đề nghị với ~/.ssh/authorized_keys của tài khoản đích. Khi không cái nào khớp, và xác thực mật khẩu đã bị tắt hoặc đã cạn cơ hội, client in ra đúng một dòng mà mọi devops engineer thuộc lòng.
Hai sự thật quan trọng khi debug. Thứ nhất, thông báo không nói bạn vừa đụng user nào — một nửa số trường hợp là một key hoàn toàn tốt đang nằm trong authorized_keys của tài khoản khác. Thứ hai, server đã nói trước lý do: sshd ghi log mọi lời đề nghị bị chê. Stack trace phía client mà không ai xin nhưng ai cũng cần chính là -vvv.
Làm sao biết SSH đang đưa ra key nào?
ssh -vvv deploy@staging 2>&1 | grep -iE "offering|identity|denied|authentications"
# debug1: Offering public key: /home/you/.ssh/id_ed25519 RSA-SHA256 (explicit)
# debug1: Authentications that can continue: publickey
# deploy@staging: Permission denied (publickey). Đọc ba dòng: Offering public key (client đề nghị gì), Authentications that can continue (server còn chấp nhận gì — nếu password vắng mặt, sẽ không bao giờ có prompt hỏi mật khẩu), và phán quyết cuối. Nếu key bạn định dùng chưa từng xuất hiện trong danh sách đề nghị, vấn đề nằm phía client: đường dẫn -i sai, một IdentityFile trong ~/.ssh/config bạn quên mất, hoặc một agent (ssh-add -l) đang giữ một identity cũ trả lời trước.
Bốn nguyên nhân thật là gì?
| Nguyên nhân | Dấu hiệu | Cách sửa |
|---|---|---|
| Sai user | Key ăn với root@host, hỏng với deploy@host | Key phải nằm trong ~/.ssh/authorized_keys của đúng user đó |
| Key chưa cài | Log server hiện Failed publickey cho mọi lời đề nghị | ssh-copy-id user@host |
| Quyền quá mở | Client: WARNING: UNPROTECTED PRIVATE KEY FILE — key bị bỏ qua, không bao giờ được đề nghị | chmod 700 ~/.ssh; chmod 600 ~/.ssh/* |
Key ssh-rsa legacy | Server chạy OpenSSH 8.8+; key RSA cũ không bao giờ được nhận | Tạo lại bằng ed25519, hoặc nâng cấp key |
Nguyên nhân quyền xứng đáng có ghi chú riêng, vì OpenSSH thi hành rất gắt: một private key mà group hoặc world đọc được sẽ bị chính client từ chối và lặng lẽ rơi khỏi danh sách đề nghị. Cách sửa là hai lệnh:
chmod 700 ~/.ssh
chmod 600 ~/.ssh/id_ed25519 ~/.ssh/authorized_keys Nguyên nhân ssh-rsa vấp phải các CI image cũ và Raspberry Pi: OpenSSH 8.8 (phát hành 2021-10-01, openssh.com/txt/release-8.8) đã tắt chữ ký ssh-rsa — biến thể dựa trên SHA-1 — theo mặc định. Theo release notes, “the ssh-rsa signature scheme is … disabled by default”. Một key RSA tạo năm 2018 không hỏng; định dạng chữ ký của nó chỉ là không còn được nói chuyện nữa. Tạo key ed25519 (ssh-keygen -t ed25519) là câu trả lời bền, và console của các nhà cung cấp cloud cho bạn serial console khi bạn tự khóa mình ngoài cửa giữa chừng sửa chữa.
Làm sao thấy vì sao server từ chối key?
Log phía server là nhân chứng trung thực. Trên Ubuntu (systemd), sshd ghi phán quyết cho từng lời đề nghị:
journalctl -u ssh -n 50 --no-pager | grep -iE "publickey|denied|accepted"
# sshd[4421]: Failed publickey for deploy from 203.0.113.7 port 51422 ssh2: RSA SHA256:...
# sshd[4421]: Accepted publickey for deploy from 203.0.113.7 port 51422 ssh2: ED25519 SHA256:... Failed publickey với fingerprint bạn không ngờ tới nghĩa là client đã đề nghị một key khác với cái bạn tưởng — quay lại -vvv. Failed publickey với đúng fingerprint của bạn nghĩa là key đúng nhưng chưa cài cho tài khoản đó, hoặc quyền thư mục home phía server bị sai (cùng luật 700/600 áp dụng cho ~/.ssh và ~/.ssh/authorized_keys của server). Nếu sshd không chịu khởi động trong khi bạn đang sửa config, đó là cuộc săn khác — xem systemd service not starting.
Làm sao cài key đúng cách?
ssh-copy-id deploy@staging
# Number of key(s) added: 1
ssh -o BatchMode=yes deploy@staging 'echo ok' # bằng chứng không tương tác ssh-copy-id nối public key của bạn vào authorized_keys của tài khoản đích và đặt quyền hợp lý — nó tồn tại vì việc tự tay dán vào authorized_keys gãy ở một xuống dòng thừa hay một thư mục còn thiếu thường xuyên vừa đủ để uổng. Kiểm tra BatchMode mới là phép thử thật: nó tắt mọi prompt, nên thành công nghĩa là một mình key đã gánh vác được lượt đăng nhập. Khi key đã chạy, scp và rsync thừa hưởng luôn cùng cơ chế xác thực — lựa chọn giữa chúng là chuyện băng thông, không phải credentials (rsync vs scp).
Phân loại nhanh trong 30 giây
ssh -vvv user@host 2>&1 | grep -i offering # 1. những key nào đã được đề nghị?
journalctl -u ssh -n 50 | grep -i publickey # 2. vì sao bị từ chối?
ls -ld ~/.ssh ~/.ssh/authorized_keys # 3. 700 / 600?
ssh-copy-id user@host # 4. cài, rồi xác minh bằng BatchMode
Permission denied (publickey)là kết quả thương lượng, không phải prompt hỏi mật khẩu — server đã chê mọi key trong lời đề nghị, và log của nó đã biết vì sao từ trước.
Chạy bốn lệnh theo thứ tự và sự cố ngừng huyền bí: một trong số chúng sẽ nêu tên thủ phạm, lần nào cũng vậy. Trường hợp của tôi là một identity cũ của agent trả lời trước key đúng — ssh-add -d, và lượt deploy chuyển màu xanh lúc 02:31.
FAQ
Vì sao SSH báo Permission denied (publickey)?
Nghĩa là mọi key mà client đưa ra đều bị server từ chối, và xác thực bằng mật khẩu hoặc keyboard-interactive không được thử hoặc không được cho phép. Đây là phán quyết thương lượng trên các key bạn đưa ra — không phải gõ sai mật khẩu.
Sửa SSH permission denied (publickey) trên Ubuntu thế nào?
Kiểm tra phía server bằng journalctl -u ssh -n 50, xác nhận public key của bạn nằm trong ~/.ssh/authorized_keys của đúng user đích, và chắc chắn quyền là 700 cho ~/.ssh và 600 cho authorized_keys cùng private key.
Vì sao ssh -i mykey vẫn thất bại?
Ba lý do thường gặp: quyền của private key quá mở nên OpenSSH từ chối nạp, server chạy OpenSSH 8.8+ đã tắt chữ ký ssh-rsa (SHA-1), hoặc key không thực sự nằm trong authorized_keys của user đích.
Làm sao thêm public key của tôi lên server?
Chạy ssh-copy-id user@host — nó nối public key của bạn vào ~/.ssh/authorized_keys với quyền chuẩn. Nếu đăng nhập bằng mật khẩu đã bị tắt, hãy làm từ một console bạn vẫn còn truy cập.
— mrsaynothing
— mrsaynothing
Ghi chú thực địa về AI, Linux và self-hosting.
Nhận how-to tiếp theo qua email
Một email mỗi bài viết. Sửa xong rồi đi tiếp.
cái này là gì?Gitignore không hoạt động? Đây là cách sửa thật
Thích kiểu viết này? Tôi build như vậy để kiếm sống. thuê tôi