创建: 2023-02-21 12:18
更新: 2023-02-22 16:49
https://scz.617.cn/unix/202302211218.txt
目录:
☆ 背景介绍
☆ 生成公私钥
☆ /etc/ssh/sshd_config
☆ $HOME/.ssh/authorized_keys
☆ WinSCP
☆ SecureCRT
☆ Linux SSH Client
☆ /var/log/auth.log
☆ ChatGPT
☆ RFC 4252
☆ RFC 4253
☆ 参考资源
☆ 背景介绍
公网上有台Ubuntu 22,考虑到暴力猜测SSH密码太疯狂,应该只允许公私钥方式登录SSH,端口应该开在非标端口。初始有个非标端口、随机生成的密码,先用密码登录,再配置公私钥登录。意外发现两个Windows客户端公私钥登录失败,排查后发现是服务端OpenSSH版本过高,出现向后不兼容的安全升级,而客户端较旧,两相一凑,歇菜。出于各种综合考虑,以向后兼容为主要矛盾,对此记录一番。
从安全角度讲,C/S两侧都升至最新版是最佳选择,但现实世界中不这样干的原因有很多;「我即宇宙」是种幼稚狂妄病,得好好治治,但对某些人来说,是绝症,治不好的。
☆ 生成公私钥
ssh-keygen -q -C "<comment>" -t rsa -b 4096 -N "<passphrase>" -m PEM -f rsa_4096
ls -l rsa_4096*
ssh-keygen生成两个文件,扩展名为.pub的是公钥,没有扩展名的是私钥,公钥需要上传到目标SSH Server。不喜欢所谓免密登录,指定了<passphrase>。
新版ssh-keygen默认不再是"-m PEM",而是OpenSSH自己的一种新格式。某些旧版SecureCRT不认新格式私钥,为此必须给ssh-keygen显式指定"-m PEM"生成旧版私钥。
rsa_4096形如
-----BEGIN RSA PRIVATE KEY-----
Proc-Type: 4,ENCRYPTED
DEK-Info: AES-128-CBC,…
…
-----END RSA PRIVATE KEY-----
作为对比,OpenSSH新版私钥形如
-----BEGIN OPENSSH PRIVATE KEY-----
…
-----END OPENSSH PRIVATE KEY-----
从安全性讲,应该用新版私钥,从向后兼容性讲,用旧版私钥。
rsa_4096.pub形如
ssh-rsa …== <comment>
☆ /etc/ssh/sshd_config
PermitRootLogin yes
StrictModes yes
Protocol 2
# RSAAuthentication yes
PubkeyAuthentication yes
PubkeyAcceptedAlgorithms +ssh-rsa
AuthorizedKeysFile .ssh/authorized_keys
PasswordAuthentication yes
将Protocol设为2,避免使用脆弱的1。注释掉RSAAuthentication,该选项只为1所用。测试阶段将PasswordAuthentication设为yes,公私钥方式登录SSH成功后再改成no。是否允许root远程登录看情况。
重启sshd使配置生效
service sshd restart
☆ $HOME/.ssh/authorized_keys
在目标SSH Server上执行
mkdir -p $HOME/.ssh
chmod 0500 $HOME/.ssh
cat rsa_4096.pub >> $HOME/.ssh/authorized_keys
chown -R <user> $HOME/.ssh
chmod 0600 $HOME/.ssh/authorized_keys
其实就是将公钥内容放入authorized_keys,chown、chmod是防止sshd以不安全为由拒绝使用authorized_keys。
$HOME/.ssh/known_hosts(0644)是Linux作为SSH Client使用时自动生成的,与本文无关。
☆ WinSCP
WinSCP和PuTTY必须使用some.ppk这种格式的私钥,可用puttygen完成格式转换
<path>puttyputtygen.exe
Load
rsa_4096
Save private key
rsa_4096.ppk
rsa_4096.ppk形如
PuTTY-User-Key-File-2: ssh-rsa
Encryption: aes256-cbc
Comment: imported-openssh-key
Public-Lines: 12
…
Private-Lines: 28
…
Private-MAC: …
WinSCP需要对目标站点配置私钥
WinSCP
Advanced Site Settings
SSH
Authentication
Private key file
rsa_4096.ppk
我用WinSCP 5.17.8,Ubuntu 22中是OpenSSH 8.9p1,这两个C/S配对时存在兼容性问题。若服务端没有"PubkeyAcceptedAlgorithms +ssh-rsa",WinSCP 5.17.8公私钥登录时提示"Server refused our key";WinSCP 5.20做了安全增强,无需修改服务端配置。
参[3],里面有一段
2021-10-12 17:36, OpenSSH 8.8 disabled ssh-rsa by default. Until WinSCP 5.20 is released, add this to server's sshd_config to re-enable it:
PubkeyAcceptedAlgorithms +ssh-rsa
Ubuntu 20中是OpenSSH_8.2p1,没这幺蛾子。
☆ SecureCRT
SecureCRT 7.3.3密码登录Ubuntu 22时失败
Key exchange failed.
No compatible key exchange method. The server supports these methods:
curve25519-sha256,
[email protected],
ecdh-sha2-nistp256,
ecdh-sha2-nistp384,
ecdh-sha2-nistp521,
[email protected],
diffie-hellman-group-exchange-sha256,
diffie-hellman-group16-sha512,
diffie-hellman-group18-sha512,
diffie-hellman-group14-sha256
No compatible cipher. The server supports these ciphers:
[email protected],
AES-128-CTR,
AES-192-CTR,
AES-256-CTR,
[email protected],
[email protected]
意思是说服务端支持上面这一堆,但客户端当前配置不支持。
检查SecureCRT的"Session Options",下面是一种方案,充分非必要
Connection
SSH2
Authentication
Password
Key exchange
ecdh-sha2-nistp256
Advanced
Cipher
AES-256-CTR
MAC
SHA2-256
先用Password登录成功,再配置公私钥登录
Connection
SSH2
Authentication
Publickey
Properties
Use session public key setting
Use identity or certificate file
rsa_4096
SecureCRT 7.3.3不认OpenSSH新版私钥
ssh-keygen -q -C "test" -t rsa -b 4096 -N "test" -f test_4096
用test_4096时,SecureCRT 7.3.3提示
The private key file could not be found
Note that the public key file and private key file must have the same name (e.g., "Identity.pub" and "Identity") and must be located in the same folder.
Unknown file format
过去的套路突然不灵,起初我挺懵逼的,后来无意中发现新旧私钥格式不一样,问ChatGPT如何生成旧版私钥,从它的回答中意识到ssh-keygen可以指定生成哪种格式的私钥,在man手册中看到
By default OpenSSH will write newly-generated private keys in its own format. Setting a format of "PEM" when generating a supported private key type will cause the key to be stored in the legacy PEM private key format.
ssh-keygen的缺省值变了,为了保持向后兼容性,应该"ssh-keygen -m PEM"。
SecureCRT 7.3.3与Ubuntu 22中的OpenSSH 8.9p1,这两个C/S配对时存在兼容性问题。若服务端没有"PubkeyAcceptedAlgorithms +ssh-rsa",SecureCRT 7.3.3公私钥登录时提示
Public-key authentication with the server for user scz failed. Please verify username and public/private key pair.
The client has disconnected from the server. Reason: Unable to authenticate using any of the configured authentication methods.
假设没有先验知识,只根据上述提示,很难定位PubkeyAcceptedAlgorithms,这个提示不合格。新版SecureCRT应该有安全增强,无需修改服务端配置,未实测。
实测SecureCRT 7.3.3不支持rsa-sha2-512、ed25519(ecdsa)。
☆ Linux SSH Client
服务端没有"PubkeyAcceptedAlgorithms +ssh-rsa"时,旧版SecureCRT、WinSCP公私钥登录失败,之前以为是不加此配置时服务端不认RSA公钥。意外发现服务端不加此配置时Linux SSH Client公私钥登录成功,用的是同一套RSA公私钥,那就不是服务端不认RSA公钥,应该有其他合理解释,与协商过程强相关,这让我对公私钥登录流程产生好奇。
用Linux SSH Client时,注意私钥权限最小化,否则拒绝使用
chmod 0400 rsa_4096
ssh -i rsa_4096 <user>@<host>
查看SSH Server/Client版本
$ sshd -V
OpenSSH_8.9p1 Ubuntu-3, OpenSSL 3.0.2 15 Mar 2022
$ ssh -V
OpenSSH_8.4p1 Debian-3, OpenSSL 1.1.1i 8 Dec 2020
查看客户端连接指定站点时所用配置
$ ssh -G -i rsa_4096 <user>@<host>
…
hostkeyalgorithms …,rsa-sha2-512,rsa-sha2-256,ssh-rsa
…
pubkeyacceptedkeytypes …,rsa-sha2-512,rsa-sha2-256,ssh-rsa
…
查看客户端连接指定站点时更详细的信息
ssh -vvv -i rsa_4096 <user>@<host>
查看客户端支持的(签名)算法
$ ssh -Q sig
ssh-ed25519
[email protected]
ssh-rsa
rsa-sha2-256
rsa-sha2-512
ssh-dss
ecdsa-sha2-nistp256
ecdsa-sha2-nistp384
ecdsa-sha2-nistp521
[email protected]
[email protected]
rsa-sha2-512/rsa-sha2-256/ssh-rsa三者公私钥都用RSA,签名算法分别用SHA-512、SHA-256、SHA-1。
客户端用PubkeyAcceptedKeyTypes指定用哪种(签名)算法,而非HostKeyAlgorithms。
rm $HOME/.ssh/known_hosts
ssh -i rsa_4096 -o PubkeyAcceptedKeyTypes=rsa-sha2-256 <user>@<host>
上述命令登录成功,等价于无"-o"参数的默认情形
rm $HOME/.ssh/known_hosts
ssh -i rsa_4096 -o PubkeyAcceptedKeyTypes=ssh-rsa <user>@<host>
上述命令登录失败,相当于模拟了旧版SecureCRT、WinSCP登录失败的情形,后两者无法指定PubkeyAcceptedKeyTypes。
☆ /var/log/auth.log
前述登录失败是旧版Client对新版Server,也有反过来的,同样可能失败,参[2]。C/S两侧在协商过程中向对方展示己方支持的算法,只要存在交集,就能成功,反之失败。从运维角度看,关注auth.log,从中发现失败的深层次原因,再在C/S两侧做相应调整,领会精神,此处不一一排列组合了。
tail -f /var/log/auth.log
旧版SecureCRT登录失败时,auth.log指明应修改PubkeyAcceptedAlgorithms
userauth_pubkey: key type ssh-rsa not in PubkeyAcceptedAlgorithms [preauth]
Linux SSH Client模拟登录失败时,可见同样的日志。登录成功时看到
Accepted publickey for scz from <sip> port <sport> ssh2: RSA SHA256:…
客户端可以这样探测服务端支持哪些算法
$ ssh -o HostkeyAlgorithms=ssh-rsa <any>@<host>
Unable to negotiate with <server> port <port>: no matching host key type found. Their offer: rsa-sha2-512,rsa-sha2-256,ecdsa-sha2-nistp256,ssh-ed25519
与此同时服务端auth.log中有
Unable to negotiate with <client> port <port>: no matching host key type found. Their offer: ssh-rsa [preauth]
(其余见TXT)
原文始发于微信公众号(青衣十三楼飞花堂):以公私钥方式登录SSH Server
- 左青龙
- 微信扫一扫
-
- 右白虎
- 微信扫一扫
-
评论