如何使用 ssh 密钥登录服务器?

在 Linux/macOS 系统上 SSH 是常用的系统工具,通过 SSH Client 我们可以连接到运行了 SSH Server 的远程机器上。

SSH 用户认证最基本的两种方式是密码认证和密钥认证。

$ ssh -V OpenSSH_8.4p1 Debian-5+deb11u1, OpenSSL 1.1.1n 15 Mar 2022

修改 sshd_config 配置文件

配置文件路径为: /etc/ssh/sshd_config

$ vi /etc/ssh/sshd_config

(1)改变 ssh 网络端口

通常,默认的 SSH 网络监听端口号为 22,我们可以自己配置 SSH 服务监听端口号(比如修改成12201等其他的端口)。

# 默认为 22 端口
# Port 22

Port 20001

(2)禁止 X11 传输

一般,服务器上是不装 GUI 的。因此,应禁用 X11 方式远程连接登录。

由于使用 X11 转发的可能带来的风险,此指令默认值为"no"。

配置文件中找到:

X11Forwarding yes

改成:

X11Forwarding no

(3)禁止用户密码认证登录

SSH 密钥认证方式有效之后,应将用户密码认证登录禁用掉。配置文件中找到:

PasswordAuthentication yes

改变其值为 no 。

PasswordAuthentication no

(3)关闭空闲会话

空闲会话可能造成安全问题。记录一个连接用户不活动的时间是个好办法。

ClientAliveInterval 的值记录的是服务器最后一次发送给客户端活动信息后未得到客户响应持续到现在的时间秒数。

下面例子是设置为每当客户在 5 分钟不响应,服务器发送询问,这样 2 次后将断开此会话。

ClientAliveInterval 300 ClientAliveCountMax 2

Port 20001

X11Forwarding no
PasswordAuthentication no
ClientAliveInterval 300
ClientAliveCountMax 3

重启 sshd 服务:

systemctl restart sshd

查看服务状态:

systemctl status sshd

查看已存在的公钥

$ ls -al ~/.ssh

id_rsa.pub id_ecdsa.pub id_ed25519.pub

创建一个新的ssh秘钥

创建一个新的ssh秘钥需要用到 ssh-keygen 命令,它是 OpenSSH 的组件,在 Linux 和 macOS 中一般都自带了。

在本地机器, 创建一个新的ssh秘钥,默认防止在 ~/.ssh 目录:

cd ~/.ssh

$ ssh-keygen -t ed25519 -C "your_email@example.com"

$ ssh-keygen -t rsa -b 4096 -C "your_email@example.com" (不推荐)

注意,Ed25519 是一个数字签名算法,签名和验证的性能都极高,这里使用 ed25519 算法,不要再使用 rsa 算法。

直接指定生成的文件名称(默认 id_ed25519):

ssh-keygen -t ed25519 -f id_ed25519 -C "test@wang1234.com"

可以指定生成文件的名称,生产一个新的名称:

ssh-keygen -t ed25519 -f ssh_id_ed25519 -C "test@wang1234.com"

生产了2个文件,一个私钥(放在本地机器),一个公钥(放在远程服务器)。

ssh_id_ed25519
ssh_id_ed25519.pub

Add your SSH private key to the ssh-agent.

如果您创建了不同名称的密钥,或者您要添加不同名称的现有密钥,请将命令中的 ssh_id_ed25519 替换为你自己的私钥文件的名称。

$ ssh-add ~/.ssh/ssh_id_ed25519

ssh_id_ed25519
ssh_id_ed25519.pub

ssh-add 命令是把专用密钥添加到 ssh-agent 的高速缓存中,从而提高 ssh 的认证速度。该命令位置在 /usr/bin/ssh-add。

在本机的 ~/.ssh/ 下创建 config 文件,并以如下格式编辑配置文件:

Host web1a
  Hostname 124.223.106.211
  Port 20001
  User root
  PreferredAuthentications publickey
  IdentityFile ~/.ssh/ssh_id_ed25519

Host *
  AddKeysToAgent yes
  UseKeychain yes
  IdentityFile ~/.ssh/id_ed25519

复制公钥到远程服务器

ssh-copy-id命令 – 复制公钥到远程服务器

在本地机器操作:

# 默认 22 端口
ssh-copy-id -i ~/.ssh/ssh_id_ed25519.pub root@124.223.106.211  
ssh-copy-id -i ~/.ssh/ssh_id_ed25519.pub -p 22 root@124.223.106.211

# 如果服务器一句修改了ssh端口,可以使用-p指定端口
ssh-copy-id -i ~/.ssh/ssh_id_ed25519.pub -p 20001 root@124.223.106.211

ssh-copy-id命令 可以把本地主机的公钥复制到远程主机的 authorized_keys 文件上,ssh-copy-id 命令也会给远程主机的用户主目录(home)和/.ssh, 和/.ssh/authorized_keys设置合适的权限。

可以手动在 远程服务器 直接创建这个 authorized_keys 文件。

在远程服务器查看上传结果:

公钥会上传到 ~/.ssh/authorized_keys 文件中:

root@web1a:~/.ssh# 
root@web1a:~/.ssh# cat ~/.ssh/authorized_keys
ssh-ed25519 AAAAC3NzaC1lZDI1NTE… test@wang1234.com

注意,authorized_keys 文件的权限要设为644,即只有文件所有者才能写。如果权限设置不对,SSH 服务器可能会拒绝读取该文件。

$ chmod 644 ~/.ssh/authorized_keys

将公钥 ssh_id_ed25519.pub 的内容填写在里面。如果有多个公钥(多台电脑都想登录这个服务器),每行一个公钥。

测试效果

在本地终端直接使用 ssh 登陆服务器,不再需要密码:

$ ssh web1a
root@capp1a:~#