实验环境:Ubuntu18.04 远程服务器 + WSL 2 本机
测评说明#
-
-
在测过程中,你需要用到的数据在这里:测评服务的公钥
-
附加:免密登录的本质到底是什么?
最终效果#
【在本地测试】
-
-
ssh 主机名,已可免密登录
-
又是绿 :)
实现过程#
两步走⭐#
【生成密钥对👉复制公钥】
- ① 在本地 WSL 2 生成公私钥 [.pub 后缀的为公钥],这里选择 RSA 加密算法
ssh-keygen -t rsa
-
- 可使用 ssh-keygen --help 查看密钥类型等各种信息
- 一般不需要设置 passphrase [用于加密私钥],除非你希望每次免密登录时输密码
- ② 将公钥配置到远程服务器上,一条命令即可
ssh-copy-id ten
-
- 这里使用的 ten 是远程服务器的别名(用户名默认为本地用户,否则可使用 hz@ten 的方式),具体设置方法可参考《Linux 入门及使用》笔记汇总 ——5 基本系统 —— 附加知识点:使用 ssh 绰号登录云主机
- 或者可以使用
ssh-copy-id 用户名@IP
的方式,下文中的 ten 和用户名 @IP 等价
🔚至此,实现了免密登录,连接云主机 ten 进行测试
ssh ten
ssh-copy-id 的细分步骤#
如果想自己手工实现 ssh-copy-id 的效果,可参考下列步骤:
- 复制本地公钥到远程服务器的家目录
scp ~/.ssh/id_rsa.pub ten:
- ssh 登录到远程服务器的家目录,将公钥的内容追加到密钥的配置文件后
cat id_rsa.pub >> .ssh/authorized_keys
rm id_rsa.pub # 可删
-
- authorized_keys 可以存储多个不同公钥,每一行对应一个
- 如果没有.ssh 目录和 authorized_key 文件,自行创建即可
- 【关键】是两者的【权限】,要特定设置一下:让.ssh 目录只有所属者有全部权限,让 authorized_keys 文件只有所属者有读写权限;否则免密登录难以成功
chmod 700 ~/.ssh
chmod 600 ~/.ssh/authorized_keys
🔚至此,也实现了免密登录
【权限要求】
- 可参考 man sshd
-
- 安全起见,如果权限设置不符合要求,将无法使用公钥文件
-
附加说明#
- 确认本机和远程服务器的 /etc/ssh/sshd_config 里的 PubkeyAuthentication 设为 yes,修改完需要重启 sshd 服务:systemctl restart sshd.service
- 想免密登录远程服务器的哪个用户,就将公钥放在那个用户的【家目录】相应位置
免密登录的本质#
流程⭐#
- 本地发起 SSH 连接,发送本机公钥
- 远程服务器拿到公钥后,与本地的公钥做比对
- 如果一致,服务器会用公钥加密 “随机字符串”,发回本地
- 本地拿出私钥解密 “随机字符串”,将结果再发给服务器
- 如果一致,连接建立
❗ 参考SSH 免密登录原理与实现—— 掘金
【这里提到了密码登录和免密登录两种方式的具体流程】
- 密码登录
-
- 利用远程服务器的公钥给密码加密
-
- 免密登录
-
- 传输过程都不会暴露私钥
-
密码登录方式比免密登录方式简单,即密码登录在连接时更快一些
但是免密登录则更加安全:
- ① 密码更容易被识破
- ② 参考文章中提到免密登录不存在 “中间人攻击” 的风险,我并不完全认同
- 两者首先都是靠.ssh/known_hosts 来识别机器
- 而免密登录多一次公钥的匹配,免密登录更安全
- 【注意】但这是在本地公钥没有被中间人盗取的情况下
附加说明#
- ssh -v ten:可以看到更详细的过程
- 网上有一张广为流传的图,但存在细节错误,如下:
-
- 请求信息不是用户名和 IP❌,而是本地的公钥
- 公钥里并没有存储 IP [否则会带来隐患],存储的是本机的用户名和主机名
- 可尝试将本地或远程服务器公钥中的用户信息 [用户名和主机名] 删去,仍可免密 SSH 连接
- 可见,远程服务器验证的是公钥字符串本身!
-
思考点#
- 第一次登录云主机显示的身份验证是什么?
-
- 什么是 ECDSA key fingerprint?来自远程服务器的密钥指纹,每台安装了 ssh 的机器都有自己的指纹
- 输入 yes 后,会将指纹相应信息存入本地的.ssh/known_hosts,当下次连接若存在伪装机,可产生警觉
- 如果首次连接就有伪装机 [中间人] 攻击,那么恭喜你中奖了
- 参考验证远程主机 SSH 指纹—— 博客
-
附加#
-
ssh-copy-id 的使用
- 直接将本机本用户的公钥复制到远程机器家目录 /.ssh 下的 authorized_keys 文件中
-
- 更简单、更直接,可指定具体公钥、特定端口等
-
可使用 man sshd_config 查看 sshd_config 的具体配置说明
-
⭐禁用密码登录,修改 /etc/ssh/sshd_config 里 PasswordAuthentication 为 no
-
- 重启 sshd 服务:systemctl restart sshd.service,生效
-
-
公钥的位置可以通过 /etc/ssh/sshd_config 里 AuthorizedKeysFile 自行设置
-
- 默认在用户家目录对应位置找公钥
-
-
ChanllengeResponseAuthentication 是什么?
-
ChallengeResponseAuthentication no
# 允许任何类型的密码认证!所以,任何 login.conf 规定的认证方式,均可适用!
# 但目前我们比较喜欢使用 PAM 模块帮忙管理认证,因此这个选项可以设定为 no 喔!
参考资料#
- SSH Login Without a Password——howchoo
- ssh 免密登录踩坑及解决—— 码农家园
- 里面提到 authorized_keys 的权限设为 644,因为文件所属者是 root;也可以修改文件所属者 [个人认为后者更安全]
- 文字接口联机服务器:SSH 服务器—— 鸟哥的 Linux 私房菜
- ssh 修改登录端口禁止密码登录并免密登录—— 简书
- SSH 用公钥验证可以阻止中间人攻击么?—— 知乎
- 不能,是通过首次连接时的 known_hosts 验证避免的