引子:linux
第一次接触到SSH,也是第一次接触到Linux(Unix Like)系统,时间上说不上来了,SSH算得上是Linux系统的的一个标准配置,对SSH的印象,它就是一种远程链接的工具,有了它就能安全的与远程主机进行链接。算法
(一)、什么是SSH shell
SSH的全称是Secure Shell,简单说来ssh是一种安全的外壳协议,用于两个计算机间安全的远程登录,说它安全,是由于ssh采用公钥加密的机制。最开始时用做远程管理的工具是telnet,这个协议工做时在网络上传输的数据全是明文,出于安全性的考虑,此协议的使用率愈来愈少。而ssh的安全性使用它成为一种互联网上远程登录主机的解决方案。在windows系统上经常使用到的有Putty、SecureCRT、XManager中的Xshell工具,而XManager工具是我见到的IT工做者中使用频率极高的一个工具,在windows上好像没有ssh协议的服务器端的实现,ssh协议的实现也分为商业的实现和开源的实现,在这里将是对ssh协议的一个开源实现的学习与记录。Openssh便是Linux系统下开源的实现,它开放且免费。数据库
(二)、ssh工做原理windows
说ssh是种安全的协议,是由于它采用公钥加密。用主机A链接主机B来讲明这个过程: 安全
一、主机A向主机B发起登录请求; bash
二、主机B向主机A发送公钥文件; 服务器
三、主机A把登录密码用接收到的公钥加密后发送给主机B; 网络
四、主机B用本身的私钥解密加密信息,获得登录密码; dom
五、主机B验证密码的正确性,正确则让其登录,不然则断开。
(三)、中间人***(Man-in-the-middleattack)
基于公钥加密这种验证方式看起比较完美,登录密码的传输都是通过公钥加密处理,即便被恶意劫持,只要私钥文件没有被泄露,那也不能解密加密信息,密码的保密性获得保障。但这种看似完美的工做方式也有其致命的弱点,若是主机B是***假装的,他接收到主机A的登录主机B的登录请求,用本身的公钥发送给主机A,而主机A很难辨别主机B的真伪,***就能够采起这种方式得到主机B正确的登录密码,这就是有名的中间人***(Man-in-the-middleattack)。
要想应对中间人的***,则需避免登录时输入用户口令的操做,ssh中的认证方式有两种,一种是基于口令的方式,另外一种是基于公钥的认证方式,后者就能在用户不输入口令的状况下登录主机。
(四)、配置文件
系统环境:
[root@bogon~]# cat /etc/redhat-release CentOSrelease 6.4 (Final) [root@bogon~]# uname -m x86_64
先看一下系统中安装openssh所用的安装包:
[root@bogon~]# rpm -qa *ssh* openssh-5.3p1-84.1.el6.x86_64 openssh-clients-5.3p1-84.1.el6.x86_64 libssh2-1.4.2-1.el6.x86_64 openssh-server-5.3p1-84.1.el6.x86_64
能够用“rpm -ql 安装包名称”命令来查看各个安装名生成的目录结构,以下:
[root@bogon~]# rpm -ql openssh-clients
对于openssh,咱们须要关注的配置文件分为两类,一类是公共配置文件,另外一类是私有配置文件。公共配置文件又分为服务端的配件文件和客户端的配置文件。
/etc/ssh/sshd_config #服务端配置文件
/etc/ssh/ssd_config #客户端配置文件
~/.ssh/* #私有配置文件
咱们主要关注的是服务端的配置文件和私有配置文件。
(五)、认证方式
ssh支持两种认证方式,一种是基于用户名与口令的认证,另外一种是基于密钥的认证。
5.1基于用户名与口令认证:
客户端经过输入用户名与用户登录密码的方式完成远程登录,虽然说是要求输入用户名及密码来验证,但ssh也会涉及到公钥的发送,即远程主机收到用户远程登录请求时会把本身的公钥发送给用户端。 在windows下以ssh的方式登录linux主机时,以xmanager为例,当用xmanager中的xshell第一次登录linux主机时会有如下的提示:
大体意思就是用户包要链接的主机在用户本地的存储key的数据库中没有存储,主机是不可信任的,而且给出了远程主机公钥的摘要信息,是否要断续的链接此主机?那怎样来验证我所要链接的主机(192.168.0.201)是真实的,不是一个假装的主机,避免中间人***。当点击“Accept&Save”,那xshell会把远程主机的公钥信息保存下来,在这里能够查看到:
应对中间人***,SSH有2种方法应对,一是远程主机把本身的公钥拿到CA处作认证,申请一个数字证书;二是远程主机把本身公钥的指纹信息公布出来,好比公布在网站上,你们均可查看到公钥的指纹信息。这样用户在登录时就能够鉴别主机的真伪了。提取主机的指纹信息的方法以下:
[root@Server-A ~]# ssh-keygen -lf/etc/ssh/ssh_host_dsa_key.pub 102439:61:e5:80:e8:09:b3:83:10:39:c8:b4:5e:ca:45:7e /etc/ssh/ssh_host_dsa_key.pub(DSA)
远程主机能够把这个采用dsa算法的指纹信息发布在一个网站上,那我用xshell去远程链接时就可对比一下指纹信息是否是同样,若是是同样的那就能证实我链接的是真实的主机。
在linux下用ssh方式登录另外一linux主机时,若是第一次登录会有以下的提示:
[root@Server-A~]# ssh 192.168.0.201 Theauthenticity of host '192.168.0.201 (192.168.0.201)' can't be established. RSAkey fingerprint is 4c:a3:2f:29:69:86:f6:0f:38:25:8c:7c:7c:3b:d5:91. Areyou sure you want to continue connecting (yes/no)?
表示的意义与用xshell登录时的提示相同,输入“yes”,再输入远程主机的口令便可登录,登录成功后本地主机会生成“~/.ssh/known_hosts”文件,这文件里保存着远程主机的公钥信息,这样下次再远程登录时就不须要发送公钥信息了,直接输入口令便可。
5.2 基于公钥的认证:
基于用户口令的认证方式每次都要求用户提供正确的口令,比较麻烦,且增长了口令泄露的机率。而基于公钥的认证则不须要用户输入口令便可完成远程登录。这种认证方式是这样工做的:用户把本身的公钥存储在远程主机上,在登录时,远程主机向用户发送一段随机字符串,用户用本身的私钥加密这段随机数字,并把加密后的信息发送给远程主机,远程主机用事先存储的公钥来解密这个数据,若是解密成功,则说明请求登录的用户是可信任的,这样就直接容许用户登录,而不要求输入密码了。这种认证方式须要把用户本身的公钥保存到远程主机上。若没有现成的公钥,那就生成:
[root@Server-A~]# ssh-keygen -t rsa Generatingpublic/private rsa key pair. Enterfile in which to save the key (/root/.ssh/id_rsa): Enterpassphrase (empty for no passphrase): Entersame passphrase again: Youridentification has been saved in /root/.ssh/id_rsa. Yourpublic key has been saved in /root/.ssh/id_rsa.pub. Thekey fingerprint is: 9b:ef:2c:6a:92:05:c7:f4:4b:b8:4e:b4:ce:05:2f:0croot@Server-A Thekey's randomart p_w_picpath is: +--[RSA 2048]----+ | | | . | | o o | | E * o | | * *S. | | B +o | | B oo | | o = .o | | o.. o+ | +-----------------+ [root@Server-A~]# ls .ssh/ id_rsa id_rsa.pub known_hosts
此时在家目录下的“./ssh”目录下生成了两个文件,一个id_rsa(私钥文件),id_rsa.pub(公钥文件)。接着把公钥文件拷贝到远程主机:
[root@Server-A ~]# scp .ssh/id_rsa.pub 192.168.0.201:/root/.ssh/authorized_keys
这里的“authorized_keys”这个文件名不能更改,这是由“/etc/ssh/sshd_config”文件定义的。
测试一下可否不输入密码就能远程登录Server_B主机:
[root@Server-A ~]# ssh 192.168.0.201 Address 192.168.0.201 maps to bogon, butthis does not map back to the address - POSSIBLE BREAK-IN ATTEMPT! [root@Server-B ~]#
没错,成功了,但有报告信息,这是由于在/etc/hosts文件里没有增长两主机的映射关系,增长就能够了,在两主机中的“/etc/hosts”文件中都增长如下两行:
[root@Server-A ~]# echo"192.168.0.200 Server-A">> /etc/hosts [root@Server-A ~]# echo "192.168.0.201 Server-B" >> /etc/hosts
上边用“scp”命令直接把主机的公钥文件拷贝到远程主机用户家目录下的“root/.ssh/authorized_keys”,其实还有一个更好的方法,ssh为咱们提供了一个客户端工具,即“ssh-copy-id”,这个工具能将本地主机的公钥自动拷贝到远程主机上生成“authorized_keys”文件,且会让这个文件的权限为“600”这样更为安全,此命令的用法以下:
[root@Server-A ~]# ssh-copy-id root@192.168.0.201
建议用这个命令来实现无密码公钥登录,由于用“scp”命令把公钥拷贝到远程主机后,不会把authorized_keys文件的权限修改为“600”,在某些linux版本下是没法实现基于公钥登录的。
用xshell这个神器也可实现基于公钥的认证,方法与在linux上相似,只是链接主机成了windows下的了,方法以下:
一、打开密钥生成向导工具
二、选择密钥的类型与加密长度
三、直接下一步
四、下一步
五、导出公钥信息
六、完成
这样就生成了一个“id_rsa_1024.pub”公钥文件,把这个公钥文件上传到远程主机,并把公钥信息追加到“~/.ssh/authorized_keys”。
最后配置xshell使用密钥方式登录服务器:
一、打开Xshell,点击“New”按钮,弹出“NewSession Properties”对话框,在“Connection”栏目中,填写好相关信息,以下图:
二、在“Authentication”中填写认证方式和私钥,以下图:
这样设置好后,也能够基于密钥登录远程主机了。