OpenSSH

  早期主机使用远程登录的协议telnetTCP/23(telnet是基于TCP的23号端口的)

  telnet有两大缺陷:

    1、用户认证过程是明文的;

    2、数据传输是明文的;

  因此telnet不再使用了。于是就出现了ssh

  1、ssh

  ssh(Secure SHell,安全的shell),与telnet一样,也是一种远程登录协议,但其与telnet的实现机制不同,ssh为TCP/22(基于TCP协议的22号端口)。

  与telnet一样,ssh是基于C/S架构的。在服务器端,需要运行服务器软件,监听在某个端口(套接字上)。客户端发起连接请求,服务器端在收到请求后响应客户端请求,双发建立数据传输的通道,并一直处于连接状态,当所有用户请求处理完成之后再退出。因此需要专门的客户端软件和服务器端软件。

  ssh在刚刚诞生时,出现了一款软件,但后来商业化了。于是就出现了基于ssh运行在Linux/Unix上的开源软件OpenSSH(Open:开源的意思)。

  ssh主要有v1,v2两个版本,通过验证发现,v1版本存在致命的缺陷,无法有效的拒绝中间人攻击,这个缺陷非常致命,到目前为止,v1处于废弃状态;最好是使用v2,但由于许多古老的设备上还在使用v1,因此不得不使得客户端能够访问v1的服务。(新购的设备尽量拒绝v1版本的协议)而OpenSSH对两种版本的协议都提供了支持。

  1.1、ssh服务器端

  SSH无法实现Windows上的服务器端,故此处的服务器端指的是工作在Unix/Linux的服务器端。名称为sshd(OpenSSH提供的)。

  服务器端也是一个可执行程序,只不过这个可执行程序直接工作在后台。而且不会退出,一旦退出服务即终止。

1.2、OpenSSH包含的两个组件

  ssh(客户端工具,命令行的)、sshd(服务器端工具)  

  2、SSH认证的实现和实现加密数据传输的简要概述

  sshd:主机密钥

  ssh服务器端需要一个主机密钥(第一次向服务器发送一个请求时,对方总是需要我们确认一个东西(对方发来一个东西,询问是否接受),这个信息就是主机密钥)。

  那么那么为什么需要主机密钥呢?若通信的双方此前从来没有通信过,那么如何建立安全通信呢?此前我们讨论过,需要借助于CA证书,但SSH客户端和服务器端都未必有证书。因此没有办法验证对方身份的可靠性,在此前提下,服务器端会向客户端发送一个主机公钥,我们的客户端就会接收对方主机公钥的指纹信息,接下来客户端会被询问是否认可这个指纹,此时就需要客户端(用户)自己确认这个服务器是否是你认可的服务器(因为没有任何有效的措施能够确认对方身份,只能凭借用户自己的判断)。因此client回答yes就表示就此接受了对方主机公钥,这个公钥是主机上一对密钥的公钥信息。

  具体过程如下所示:

openssh关闭3des 关闭openssh服务_运维

  客户端通过远程连接进行身份认证时,需要将账号密码加密后传输至服务器端,在传输过程中,账号密码存在被窃取的风险。因此SSH还支持另外一种认证方式。SSH认证方式分为以下两种:

  •   基于口令的认证:默认情况下都是基于口令的认证;
  •   基于密钥的认证:客户端用户自身也生成一对密钥,它把公钥放在服务器上的某个家目录下(这个公钥信息必须严格保密,不能让任何第三方知道),私钥自己保留。以后远程登录这台服务器时,不再要求输入密码,而是传输数据时用对方的公钥加密数据,若对方能用私钥将数据解密即配对成功,此时不再需要口令。但基于密钥的认证需要事先配置

 3、注意(基本安全技巧)

  1. 基于口令的认证存在风险,在认证时输入用户名root和密码之后,有可能被第三方暴力将密码破解,因此,一般不允许使用root用户直接在基于ssh的客户端登录,若一定要使用root用户,只能通过登录普通用户后再su过去的方式实现。口令认证时位于互联网上的服务器最后一道也是唯一一道防线;
  2. 并且为了安全起见,也需要对普通用户登录的主机进行限制,若一定要在不被信任的主机上远程登录,则需要通过一台VPN服务器,先连接到VPN服务器上,再由VPN服务器转连;
  3. 更重要的是,最好不要使用22号端口进行远程登录,因为22号端口默认为远程登录端口,易被监控暴力破解;可以换一个端口使得别人无从揣测;
  4. 远程登录与系统安全性密切相关,怎么强调其安全性都不为过;
  5. 经常换密码(一般一个月换一次,最好密码是随机的并且足够长)

  4、OpenSSH配置详解

  在RedHat系列的系统上,ssh是由多个rpm包组成的rpm服务。这多个rpm包有的是提供客户端的,有的是提供服务器端的,有的是提供通用组件的。如下所示:

  

openssh关闭3des 关闭openssh服务_运维_02

  上图中:

    openssh-server-...:服务器端

    openssh-clients-...:客户端

    openssh-5.3p2-...:通用组件库

    openssh-askpass-...:建立会话时用到的工具和库文件

4.1、获取服务的运行状态:(如果当前有22号端口表明,ssh服务处于已经启动并工作的状态)

    netstat -tnl(-t表示当前主机上根TCP建立连接的所有会话,-n表示以数字的方式显示IP地址和端口,-l表示显示处于监听状态(客户端已经启动并等待与客户端连接的状态)的服务)

    netstat

      -r:显示路由表

      -n:

      -t:TCP connection

      -u:UDP connection

      -l:listening

      -p:process,哪一个进程或程序监听了当前这个服务

       

openssh关闭3des 关闭openssh服务_嵌入式_03

      

openssh关闭3des 关闭openssh服务_运维_04

     获取sshd服务运行状态的另外一种方法:

    

openssh关闭3des 关闭openssh服务_客户端_05

  4.2、配置文件详解

  ssh客户端和ssh服务器端都需要配置文件:

    /etc/ssh目录下:

    

openssh关闭3des 关闭openssh服务_网络_06

    客户端ssh配置文件:/etc/ssh/ssh_config

    服务器端sshd配置文件:/etc/ssh/sshd_config

    moduli:ssh中用到的密钥交换的相关信息

    v1版本主机密钥对:ssh_host_key,ssh_host_key.pub

    v2版本主机密钥对

      DSA算法:ssh_host_dsa_key,ssh_host_dsa_key.pub

      RSA算法:ssh_host_rsa_key,ssh_host_rsa_key.pub

    主机密钥是ssh会话建立的根本前提,至关重要。

    此处也反映了Linux的哲学思想之一:使用文本文件保存程序的配置信息。

 

    sshd_config配置文件解释:

      man sshd_config  #获取帮助文档信息

      sshd服务的任何改变配置要想其生效需重启服务(脚本服务在/etc/init.d/sshd



service sshd {start|stop|restart|reload|force-reload|condrestart|try-restart|status}



openssh关闭3des 关闭openssh服务_网络_07

      #后带空格表示注释,#后不带空格表示可用选项;

      Port:指定服务的端口号;

      Protocol:启用的协议版本(默认优先使用v2版本);

      AddressFamily:表示若当前主机同时启用了IPv4和IPv6的地址,那么打算在哪一类地址上启用ssh服务,any表示IPV4,IPV6都可以;

      ListenAddress:表示监听在哪一个地址上(若当前主机配置了两个个IP地址,只需要其中一个提供服务,需要手动指定,若不指定,默认两个都提供服务。0.0.0.0表示任意地址,当前主机配置了哪个地址,哪个地址就能提供服务,配置了多个地址就在每一个地址上提供服务,否则手动指定);

      HostKey:指定密钥;

      KeyRegenerationInterval:客户端临时密钥生成的间隔时间,间隔指定时间后重新生成密钥;

      ServerKeyBits:服务器端密钥长度;

      SyslogFacility:指定哪一个facility记录日志;

      LogLevel:日志级别;

openssh关闭3des 关闭openssh服务_网络_08

      LoginGraceTime:登录时的宽容时间(登录时等待登录的时间,不登录则强行退出);

      LoginGraceTime:是否允许管理员直接登录;

      StrictModes:是否使用严格限定模式(不重要);

      MaxAuthTries:最大登录次数;

      RSAAuthentication:是否支持RSA密钥认证(基于RSA机制的密钥认证);

      PubKeyAuthentication:基于密钥的认证(如果启用,客户端会生成一对密钥,公钥会放在服务器端的某个家目录下);

      AuthroizedKeysFile:指定客户端公钥文件存放的家目录的文件路径;

      RhostRSAAuthentication:主机认证(指的是是否信任对方主机,接下来就不需要登录了而是直接使用,不安全);

      PasswordAuthentication:是否允许基于口令的认证;

      ChallengeResponseAuthentication:是否使用挑战式握手协议认证(不安全,一般不允许使用);

openssh关闭3des 关闭openssh服务_网络_09

      UsePAM:是否使用UsePAM(这是一种可插入式认证模块,一般都是启用的);

      X11Forwarding:是否转发X11请求;

      PrintMotd:在用户登录是是否打印/etc/motd文件的内容;

      PrintLastLog:在登录时是否显示哪个主机在什么时候登录过(不推荐显示,会为不法用户提供信息,在互联网上,这种信息越少出现越好,最好软件版本号都不应该提供);

            

openssh关闭3des 关闭openssh服务_客户端_10

      Banner:欢迎标语(用户登录SSH时会将指定文件的内容当做欢迎标语为用户打印一次,启用后建立一个文件,文件路径在此处指定,登录后会显示文件中的信息);

      Subsystem:(将ftp基于SSH实现叫做sftp,将ftp基于SSL实现叫做ftps)指定sftp的服务器程序,只要指定的程序存在即可默认启动。

    ssh客户端工具的使用:      



ssh [-1246AaCfgKkMNnqsTtVvXxYy] [-b bind_address] [-c cipher_spec] [-D  [bind_address:]port] [-e escape_char] [-F configfile] [-I pkcs11] [-i identity_file] [-L
             [bind_address:]port:host:hostport] [-l login_name] [-m mac_spec] [-O ctl_cmd] [-o option] [-p port] [-R  [bind_address:]port:host:hostport] [-S ctl_path]
             [-W host:port] [-w local_tun[:remote_tun]] [user@]hostname [command]



    常用命令组合:



    ssh -l USERNAME REMOTE_HOST ['COMMAND']



ssh USERNAEM@REMOTE_HOST ['COMMAND']



    -p port:指定端口

    -X:登录到远程主机上,并且能够执行远程主机的窗口命令,因为这些窗口要在本地显示,因此,本地必须是图形化的

    -Y:功能与-X一样,单比-X更安全

  

  在第一次远程登录接受了密钥之后,系统会认为这是可信任的主机,因此它会将主机的密钥信息添加到可信任主机列表中。每个用户只要登录过远程主机,在当前用户的家目录下会生成一个.ssh文件夹,文件夹中有一个knows_host文件,任何时候接受了主机,哪个主机的公钥信息就会保存在这个文件中。因此当第二次进行远程登录时,会将文件中的公钥与远程主机的私钥一建立会话测试是否能匹配上,若配对成功,表示认可了对方主机,因此就不需要进行密钥接受了。(此过程信任是单向的

  SSH支持不登录远程主机但却可以在远程主机上执行命令,并将命令的执行结果返回到本地。只需在命令的最后加上可执行命令即可。

 

 5、基于密钥的认证的实现:

    需要一台主机作为客户端(前提是基于某个用户实现):

  (1).生成一对密钥

    ssh-keygen

      -t [指定加密算法rsa或dsa](生成的密钥默认保存在用户家目录下面的.ssh/id_rsa和.ssh/id_rsa.pub)

      -f /path/to/keyfile:指定生成的私钥文件目录

      -N 'password':指定密码为password

openssh关闭3des 关闭openssh服务_运维_11

openssh关闭3des 关闭openssh服务_嵌入式_12

      注:.ssh的权限为700,若大于700,.ssh将无法使用。

  (2).将生成的公钥传输至服务器端某用户及目录的.ssh/authrorized_keys文件中(可与当前用户不一致

    方法一:使用文件传输工具实现,专用命令:ssh-copy-id

      ssh-copy-id -i /path/to/pubkey(公钥文件位置) USERNAME@ROMATE_HOST(既复制又能追加到文件尾部)

    方法二:ssh另外一个重要的客户端工具scp(基于ssh的远程复制命令,能够在主机之间传输数据(因为是基于ssh传输,因此传输与过程是加密的))

      scp [opetions] SRC DEST

        -r:递归复制目录

        -p:保存权限

        -a:相当于-rp

      SRC或DEST为REMOTE_MACHINE(远程主机)时的格式:

        USERNAME@HOSTNAME:/path/to/somefile

      scp的实现是需要先复制到临时文件中,再将临时文件使用cat 文件名 >> 目标文件 追加到文件中

  (3).测试登录即可

  sftp:基于SSH的ftp,既是客户端又是服务器端,数据传输过程是加密的;

    sftp USERNAME@IP  #连接远程主机

    下载文件到本地:get /path/to/somefile

    多个文件使用mget;

总结:

  1.密码应该经常切换且足够复杂;

  2.使用非默认端口;

  3.限制登录的客户端地址;

  4.禁止管理员直接登录;

  5.仅允许有限用户登录;

  6.使用基于密钥的认证;

  7.不要使用版本1;

 

  嵌入式系统专用的ssh软件:dropbear(可安装测试使用)