問題描述
通常(在剛接觸 Linux 系統時),我們能夠通過輸入帳號密碼來登錄服務器(基礎操作),后來我們又學會通過密鑰實現無密碼登錄服務器的方法,再后來我們又學會分發公鑰的正確方法,再再后來我們有學會使用 ssh-agent 來管理密鑰,再再再后來……
掌握的知識越多,問題也越多……我們慢慢開始記錄這些相關的問題,這也是該筆記的主要內容。
該筆記將記錄:在 Linux 中,創建 SSH 密鑰並分發公鑰到服務器的方法,以及常見問題處理。
解決方案
第一步、創建密鑰
執行 ssh-keygen 命令,然后一路
# ssh-keygen Generating public/private rsa key pair. Enter file in which to save the key (/root/.ssh/id_rsa): Enter passphrase (empty for no passphrase): Enter same passphrase again: Your identification has been saved in /root/.ssh/id_rsa Your public key has been saved in /root/.ssh/id_rsa.pub The key fingerprint is: SHA256:WryBnMpzdq2ISReQ4ZD94a3oJSpy8sDP3RrZqrDSbtw root@macmini The key's randomart image is: +---[RSA 3072]----+ | .o. | | .o.o. | | +o o | | oo+. | | .=.S | |. .o.=+ + | |.= +===.o . | |=.@.EB+o . | |oOo+++o.. | +----[SHA256]-----+
密鑰文件將保存在 ~/.ssh/ 目錄中,id_ras 為公鑰,id_rsa.pub 為私鑰;
第二步、分發公鑰
方法一、手動分發(不推薦)
將 id_ras.pub 文件追加到遠程服務器 ~/.ssh/authorized_keys 文件中(或者,寫入 authorized_keys2 文件)。
雖然不推薦,但是手動添加注釋(使用 # 符號):
# This key is for xxxx. ssh-dss AAAAB3NzaC1kc3MAAACBAN+NX/rmUk... # This Key is for zzzz. ssh-dss AAAAB3NkabJ63dV0P5lDabJ8BwuCND...
方法二、ssh-copy-id(推薦)
命令 ssh-copy-id 分發密鑰:
ssh-copy-id "user@hostname" ssh-copy-id -i "/path/to/id_*.pub" "user@hostname"
如何向其他用戶分發公鑰?
問題描述:我們擁有ROOT帳號的登錄權限,但是我們需要向WWW用戶分發公鑰,並且我們沒有WWW用戶的密碼。
解決方案:
cat ~/.ssh/id_ras.pub \ | ssh "root@hostname" "sudo -u www tee -a /home/www/authorized_keys"
第三步、登錄服務器
此時,再登錄服務器便無需輸入密碼:
ssh "user@hostname" # 或者,手動指定私鑰文件位置 ssh -i /path/to/id_ras "user@hostname"
ssh-agent
運行 ssh-agent -s 命令,將創建 ssh-agent 進程,並輸出需要在 shell 中執行的環境變量。ssh 將使用這些環境變量找到 ssh-agent 進程,並連接 ssh-agent 進程。然后 ssh-agent 將代理 ssh 連接服務器。而連接服務器使用的 ssh 私鑰將通過 ssh-add 添加到 ssh-agent 中。
SSH Client (ssh) => SSH Agent (ssh-agent) => SSH Server (sshd)
ssh-agent 存在的目的是為了避免客戶端(ssh)或者第三方程序接觸私鑰。管理員通過 ssh-add 向 ssh-agent 中添加密鑰,客戶端通過 ssh-agent 來訪問服務器。同時,管理員還能設置密鑰的失效時間。
簡單示例
# source <(ssh-agent -s) Agent pid 1373063 # echo $SSH_AUTH_SOCK $SSH_AGENT_PID /run/user/1000/keyring/ssh 1728 # ssh-add .ssh/id_rsa Identity added: .ssh/id_rsa (.ssh/id_rsa) # ssh root@hostname ...
啟動 ssh-agent 進程
我們的 ssh-agent 進程未運行(在用戶登錄時,這通常由桌面環境自動啟動),因此我們需要啟動它。
# source <(ssh-agent -s) >/dev/null ssh_agent_sock=~/.cache/ssh-agent.sock ssh_agent_pid=$(pidof ssh-agent) if [ -z "${ssh_agent_pid}" ]; then source <(ssh-agent -s -a $ssh_agent_sock) > /dev/null fi export SSH_AUTH_SOCK=$ssh_agent_sock
gnome-keyring-daemon
在 GNOME 中,gnome-keyring-daemon 也提供 SSH Agent 功能,它監聽 /run/user/<user id>/keyring/ssh 文件。
所以,能夠直接使用 ssh-add 而無需運行 ssh-agent 服務:
# echo $SSH_AUTH_SOCK /run/user/1001/keyring/ssh # echo $SSH_AGENT_PID 3576 # ssh-add .ssh/id_rsa Identity added: .ssh/id_rsa (.ssh/id_rsa)
參考文獻
ssh-copy-id key to other user than yourself?
authorized_keys
Add comment to existing SSH public key - Server Fault
Howto: auto-start ssh-agent with systemd on Debian Bullseye — Debiania
GNOME/Keyring - ArchWiki
Projects/GnomeKeyring/Ssh - GNOME Wiki!