问题描述
通常(在刚接触 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 文件):
cat >> ~/.ssh/authorized_keys2 <<EOF ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDni/qEpL3Q5fPYGSmrr0Oeaq5VgJvDdEtg76wiE1gnhYUAW0CSBMouAI7VjBcx64e6CygDyi8ofr+hzjFmtLec9oAr2aY8bQjGu4OjPNoh+gaFNobV/QKripRHHvH4LvjKdacYNlSpfajy64J/YnepBXBzYCDgVDy7wr8slMYoYC6TpyYhurFFLowejQ3BHGAneK7yyi4Rf26DfnAVu+HyYFqMHZXNXwrgxNB3R7+YplR+hUp5p4weRAdX1w9b3pBkmFiX2joloFTq3dxMNx5jUXca6G3FPifMfLtHZX8O4hRz8huU6iDrNPwq1215mywvCbNXjj7PfCALUT0WUj9Z pearly@rivtower.com EOF
虽然不推荐,但是手动添加注释(使用 # 符号):
# This key is for xxxx. ssh-dss AAAAB3NzaC1kc3MAAACBAN+NX/rmUk... # This Key is for zzzz. ssh-dss AAAAB3NkabJ63dV0P5lDabJ8BwuCND...
方法二、ssh-copy-id(推荐)
Windows 10 OpenSSH Equivalent of ssh-copy-id | Christopher Hart
命令 ssh-copy-id 分发密钥:
ssh-copy-id "user@hostname" ssh-copy-id -i "/path/to/id_*.pub" "user@hostname" # for Windows type $env:USERPROFILE\.ssh\id_rsa.pub | ssh {IP-ADDRESS-OR-FQDN} "cat >> .ssh/authorized_keys"
场景:向其他用户分发公钥
问题描述:我们拥有 ROOT 帐号的登录权限,但是我们需要向 WWW 用户分发公钥,并且我们没有 WWW 用户的密码。
解决方案:
cat ~/.ssh/id_ras.pub \ | ssh "root@hostname" "sudo -u www tee -a /home/www/authorized_keys"
场景:通过已有密钥要分发其他公钥
How to ssh-copy-id 2nd key when the server only allows publickey authentication
ssh-copy-id -i ~/.ssh/<your-new-id-to-install> -o 'IdentityFile ~/.ssh/<your-already-existing-id>' <servername>
或,通过 SSH Agent 服务,则在复制公钥时不需要进一步认证;
第三步、登录服务器
此时,再登录服务器便无需输入密码:
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 config
SSH config wildcard on expanded Hostname – Super User
Multiple similar entries in ssh config – Unix & Linux Stack Exchange
~/.ssh/config
Host developing HostName 172.31.252.100 User k4nz IdentityFile ~/.ssh/id_rsa # 172.31.253.0/24 Host 172.31.253.* User root IdentityFile ~/.ssh/id_rsa
在登录 172.31.252.100 主机时:需要使用 ssh root@developing 登录,而 root@172.31.252.100 无法使用该 config 配置;
参考文献
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!
常见问题
no-port-forwarding,no-agent-forwarding,no-X11-forwarding,command=”echo ‘Please login as the user \”centos\” rather than the user \”root\”.’;echo;sleep 10″