最近发现 ssh 直接可以免密登录远程服务器,感觉挺有趣的,于是想试试顺便了解下原理。首先便是百度下 ssh 的概念及登录方式及原理,接着就是自己实践了,一开始老是有问题,后面思考可能的原因再尝试便慢慢解决了,结果还是不错的。
简单说下 ssh 的概念吧。主要了解以下几点就差不多了。
- 概念:ssh 全称是 Secure Sshell,即安全外壳协议,由 IETF 的网络小组(Network Working Group)所制定。
- 作用:为建立在应用层基础上的安全协议。SSH 是较可靠,专为远程登录会话和其他网络服务提供安全性的协议。利用 SSH 协议可以有效防止远程管理过程中的信息泄露问题。ftp、pop和telnet在本质上都是不安全的,因为它们在网络上用明文传送口令和数据,别有用心的人非常容易就可以截获这些口令和数据。而且,这些服务程序的安全验证方式也是有其弱点的, 就是很容易受到“中间人”(man-in-the-middle)这种方式的攻击。通过使用SSH,你可以把所有传输的数据进行加密,这样"中间人"这种攻击方式就不可能实现了,而且也能够防止DNS欺骗和IP欺骗。使用SSH,还有一个额外的好处就是传输的数据是经过压缩的,所以可以加快传输的速度。SSH有很多功能,它既可以代替Telnet,又可以为FTP、PoP、甚至为PPP提供一个安全的"通道"。
- 适应平台:几乎所有UNIX平台—包括 HP-UX、Linux、AIX、Solaris、Digital UNIX、Irix,以及其他平台,都可运行SSH。
- 从客户端来看,SSH 提供两种级别的登录安全验证。
1.基于口令的安全验证,意思就是通过账号和密码进行登录到远程主机。所有传输的数据都会被加密,但是不能保证你正在连接的服务器就是你想连接的服务器。可能会有别的服务器在冒充真正的服务器,也就是受到“中间人”这种方式的攻击。
2.基于密匙的安全验证,需要在发起连接的机器(客户机)建立密钥对,即公钥以及匹配的密钥,将公钥放置到要连接的目标服务器的用户的家目录下的 .ssh 目录下,连接时向服务器发出请求,请求用你的密匙进行安全验证。服务器收到请求,先在该服务器上你要连接的用户的主目录下寻找对应的公用密匙,然后把它和你发送过来的公用密匙进行比较。如果两个密匙一致,服务器就用公用密匙加密“质询”(challenge)并把它发送给客户端软件。客户端软件收到“质询”之后就可以用你的私钥解密再把它发送给服务器。不需要在网络传输密码(口令),不仅加密所有传送的数据,而且“中间人”这种攻击方式也是不可能的(因为他没有你的私人密匙)。
实践开始:我是在 win10 下测试的,使用了 win10 子系统 ubuntu 作为其中的客户端机器,再开启虚拟机(centos 系统)作为服务器。
默认 ubuntu 和 centos 都安装了 ssh 服务,没有的话可以自行百度命令安装。先查看 centos 下 sshd 服务是否开启,未开启的话就开启。#查看 ssh 默认运行端口是否有 sshd 服务进程 netstat -anp|grep 22 #也可以直接查看 sshd 服务运行状态 ps -ef|grep sshd #开启或重启 sshd 服务 systemctl start(restart) sshd 或 service sshd start(restart)linux 系统 bash 查看 ip 命令:ifconfig 获取机器 ip 后,就可以直接在客户机,直接 bash 敲命令:ssh root@192.168.43.83 再回车,此时会提示输入目标服务器密码,正确输入即可正常登录了。如下图:

如图所示,首次连接远程目标服务器,会提示对方身份不可确定,提供密钥供客户端去核实,假如是目标服务的密钥就允许继续连接,这也是为了防止冒充目标服务器发送密钥的行为。这边接受密钥之后,该主机就会记录下到 ~/.ssh/known_hosts 文件,下次就不需要再确认了。如图连接成功发现可以正常获取虚拟主机服务器目录文件即成功。
为了免去每次连接都需要输入密码的麻烦,密码也容易忘记,所以接下来测试免密登录操作。
1.先在客户机生成密钥对,有多种密钥可选择,可通过命令 ssh-keygen --help 查看,-b 参数指定密钥位数(bit),-t指定密钥类型。
根据你生成的密钥对,获取对应的公钥,比如 id_rsa.pub 或者 id_dsa.pub,将其上传到目标服务器的需要免密登录的用户对应家目录下 .ssh 目录下并改名为 authorized_keys ,root 用户默认位置是:/root/.ssh/authorized_keys,其它用户如 yibin,位置是 /home/yibin/.ssh/authorized_keys 。
可以使用命令 ssh-copy-id 将公钥文件复制到服务器的 authorized_keys 文件并自动设置权限为 644 。-i 后面指定要上传的公钥文件,再往后就是目标服务器的 user@host。然后目标服务器对应 ~/.ssh/authorized_keys 就会自动生成。
这里还有个坑我一开始不知道,就是我可能出于好奇,在上面就选择生成了 dsa 类型的密钥对,结果一顿操作基本没大问题,就是死活无法免密登录。测试 n 多次也没用,后面百度后发现是 openssh 7以上版本默认不支持 dsa 公钥登录了,可以 ssh -V 查看 OpenSSH 版本。然后网上说去 sshd 服务配置文件(/etc/ssh/sshd_config)新增配置项vim /etc/ssh/sshd_config #上述命令进去后新增配置项如下 PubkeyAcceptedKeyTypes=+ssh-dss #保存退出重启 sshd 服务 systemctl restart sshd你们可以尝试这样看能否解决,我这边测试依旧没起作用。所以下面都是采用的 rsa 密钥对进行测试的,基本正常。
1、注意目录权限:.ssh 目录权限必须是 700,chmod -R 700 .ssh/。然后就是 authorized_keys 文件的权限了,默认文件所属用户是 root ,这种情况下假如你只需要在客户机用 root 用户访问目标服务器的 root 用户进行免密登录的话,就可以设置权限为 600,表示只有 root 用户有 rw 权限即读写权限,后面 00 代表组和其它用户无 rwx 权限。现在你就可以去客户机在 root 用户下执行命令:ssh root@192.168.43.83 或 ssh 192.168.43.83 (192.168.43.83 是目标服务器 ip)进行登录操作,假如直接跳过密码登录,那么恭喜你成功了!假如提示需要输入密码的话,就到目标服务器查看 sshd 配置文件:/etc/ssh/sshd_config,将配置参数 PubkeyAuthentication 值改为 yes,并去掉注释符 #,还需要看看是否允许 root 登录,即将 PermitRootLogin 值置为 yes,再保存文件,后重启 sshd 服务即可。#ubuntu 系统重启 sshd 服务命令 /etc/init.d/ssh restart #centos 系统重启 sshd 服务命令 service sshd restart
上面成功实现客户机 root 用户免密登录目服务器 root 用户,方法就是将客户机 root 用户生成的密钥对中的公钥放置到目标服务器要免密登录的 root 用户下的 ~/.ssh/authorized_keys 文件,并设置对应 sshd 服务的配置文件,允许公钥认证登录,此时 authorized_keys 文件权限可以是 600 或者 644 都没问题。
2、接下来我就想在客户机用 root 用户免密登录目标服务器的非 root 用户,比如 yibin 用户,聪明的你肯定想到了,没错就是将客户机 root 用户的公钥放置到目标服务器的 yibin 用户家目录下 .ssh 目录下,改名为 authorized_keys,完整路径为 /home/yibin/.ssh/authorized_keys,注意 .ssh 文件夹权限需设置为 700,aurhoriized_keys 文件权限为 600 或 644。
3、客户机非 root 用户免密登录服务器 root 用户:
同样的原理,此时需要在客户机非 root 用户下,我这边是 yibin 用户,从 root 用户切换到 yibin 用户命令,su yibin ,接下来就是生成密钥对了,可以直接使用命令 ssh-keygen 按回车默认生成 rsa 密钥对,再将公钥 id_rsa.pub 上传到服务器的 root 用户家目录的 .ssh 目录下,生成文件:~/.ssh/authorized_keys(即 /root/.ssh/authorized_keys),检查 .ssh 文件夹权限是否为 700,authorized_keys 文件权限是否为 644,注意这里是设置为 644 而不是 600了,否则一直提示需要密码登录。失败原因和下面第4点情况一致,所以统一在第4点解释。
4、客户机非 root 用户免密登录服务器非 root 用户:
比如客户机 yibin 用户需要免密登录到服务器 yibin 用户,首先在 yibin 用户下生成密钥对,再将公钥复制到服务器 yibin 用户家目录 .ssh 目录下,确保生成文件:~/.ssh/authorized_keys(即 /home/yibin/.ssh/authorized_keys),保证目录 .ssh 权限为 700,authorized_keys 文件权限为 644,一开始我设置成权限为 600,结果就踩坑了,一直没缓过神来,无意间发现文件所属还是 root,然后设置权限是 600 的话,意思是只有 root 有读写权限,组和其它用户都无权限,导致无法免密登录。
解决方法之一:我直接将文件所属改为 yibin 了,比较暴力,虽然 yibin 可以免密登录 yibin 了,但是其它非 yibin 用户估计就无法免密登录服务器的 yibin 用户了,所以还是参考解决方法二。

解决方法之二:将文件权限设置为 644,即 root 拥有读写权限,组和其它用户都是 4 权限即 r 权限(读权限),所以客户机 yibin 用户也能免密登录服务器的 yibin 用户,这个解决方案比较合理。见下图:
至此,客户端(非)root 用户免密登录服务器(非)root 用户的场景就基本讲完了。假如报错如下图,可以查看服务器端是否正确放置 authorized_keys 文件(内容为客户机对应用户的公钥文件),并确认权限是否设置正确,再检查 /etc/ssh/sshd_config 配置文件参数如 PermitRootLogin(假如允许 root 登录就开启,否则最好关闭),PubkeyAuthentication 是否设置为 yes(免密登录需要设置为 yes,否则设置为 no)等。
/etc/ssh/sshd_config 配置文件参数
最后假如需要使用别名连接远程服务器,可以在客户端的 ssh_config(/etc/ssh/ssh_config)进行配置。vim /etc/ssh/ssh_config #新增如下内容 Host yibin HostName 192.168.43.83 Port 22 USER yibin IdentityFile ~/.ssh/id_rsa #这个默认的,不加也行 #保存退出就可以使用下面命令连接了 ssh yibin
总结:
1、最好生成密钥对类型为 rsa 的,dsa 我这边测试没成功,一开始就踩坑了。
2、.ssh 文件夹权限设置为 700,authorized_keys 文件权限设置为 644 比较稳妥,除非你客户机都是由 root 用户发起连接就可以设置为 600,否则就像我一样踩坑了!
3、实时查看 sshd 连接日志文件:tail -f /var/log/secure。
- 从客户端来看,SSH 提供两种级别的登录安全验证。
本文详细介绍了SSH的原理和安全验证方式,包括基于口令和密钥的安全验证,并在Win10环境下通过Ubuntu子系统和CentOS虚拟机演示了SSH的免密登录过程。在实践过程中,作者遇到了因DSA密钥对不被支持导致的登录问题,最终通过RSA密钥对和调整权限设置成功实现不同用户间的免密登录。总结中强调了密钥类型选择、目录权限设置和日志查看的重要性。
1626

被折叠的 条评论
为什么被折叠?



