问题描述
通常(在刚接触 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!