叢集節點互聯、Ansible 控制機、備份傳輸——SSH 免密是自動化的前提。本文提供標準化 ssh-keygen + ssh-copy-id 流程、權限鎖死清單、ssh-agent 輔助、四大常見報錯根因與修復。
# 1. 產生金鑰(Ed25519 推薦)
ssh-keygen -t ed25519 -C "auto-$(hostname)-$(date +%F)"
# 一路 Enter:預設 ~/.ssh/id_ed25519、無密語
# 2. 分發公鑰至目標機器
ssh-copy-id -i ~/.ssh/id_ed25519.pub user@target-host
# 或批量
for h in node{1..10}; do ssh-copy-id -i ~/.ssh/id_ed25519.pub user@$h; done
# 3. 驗證
ssh user@target-host "hostname"
# 直接進 Shell,無需密碼
| 路徑 | 權限 | 擁有者 | 指令 |
|---|---|---|---|
~/.ssh | 700 | user:user | chmod 700 ~/.ssh |
~/.ssh/id_ed25519 | 600 | user:user | chmod 600 ~/.ssh/id_ed25519 |
~/.ssh/id_ed25519.pub | 644 | user:user | chmod 644 ~/.ssh/id_ed25519.pub |
~/.ssh/authorized_keys | 600 | user:user | chmod 600 ~/.ssh/authorized_keys |
~/.ssh/known_hosts | 644 | user:user | chmod 644 ~/.ssh/known_hosts |
家目錄 ~ | ≤755 | user:user | chmod 755 ~ |
原則:私鑰只能自己讀寫;authorized_keys 只能自己讀寫;家目錄不可被群組/其他寫入。
# 1. 啟動 agent 並載入金鑰
eval $(ssh-agent -s)
ssh-add ~/.ssh/id_ed25519
# 輸入密語一次,後續 ssh 免密
# 2. 系統級持久化(GNOME Keyring / KDE Wallet / systemd user service)
# 已內建於現代桌面環境,登入自動解鎖
# 3. 轉發 Agent(跳板機場景)
ssh -A user@bastion
# 從 bastion 再 ssh 內網機器,憑證自動轉發
| 報錯 | 根因 | 修復 |
|---|---|---|
Permission denied (publickey,gssapi-keyex,gssapi-with-mic) |
公鑰未授權、權限過鬆、SELinux 標籤錯 | 檢查 authorized_keys 內容、chmod 600、restorecon -Rv ~/.ssh |
Agent admitted failure to sign using the key |
ssh-agent 未載入私鑰 | ssh-add ~/.ssh/id_ed25519;若失敗 eval $(ssh-agent) && ssh-add |
POSSIBLE BREAK-IN ATTEMPT! |
反向 DNS 解析不一致 | Server /etc/ssh/sshd_config:UseDNS no、GSSAPIAuthentication no,重啟 sshd |
WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED! |
目標機器重裝/換 IP/中間人 | ssh-keygen -R hostname 刪除 known_hosts 舊記錄,重新接受指紋 |
# 僅允許執行 rsync --server(備份專用金鑰)
command="rsync --server --sender -vlOgDtpre.iLsfxC . /backup/",no-agent-forwarding,no-port-forwarding,no-pty,no-user-rc ssh-ed25519 AAAA... comment
# 僅允許從特定 IP 使用
from="10.0.1.0/24" ssh-ed25519 AAAA... comment
# 禁用 PTY、端口轉發、X11
no-pty,no-port-forwarding,no-X11-forwarding ssh-ed25519 AAAA... comment
#!/bin/bash
# deploy_ssh_trust.sh — 從控制機推送金鑰至所有節點
CONTROL_USER="ansible"
NODES_FILE="inventory/nodes.txt" # 每行一個 IP/主機名
# 1. 控制機生成金鑰(若無)
[ -f ~/.ssh/id_ed25519 ] || ssh-keygen -t ed25519 -N "" -f ~/.ssh/id_ed25519
# 2. 並發推送
cat "$NODES_FILE" | xargs -P 10 -I {} ssh-copy-id -o StrictHostKeyChecking=no -i ~/.ssh/id_ed25519.pub $CONTROL_USER@{}
# 3. 驗證
for n in $(cat "$NODES_FILE"); do
ssh -o BatchMode=yes -o ConnectTimeout=5 $CONTROL_USER@$n "echo OK" && echo "✓ $n" || echo "✗ $n"
done
結語: SSH 免密 = ssh-keygen + ssh-copy-id + chmod 600/700。加上 ssh-agent 托管密語、authorized_keys 限制命令、UseDNS no 關閉反查,即可構建「安全、便捷、可審計」的自動化互信基礎設施。