密码认证被认为是一种薄弱的机制。正如我们此前所看到的,它可能遭受多种类型的攻击,例如字典攻击、暴力破解攻击,或者中间人攻击(Man In The Middle)。
在配置 SSH 服务时,强烈建议配置更为稳健的认证方式,例如加密密钥认证,或者双因素认证(2FA)。
第 1 步:在 SSH 服务上配置密钥认证
首先需要在配置文件中允许使用 SSH 密钥:
sudo nano /etc/ssh/sshd_config
需要查找 " PubkeyAuthentication ",并将其值设为 yes:
PubkeyAuthentication yes
AuthorizedKeysFile .ssh/authorized_keys
为使更改生效,需要重新启动 SSH:
service ssh restart
第 2 步:在客户端生成 SSH 密钥
在客户端机器上,我们需要生成一个公钥和一个私钥,以便能够在 SSH 服务器上进行认证:
ssh-keygen -b 256 -t ecdsa

ssh-keygen 命令生成了两个密钥:
- 一个位于 $home/.ssh/id_ecdsa 的私钥,只有您本人才应能够访问
- 一个位于 $home/.ssh/id_ecdsa.pub 的公钥,可以对外共享
现在我们要明确授权客户端机器通过 SSH 访问服务器。需要把公钥(id_ecdsa.pub)添加到所选用于连接的用户的 .ssh 目录下的 authorized_keys 文件中(例如:/home/$user/.ssh)。
最简单的方法是使用 ssh-copy-id 命令,但它在 Windows 上默认不可用。因此我们将在 Windows 上使用以下命令,它会把密钥复制到您 Linux 用户的 authorized_keys 文件(~/.ssh/authorized_keys)中,即使该文件此前并不存在。但至关重要的是,.ssh 目录必须已经创建。如有必要,您可以使用 mkdir 创建它。
将公钥从 Windows 客户端复制到 Linux:
type %userprofile%\.ssh\id_ecdsa.pub | ssh user@192.168.8.128 "cat >> .ssh/authorized_keys"
更进一步,还可以关闭密码认证,只保留密钥认证。
注意! 如果关闭了密码认证,必须先确认密钥认证已经可以正常工作,否则将完全无法再访问这台远程机器!
在配置文件 /etc/ssh/sshd_config 中,需要取消 PasswordAuthentication 指令的注释,然后将参数设为 no。
sudo nano /etc/ssh/sshd_config
PasswordAuthentication no
文件保存后,还需要重新启动服务,才能使更改生效。
service ssh restart
以下建议摘自 ANSSI 发布的推荐规范:
- 检查 /etc/ssh/ 目录中存放的加密私钥归 root 用户所有,且仅具有读写权限
- 确认所使用的确实是 SSH 协议的第 2 版
- SSH 服务器应监听 22/TCP 以外的端口
- 检查 SSH 是否严格地对文件权限加以控制
- 必须禁止 root 用户通过 SSH 访问
- 借助沙箱(sandbox)实现权限分离
- 禁止没有设置密码的账户进行远程访问
- 密码输入错误时,允许连续尝试连接 3 次
- 用户连接时,服务应向其显示上次连接的信息
- 仅授权确实需要连接到服务器的用户。
