4.SSH服务

第一章 需要SSH原因

1.远程连接Linux的姿势

1.SSH连接
2.Telnet连接
3.本地显示器键盘⽀直连

2.为什么使⽤SSH连接

SSH:
linux默认 安全性好 传输加密 默认端⼝号22

TELNET:
⽹络设备上默认的是telnet 安全性较差 传输明⽂ 默认不允许⽤root登录 默认端⼝号23

3.抓包演示

安装telnet服务

yum provides telnet*
yum install telnet-server -y
systemctl start telnet.socket
systemctl status telnet.socket
netstat -lntup|grep 23

使⽤telnet连接虚拟机:

telnet 10.0.0.61

telnet抓包:

[i:\~]$ telnet 10.0.0.100


Connecting to 10.0.0.100:23...
Connection established.
To escape to local shell, press 'Ctrl+Alt+]'.

Kernel 3.10.0-1062.el7.x86_64 on an x86_64
ceisi login: oldboy
Password: 
Last login: Mon Apr 26 19:18:10 from ::ffff:10.0.0.1
image.png

SSH抓包:

[i:\~]$ ssh root@10.0.0.100


Connecting to 10.0.0.100:22...
Connection established.
To escape to local shell, press 'Ctrl+Alt+]'.

Last login: Mon Apr 26 19:25:59 2021 from 10.0.0.1
[root@ceisi ~]# 
image.png

第二章 SSH远程连接流程

1.SSH加密原理

对称加密:
就是指双方共用一套公钥和私钥,加密解密使用的都是同一套公钥私钥,如果被泄露,双方的数据都有
风险。
非对称加密:
非对称加密则包含了两套秘钥,公钥 以及 私钥
其中公钥用来加密,私钥用来解密。双方都是用对方的公钥加密数据,使用自己的私钥来解密数据,而
公钥可以随便传递,即使泄露也无风险。
image.png

2.SSH密钥认证过程

1.A服务器发起连接B服务器的请求
2.B服务端返回自己的公钥以及一个会话ID,此时A服务器得到了B服务器的公钥
3.A服务器生成密钥对
4.A服务器用自己的公钥异或会话ID,计算出一个值,并用B服务器的公钥加密
5.A服务器发送加密后的值到B服务器,B服务器用私钥解密
6.B服务端用解密后的值异或会话ID,计算出客户端的公钥,此时B服务器得到了A服务器的公钥
7.最后双方服务器都持有了3个密钥,分别为自己的一对公钥私钥,以及对方的公钥
image.png

3.SSH身份认证方式

SSH的身份认证分为两个流程:

1.基于密码方式认证
2.基于密钥方式认证

基于密码方式认证:

A为客户端,B为服务端
1.服务端收到登录请求后,首先互换公钥
2.客户端用服务端的公钥加密用户密码并发送给服务端
3.服务端用自己的秘钥解密后得到账号密码,然后进行验证
4.服务端用客户端的公钥加密验证结果并返回
5.服务端用自己的秘钥解密后得到验证结果
无标题.jpg

基于密钥方式认证:

A为客户端,B为服务端
1.客户端在本地生成一对密钥
2.客户端将自己的公钥使用ssh-copy-id命令发送到服务端
3.此时会提示客户端输入账号密码。客户端再次发送连接请求,包括ip、用户名
4.服务端得到客户端的请求后,会在家目录下.ssh目录里的authorized_keys中查找,如果有响应的
IP和用户,就会随机生成一个字符串
5.服务端将生成的字符串使用客户端发送过来的公钥进行加密,然后再发送给客户端
6.客户端收到加密后的内容后,会使用自己的私钥进行解密,然后将解密后的随机字符串发送给服务端
7.服务端接受到客户端发来的随机字符串后,跟之前的随机字符串进行比对,如果一致,就允许免密码登录
无标题0001.jpg

4.流程总结

1. 客户端 - 服务端 请求建⽴ssh远程连接
2. 服务端 - 客户端 请求确认公钥信息
3. 客户端 - 服务端 确认接收公钥信息,保存到~/.ssh/authorized_keys⽂件中 
4. 服务端 - 客户端 询问⽤户密码信息
5. 客户端 - 服务端 ⽤户密码信息
6. 服务端 - 客户端 确认密码信息正确 远程连接建⽴
1之后:不⽤反复确认公钥信息
6之后:所有传输的数据信息会进⾏加密处理

第三章 SSH密钥对⽅式连接

1.SSH密钥对创建流程

1.执⾏密钥对创建命令⽣成公钥和私钥
2.执⾏命令分发公钥到远程服务器
3.根据提示输⼊远程服务器的密码
4.公钥分发成功后即可使⽤私钥免密码登陆

2.创建密钥对

[root@m-61 ~]# 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:n2WWZ2Xy7gA4oiPg3nTKRcQXeUt9MCv2nOgbVYxLuGY root@m-61
The key's randomart image is:
+---[RSA 2048]----+
| .. .o. |
| . ..o..=. |
| o .o+.+.+ o|
| . . ..O = = |
| . . S E % o .|
| . . . . * B + . |
| . o = = . .|
| . + = . o o |
| . + . .|
+----[SHA256]-----+
[root@m-61 ~]#

3.查看⽣成的密钥对

[root@m-61 ~]# ls -l ~/.ssh/
总⽤量 8
-rw------- 1 root root 1675 4⽉ 22 20:21 id_rsa
-rw-r--r-- 1 root root 391 4⽉ 22 20:21 id_rsa.pub

4.分发公钥到远程机器

[root@m-61 ~]# ssh-copy-id 10.0.0.31 #分发命令
/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.31 (10.0.0.31)' can't be established.
ECDSA key fingerprint is
SHA256:iX3CX/sXoReWtwFzV0Xdiyhmim53Q5kPomfgPNTAMIA.
ECDSA key fingerprint is
MD5:06:ee:3f:fa:0f:02:6f:0e:4f:37:50:fd:cd:60:3f:43.
Are you sure you want to continue connecting (yes/no)? 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.31's password: #输⼊密码
Number of key(s) added: 1
Now try logging into the machine, with: "ssh '10.0.0.31'"
and check to make sure that only the key(s) you wanted were added.

5.验证是否可以免密码登陆

[root@m-61 ~]# ssh 10.0.0.31 
Last failed login: Thu Apr 22 20:23:23 CST 2021 from 10.0.0.61 on
ssh:notty
There was 1 failed login attempt since the last successful login.
Last login: Thu Apr 22 15:10:16 2021 from 10.0.0.1
[root@nfs-31 ~]# hostname
nfs-31
[root@nfs-31 ~]# whoami
root
[root@nfs-31 ~]# 登出
Connection to 10.0.0.31 closed.

6.客户端检查服务端公钥信息

[root@nfs-31 ~]# cat ~/.ssh/authorized_keys
ssh-rsa
AAAAB3NzaC1yc2EAAAADAQABAAABAQCnFtguJhyxJnNs7rMiE/VSNUm6SHne6YpbSgcRBOoJpcTa
IOqvxo7lInzYwJZGxzTzbIIcQdSD8+Px63+utbKxZn1r2go4v23VHE4CgYMR+Nc5tnHS9G76giCJ
dZsP6Glx8Quqv0lT6/9wA+mnYIKZLThPxFWuz2dUEN6dQtQM25HCBxqibzlm2v6vrXVM7kwpGCYA
9vdqF0ZjS+CF6P6hy9kG7Df/LTMbGiZ1L9wE/AP4nhe61EzVjRjMMLSw0ds2UXp7hhZGd9Oj+wJN
UcupvW5fOld7bd3td+X3nwLP2JKUVknAw8C6dCQydDVPcK4x6rdVyhOVqeHYaXOCfHq5 root@m�61

7.SSH密钥对关键⽂件解释

SSH服务端:

[root@m-61 ~]# ll ~/.ssh/
总⽤量 12
-rw------- 1 root root 1675 4⽉ 22 20:21 id_rsa #私钥,⾃⼰保留,注意,
权限是600
-rw-r--r-- 1 root root 391 4⽉ 22 20:21 id_rsa.pub #公钥,发给需要被连接的
服务器
-rw-r--r-- 1 root root 171 4⽉ 22 20:23 known_hosts #保存已经连接过的主机的
指纹信息

SSH客户端:

[root@nfs-31 ~]# ll ~/.ssh/
总⽤量 4
-rw------- 1 root root 391 4⽉ 22 20:23 authorized_keys #⽤来保存接收到的公
钥,注意,权限是600

第四章 SSH远程执⾏命令

1.SSH远程执⾏命令说明

SSH不仅仅可以⽤来连接服务器,也可以远程执⾏命令。
SSH远程执⾏命令并不需要登陆到远程服务器,只需要配置好密钥对即可,执⾏完成后进程就结束了。

2.SSH远程执⾏命令实战

#1.远程连接命令后直接加上需要执⾏的命令即可
[root@m-61 ~]# ssh 10.0.0.31 hostname
nfs-31
#2.远程执⾏命令不⽀持别名
[root@m-61 ~]# ssh 10.0.0.31 'll /root'
bash: ll: 未找到命令
[root@m-61 ~]# ssh 10.0.0.31 'ls -l /root'
总⽤量 12
-rw-------. 1 root root 1270 12⽉ 13 11:04 anaconda-ks.cfg
-rw-r--r-- 1 root root 1920 12⽉ 13 11:30 init.sh
-rwxr-xr-x 1 root root 698 12⽉ 13 11:50 set-ip.sh

第五章 SSH安全防范

1.⽬前SSH存在的安全隐患

问题1: 虽然使⽤了秘钥连接,但是原来的密码连接还是可以使⽤的
问题2: 默认端⼝号所有⼈都知道,需要修改
问题3: 如果被别⼈偷⾛了私钥,在不受信任的机器可以不需要root账号密码登录

2.SSH安全优化步骤

优化1: 禁⽌使⽤账号密码登陆

PubkeyAuthentication yes
PasswordAuthentication no

优化2:修改默认端⼝

Port 9527

优化3:限制主机登陆条件

#1.更改SSH监听地址为内⽹地址
ListenAddress 172.16.1.41
#2.配置防⽕墙规则,只允许通过跳板机登陆,其他地址的连接拒绝掉
yum install iptables-services -y
modprobe ip_tables
modprobe iptable_filter
modprobe iptable_nat
modprobe ip_conntrack
modprobe ip_conntrack_ftp
modprobe ip_nat_ftp
modprobe ipt_state
systemctl stop firewalld
systemctl disable firewalld
systemctl start iptables.service
systemctl enable iptables.service
iptables -F
iptables -X
iptables -Z
iptables -A INPUT ! -s 172.16.1.61 -p tcp --dport 9527 -j DROP

3.测试⽅法

⽬前被管理的机器只能通过管理机的内⽹⽹段并且只能使⽤秘钥⽅式连接

ssh 172.16.1.41 -p 9527

第六章 SSH免交互分发密钥

1.⽬前存在的问题

正常操作的步骤:

1.⽣成秘钥对
2.服务端分发秘钥需要⼿动确认
 - yes
 - 密码
3.修改客户端SSH配置⽂件,端⼝号,监听IP,秘钥⽅式,拒绝密码
4.重启服务
5.测试是否可以免密登录

存在的问题:

1.操作步骤繁琐,如果服务器数量很多,⼯作量⾮常⼤,效率⾮常低
2.⼿动操作容易出现失误,出现失误不好检查,总之,⼈不可靠

2.我们想要的效果

新服务器安装好系统后,管理机只需要运⾏⼀次脚本,上述所有操作全部⾃动完成,不需要⼈⼯介⼊,不
需要交互输⼊确认

3.收集正常创建密钥对的交互步骤

第⼀次交互:解决yes

/usr/bin/ssh-copy-id: INFO: Source of key(s) to be installed:
"/root/.ssh/id_dsa.pub"
The authenticity of host '10.0.0.41 (10.0.0.41)' can't be established.
ECDSA key fingerprint is SHA256:S+jjKXhBPHotvqYLV5PISxrgn0cPljD9njCavfx+0Fo.
ECDSA key fingerprint is
MD5:e3:59:ff:b9:3c:75:78:5f:6a:29:53:e5:22:09:0a:51.
Are you sure you want to continue connecting (yes/no)? 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.41's password:
Number of key(s) added: 1
Now try logging into the machine, with: "ssh '10.0.0.41'"
and check to make sure that only the key(s) you wanted were added.

4.解决第⼀次交互

ssh-copy-id 172.16.1.31 -o StrictHostKeyChecking=no

5.解决第⼆次交互

yum install sshpass -y
sshpass -p '123456' ssh-copy-id 172.16.1.31 -o StrictHostKeyChecking=no

6.编写免交互分发密钥脚本

[root@m-61 /server/scripts]# cat fenfa.sh
#!/bin/bash
#1.⽣成秘钥
if [ -f /root/.ssh/id_rsa ]
then
 echo "秘钥已经创建"
else
 ssh-keygen -t dsa -f /root/.ssh/id_rsa -N '' > /dev/null 2>&1
 echo "秘钥已经创建"
fi
for ip in {31,41}
do
 echo
"====================================================================="
 #2.分发秘钥
 sshpass -p '123456' ssh-copy-id 172.16.1.${ip} -o
StrictHostKeyChecking=no > /dev/null 2>&1
 if [ $? == 0 ]
 then
 echo "秘钥分发完毕: 172.16.1.${ip}"
 else
 echo "秘钥分发失败"
fi
 #3.测试
 ssh 172.16.1.${ip} hostname
 if [ $? == 0 ]
then
 echo "OK boy!"
 else
 echo "NO boy!"
 fi
done

第七章 拓展练习

正常⼈类作业:

windows:
1.xshell⽣成密钥对
2.将xshell公钥上传到管理机
管理机:
1.更改ssh默认端⼝号为9999
2.关闭⽤户名密码登录⽅式
3.开启通过密钥对⽅式连接
被管理机:
1.更改ssh默认端⼝号为9999
2.关闭⽤户名密码登录⽅式
3.开启通过密钥对⽅式连接
4.指定监听内⽹地址 172.16.1.x
实现效果:
1.管理机m01只能通过xshell的秘钥⽅式连接,IP地址⽤户名密码⽅式不允许
2.所有主机ssh端⼝修改为9999
3.被管理机只能通过内⽹地址使⽤秘钥认证连接,10⽹段不允许连接.不允许使⽤账号密码⽅连接

⾮正常⼈类作业:

⼀个脚本完成以下所有任务:
1.管理机⾃动创建密钥对
2.管理机⾃动将公钥发送到被管理机
3.修改被管理机的SSH连接端⼝为9999
4.修改被管理机的SSH监听地址为172.16.1.X
5.修改被管理机不允许使⽤账号密码⽅式登陆,只允许使⽤密钥⽅式连接
6.修改完之后验证是否⽣效,验证⽅法为使⽤9999端⼝连接被管理机并打印出主机信息

写脚本经验:

1.先理解需求
2.梳理思路
- 先手动用命令行实现
- 把命令收集起来
- 最后在写进脚本里
3.如果要添加新功能,复制一份脚本
fenfa.sh  
fenfa_v2.sh 
fenfa_v3.sh 
4.修改任何配置文件之前,先备份一份
5.如果需要修改配置文件,如果有注释,复制一行,再修改

在m-61上完成以下所有任务:

1.管理机自动创建密钥对
2.管理机自动将公钥发送到被管理机
3.修改被管理机的SSH连接端口为9999
cp /etc/ssh/sshd_config{,.bak}
sed -i 's@#Port 22@Port 9999@' /etc/ssh/sshd_config

4.修改被管理机的SSH监听地址为172.16.1.X
sed -i 's@#ListenAddress 0.0.0.0@ListenAddress 172.16.1.7@' /etc/ssh/sshd_config

5.修改被管理机不允许使用账号密码方式登陆,只允许使用密钥方式连接
sed -i 's@PasswordAuthentication yes@PasswordAuthentication no@' /etc/ssh/sshd_config

6.修改完之后验证是否生效,验证方法为使用9999端口连接被管理机并打印出主机信息
systemctl restart sshd
ssh 172.16.1.7 -p 9999 hostname

v2版本的脚本:

#!/bin/bash

#1.跳过输入密码
echo "正在创建..."
if [ -f /root/.ssh/id_rsa ]
then
  echo "密钥对已经存在"
else
  ssh-keygen -f /root/.ssh/id_rsa -N '' > /tmp/create_ssh.log 2>&1
fi

#2.自动输入密码 
echo "正在分发..."
for ip in {7..8}
do
  sshpass -p '123' ssh-copy-id 172.16.1.${ip} -o StrictHostKeyChecking=no > /tmp/create_ssh.log 2>&1
  echo "验证结果: $(ssh 172.16.1.${ip} hostname)"
done

#3.备份配置文件
echo "正在备份"
ssh 172.16.1.7 cp /etc/ssh/sshd_config{,.bak}

#4.修改被管理机的SSH连接端口为9999
echo "正在修改端口"
ssh 172.16.1.7 "sed -i 's@#Port 22@Port 9999@' /etc/ssh/sshd_config"

#5.修改被管理机的SSH监听地址为172.16.1.X
echo "正在修改地址"
ssh 172.16.1.7 "sed -i 's@#ListenAddress 0.0.0.0@ListenAddress 172.16.1.7@' /etc/ssh/sshd_config"

#6.修改被管理机不允许使用账号密码方式登陆,只允许使用密钥方式连接
echo "正在修改连接方式"
ssh 172.16.1.7 "sed -i 's@PasswordAuthentication yes@PasswordAuthentication no@' /etc/ssh/sshd_config"

#7.重启并验证服务
echo "正在重启服务"
ssh 172.16.1.7 systemctl restart sshd
sleep 1

echo "验证连接:"
ssh 172.16.1.7 -p 9999 hostname

v3版本的脚本: 批量多台主机执行

#!/bin/bash

#1.跳过输入密码
echo "正在创建..."
if [ -f /root/.ssh/id_rsa ]
then
  echo "密钥对已经存在"
else
  ssh-keygen -f /root/.ssh/id_rsa -N '' > /tmp/create_ssh.log 2>&1
fi

#2.自动输入密码 
echo "正在分发..."
for ip in {7..8}
do
  echo "正在操作: 172.16.1.${ip}"
  sshpass -p '123' ssh-copy-id 172.16.1.${ip} -o StrictHostKeyChecking=no > /tmp/create_ssh.log 2>&1
  #3.备份配置文件
  ssh 172.16.1.${ip} cp /etc/ssh/sshd_config{,.bak}
  
  #4.修改被管理机的SSH连接端口为9999
  ssh 172.16.1.${ip} "sed -i 's@#Port 22@Port 9999@' /etc/ssh/sshd_config"
  
  #5.修改被管理机的SSH监听地址为172.16.1.X
  ssh 172.16.1.${ip} "sed -i 's@#ListenAddress 0.0.0.0@ListenAddress 172.16.1.${ip}@' /etc/ssh/sshd_config"
  
  #6.修改被管理机不允许使用账号密码方式登陆,只允许使用密钥方式连接
  ssh 172.16.1.${ip} "sed -i 's@PasswordAuthentication yes@PasswordAuthentication no@' /etc/ssh/sshd_config"
  
  #7.重启并验证服务
  ssh 172.16.1.${ip} systemctl restart sshd
  sleep 1
  
  echo "验证连接:"
  ssh 172.16.1.${ip} -p 9999 hostname
done

v4版本的脚本: 增加判断是否已经修改过端口功能

#!/bin/bash

#1.跳过输入密码
echo "正在创建..."
if [ -f /root/.ssh/id_rsa ]
then
  echo "密钥对已经存在"
else
  ssh-keygen -f /root/.ssh/id_rsa -N '' > /tmp/create_ssh.log 2>&1
fi

#2.自动输入密码 
echo "正在分发..."
for ip in {7..8}
do
  echo "正在操作: 172.16.1.${ip}"
  sshpass -p '123' ssh-copy-id 172.16.1.${ip} -o StrictHostKeyChecking=no > /tmp/create_ssh.log 2>&1
  
  if [ $? == 0 ]
  then
    #3.备份配置文件
    ssh 172.16.1.${ip} cp /etc/ssh/sshd_config{,.bak}
    
    #4.修改被管理机的SSH连接端口为9999
    ssh 172.16.1.${ip} "sed -i 's@#Port 22@Port 9999@' /etc/ssh/sshd_config"
    
    #5.修改被管理机的SSH监听地址为172.16.1.X
    ssh 172.16.1.${ip} "sed -i 's@#ListenAddress 0.0.0.0@ListenAddress 172.16.1.${ip}@' /etc/ssh/sshd_config"
    
    #6.修改被管理机不允许使用账号密码方式登陆,只允许使用密钥方式连接
    ssh 172.16.1.${ip} "sed -i 's@PasswordAuthentication yes@PasswordAuthentication no@' /etc/ssh/sshd_config"
    
    #7.重启并验证服务
    ssh 172.16.1.${ip} systemctl restart sshd
    sleep 1
  fi
    echo "验证连接:"
    ssh 172.16.1.${ip} -p 9999 hostname
done

v5版本的脚本: 增加从文件里读取IP的功能

[root@m-61 /scripts]# cat fenfa-v5.sh 
#!/bin/bash

#1.跳过输入密码
echo "正在创建..."
if [ -f /root/.ssh/id_rsa ]
then
  echo "密钥对已经存在"
else
  ssh-keygen -f /root/.ssh/id_rsa -N '' > /tmp/create_ssh.log 2>&1
fi

#2.自动输入密码 
echo "正在分发..."
for ip in $(cat ip_list.txt)
do
  echo "正在操作: 172.16.1.${ip}"
  sshpass -p '123' ssh-copy-id 172.16.1.${ip} -o StrictHostKeyChecking=no > /tmp/create_ssh.log 2>&1
  
  if [ $? == 0 ]
  then
    #3.备份配置文件
    ssh 172.16.1.${ip} cp /etc/ssh/sshd_config{,.bak}
    
    #4.修改被管理机的SSH连接端口为9999
    ssh 172.16.1.${ip} "sed -i 's@#Port 22@Port 9999@' /etc/ssh/sshd_config"
    
    #5.修改被管理机的SSH监听地址为172.16.1.X
    ssh 172.16.1.${ip} "sed -i 's@#ListenAddress 0.0.0.0@ListenAddress 172.16.1.${ip}@' /etc/ssh/sshd_config"
    
    #6.修改被管理机不允许使用账号密码方式登陆,只允许使用密钥方式连接
    ssh 172.16.1.${ip} "sed -i 's@PasswordAuthentication yes@PasswordAuthentication no@' /etc/ssh/sshd_config"
    
    #7.重启并验证服务
    ssh 172.16.1.${ip} systemctl restart sshd
    sleep 1
  fi
    echo "验证连接:"
    ssh 172.16.1.${ip} -p 9999 hostname
done
----------------------------------------------------
[root@m-61 /scripts]# cat ip_list.txt 
7
8
31
41

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容