Linux ssh协议

  • Linux ssh协议已关闭评论
  • 12 次浏览
  • A+
所属分类:linux技术
摘要

ssh:secure shell protocol,安全的远程登录作用:是建立在应用层基础上的安全协议,实现数据传输过程中数据的加密,代替telent协议


基础知识

  • ssh:secure shell protocol,安全的远程登录

  • 作用:是建立在应用层基础上的安全协议,实现数据传输过程中数据的加密,代替telent协议

  • 使用tcp协议,端口号为22

ssh服务具体的软件实现:

  • openSSH

  • dropbear

OpenSSH:ssh协议的开源实现,linux(centos、ubuntu等)默认使用的是openssh来实现ssh这个服务的  dropbear:另一个ssh协议的开源项目的实现 

ssh的通信过程:

第一次连接的时候就要进行公钥的交换

  • 客户端发起请求

  • 服务端返回给客户端自己的公钥,以及生成一个会话ID

  • 客户端生成密钥对:将自己的公钥和会话ID做异或运算,然后再使用服务端的公钥来加密异或运算的到的值

  • 服务端的到这个加密的数据后使用自己的私钥解密得到数据

  • 服务端使用解密后得到的数据和会话ID进行异或运算得到客户端的公钥(服务器得到客户端公钥)

最终:双方各自持有三个秘钥,分别为自己的一对公、私钥,以及对方的公钥,之后的所有通讯都会被加密  服务器的公钥表现为一个磁盘文件  客户端的公钥是临时生成的(在连接的时候自动生成一个公钥) 

ssh加密通信原理

假如A和B通信,A是客户端,B是服务端 A--->B 客户端A使用服务端B的公钥来加密数据,服务端B使用自己的私钥来解密数据  B--->A 流程和A--->B的流程是一样的  #第一次连接的时候会把目标主机的公钥利用哈希算法生成一个摘要,需要手动确认目前连接的机器是想要连接的目标主机 #确认以后会自动把对方的公钥下载下来,下次再连接的时候就能确保是否和第一次是同一个主机。  #对方公钥存放位置: 当前用户的家目录下面一个叫做ssh的隐藏文件夹,里面有个叫做known_hosts的文件,里面记录了远程主机的公钥。  #拿到公钥的好处: 如果下次访问的时候有一个假冒的主机(同样的ip地址等信息),系统是能够发现的。  #新的机器地址和旧地址一样,只需要删除旧机器对应的公钥文件就可以重新连接上去了 .ssh/known_hosts里面 

openssh服务

OpenSSH是SSH(Secure SHell)协议的免费开源实现,一般在各种Linux版本中会默认安装,基于C/S结构

Openssh软件相关包组成:

  • openssh

  • openssh-clients:服务器的配置文件带D,客户端的配置文件不带D

  • openssh-server:这个包定义了服务器的配置文件

#可以使用rpm -ql 包名 :查看软件包中的内容  服务端: [root@Centos8 CA]# rpm -ql openssh-server /etc/pam.d/sshd  #服务端程序 /etc/ssh/sshd_config #服务端配置文件 /etc/sysconfig/sshd ... 服务端对应的unit文件:/usr/lib/systemd/system/sshd.service   客户端: [root@Centos8 ~]# rpm -ql openssh-clients /etc/ssh/ssh_config  #客户端的配置文件,可以更改默认端口,公钥检查等 /etc/ssh/ssh_config.d /etc/ssh/ssh_config.d/05-redhat.conf /usr/bin/scp /usr/bin/sftp /usr/bin/ssh /usr/bin/ssh-add /usr/bin/ssh-agent /usr/bin/ssh-copy-id /usr/bin/ssh-keyscan ... 

客户端:openssh-clients

Linux Client: ssh, scp, sftp,slogin  #linux的openssh-clients经常使用的工具  Windows Client: xshell, MobaXterm, putty, securecrt, sshsecureshellclient 

客户端 ssh命令

ssh命令:是ssh客户端的一个工具,允许实现对远程系统经验证地加密安全访问

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

ssh命令使用格式

ssh [user@]host [COMMAND] 或者 ssh -l user host [COMMAND] #后面加COMMAND,在远程主机上执行对应的命令  选项: -p port    #指定openssh-server使用的端口  -X          #支持x11转发(远程显示的图形界面在本机显示(前提是双方都是图形界面))  -t          #强制伪tty分配,通过间接的方式连接到目标主机             #如:ssh -t remoteserver1 ssh -t remoteserver2   ssh remoteserver3   -o option   #如:-o StrictHostKeyChecking=no #表示登录的时候不用确认,直接下载公钥  -i <file>   #指定私钥文件路径,实现基于key验证,默认使用文件: ~/.ssh/xxx 
范例: 利用windows 显示 Linux 的图形工具
使用到了x协议,x协议是用来实现图形处理的。 #windows的图形界面和操作系统绑在一起的,linux里面图形界面只是一个组件,不输入操作系统本身。 	x_server组件:一个服务器,是真正画图的组件 	x_client组件:图形界面客户端,比如firefox等  	x_client代指图形工具,运行一个x_client的时候,借助x协议把请求发送给x_server。 	x_server再连接图形显卡进行界面的显示。 	#两者可以属于不同的主机,可以使用不同的协议。  #利用windows 显示 Linux 的图形工具 在linux上装x_client,在windows上装x_server。 在linux运行客户端软件,通过x协议发送給windows的服务器,实现了windows显示linux上的图像。  #windeows的x_server软件: xmanager(用的比较多) #linux的x_client:firefox 

ssh登录验证的方式

  • 口令验证

  • 密钥验证

口令验证
1. 客户端发起ssh请求,服务器会把自己的公钥发送给用户  2. 用户会根据服务器发来的公钥对密码进行加密  3. 加密后的信息回传给服务器,服务器用自己的私钥解密,如果密码正确,则用户登录成功 
密钥验证实现方式

在每次连接对方的时候就不用在输入密码了,可以直接连接

1. 首先在客户端生成一对密钥(ssh-keygen)(公钥、私钥)  2. 客户端的公钥通过ssh-copy-id命令拷贝到服务端,存放在(authorized_keys)这个文件中  3. 客户端再次发送连接请求,用客户端公钥加密并传给客户端  4.客户端接接收到这个加密的文件后用私钥解密,将解密的字符用服务器的公钥(第一次登录得到的)加密发给服务器端  5.服务端用自己的私钥解密得到结果。通过对比字符串来实现免密登录 
实现基于密钥的登录方式实现过程
  • 1.客户端生成密钥对

  • 2.客户端把公钥拷给服务端

1.ssh-keygen:直接回车默认使用rsa这种非对称加密算法生成一个公钥私钥对文件  -f:指定公钥私钥存放的路径,不指定默认存放在家目录下的ssh这个隐藏文件 .ssh/xxx -t:指定加密算法 -p: 指定密码  2.ssh-copy-id -i 公钥文件的路径  目标主机  会自动拷到目标主机额度.ssh目录下的authorized_keys这个文件中(不存在会自动创建) 

范例

#使用sshpass工具实现非交互式登录:(一般用在脚本里面)  sshpass:实现口令的提交  前提:要实现和对方远程通信,需要先将对方的公钥加到自己的.ssh/known_hosts文件中  [root@centos8 ~]# sshpass -p 123456 ssh -o StrictHostKeyChecking=no root@10.0.0.8 #在访问对方的时候就不需要输入密码了   #非交互式实现公钥的拷贝 sshpass -p 123456 ssh-copy-id -i 本机的公钥 -o StrictHostKeyChecking=no 10.0.0.8(需要复制到的远程主机) 
#范例:批量部署多台主机基于key验证脚本 #!/bin/bash  #添加shebang机制 HOSTS="  #指定需要远程连接到的主机ip地址 10.0.0.6 10.0.0.7 10.0.0.18 10.0.0.28 " PASS=redhat #用于存储这几台主机的密码 [ -f /root/.ssh/id_rsa ] || ssh-keygen  -P ""  -f /root/.ssh/id_rsa &> /dev/null #如果有私钥了就不用再创建了 apt -y install sshpass &> /dev/null #如果没有安装sshpass就安装 for i in $HOSTS;do #循环ip地址 {    sshpass  -p $PASS ssh-copy-id  -o StrictHostKeyChecking=no -i /root/.ssh/id_rsa.pub $i &> /dev/null #使用非交互式的方式来将自己的公钥拷贝过去  -i:指定私钥的路径 }& #后台并行执行 done wait 
#实现多台主机之间彼此都能基于Key验证 1.生成密钥对 ssh-keygen #默认保存在.ssh下面  2.将自己的私钥文件保存到自己的authorized_keys文件中。 ssh-copy-id 127.0.0.1  3.使用rsync工具将.ssh文件整个复制到目标所有主机  #例如:rsync -av .ssh serverhost/.ssh/root   #原理就是所有人共用一个公钥私钥对。 因为使用ssh-keygen生成一个密钥对是放在/.ssh里面的且authorized_keys存放自己的公钥(自己信任自己) 
如果生成密钥对的时候指定了密码:ssh-keygen -P 。下次远程的时候不想输入这个密码, 可以使用ssh-agent bash 来开启一个代理,然后把私钥的密码托管给代理  ssh-keygen -p  ssh-agent bash #是一个后台执行的程序 ssh-add #将要密码托管给agent,下次就不需要手动输入密码了 

其他ssh客户端工具

他们都是基于ssh协议开发的ssh_client工具

  • scp

  • rsync

  • stfp

scp:实现跨主机的远程拷贝

格式: scp [选项] 源文件 目标文件 scp [选项]  /source_file [user@]remote_houst/dest_file scp [选项]  [user@]remote_houst/dest_file /source_file  选项: -r:复制文件夹 -P PORT 指明remote host的监听的端口  #复制目录文件后面有无斜线的区别 	有斜线:复制文件夹里面的内容 	无斜线:复制整个文件夹 

rsync:实现数据的更新(增量备份)

主要用来实现数据的增量备份、数据的更新。

工具来源:rsync包 #通信双方都需要安装rsync这个工具  #选项: -a:保留源文件的属性,但是无法保留acl和selinux属性  -a选项自带递归的功能 -v:显示详细的过程 --delete:保证两边的数据一样,如果目标文件存在某个源文件没有的文件,就会把目标文件的这个文件删除掉  rsync  -av /etc server1:/tmp #复制目录和目录下文件 rsync  -av /etc/ server1:/tmp #只复制目录下文件 和scp一样  rsync -av --delete source_file host:/dest_file | dest_file  #可以跨主机备份也可以本地备份  

sftp:交互式文件传输工具

用法和ssh工具差不多。

ssh服务器端配置

服务器端对应的程序名称:sshd  服务器端的配置文件: /etc/ssh/sshd_config  服务器端的配置文件帮助:man 5 sshd_config 
Port        #端口号,生产建议修改 ListenAddress ip LoginGraceTime 2m PermitRootLogin yes #默认ubuntu不允许root远程ssh登录 StrictModes yes   #检查.ssh/文件的所有者,权限等 MaxAuthTries   6     #pecifies the maximum number of authentication attempts permitted per connection. Once the number of failures reaches half this value, additional failures are logged. The default is 6. MaxSessions  10         #同一个连接最大会话 PubkeyAuthentication yes     #基于key验证 PermitEmptyPasswords no      #空密码连接 PasswordAuthentication yes   #是否支持密码验证 GatewayPorts no ClientAliveInterval 10 #单位:秒 ClientAliveCountMax 3 #默认3 UseDNS yes #改为no,一般用不到,可以让ssh连接速度加快 GSSAPIAuthentication yes #提高速度可改为no MaxStartups    #未认证连接最大值,默认值10 Banner /path/file #以下可以限制可登录用户的办法: AllowUsers user1 user2 user3 DenyUsers user1 user2 user3 AllowGroups g1 g2 DenyGroups g1 g2 
ssh服务配置的最佳实践
建议使用非默认端口 禁止使用protocol version 1 限制可登录用户 设定空闲会话超时时长 利用防火墙设置ssh访问策略 仅监听特定的IP地址 基于口令认证时,使用强密码策略,比如:tr -dc A-Za-z0-9_ < /dev/urandom | head -c 12| xargs 使用基于密钥的认证 禁止使用空密码 禁止root用户直接登录 限制ssh的访问频度和并发在线数 经常分析日志 

范例:

#设置 ssh 空闲60s 自动注销 Vim /etc/ssh/sshd_config  	ClientAliveInterval   60 	ClientAliveCountMax   0 Service sshd restart #注意:新开一个连接才有效 
#解决ssh登录缓慢的问题 vim /etc/ssh/sshd_config 	UseDNS no 	GSSAPIAuthentication no 
#在 ubuntu 上启用 root 远程ssh登录 #修改sshd服务配置文件 vim /etc/ssh/sshd_config  	#PermitRootLogin prohibit-password 注释掉此行 	PermitRootLogin yes 修改为下面形式 

ssh客户端的配置

客户端名称:ssh  配置文件: /etc/ssh/ssh_config  #客户端的配置文件,可以更改默认端口,公钥检查等 

轻量自动运维化工具

  • sshfs

  • pssh

  • sshpass

挂载远程ssh目录:

sshfs:由EPEL源提供,目前CentOS8 还没有提供,可以利用ssh协议挂载远程目录 轻量级自动化运维工具 pssh 
#范例 sshfs 10.0.0.8:/data /mnt #将远程主机的data目录挂载到本地的mnt目录 

pash

pssh:批量管理目标主机,需要提前做好基于key验证。,可在多台服务器上执行命令的工具,也可实现文件复制,提供了基于ssh和scp的多个并行工具

 选项: -H:指定要远程管理的主机地址 -h file:主机列表文件,内容格式”[user@]host[:port]” -A :手动输入密码模式 -i:每个服务器内部处理信息输出 
范例
#默认使用ssh的key认证,通过 -A选项,使用密码认证批量执行指令 pssh -H "192.168.1.10"   -A   hostname  #多台主机 pssh -H "192.168.1.10 192.168.1.20"  -i   hostname  #多台主机 cat hosts.txt  10.0.0.8 10.0.0.6 pssh -h hosts.txt  -i   hostname  #将标准错误和标准正确重定向分别保存至本地主机的/data/stdout和/data/stderr目录下 pssh -H 192.168.1.10 -o /data/stdout -e /data/stderr   -i “hostname”  -o:输出的文件目录 -e:错误输出文件  #使用pssh的时候 变量 *号等通配符需要使用单引号括起来 

pscp.pssh命令

是将本地文件批量复制到远程主机

#选项: -v 显示复制过程 -r 递归复制目录  #将本地curl.sh 复制到/app/目录 pscp.pssh -H 192.168.1.10 /root/test/curl.sh   /app/ pscp.pssh -h host.txt /root/test/curl.sh   /app/  #将本地多个文件批量复制到/app/目录 pscp.pssh -H 192.168.1.10 /root/f1.sh /root/f2.sh   /app/  #将本地目录批量复制到/app/目录 pscp.pssh -H 192.168.1.10  -r /root/test/   /app/ 

pslurp命令

将远程主机的文件批量复制到本地

#批量下载目标服务器的passwd文件至/app下,并更名为user pslurp -H 192.168.1.10 -L /app /etc/passwd user  #选项 -L 指定从远程主机下载到本机的存储的目录,local是下载到本地后的名称 -r 递归复制目录