Linux ssh协议,客户端:一种使用Se


SSH协议

1. SSH协议介绍
  • ssh含义:secure shell(安全外壳)的缩写,为远程登录会话和其他网络服务提供安全性的协议

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

  • ssh协议使用的端口号:ssh是应用层协议,它的传输层协议是tcp,使用tcp协议22号端口

2. SSH服务的架构:SSH服务采用C/S架构(由客户端和服务端的软件组成)
  • 服务端是一个守护进程(daemon),他在后台运行并响应来自客户端的连接请求。

  • 客户端:一种使用Secure Shell (SSH)协议连接到运行了SSH服务端的远程服务器。

常见的SSH客户端:

  • Windows: Putty、 Xshell、 CRT、 MobaXterm、 FinalShell

  • Linux:ssh, scp, sftp,slogin (linux的openssh-clients经常使用的工具)

常见的SSH服务端:OpenSSH、dropbear

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

dropbear:另一个ssh协议的开源项目的实现
利用SSH协议实现数据传输的过程

数据传输的时候使用对方的公钥来加密数据,对方收到数据后使用自己的私钥来解密数据。

注意:

  • 第一次连接时会把目标主机的公钥利用哈希算法生成一个摘要,需要手动确认目前连接的机器是想要连接的目标主机,确认以后会自动把对方的公钥下载下来,下次再连接的时候就能确保是否和第一次是同一个主机。

  • 对方公钥存放位置:当前用户的家目录下面一个叫做ssh的隐藏文件夹(~/.ssh),里面有个叫做known_hosts的文件,里面记录了远程主机的公钥。

  • 拿到公钥的好处:如果下次访问的时候有一个假冒的主机(同样的ip地址等信息),系统是能够发现的。

新的机器地址和旧地址一样,只需要删除旧机器对应的公钥文件就可以重新连接上去了 .ssh/known_hosts里面
3. SSH客户端和服务端公钥交换过程:

  1. 客户端向远程服务端发起链接请求

  2. 服务端返回自己的公钥,以及一个会话ID(这一步客户端得到服务端公钥)

  3. 客户端生成密钥对

  4. 客户端用自己的公钥异或会话ID,计算出一个值Res,并用服务端的公钥加密

  5. 客户端发送加密后的值到服务端,服务端用私钥解密,得到Res

  6. 服务端用解密后的值Res异或会话ID,计算出客户端的公钥(这一步服务端得到客户端公钥)

公钥交换后:客户端和服务端各自持有三个秘钥,分别为自己的一对公、私钥,以及对方的公钥,之后的所有通讯都会被加密

服务器的公钥表现为一个磁盘文件

客户端的公钥是临时生成的(在连接的时候自动生成一个公钥)

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

3## OpenSSH的客户端程序ssh

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

#ssh客户端配置文件:/etc/ssh/ssh_config
ssh命令使用格式
ssh  [user@]host [COMMAND] 或者 ssh -l user host [COMMAND]

#后面加COMMAND,在远程主机上执行对应的命令

#不指定user,默认使用当前用户的身份登录到远程主机


使用选项:
-p port    #指定openssh-server使用的端口

-o option   #如:-o StrictHostKeyChecking=no #表示登录的时候不用确认,直接下载公钥

-i <file>   #指定私钥文件路径,实现基于key验证,默认使用文件: ~/.ssh/xxx

SSH登录验证的方式

  • 口令验证:通过账号和口令登录到远程主机

  • 密钥验证:需要把公用密匙放在需要访问的服务器上

口令验证

  1. 客户端发起ssh请求,服务器会把自己的公钥发送给用户

  2. 用户会根据服务器发来的公钥对密码进行加密

  3. 加密后的信息回传给服务器,服务器用自己的私钥解密,如果密码正确,则用户登录成功

密钥验证

  1. 首先在客户端生成一对密钥(ssh-keygen)(存放在.ssh文件中)

  2. 并将客户端的公钥ssh-copy-id 拷贝到服务端(.ssh/authorized_keys文件)

  3. 当客户端再次发送一个连接请求,包括ip、用户名

  4. 服务端得到客户端的请求后,会到authorized_keys中查找,如果有响应的IP和用户,就会随机生成一个字符串

  5. 服务端将使用客户端拷贝过来的公钥进行加密,然后发送给客户端

  6. 得到服务端发来的消息后,客户端会使用私钥进行解密,然后将解密后的字符串发送给服务端

  7. 服务端接受到客户端发来的字符串后,跟之前的字符串进行对比,如果一致,就允许免密码登录

基于KEY验证的登录实现

  • 1.客户端生成密钥对:ssh-keygen

  • 2.客户端把公钥拷给服务端:ssh-copy-id

#生成密钥对
[root@CentOS8 ~]# ssh-keygen 
Generating public/private rsa key pair.
Enter file in which to save the key (/root/.ssh/id_rsa):   #直接回车默认使用rsa这种非对称加密算法生成一个公钥私钥对文件
Created directory '/root/.ssh'.
Enter passphrase (empty for no passphrase): 
Enter same passphrase again: 
Your identification has been saved in /root/.ssh/id_rsa.
Your public key has been saved in /root/.ssh/id_rsa.pub.
The key fingerprint is:
SHA256:Ri4OI0fZhf+h9slKAvIdRz2H2IqcXwM5L2iuOKO0sVA root@CentOS8.cc
The key's randomart image is:
+---[RSA 3072]----+
|       ..        |
|     o.. = .     |
|    o ..B = .    |
|   . . B.=.o     |
|  E = O So+.     |
| . = O *oo..     |
|.o  . =.oo .     |
|o *. . o  +      |
|.+.o.   ..       |
+----[SHA256]-----+

#此时客户端已经生成了密钥对
[root@CentOS8 ~]# cd .ssh
[root@CentOS8 .ssh]# ls
id_rsa  id_rsa.pub
#客户端拷贝密钥对到服务端的指定文件
[root@CentOS8 .ssh]# ssh-copy-id 10.0.0.13
/usr/bin/ssh-copy-id: INFO: Source of key(s) to be installed: "/root/.ssh/id_rsa.pub"
The authenticity of host '10.0.0.13 (10.0.0.13)' can't be established.
ECDSA key fingerprint is SHA256:aLGR+NSxBzsNATFmNFW/QfzzIv3Dq+VS9Ggve2wlR4k.
Are you sure you want to continue connecting (yes/no/[fingerprint])? yes
/usr/bin/ssh-copy-id: INFO: attempting to log in with the new key(s), to filter out any that are already installed
/usr/bin/ssh-copy-id: INFO: 1 key(s) remain to be installed -- if you are prompted now it is to install the new keys
root@10.0.0.13's password: 

Number of key(s) added: 1

Now try logging into the machine, with:   "ssh '10.0.0.13'"
and check to make sure that only the key(s) you wanted were added.
#服务端查看:已经生成了authorized_keys文件,里面记录了客户端的公钥信息
[root@CentOS8 .ssh]# ls
authorized_keys

[root@CentOS8 .ssh]# cat  authorized_keys
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQDssNA/z9sb/+RMplQI53tHXFXXpgIA3V7WvijV9lkBJ2K8K4s5wXYUnWqgHM5pNaWdcMYtoT5n6sPPyJqyZ2R0Pi4hNRcefsZLB9jmDMtNlEai9vw0XXIbWalXGmAvcrcaNot+WyAgXORRFXPmk8F1DsP992DSBJrqqEXjOvFDzrYIU1g01QFBtGWGj6tlhHO2rhL0nRi9RshJoHOMd+DXglGO7Uympovwh/K8PncWwMAq3e+gvFbNHIYXUGQrXmycrnlAUvNKBhddVE7b5R+LXyUDWH/LK8qYBPP4zNN1yqb91OZv5pY7HsniVGrTJ+wgjFu1Qjf09FqYS1L+X2fAtj0fX/I9HLWzW2sQDT+g6NR9fYy8gaLWzeSj6pcE/YC/F3l1s55xBshVNxdrJawR4ektDyzvDbMNPOb8ZFUZ5QJmH2R4DagSfAiQsDn08iKol+NKmLNCkHR4EkNZLnOFNJRlGoCwZHZfaMOzJMTAaCU3z2Ysb5oCEYqTs3fX/Q0= root@CentOS8.cc

ssh-keygen:客户端生成密钥对

使用ssh-keygen生成密钥对时,直接回车默认使用rsa这种非对称加密算法生成一个公钥私钥对文件

-f:指定公钥私钥存放的路径,不指定默认存放在家目录下的ssh这个隐藏文件 .ssh/xxx
-t:指定加密算法,默认使用加密算法类型为rsa
-p: 指定密码,不输入内容,默认密码为空

ssh-copy-id:将客户端的公钥复制给指定的远程主机

ssh-copy-id   目标主机

-i 公钥文件的路径,默认自动拷贝到目标主机的.ssh目录下authorized_keys这个文件中(.ssh若不存在会自动创建)

实现多台主机之间彼此都能基于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存放自己的公钥(自己信任自己)

例如:

[root@CentOS8 ~]# ssh-keygen
Generating public/private rsa key pair.
Enter file in which to save the key (/root/.ssh/id_rsa): 
Created directory '/root/.ssh'.
Enter passphrase (empty for no passphrase): 
Enter same passphrase again: 
Your identification has been saved in /root/.ssh/id_rsa.
Your public key has been saved in /root/.ssh/id_rsa.pub.
The key fingerprint is:
SHA256:II5nWyWBGr9LwS6H58NNYSXPxNgvH6lcf7QW3WAdguQ root@CentOS8.cc
The key's randomart image is:
+---[RSA 3072]----+
|     ..+  .... o.|
|  . . o.= ..  + .|
|   =. o*.. E . o.|
|  .o+.o++ =   o o|
|  .o++.oS= o . o |
|  oo*o. o . . +  |
|   B.+       o   |
|    = .          |
|     .           |
+----[SHA256]-----+

[root@CentOS8 ~]# ssh-copy-id 127.0.0.1
/usr/bin/ssh-copy-id: INFO: Source of key(s) to be installed: "/root/.ssh/id_rsa.pub"
The authenticity of host '127.0.0.1 (127.0.0.1)' can't be established.
ECDSA key fingerprint is SHA256:aLGR+NSxBzsNATFmNFW/QfzzIv3Dq+VS9Ggve2wlR4k.
Are you sure you want to continue connecting (yes/no/[fingerprint])? yes
/usr/bin/ssh-copy-id: INFO: attempting to log in with the new key(s), to filter out any that are already installed
/usr/bin/ssh-copy-id: INFO: 1 key(s) remain to be installed -- if you are prompted now it is to install the new keys
root@127.0.0.1's password:

Number of key(s) added: 1

Now try logging into the machine, with:   "ssh '127.0.0.1'"
and check to make sure that only the key(s) you wanted were added.


[root@CentOS8 ~]# ll .ssh
total 16
-rw------- 1 root root  569 Oct  7 01:39 authorized_keys
-rw------- 1 root root 2602 Oct  7 01:39 id_rsa
-rw-r--r-- 1 root root  569 Oct  7 01:39 id_rsa.pub
-rw-r--r-- 1 root root  171 Oct  7 01:39 known_hosts
[root@CentOS8 ~]# rsync -av .ssh 10.0.0.13:/root
The authenticity of host '10.0.0.13 (10.0.0.13)' can't be established.
ECDSA key fingerprint is SHA256:aLGR+NSxBzsNATFmNFW/QfzzIv3Dq+VS9Ggve2wlR4k.
Are you sure you want to continue connecting (yes/no/[fingerprint])? yes
Warning: Permanently added '10.0.0.13' (ECDSA) to the list of known hosts.
root@10.0.0.13's password:
sending incremental file list
.ssh/
.ssh/authorized_keys
.ssh/id_rsa
.ssh/id_rsa.pub
.ssh/known_hosts

sent 4,431 bytes  received 96 bytes  1,006.00 bytes/sec
total size is 4,082  speedup is 0.90

方法二:(脚本实现)

#!/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

OpenSSH服务端和客户端的配置

服务端配置文件
服务器端对应的程序名称:sshd

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

服务器端的配置文件帮助:man 5 sshd_config
配置文件说明
Port                      #ssh服务使用的默认端口号,生产建议修改

ListenAddress ip          #设置sshd服务器绑定的IP地址。

LoginGraceTime 2m         #设置如果用户不能成功登录,在切断连接之前服务器需要等待的时间(以秒为单位)

PermitRootLogin yes  	  #是否允许root用户登录,默认ubuntu不允许root远程ssh登录

StrictModes yes     	  #检查.ssh/文件的所有者,权限等

MaxAuthTries   6          #设置允许登录失败重试次数,失败次数超过一般则记录进日志,默认为6

MaxSessions  10           #同一个连接最大会话

PubkeyAuthentication yes  #是否基于key验证

PermitEmptyPasswords no   #是否允许空密码连接

PasswordAuthentication yes   #是否支持密码验证

GatewayPorts no              #指定是否允许远程主机连接到为客户端转发的端口

ClientAliveInterval 10       #每隔指定时间,服务器向客户端发一个消息,用于保持连接,单位:秒

ClientAliveCountMax 3        #发送alive的次数,发送到上限后会强制断开连接,默认3

UseDNS yes                   #不使用DNS查询客户端,一般用不到,可以让ssh连接速度加快

GSSAPIAuthentication yes     #是否允许使用基于 GSSAPI 的用户认证。默认值为"no" 关闭可提高链接速度

MaxStartups                  #未认证连接最大值,默认值10

Banner /path/file


#以下可以限制可登录用户的办法:
AllowUsers user1 user2 user3  #设定用户白名单,默认不在白名单的用户无法登录

DenyUsers user1 user2 user3   #设定用户黑名单,添加后无法使用ssh进行登录

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  #客户端的配置文件,可以更改默认端口,公钥检查等
#StrictHostKeyChecking ask
#首次登录不显示检查提示
StrictHostKeyChecking no 
#   IdentityFile ~/.ssh/id_rsa
#   IdentityFile ~/.ssh/id_dsa
#   IdentityFile ~/.ssh/id_ecdsa
#   IdentityFile ~/.ssh/id_ed25519
#   Port 22  #指定要在远程主机上连接的端口号

OPEN SSH的相关文件

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

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

  • .ssh文件:

[root@CentOS8 ~]# ll .ssh
total 16
-rw------- 1 root root  397 Sep 27 21:49 authorized_keys
-rw------- 1 root root 1679 Sep 27 21:49 id_rsa
-rw-r--r-- 1 root root  397 Sep 27 21:49 id_rsa.pub
-rw-r--r-- 1 root root  684 Sep 27 21:50 known_hosts


- authorized_keys:存放客户端通过ssh-copy-id命令拷贝过来的公钥(用于密钥验证)

- id_rsa:自己的私钥

- id_rsa.pub:自己的公钥

- known_hosts:记录了远程主机的公钥

#客户端执行ssh-kgen时才会生成自己的公钥和私钥

其他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工具差不多。

相关内容