实验环境:RHEL5.8 32Bit

SSH详解

·telnet

    telnet是一种远程登录机制,一般来讲是需要一个服务器端的,因为它是一个C/S架构的应用,需要一个服务器端,也就是S(Server)端来运行telnet服务器,还需要一个客户端也就是C(Client)端,在客户端只需要一个远程拨号的工具或者是一个远程连接的工具就可以连接至服务器端,所以被称为telnet客户端,故我们将这种模式的应用称为C/S架构的应用,早期的远程登录都是使用telnet服务来实现的,但是telnet有一个巨大的缺陷,无论是telnet的命令还是telnet的认证过程都是明文发送,这样会很不安全,因此后面就出现了ssh,telnet只是一种远程登录的协议,在这种协议的支撑下,我们需要有服务器端和客户端,所以我们得需要一个服务器端的程序和客户端程序,telnet协议是一种应用层协议,基于TCP协议进行工作,telnet协议默认工作在TCP协议的23号端口上。

·ssh(secure shell)

    ssh也是一种远程登录的协议,ssh协议也一样是一种应用层的协议,由于是远程登录,因此为了可靠以及在线连接等情况,ssh协议也是基于TCP协议工作的,ssh默认是工作在TCP协议的22号端口上,ssh的整个通信过程和认证过程都是加密的,ssh还可以实现主机认证。

    ->ssh的主机认证

     所谓主机认证就是,当客户端使用ssh去连接服务端的时候,服务端要向客户端发送一个主机密钥过来,我们的客户端有另外一半的密钥,这种加密方式我们称为非对称加密,也就是所谓的公钥加密,私钥解密,服务器端持有私钥(Secret key),而客户端持有公钥(Public key)。

    ->ssh的通信机制

     首先服务端发送公钥到客户端,必须得保证客户端持有服务端的公钥,无论是通过什么途径,客户端必须得获得服务端的公钥,我们一般使用ssh第一次去连接一个陌生主机的时候,系统会提示我们是否接受对方主机所发送过来的公有密钥,就是这个意思:

      wKioL1hD8ZGjhujxAAAZQWkyJqM421.png

    我们输入了yes就表示接受对方主机发送过来的公有密钥,我们的本地主机会将接收下来的公有密钥保存在我们的本地主机上,这样当我们再次使用ssh去连接这台主机的时候,只要我们的本地主机上有对方主机的公有密钥,就不会再出现上图中的提示了,接下来通信双方就会利用公有密钥和私有密钥完成主机认证并建立通信了,但是非对称加密的速度是非常慢的,比对称加密(对称加密指的是加密和解密用的是同一个密码)要慢好几个数量级,所以一般我们不会使用非对称加密的方法去加密数据的,通信双方为了能够正常的通信,一般会使用对称加密的方法来加密数据,当客户端接收到服务端发送过来的公有密钥的时候,会试图在本地生成一个对称密码,并使用服务端的公钥来加密这段密码,再将这个使用服务端公钥加密的密码发送给服务端,这个过程叫做密钥交换,这个时候客户端和服务端都有了对称密码,接下来的数据的加密就是用该对称密码来加密,所有我们在使用ssh连接远程主机的时候,会首先输入自己的登录账号,这个账号会在本地使用之前使用的对称密码进行加密,再发送至服务端,服务端再使用对称密码进行解密,服务端解密之后,发现该账号在自己的主机上是存在的,于是要求客户端的用户输入该账号所对应的密码,密码也是一个字符串,客户端会将用户输入的这个密码也使用之前生成的对称密码进行加密,加密之后将加密过的密码发送给服务端,服务端再次使用对称密码进行解密,接着服务端会检验该密码是否对应该账号,如果二者对应,那么认证就会通过,通信就会建立,这就是ssh的主机认证的全过程,客户端用户输入的密码是用来登录对方主机的账号的密码,而客户端生成的对称秘钥是用来使得通信双方建立安全连接的密钥,这个密钥不需要用户输入,由双方主机自行维护,密钥也有使用期限,也是由两个主机自行维护的,所以ssh要比telnet安全的多了。

    ->ssh的安全性

     1,主机要认证

     2,用户要认证

       用户的认证过程需要加密

     3,数据的传输过程需要加密


    ssh是一种协议,这个协议有两个版本:

    1,ssh v1

      这个版本的ssh协议已经不安全了,已经是能够被破解的了,尤其是无法避免中间人(man-in-middle)***。

      ->中间人***(man-in-middle)

       在我们的客户端使用ssh第一次和我们的服务端进行连接的时候,在二者之间有一个主机恶意的冒充我们的服务端,在我们的客户端向我们的服务端发起连接请求的时候,服务端会验证客户端的身份,这个中间主机会将客户端发往服务端的验证信息截获,然后冒充客户端的身份去连接服务端,之后在服务端将返回的信息发出的时候,该主机又会冒充客户端截获这份消息,然后再冒充服务端将这份消息发给客户端,这个时候客户端会认为这个中间主机就是服务端,而服务端也会认为这个中间主机就是客户端,而这个中间主机同时截获了客户端和服务端的所有通信数据,这个中间主机就称为中间人,而这种***方式就称为中间人***。

    2,ssh v2

      由于v1版本的ssh存在中间人***的漏洞,故我们一般在服务器上都会去使用v2版本的ssh。


    ->ssh的用户认证过程

    用户如果想要远程登录到服务器上,必须要通过服务端的认证,但是在认证的过程当中虽然说服务器主机的密码是通过客户端生成的对称密钥加密的,但是密码总是会在网络中传送,这样总是不安全的,我们可以使用一种方法使得我们的密码不用在网络中传送,我们可以通过在客户端生成一对密钥的方法来实现,之前生成的那份密钥是用来进行主机认证的,现在生成的这份密钥是用来进行用户认证的,假设我们要使用root的用户身份去登录远程主机,首先我们会输入用户名,之后这个用户名会被发送至服务端,之后客户端会生成一对密钥,公有密钥和私有密钥,公钥发送到远程服务端,私钥保存在客户端,发送过去的公钥会保存在服务端的家目录的一个文件里面,之后再次连接的时候,我们将账号发送至远程服务端,接着在客户端使用私钥加密一段数据,服务端先使用主机认证时的对称密钥进行解密,解密后发现发送过来的是一个加密的数据,然后再使用之前保存在服务端下的密钥去进行解密,这时候我们没有发送服务端主机的密码,而发送的是服务端的用户名和一段加了密的临时数据,客户端使用自己的私有密钥进行加密这段数据,再使用主机认证过程中生成的对称密钥对这段加密的数据再进行加密,再把这个整体一起发送给服务端,然后服务端先解密出这段加了密的数据,然后使用保存在自己家目录下的公有密钥进行解密,可以解密说明用户的身份得到了认证,这就是ssh实现安全的机制。

    ->ssh支持两种认证机制

     1,基于口令的认证

       输入账号密码进行认证

     2,基于密钥的认证

       不需要输入密码,由客户端先随机生成一段数据,然后使用自己的私钥进行加密,然后让对方来认证即可,公有密钥已经提前保存至对方的主机上了,只要对方主机能够解密这段加密的数据,说明可以完成用户认证。

·openssh

    ssh协议是公开的,但是它有很多的实现,协议本身无法工作,我们要有服务端和客户端软件,它才可以正常工作起来,服务端和客户端彼此间通过这中协议来建立通信,协议只是一种规范,实现就指的是我们由所谓的服务端和客户端两端使用这种规范来建立会话,而在我们的Linux系统上,常用的实现软件叫做openssh(开源的ssh软件),openssh是一种C/S架构的软件,服务端程序叫做sshd,在红帽系列的操作系统上sshd的配置文件在/etc/ssh/下叫做sshd_config:

    wKioL1hECzHDGy_YAAAJeYVpSRU702.png

    客户端程序有好几种:

    ->ssh:在红帽系列操作系统上ssh的配置文件在/etc/ssh/下叫做ssh_config:

        wKiom1hEC6zQwiJbAAAJepSBIXg297.png

    ->ssh-keygen(key generation):顾名思义,密钥生成器,基于密钥认证的时候我们就得生成一段密钥,这就是为某个用户生成一对密钥而使用的,用于生成一对密钥,而且我们还可以使用ssh-copyid将公钥传送至远程主机,来实现基于密钥的ssh用户认证。

    ->ssh-copy-id:这个命令专门用于将基于密钥认证的时候将客户端生成的公有密钥传送至服务端主机上的,并且可以将公钥保存在服务端主机家目录的特定文件里面。

    ->scp:跨主机的安全复制工具,scp可以在两台主机之间复制数据,而且复制的过程是加密的。

·openssh的客户端程序的使用

    1,ssh命令

    如果要想远程登录服务器,只需要使用ssh命令即可。

    用法:ssh 服务端主机的IP地址,如果我们使用客户端进行远程登录的时候,没有指定登录的用户的话,那么ssh会默认按照客户端当前的用户身份去登录服务器的主机:

    wKioL1hEDjvgRmJOAAAOzpFL614630.png

    ->指定用户的命令用法:

      1,ssh USERNAME@HOST

      wKiom1hEDq-iYFw3AAAP8jRmXhg847.png

      服务端发送到客户端的用来进行主机认证的公有密钥称为主机密钥,主机密钥会被放在一个公共的目录中,第一次主机认证通过之后,就不需要再进行主机认证了,这个主机密钥在客户端的家目录下,有一个隐藏目录.ssh,每一次我们接受到一个密钥之后都会保存在这个目录中的一个叫做known_hosts的文件中:

      wKioL1hEEBrSRtUEAABK56xvd8M228.png

    以后我们再次连接服务端主机的时候就不需要再让服务端主机发送密钥了,我们就可以通过客户端主机保存的密钥来和服务端主机建立口令联系了。

      2,ssh -l USERNAME HOST

        wKioL1hEEI_CyEgCAAAP0I3HpOI374.png

    我们也可以不用登录到远程主机上面而执行远程主机上的命令,我们不用远程登录服务端主机,而是以对应的用户的身份,在远程主机上执行对应的命令,再退出,而且是在客户端显示命令的执行结果,命令的发送和返回结果都是加密的,而且不用登录对方主机,命令用法:

    ssh USERNAME@HOST 'COMMAND'

    wKiom1hEEdHzgzNjAAAdnHcP8hI904.png

    2,scp命令

     用法:scp SRC DEST,和cp命令的用法一致

        -r选项表示递归复制,也可以使用-a选项

     scp命令的具体使用格式:

      ->从远程主机到本地

       scp USERNAME@HOST:/path/to/somefile /path/to/local

       wKiom1hEE3bBeshzAAAgNWo8dFA422.png

      ->从本地到远程主机

       scp /path/to/local USERNAME@HOST:/path/to/somefile

       wKiom1hEFCTTrn6rAAATZdEdPGM868.png

    这些过程都是加密的。

    3,ssh-keygen命令:

       该命令可以帮助我们在客户端生成密钥,使得我们不用输入密码就可以登录远程主机,而是使用密钥去登录远程主机,这样基于密钥认证之后,只要密钥存在,就可以直接密钥来认证,因此我们就得使用该命令在客户端生成一对密钥,命令用法:

      ssh-keygen -t(指定密钥的加密方法,有两种加密方法,rsa和dsa,一般都用rsa) rsa

      wKiom1hEFcPBcEndAAAuXTlffS0459.png

      生成密钥之后,密钥会保存至当前用户的家目录下的隐藏目录.ssh目录中,私钥保存在id_rsa文件中,公钥保存在id_rsa.pub文件中,这是一对密钥,是一起生成的:

      wKiom1hEFovis0KsAAAJdKG4eu0319.png

      -f选项,用于指定密钥的文件名:

      wKioL1hEGiri_B1wAAAt_fI39Rg500.png

      -P选项,指定用于加密私钥的密码:

       wKioL1hEGC-ASUzeAAAvUnkdhpY925.png

    3,ssh-copy-id命令:

      该命令专门用于将客户端生成的公有密钥复制到远程主机中去,并且自动追加保存至远程主机家目录下的隐藏目录.ssh目录中的authorized_keys文件当中,.ssh目录不存在该命令也会使得它自动创建,命令用法:

      -i选项,用于指定公有key的路径:

      ssh-copy-id -i /path/to/publickey USERNAME@HOST

      wKioL1hEG03yLYedAAAxTga3rQY343.png

      之后我们再使用ssh命令连接服务端主机,就不需要再输入密码了,这就是基于密钥的ssh的认证。

    基于密钥的认证是本地用户使用私有密钥,而远程用户使用公有密钥,这个过程是单向的,所以只可以是客户端远程登录服务端不需要输入密码,而服务端远程登录客户端还是需要输入密码的。