SSH中的安全 | 配置SSH公钥登录及常见错误
使用公钥登录,也被描述为「SSH 免密码登录」,本文将介绍这种登录方式配置方法、常见错误,并探讨使用公钥的特点与原理。

TL;DR 什么是公钥登录

使用公钥登录,也被描述为「SSH 免密码登录」,主要特点是不需要密码

确实,连接服务器时使用公钥登录不需要再次输入密码,但这只是他的附赠优点。

ssh 命令提示输入用户密码

不严谨地说,在 ssh 连接时输入密码,本地的 ssh 客户端将密码发送至服务器,服务器验证密码是否有效后进进行后续处理(比如接入终端、端口转发……)。关于 ssh 协议的更多介绍可以看另一篇文章

如果只是单纯的希望客户端能记住登录密码,使用类似 NextSSH 这样的 ssh 工具即可完成。

公钥验证的本质不同是?

使用公钥登录之前,要事先在本地生成一种特殊的密码。这种密码一创建就是两部分,像是掰开的饼干,可以严丝合缝的拼合在一起。其中一块密码(被称为 公钥,Publickey)需要被上传到服务器的指定目录内。

登录时,ssh 客户端会主动发送本地密码部分(私钥,Privatekey),服务器验证两部分是否匹配,并进行后续操作。

配置

生成密钥对

(根据微软的文档ssh-keygen 亦适用于 Windows)

本地终端,执行 ssh-keygen 命令生成密钥对。完成后,密钥文件默认保存在用户目录的.ssh 文件夹下。

其中 id_rsa 为私钥,保留不动即可,后续 ssh 命令会自动读取此文件。

id_rsa.pub 为公钥,此文件需要被保存至目标服务器,用作验证。

生成 ssh 密钥对

-> % ssh-keygen      
Generating public/private rsa key pair.
Enter file in which to save the key (/Users/zhshch/.ssh/id_rsa):  # 保存密钥文件的路径
Enter passphrase (empty for no passphrase):                       # 为密钥文件自身设置密码,可以留空
Enter same passphrase again:                                      # 重复密码
Your identification has been saved in /Users/zhshch/.ssh/id_rsa   # 私钥保存位置
Your public key has been saved in /Users/zhshch/.ssh/id_rsa.pub   # 公钥保存位置
The key fingerprint is:                                           # 密钥摘要信息
SHA256:A84eKmD4oR0/bvFBMVZMLJZj/WTfYiH1fouYJssBNjU zhshch@zhshch-MBP.local

上传公钥

上步生成的 id_rsa.pub 需被复制到服务器的 ~\.ssh\authorized_keys 文件内。如果存在多个使用中的公钥,则一行保存一个。如需操作多个服务器,则上传多次。

在本地终端,使用 ssh-copy-id 命令可以快速上传公钥文件,此命令会自动获取用户目录下的公钥文件,并完成上传。

此处需要使用密码或其他的登录方式传输密钥,设置完成后可以再禁用密码。

使用 ssh-copy-id 上传公钥

-> % ssh-copy-id zhshch@192.168.3.55
/usr/bin/ssh-copy-id: INFO: Source of key(s) to be installed: "/Users/zhshch/.ssh/id_rsa.pub"
/usr/bin/ssh-copy-id: INFO: attempting to log in with the new key(s), to filter out any that are already installed
/usr/bin/ssh-copy-id: INFO: 1 key(s) remain to be installed -- if you are prompted now it is to install the new keys
(zhshch@192.168.3.55) Password: # 此处会要求输入密码

Number of key(s) added:        1

除此之外,使用其他方法(连接到终端、实用 SFTP 或 SCP)上传公钥文件也可以。

更新完成后的~\.ssh\authorized_keys 文件如下图所示。

上传后的 authorized_keys 文件

大功告成

直接使用 SSH 命令连接服务器将不再提示输入密码。

连接服务器

常见异常

一些常见的错误可能导致依旧提示输入密码。

权限

OpenSSH 实现的服务器对密钥文件的权限要求十分严格,如不满足条件,服务器不会接受密钥验证。如果上传公钥后无法连接,可以尝试使用下列命令更新这些文件的权限。

chmod 600 ~/.ssh/authorized_keys
chmod 700 ~/.ssh

服务器配置

SSH 服务器的配置文件可能禁用了公钥验证模式。查看 /etc/ssh/sshd_config 确认下列配置是否正确

CleanShot 2022-09-28 at 13.28.03@2x

RSAAuthentication yes               # 是否可用RSA密钥对验证
PubkeyAuthentication yes            # 是否可用公钥方式验证
PasswordAuthentication no           # 是否可用密码验证(可用于限制密码登录)
PermitRootLogin prohibit-password   # 是否可用密码登录root用户(可用于限制密码登录)

好麻烦啊!

免密码登录

是的,这比直接设置密码然后登录要复杂一些。但也有不得不说的实用性和优点。

仅仅在登录时免去输入密码可能不是很必要。但如果使用脚本完成某些任务(比如备份、定时上传文件)的时候就避免了向 ssh 命令输入密码的过程。

此外,在 CI/CD 中,也经常使用这种方式将构建产物上传至其他设备,或连接到服务器执行自动更新等动作。

防止暴力猜解

暴露在公网上的服务器,攻击者可以通过反复尝试密码来突破简单的密码设置。即便密码复杂度可靠,有人反复发起 ssh 连接验证身份也会对服务器造成影响。

使用公钥作为登录验证方式可以一定程度避免此类问题。通常私钥文件都很长,通过暴力猜解几乎不可能找到正确的密码。

防范密码泄露与社会工程攻击

密码作为一个简短地字符串(相对于公私钥来说)通常都是可以记忆或者记录下来的。对于安全要求较为严格的场合,这样的密码可能会遭到社会工程攻击而泄漏。

使用公钥虽然不能对抗这类攻击,但可以减少密码意外泄露的可能,并且更便于团队管理。


本文转载不得删改,应全文转载并保留原文出处链接。


最后修改于 2021-10-09

此篇文章的评论功能已经停用。