ssh使用密钥认证
SSH 为 Secure Shell 的缩写,专为远程登录会话和其他网络服务提供安全性的协议。利用 SSH 协议可以有效防止远程管理过程中的信息泄露问题。
验证方式
(一)、基于口令的安全验证
只要你知道自己帐号和口令,就可以登录到远程主机。所有传输的数据都会被加密,但是不能保证你正在连接的服务器就是你想连接的服务器。可能会有别的服务器在冒充真正的服务器,也就是受到“中间人”这种方式的攻击。
基于密钥的认证方式必须为自己创建一对密匙(公钥和私钥),并把公用密匙放在需要访问的服务器上。如果你要连接到SSH服务器上,客户端软件就会向服务器发出请求,请求用你的密匙进行安全验证。服务器收到请求之后,先在该服务器上你的主目录下寻找你的公用密匙,然后把它和你发送过来的公用密匙进行比较。如果两个密匙一致,服务器就用公用密匙加密“质询”(challenge)并把它发送给客户端软件。客户端软件收到“质询”之后就可以用你的私人密匙解密再把它发送给服务器。
第一种级别相比,第二种级别不需要在网络上传送口令。基于密钥认证可以实现免密码登录。此处主要总结一下与ssh相关的一些命令,我们使用ssh-keygen命令即可生成私钥与公钥。
生成公钥和密钥
直接执行ssh-keygen命令,会进入交互模式,并等待用户输入生成密钥文件的路径,私钥与公钥默认生成在当前用户家目录下的 .ssh 目录中。如果不指定其他路径,直接回车即可,如果对应目录下已经存在了同名的密钥文件,还会提示你是否覆盖。随后,出现了Enter passphrase(输入密码)的提示,我们可以为生成的私钥设置码,如果为私钥设置了密码,在每次使用私钥的时候,都会提示我们输入私钥的密码,直接回车,代表不为私钥设置密码,Enter same passphrase again表示确认密码。
[root@all ~]# ssh-keygen Generating public/private rsa key pair. Enter file in which to save the key (/root/.ssh/id_rsa): Enter passphrase (empty for no passphrase): Enter same passphrase again: Your identification has been saved in /root/.ssh/id_rsa. Your public key has been saved in /root/.ssh/id_rsa.pub. The key fingerprint is: 98:f3:e0:08:75:47:d7:d7:95:7b:3c:2e:1a:10:b2:d3 root@all The key's randomart image is: +--[ RSA 2048]----+ | . .. .+| | o o . ...| | . . = . . ..| | . . * E oo| | . = S . . o| | . o + . . . | | . . . o . | | . | | | +-----------------+
完成上述步骤后,即在用户家目录的.ssh目录中生成了一对密钥文件,私钥文件id_rsa与公钥文件id_rsa.pub
从文件名称可以看出,我们生成的是rsa密钥,我们也可以选择其他算法,从而生成其他类型的密钥文件,默认生成RSA类型的密钥。在版本2的ssh协议中我们可以使用的密钥类型有: "dsa", "ecdsa", "ed25519", "rsa"。
拥有了自己的私钥与公钥,还需要把公钥交给要访问的服务器,才实现免密登录。假设我们要访问的服务器是 192.168.126.131 。这时候就可以使用 ssh-copy-id 命令完成公钥的交付工作。
ssh-copy-id -i ~/.ssh/id_rsa.pub root@192.168.126.131
使用"-i"选项指定要传输的公钥,然后指明账户与IP地址。传输公钥第一次需要输入密码验证。
[root@all ~]# ssh-copy-id -i ~/.ssh/id_rsa.pub root@192.168.126.131 root@192.168.126.131's password: Now try logging into the machine, with "ssh 'root@192.168.126.131'", and check in: .ssh/authorized_keys to make sure we haven't added extra keys that you weren't expecting.
提示我们已经添加了密钥,可以通过 ssh root@192.168.126.131 进行验证了。
注意:也可以root用户的公钥发给其他服务器的普通账户,只有认证的两个用户之间可以免密登录。
我们已经把公钥交给了192.168.126.131的root账户。root将别人家的公钥放在了自己家目录的.ssh/authorized_keys文件中。通过查看可以发现,authorized_keys文件的内容和源服务器的id_rsq.pub的内容是一致的。所以,我们通过拷贝文件内容一样也可以实现公钥的交付。
cat ~/.ssh/id_rsa.pub | ssh -p 22 zsy@192.168.126.131 "umask 077;mkdir -p ~/.ssh;cat - >> ~/.ssh/authorized_keys"
上述这条命令和ssh-copy-id效果是相同的。纯手动的去'复制'、'粘贴'公钥中的内容,但是这样容易出错,因为对方服务器的账户中可能还没有对应的.ssh目录,也没有authorized_keys文件,你需要手动的创建它们,权限设置也容易出错,所以还是建议使用ssh-copy-id命令。
注意:有些服务的sshd服务不用默认端口,在使用ssh-copy-id命令时,需要指定端口,在redhat6 和 readhat7 中,命令略有差别。6需要加双引号
# 当前系统为redhat6 ssh-copy-id -i ~/.ssh/id_rsa.pub "zsy@192.168.126.131 -p 22222" # 当前系统为redhat7: ssh-copy-id -i ~/.ssh/id_rsa.pub root@192.168.126.131 -p 22222
常见问题
通常的问题是,你已经将本机的公钥推送到了对方服务器的某个账户中,但是仍然不能免密码登录对应账户。
出现上述问题,通常可能是由于如下原因引起的:
1、ssh服务端不支持基于公钥认证或者修改了默认的公钥认证文件
服务端可以禁用使用公钥认证的机制,PubkeyAuthentication配置项用于控制是否可以使用公钥进行认证,PubkeyAuthentication默认值为yes,表示支持公钥认证,服务端默认使用authorized_keys作为存储用户公钥的文件,在服务端的sshd_config配置文件中可以使用AuthorizedKeysFile配置项指定其他文件为认证文件。
2、ssh服务端相关目录或者文件的权限过大
服务端用户家目录.ssh目录的权限正常700,服务端用户家目录.ssh/authorized_keys文件的权限默认为600
3、ssh服务端的authorized_keys文件中包含windows字符
通常纯手动复制粘贴公钥内容到authorized_keys并且操作时经过windows系统处理,会出现这种情况
4、ssh客户端连接服务端时,没有指定对应账户的用户名
如果我们想要从hostB的B账户连接到hostA的A账户,则需要在hostB中执行命令ssh A@hostA,如果在hostB的B账户中直接执行命令ssh hostA,并没有指定连接的用户名,则表示连接到hostA中的B账户,也就是说,如果你在hostB的B账户中执行ssh hostA,相当于执行了ssh B@hostA,如果你把B的公钥交给了hostA的A账户,却在链接时没有指明A账户,则很有可能会连错账户,自然无法认证成功,这种低级错误在你有些疲惫的时候很难发觉。
5、ssh客户端的私钥权限过大,正常情况下,将私钥的权限设置为600即可,如果权限过大,可能会在连接ssh服务端时看到如下提示
Permissions 0644 for '/root/.ssh/id_rsa' are too open.
It is required that your private key files are NOT accessible by others.
This private key will be ignored.
bad permissions: ignore key: /root/.ssh/id_rsa
6、在创建密钥对时,没有使用默认的密钥名称,比如id_rsa或者id_dsa,而是使用了自定义的密钥名称,如果将自定义名称密钥对中的公钥拷贝到了远程主机中,在连接到远程主机时,需要指定对应的自定义名称的私钥才能够实现免密码连接,使用"-i"选项可以指定密钥,当指定密钥后,ssh会使用指定的密钥与远程主机上的公钥进行认证,否则ssh仍然使用默认名称的私钥进行认证,如果你自定义了密钥对的名称,但是在连接时没有指定对应私钥,由于默认私钥与远程主机中的自定义公钥不匹配,自然无法基于密钥进行认证,会再次提示你输入密码。
第一次登录询问
首次进行ssh链接时,出现以下提示:
The authenticity of host '192.168.100.1(192.168.100.1 )' can't be established. RSA key fingerprint is a0:00:d3:33:54:96:40:03:ff:ad:15:a9:59:22:f4:2a.
Are you sure you want to continue connecting (yes/no)?
批量连接时或者在脚本中在跳出这个提示很麻烦。可以通过以下三种方式避免第一次登录询问 yes/no
一、修改配置文件
修改本机的/etc/ssh/ssh_config文件中的"# StrictHostKeyChecking ask" 为 "StrictHostKeyChecking no",然后重启sshd服务。
二、创建config文件
创建文件 ~/.ssh/config,添加一行:
StrictHostKeyChecking no
保存退出,再使用ssh连接其他机器就不再跳了
三、使用 -o 参数
ssh -o stricthostkeychecking=no
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· 【自荐】一款简洁、开源的在线白板工具 Drawnix