Linux系统的 SSH 优化
在 Linux 系统中,我们想使用 SSH 命令登录到另一台服务器中,在第一次登录时,会提示我们验证指纹,如下所示
同一网络下,为了确保你想 SSH 访问的 Linux 系统是无误的,可以在另一端确认指纹(指纹通过公私钥得到,因此需要根据客户端提示的密钥类型和加密方式在服务端得出指纹二者进行比较)
由上述对比,发现我们想要登录的一端和我们登录提示显示的指纹一致,因此只需要在 SSH 客户端确认指纹信息并输入服务端的密码即可登录成功
我们先确认指纹,不输入密码,然后我们会发现我们当前用户的家目录下会生成一个 .ssh 的目录,并且该目录下会有一个 known_hosts 的文件,该文件就记录了服务端的公钥确认指纹后,客户端再次登录服务端的时候就不会提示验证指纹了
上面情况是客户端和服务端指纹一致的情况,下面我们模拟指纹不一致的情况,即我们手动修改 known_hosts 文件里服务端的公钥,修改后,我们再次登录会提示以下内容
由于系统本身的差异,所以 debian 系统的反馈是 known_hosts 文件里的指纹和目标主机指纹不一致,所以需要重新验证指纹
但如果我们把 stream9 作为客户端,debian 作为服务端,即我们在 stream9 端 SSH 登录 debian,然后同样的手动修改 known_hosts 文件里记录的 debian 的公钥,此时会提示我们公钥验证失败
解决办法:删除 known_hosts 文件(如果 known_hosts 文件里还有其它远程主机的公钥,那就删除该文件里对应主机和公钥的一行或多行),重新 SSH 登录验证指纹获取 debian 端的公钥(删除后再登录就不会提示公钥验证失败)
在我们每次登录到远程主机的时候,都提示我们需要验证指纹,验证指纹的办法无疑是提高了系统的安全性,但另一方面,也给自动化运维增加了不便,因为自动化运维涉及的服务器较多,需要登录到很多服务器上进行操作,因此在做自动化运维的时候基本是把验证指纹关闭的。同时,SSH 命令也给我们提供了一个可以临时关闭验证指纹的选项
上面命令可以在不验证指纹的情况下将服务端公钥放入 known_hosts 文件中,但我们不想每次敲这么长的选项,因此我们可以在 SSH 客户端配置文件中添加参数来永久关闭验证指纹
(UserKnownHostsFile=/dev/null 表示将客户端的公钥放入黑洞文件中,这样即使公钥和主机不匹配,也不会出现上面公钥验证失败的情况)
我们可以通过修改 SSH Port 和禁用 root 用户远程登录来增强我们系统的安全性
参考命令:sed -i -e '/^#Port 22/a Port 21212' -e '/^#PermitRootLogin/a PermitRootLogin prohibit-password' /etc/ssh/sshd_config ; systemctl restart sshd
(上面命令可以将 SSH 服务的端口改为21212并且关闭 SSH 服务的 root 用户远程登录)
我们还可以通过 SSH 禁止密码登录,开启密钥登录来增强安全性(openssh 的密码登录和密钥登录默认都是开启的)
然后客户端生成密钥对,并把公钥拷贝给服务端
ssh-copy-id 命令的本质是拷贝文件到另一台服务器(scp/rsync),如果你知道服务端记录客户端公钥文件的位置,使用(scp/rsync)也可以
远程复制客户端公钥到服务端,需要输入服务端密码,如果不知道服务端密码,可以将客户端公钥复制给服务端管理人员,它将你的公钥放进公钥文件你即可远程免密登录
如果复制公钥后不能远程免密登录,那可能是 C/S 两端所支持的密钥类型和加密方式不同,因此尽量保持 C/S 两端的 openssh 软件版本别相差太大
如有需求要源码包编译安装升级 openssh,可参考:源码包编译安装openssh9.0
查看服务端存放客户端公钥的文件
如果需要更改该位置,更改后记得重启 sshd 服务
SSH 服务端可更改的选项很少,但 SSH 客户端可更改的选项有很多,并且客户端选项更改后不需要重启服务
# 禁止除 root 用户外的所有用户 ssh 登录
touch /etc/nologin