1.ssh介绍



SSH 是 Secure Shell Protocol 的简写,由 IETF 网络工作小组(Network Working Group )制定;在进行数据传输之前,SSH先对联机数据包通过加密技术进行加密处理,加密后在进行数据传输。确保了传递的数据安全。
SSH是专为远程登录会话和其他网络服务提供的安全性协议。利用 SSH 协议可以有效的防止远程管理过程中的信息泄露问题,在当前的生产环境运维工作中,绝大多数企业普遍采用SSH协议服务来代替传统的不安全的远程联机服务软件,如telnet(23端口,非加密的)等。
默认端口为22,安全协议版本:ssh2,其中centos7.4已经不支持ssh1协议



在默认状态下,SSH服务主要提供两个服务功能:



一是提供类似telnet远程联机服务器的服务,即上面提到的SSH服务。
另一个是类似FTP服务的sftp-server,借助SSH协议来传输数据的.提供更安全的SFTP服务(vsftp,proftp),是加密的协议。
注意:ssh客户端还包含一个scp,sftp远程安全拷贝命令,也是基于ssh协议工作的。



2.ssh结构

基本概念



加密:
  加密的意思是将一段数据经过处理之后,输出为一段外人无法或者很难破译的数据,除了指定的人可以解密之外。 一般来说,加密的输入还会有一个key,这个key作为加密的参数, 而在解密的时候也会用一个相关联(有可能是相同)的key作为输入。

私钥加密:也叫对称加密
  所谓的私钥加密,是说加密方和解密方用的都是同一个key,这个key对于加密方和解密方来说是保密的,第三方是不能知道的。在第三方不知道私钥的情况下,是很难将加密的数据解密的。一般来说是加密方先产生私钥,然后通过一个安全的途径来告知解密方这个私钥。

公钥加密:
  公钥加密,是说解密的一方首先生成一对密钥,一个私钥一个公钥,私钥不会泄漏出去,而公钥则是可以任意的对外发布的。用公钥进行加密的数据,只能用私钥才能解密。加密方首先从解密方获取公钥,然后利用这个公钥进行加密,把数据发送给解密方。解密方利用私钥进行解密。
  如果解密的数据在传输的过程中被第三方截获,也不用担心,因为第三方没有私钥,没有办法进行解密。
  公钥加密的问题还包括获取了公钥之后,加密方如何保证公钥来自于确定的一方,而不是某个冒充的机器。假设公钥不是来自我们信任的机器,那么就算我们用公钥加密也没有用,因为加密之后的数据是发送给了冒充的机器,该机器就可以利用它产生的私钥进行解密了。
  所以公钥加密里面比较重要的一步是身份认证。
需要说明一下,一般的私钥加密都会比公钥加密快,所以大数据量的加密一般都会使用私钥加密,而公钥加密会作为身份验证和交换私钥的一个手段。

数据一致性/完整性:
  数据一致性说得是如何保证一段数据在传输的过程中没有遗漏、破坏或者修改过。一般来说,目前流行的做法是对数据进行hash,得到的hash值和数据一起传输,然后在收到数据的时候也对数据进行hash,将得到的hash值和传输过来的hash值进行比对,如果是不一样的,
  说明数据已经被修改过;如果是一样的,则说明极有可能是完整的。

  目前流行的hash算法有MD5和SHA-1算法。

身份验证:
  身份验证说的是,判断一个人或者机器是不是就是你想要联系的。也就是说如果A想要和B通信,一般来说开始的时候会交换一些数据,A怎么可以判断发送回来的数据就真的是B发送的呢?现实中有很多方法可以假冒一个机器。
  在SSH里面,这主要是通过公钥来完成的。首先客户端会有一个公钥列表,保存的是它信任的机器上面的公钥。在开始SSH连接之后,服务器会发送过来一个公钥,然后客户端就会进行查找,如果这个公钥在这个列表里面,就说明这个机器是真的服务器。
  当然实际的情况会复杂一些。实际上服务器不是真的发送公钥过来,因为这很容易被第三方盗取。
ssh v2协议流程图

  可以看到,里面有几个关键的key:

  1.session key: 这个是用来作为secret key加密用的一个key,同时也作为每个ssh连接的标识ID。
  2.host key: 这个是用来作为server的身份验证用的。
  3.known-hosts: 这个是存在客户端的一个可信server的public key列表。
  4.user key: 这个是用来作为client的身份验证用的。

  当server和client交换了session key之后,所有的数据都会使用这个session来进行私钥加密。

   上面的图是一个很粗略的描述,下面这个图是对SSH2协议的一个详细的描述:

android11 开启ssh服务 安卓ssh服务_shell

上面这幅图大致的说明了SSH2协议的全景。首先SSH2协议分为3个子协议,分别是SSH-TRANS(传输层协议), SSH-AUTH(用户认证)和SSH-CONN(链接协议)。其中SSH-TRANS是传输协议,定义了传输的包和加密通道,其他两个协议是建立在这个协议之上的。

SSH-AUTH是SSH里面用于验证客户端身份的协议。我们在用ssh命令输入密码的那一步实际上就是在这个阶段。可以看到的是,虽然传输的是用户名和密码,但是由于这个协议建立在SSH-TRANS之上,所以内容都是加密的,可以放心的传输。

而SSH-CONN是真正的应用协议。在这里可以定义各种不同的协议,其中我们经常使用的scp、sftp还有正常的remote shell都是定义在这里的一种协议实现。这里的各种应用协议都要首先经过SSH-AUTH的验证之后才可以使用。

这个三个协议之间的关系可以用下面这幅图来说明:

android11 开启ssh服务 安卓ssh服务_android11 开启ssh服务_02

其中SSH-TRANS是基本的协议,SSH-AUTH和SSH-CONN都是通过这个协议来实现安全加密的。虽然在时序上,SSH-CONN发生在SSH-AUTH之后,但是SSH-CONN并不依赖于SSH-AUTH。

osi七层模型内的ssh

android11 开启ssh服务 安卓ssh服务_android11 开启ssh服务_03

详解



 



ssh服务有服务端openssh软件和客户端的ssh(linux),xhsell,SecureCRT组成的,默认使用22端口,他有两个不兼容的ssh协议版本,1.x和2.x,其中openssl负责加密。
其中ssh服务端是一个守护进程(demon)他在后台运行并响应来自客户端的链接请求,ssh客户端的进程名为sshd,负责实时监控远程ssh客户端的链接请求,并进行处理,一般包括:公共秘钥认证,密钥交换,对称秘钥加密和非安全链接等等
ssh客户端包含:ssh程序,以及scp(远程拷贝),slogin(远程登录),sftp(安全ftp文件传输)等应用程序

ssh工作机制:
ssh的工作机制大致是本地的ssh客户端先发送一个连接请求到远程的ssh服务端,服务端检查连接的客户端发送的数据包和IP地址,如果确认合法,就会发送密钥给 SSH的客户端,此时,客户端将本地再将密钥和服务器的秘钥整合发回给服务端,自此连接建立。



ssh协议加密方式



ssh实现多机互联采用的加密方式是非对称方式对所要传输的数据进行加密的,其无密码访问过程可通过配置文件完成。非对称加密的方式的具体流程如下: 
(1)client与sever互联,client发送消息给sever,双方都产生一对用于加密和解密的公钥和私钥。 
(2)client将自己的公钥告诉sever,私钥保密;同样sever将自己的公钥告诉client,私钥保密。 
(3)client给sever发送消息的时候,会用sever的公钥加密信息。 
(4)client将消息发送给sever。 
(5)sever收到消息后用自己的私钥解密client的消息,因此只有sever拥有自己的私钥所以其他收到消息的人都无法解密该消息。
目前主要的加密算法为RSA和DSA,其中ssh v1(不安全,服务器在接收到key pair后不验证)只支持rsa 详解

rsa与dsa的区别:
  rsa:数字签名认证,即可以进行加密,也可以进行数字签名认证
  dsa只能用于数字签名从而实现人证



3.ssh服务认证类型

android11 开启ssh服务 安卓ssh服务_shell_04

android11 开启ssh服务 安卓ssh服务_客户端_05

4.ssh配置文件

openssh-clients



[root@nfs01 ~]# rpm -ql openssh-clients
/etc/ssh/ssh_config         ---ssh客户端配置文件
/usr/bin/.ssh.hmac
/usr/bin/scp                  ---远程复制命令
/usr/bin/sftp                 ---远程文件传输服务
/usr/bin/slogin              ---远程登陆命令
/usr/bin/ssh                  ---ssh远程登陆管理主机
/usr/bin/ssh-add
/usr/bin/ssh-agent
/usr/bin/ssh-copy-id        ---ssh服务分发公钥命令
/usr/bin/ssh-keyscan



openssh-server



root@nfs01 ~]# rpm -ql openssh-server
/etc/rc.d/init.d/sshd      #ssh服务启动脚本
/etc/ssh/sshd_config       #ssh服务配置文件
/etc/sysconfig/sshd        #ssh创建密钥有关
/usr/sbin/.sshd.hmac       #ssh加密算法有关文件
/usr/sbin/sshd             #ssh服务进程启动命令



ssh配置文件



cat /etc/ssh/sshd_config #服务端的配置文件,centos7已经不采用ssh v1版本的协议了
cat /etc/ssh/ssh_config #客户端的配置文件

 井号(#)注释的参数信息为默认配置
 井号(#)后面有空格的为描述信息
 井号(#)后面没有空格的为参数信息
 另外:配置文件参数信息修改后,一旦变为注释,即还原为默认配置 

在更改默认的配置之前,应该进行备份
cp /etc/ssh/sshd_config  /etc/ssh/sshd_config.bak
  Port 25113                   #端口
  ListenAddress 10.0.0.41   #监听地址(本地网卡地址),指定本地网卡那个网卡提供服务
  PermitRootLogin no         #是否允许root用户登陆
  #PermitEmptyPasswords no  #禁止空密码登陆
  #UseDNS no                   #不使用DNS
  GSSAPIAuthentication no    #API认证
  # 连接慢的解决
  #AddressFamily any         #指定监听ipv4地址,或是ipv6地址,或者所有都监听
修改ssh端口的方法



5.ssh链接

  5.1 远程连接ssh服务



ssh 192.168.10.232 22      #直接连接过去
ssh 192.168.10.232 ifconfig    #不连过去,执行命令



  5.2 ssh附带的scp命令



发送:
scp  -P22 -rp /tmp/test.log root@192.168.10.232:/mnt
          源地址               目标地址
接受:
scp  -P22 -rp root@192.168.10.232:/mnt/test.txt /tmp

P:表示端口号
-r:表示拷贝目录
-p:表示在拷贝前保持文件或目录的属性

注意:scp的每一次都是全量拷贝,但是rsync是增量拷贝



  5.3 ssh附带的sftp命令



windows到linux拷贝工具:
1.re,sz
2.winscp
3.SFX
4.sftp:基于ssh协议,加密传输
5.samba,http,ftp,nfs

linux客户端sftp命令
sftp -oPORT=指定端口 root@192.168.102.231
  1.可以使用cd ls mkdir等命令
  2.put /home/test.log 把test.log从客户端上传到远程服务器
  3.get /home/test.log 把test.log从服务器下载到本地家目录



  5.4 ssh登录链接慢



1.如果在链接ssh时比较慢,需要添加一下两个参数
  GSSAPICleanupCredentials no
  UseDns no
2.将主机名和ip的对应关系放到各自服务器的host文件里面
3.使用ssh -v去查看ssh链接的详细信息,分析原因

重新启动sshd



  5.5 ssh优化



1.修改默认端口 链接
2.禁止root远程连接 链接
3.sshd守护进程要开机自启动
4.公钥在服务器端,私钥在客户端
5.参考ssh安全配置



   5.6 ssh内网批量免秘钥登录



要求:在禁止root远程登录的情况下,利用系统用户p0st实现a机器到b,c机器的分发数据,在分发数据过程中,不需要提示密码验证,除了分发,还可以批量查看客户机上的cpu,load,men等信息
1.添加系统账户p0st
  useradd p0st
  echo "123456" |passwd --stdin p0st 相当于 passwd p0st

 2.在a(192.168.10.231)机器上创建密钥对,公钥发给服务器b(192.168.10.232),c(192.168.10.233),私钥留在a服务器上
   a.su - p0st 切换用户
   b.ssh-keygen 创建密钥对,相当于执行 ssh-keygen -t rsa & ssh-keygen -t dsa
   c.ssh-keygen -t rsa
      Generating public/private rsa key pair.
     Enter file in which to save the key (/home/p0st/.ssh/id_rsa):  密钥对保存地址
     Created directory '/home/p0st/.ssh'.
     Enter passphrase (empty for no passphrase): 是否输入密码
     Enter same passphrase again:  确认密码
     Your identification has been saved in /home/p0st/.ssh/id_rsa.
     Your public key has been saved in /home/p0st/.ssh/id_rsa.pub. 用户家目录下生成隐藏文件夹/.ssh/
     The key fingerprint is:
     SHA256:aO2wdihLQKgZBVsjF67EoFANYVkvcDOB9BRT7l5Wtn8 p0st@node1
     The key's randomart image is:
     +---[RSA 2048]----+
      |=+&OX+. |
     |=Xo*.* |
     |=oo o o o |
     |o= o o o . |
     |+ . = S . |
     | . o B . |
     | o = o . E |
     | . + . . |
     | . |
     +----[SHA256]-----+

其中/.ssh/目录的权限为700,私钥文件600,id_rsa其中私钥文件的权限必须为600,id_rsa.pub公钥文件644

d.ssh-copy-id -i id_rsa.pub p0st@192.168.10.232 秘钥分发,就是公钥传给要连接的服务器 (带端口的服务器公钥分发ssh-copy-id -i id_rsa.pub "-p 52113 p0st@192.168.10.232")

   e.在192.168.10.232的p0st的家目录里面会有一个authorized_keys文件,这是功发送过来修改过名字的id_rsa.pub文件

注意:在做免秘钥登录的时候,不一定是两台机器相同用户

    注意:为什么id_rsa.oub会被改成authorized_keys那?

     因为这是ssh-copy-id给自动修改的,通过阅读ssh-copy-id的源码可知.ssh/authorized_keys为秘钥的默认目录及文件名,authorized_keys的文件权限已经修改为600,而原来的公钥权限为644

就是将服务器分发的公钥通过ssh链接到远程接收的服务器,并创建.ssh目录,并修改公钥名字为authorized_keys,存放到.ssh目录下(.ssh目录权限是700)

which ssh-copy-id

 注意:ssh免秘钥是基于用户的,假如a机器上有p0st用户,b机器上有b1,b2用户,ssh-copy-id进行分给b1,那么p0st只能免秘钥链接b机器上的b1,而链接b2还是需要密码



   5.7 ssh内网批量免秘钥分发



1.由于都是普通用户,所以要使用root账户对普通用户进行授权,/bin/cp命令,
  普通用户如何提权
  1.切换到root用户下,编辑visudo文件

   

android11 开启ssh服务 安卓ssh服务_运维_06

   按照其格式在最后一行添加自己的用户,只给p0st用户sudo权限的cp命令

   

android11 开启ssh服务 安卓ssh服务_操作系统_07

  2.检查语法

  [root@node2 ~]# visudo -c

  /etc/sudoers: parsed OK

  3.切换回普通用户,就可以像没有权限的目录拷贝文件了

    sudo cp hosts /etc

  4.分发服务器远程执行命令

  scp -rp p0st@192.168.10.232:/tmp >/dev/null 2>&1 将所有机器的ip和hostname对应的问价,传给所有内网机器

  ssh p0st@192.168.10.232 sudo cp /tmp/hosts /etc  分发服务器连接到内网机器,并执行命令,井上传到/tmp下的hosts上传到/etc

  5.验证etc下的hosts

 

. /etc/init.d/functions /bin/true /bin/false

 

批量小结:

 1.利用root做ssh key验证:简单易用,安全性差,同时无法禁止root远程连接

 2.利用普通用户,如p0st来做,先把分发的文件拷贝到服务器用户家目录,然后sudo提权,拷贝到服务器的对应权限目录:安全,操作复杂

 3.同2,不用sudo,使用suid对固定命令进行提权,相对安全 chmod 4755 /usr/sbin/rsync 或者是chmod u+s /usr/sbin/rsync

 4.分发最大的问题是:管理好分发机器,因为权限很大,很重要

    1。对分发机器取消外网ip地址

    2. 开启防火墙,禁止ssh对外访问,并且尽让某一台后端无外网的服务器访问



 分发脚本



#!/bin/sh
file="$1"
remotedir="$2"
. /etc/init.d/functions

if [ $# -ne 2 ]
  then
   echo "USAGE:/bin/sh $0 arg1 arg2"
   exit 1
fi

for n  in 232 233
do
        scp -rp $file p0st@192.168.10.$n:~ >/dev/null 2>&1 &&\
        ssh p0st@192.168.10.$n sudo /bin/cp ~/$file $remotedir &>/dev/null
        if [ $? -eq 0  ]
         then
            action "scp $file to  $remotedir is ok" /bin/true
        else
            action "scp $file to  $remotedir is fail" /bin/false
        fi
done

开源的常见的mail服务为sendmail或者posfix
发邮件:
  mail -s "标题" sb@qq.com <文件                 mail -s "test" test@qq.com <etc/host
  echo "正文" | mail -s "标题" test@qq.com       echo "error server" |mail -s "test" test@qq.com



   5.8 ssh内网批量免秘钥分发基于expect