一。回顾#
1.1 ssh#
ssh
secure shell
- 远程登录连接,控制主机
- 数据的传输都是加密的
- 基于非对称加密技术
1.2 加密技术#
加密技术
对称加密
-
双方共同拥有一把钥匙,其中一方拿着加密,另外一方就拿着解密
-
弊端:这个公钥的钥匙很容易被有心人获取
非对称加密
- 使用公钥对进行加解密
- 生成一对钥匙,其中一方作为私钥,另一方就是公钥
- 私钥是只有自己知道,私钥保存在本地
- 公钥是给需要通信的人,公钥可以给其他人
- 使用公钥加密,私钥解密,一般用在数据加密传输
(A、B 2 个人,B 给 A 用加密的方式传输数据,私钥在 A 手里,B 用 A 的公钥对数据加密) - 使用私钥加密,公钥解密,一般用于认证
(A 向 B 发送数据,B 用于确认是不是 A 发送的数据,客户端 A 用 A 的私钥对数据进行加密,服务端 B 拿 A 的公钥进行解密。只管认证,不管加密性)
1.3 ssh 登录#
ssh 登录
登录方式
- 密码登录
流程
1、客户端发送登录请求
2、服务器发送机器的公钥发送给客户端
3、客户端用服务器的公钥对密码进行加密,发送给服务端
4、服务器收到密文之后,用私钥进行解密,与 /etc/shadow 进行验证
5、返回验证结果 - 密钥登录,公钥认证
1、客户端生成公钥对
2、将客户端的用户公钥发送给服务器,保存在目标用户~/.ssh/authorized_keys
3、客户端发送请求,服务器返回 1 个随机字符串
4、客户端收到随机字符串之后,用自己的私钥加密,发送给服务器
5、服务器收到密文之后,用客户端的公钥进行解密,拿到随机字符串与生成的字符串比较。返回认证结果 (随机字符串其他人拿到了就拿到了,没有任何关系,因为 A 的公钥很多人都可以有) - 弊端
- 第三方攻击
- A 无法判定收到的这个公钥是不是 B 的
- 为了解决这个问题
- 第一次登录的时候会进行人为确认
- 确认了之后,将 B 机器主机公钥存放在~/.ssh/known_hosts,以后每次登录都会进行对比 (如果系统重装后,登录不上,提示 known_hosts……,将 known_hosts 删掉)
公钥认证
1、使用命令生成公钥对
ssh-keygen
-t 选项 指定生成的加密算法
默认是 rsa 算法加密,过程中一直敲回车就可以了
2、客户端将公钥发送给服务器
保存在目标用户的~/.ssh/authorized_keys
3、检测权限
authorized_keys 600 权限
.ssh 以及家目录都给 755 以下权限
或者 允许密码验证登录时 (前提条件) # ssh-copy-id wy@192.168.0.39 -p 2233 把公钥发送过去
[root@cPen_python ~]# ssh-copy-id wy@192.168.0.39 -p 2233 # 注:需要可以支持密码登录
1.4 ssh 远程操作工具#
ssh 远程操作工具
- ssh
- 远程执行命令,远程登录
- 登录方式
- ssh 服务器 ip 地址
- 使用当前用户和默认端口登录
- 使用客户端的当前用户名,登录到远端服务器的同名用户下,默认端口 22
(没有同名用户,登录失败)- ssh 用户名 @服务器 ip 地址
- 登录到远端服务器的指定用户下,使用默认端口 22 登录
- ssh 服务器地址 -l 用户名 -p 端口号
- 指定用户名和端口去登录
- ssh -o 接一些配置选项 服务器的 ip 地址
#无序输入 yes,自动保存 hostkey
ssh -o StrictHostKeyChecking=no 192.168.0.132 -p 223- ssh -i /tmp/id_rsa 指定私钥认证文件
默认情况在~/.ssh/ 这下面找私钥- ssh -vvv
打印登录过程的详细信息
1.5 服务配置#
服务配置
- 服务安装包
-
oepnssh#
[root@cPen_python ~]# which ssh
/usr/bin/ssh
[root@cPen_python ~]# rpm -qf /usr/bin/ssh
openssh-clients-7.4p1-21.el7.x86_64
-
- 配置文件
- /etc/ssh/sshd_config 服务端配置文件
- /etc/ssh/ssh_config 客户端配置
- 主程序
服务端 /usr/sbin/sshd
客户端 /usr/bin/ssh - 重新加载配置
重启服务 service sshd restart/reload
kill -1 sshd 的 pid
kill -HUP sshd 的 pid 号
1.6 查看 ssh 服务启动情况#
查看 ssh 服务启动情况
1、ps -aux/-ef
2、pidof sshd
3、netstat -autpln 所有接口 (a) 的 udp tcp 连接,显示出所有程序 (p) 监听状态 (l) n 数字显示端口号
# 注:查看网络连接状态
# ps -eo pid,uid,comm|grep sshd # 注:-eo 查看特定字段信息
4、lsof -i:22 打印出程序所需要的文件
[root@localhost ~]# ps aux |grep sshd
root 1066 0.0 0.1 112924 4316 ? Ss 09:41 0:00 /usr/sbin/sshd -D
root 1608 0.0 0.1 158928 5608 ? Ss 09:43 0:00 sshd: root@pts/0
root 9546 0.0 0.0 112824 980 pts/0 S+ 11:26 0:00 grep --color=auto sshd
[root@localhost ~]# ps -ef |grep sshd
root 1066 1 0 09:41 ? 00:00:00 /usr/sbin/sshd -D
root 1608 1066 0 09:43 ? 00:00:00 sshd: root@pts/0
root 9550 1612 0 11:26 pts/0 00:00:00 grep --color=auto sshd
[root@localhost ~]# ps -eo pid,uid,comm|grep sshd # 注:-eo查看特定字段信息
1066 0 sshd
1608 0 sshd
1.7 ssh-agent#
ssh-agent
管理密钥
在你自己的机器上开启这个服务
配置: xshell--> 主机属性 --》ssh --》勾选 使用 xagent 进行身份验证;勾选 使用代理转发
#注:自己的机器是 Windows,在 Windows 上开启 ssh-agent 服务,现在有 A、B 2 台机器,A、B 两台机器都有 Windows 的公钥,这种情况开启 ssh-agent (xshell 里面开启),A 登录 B 时默认情况会拿 windows 的公钥进行加密,B 机器用 Windows 的私钥进行解密 必须在 xshell 里进行操作,这都是 xshell 的行为
二。跳板机#
#注:跳板机给办公人员用的 跳板机 / 堡垒机 为了保护系统的安全
#注:使用 ssh-agent 访问跳板机和想要访问的主机
#注:使用场景 阿里的业务 本来有 10 万台主机 (在局域网里面,没有外网,外部不能访问),我在家里,十万台机器捞出一台,这 1 台主机可以访问外网 (跳板机 / 堡垒机),这 1 台跳板机的配置尤其重要
开启 ssh-agent,把自己主机的公钥添加到目标主机和堡垒机下 (目标主机的权限和堡垒机的权限)
#注:连到 A 上,从 A 跳到 B 上,B 不一定有当前主机的公私钥
#跳板机 安全加固:
不能使用 root 直接登录,使用 sudo 赋予相应权限
不能使用默认端口登录
不能使用密码登录,都使用公钥登录
添加防火墙配置
总结:
#跳板机
#安全加固
1、不能使用密码登录
2、不能使用 root 登录
3、修改默认端口
4、添加防火墙配置
5、使用跳板机登录
示例1:查看路由 ip r
--------------------------------------------------------------------------------------------
[root@cPen_python ~]# ip r # 注:查看路由
default via 192.168.0.1 dev ens33 proto dhcp metric 100
192.168.0.0/24 dev ens33 proto kernel scope link src 192.168.0.32 metric 100
[root@cPen_python ~]# ip r delete default via 192.168.0.1 # 注:删除网关
[root@cPen_python ~]# ip r
192.168.0.0/24 dev ens33 proto kernel scope link src 192.168.0.32 metric 100
[root@cPen_python ~]# ping www.baidu.com # 注:删除后ping不通外网
connect: 网络不可达
[root@cPen_python ~]# ping 8.8.8.8
connect: 网络不可达
[root@cPen_python ~]# ip r add default via 192.168.0.1 # 注:还原
============================================================================================
示例2:A机器登录到B机器(简化登录) vim .ssh/config
#以后会遇到很多机器,ip地址是记不住的
--------------------------------------------------------------------------------------------
#A机器登录到B机器,操作前需要先把A机器公钥放到B机器上 进行授权
#不修改全全局配置,只修改个人配置:在用户家目录下创建.隐藏文件
#在客户端上配置(配到自己的主机上)
#注:意思是将机器root@192.168.0.31 -p 2233 取个别名叫B
#ForwardAgent yes # 注:转发 开启
#StrictHostKeyChecking no # 注:不需要输入yes 直接把key保存在known_hosts里面
#ServerAliveInterval 60 # 注:存活状态,检测服务存活状态
#IdentityFile ~/.ssh/id_rsa # 注:指定认证私钥
#示例如下
[root@cPen_python ~]# vim .ssh/config
###############################################
ForwardAgent yes
StrictHostKeyChecking no
ServerAliveInterval 60
IdentityFile ~/.ssh/id_rsa
###############################################
Host B
HostName 192.168.0.31
User cPen
Port 2233
[root@cPen_python .ssh]# chmod 600 config # 注:授予权限 不执行这条语句 可能会报错
[root@cPen_python .ssh]# ssh B
Last login: Mon Nov 23 15:05:16 2020 from 192.168.0.32 # 注:登录成功
[root@cPen_centos8 ~]#
#注:即简化 # ssh 192.168.0.31 -l root -p 2233 操作 (比如登录到ftp服务器 ssh ftp)
============================================================================================
示例3:查看端口连接状态 (客户机想访问服务器的时候使用 客户机上telnet) telnet 192.168.0.31 2233
#注:这个命令只能测tcp的 udp的测不了,但是大部分服务都是tcp的
#查看端口是否可以访问(即服务是否可达) telnet 192.168.0.31 2233
--------------------------------------------------------------------------------------------
#ping命令 是查看2台机器网络是否连通
#查看服务是否可达使用 telnet命令
#示例:查看端口是否可达(服务是否可达)
[root@cPen_python .ssh]# yum install telnet -y
[root@cPen_python .ssh]# telnet 192.168.0.31 2233
Trying 192.168.0.31...
Connected to 192.168.0.31. # 注:服务可达
Escape character is '^]'.
SSH-2.0-OpenSSH_8.0
============================================================================================
示例4:提示主机不被信任 WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED!
--------------------------------------------------------------------------------------------
#注:提示WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED!
将~/.ssh/known_hosts 删掉
============================================================================================
示例5:永久修改主机名 hostnamectl set-hostname "A"
--------------------------------------------------------------------------------------------
#方法1
[root@cPen_python .ssh]# hostnamectl set-hostname "A"
#注:其实是修改 /etc/hostname
[root@A ~]# less /etc/hostname
#方法2
#或者直接修改 /etc/hostname
#临时修改主机名
[root@B ~]# hostname cp
============================================================================================
示例6:查看进程数 pstree -p
--------------------------------------------------------------------------------------------
#注:看程序树状结构 pstree -p
[root@cPen_python .ssh]# pstree -p |grep sshd
|-sshd(1065)-+-sshd(3782)---bash(3784)
| |-sshd(3980)---bash(3982)-+-grep(4318)
| |-sshd(4059)---bash(4061)
| `-sshd(4288)---bash(4290)
#注:前面是父程序,后面是父程序创造出来的子程序,子程序分配新的bash环境,bash环境在操作命令grep
#注:父进程创造出子进程,子进程有创造出一个子进程,子进程创造出一个新的bash环境
#-------------------------------------------------------------------------------------------
#注:连接到B机器后bash环境多了一个ssh子进程去处理B机器
[root@a ~]# ssh B
Last login: Mon Nov 23 15:52:16 2020 from 192.168.0.32
[root@a .ssh]# pstree -p |grep sshd
|-sshd(1065)-+-sshd(3782)---bash(3784)
| |-sshd(3980)---bash(3982)-+-grep(4325)
| |-sshd(4059)---bash(4061)---ssh(4323)
| `-sshd(4288)---bash(4290)
============================================================================================
示例7:修改客户端配置 ~/.ssh/config
#配置文件:~/.ssh/config
#工作中使用跳板机代理登录 (客户端的配置,方便开发配置)
--------------------------------------------------------------------------------------------
#注:假设现在有A、B、C三台机器,B是跳板机,假设A C不通,A通B,B通C,B通D,B通E…………
#注:B机器当做跳板机,A是自己的本地机,A机器做代理,B机器自动做转发
#注:在本地机A机器中操作
[root@a ~]# vim ~/.ssh/config
###############################################
ForwardAgent yes
StrictHostKeyChecking no
ServerAliveInterval 60
IdentityFile ~/.ssh/id_rsa
###############################################
Host B
HostName 192.168.0.31
User sanchuang
Port 2233
Host 192.168.0.54
User sanchuang
Port 2233
ProxyCommand ssh 192.168.0.31 -W %h:%p -l sanchuang -p 2233
#注:ProxyCommand表示 A通过跳板机(192.168.0.31)B登录到
#-------------------------------------------------------------------------------------------
Host * /ftp* /10.* 以10网段开头的ip地址 ssh 10.0.0.1 跳到这个配置执行
User sanchuang
Port 2233
ProxyCommand ssh B nc %h %p -w 10 2>/dev/null
#注:上课时冲突 前面写Host *与ssh B冲突
============================================================================================
示例8:远程执行命令 ssh B
--------------------------------------------------------------------------------------------
#不登录B机器,执行B机器上的命令 (一般用于脚本)
[root@a ~]# ssh B ifconfig # 注:登录到B执行 ifconfig命令
[root@a ~]# ssh B ip a # 注:登录到B执行 查看ip地址 命令 ;命令的返回是B机器给的
[root@a ~]# ssh B "/usr/sbin/ip a" # 注:脚本里建议使用命令的绝对路径
============================================================================================
示例9:远程传输 scp (前提ssh可以连接)
--------------------------------------------------------------------------------------------
#注:传输文件
[root@a ~]# touch ahost
[root@a ~]# scp ahost B:/tmp # 注:将A机器 当前路径ahost文件cp到B机器下的/tmp路径下
ahost 100% 0 0.0KB/s 00:00
[root@a ~]# scp B:/tmp/bhost ./ # 注:将B机器 /tmp/bhost文件cp到当前路径
bhost 100% 0 0.0KB/s 00:00
[root@a ~]# scp B:tmp/testhost ./ # 注:将B机器 家目录下 tmp/testhost文件cp到当前路径
#注:传输目录
[root@a ~]# scp -r adir B: # 注:将A机器当前路径下 adir文件夹 cp到B机器家目录下
[root@a ~]# scp -r adir B:bdir # 注:复制文件夹并改名
[root@a ~]# scp -r adir B:bdir/ # 注:和上面的没有区别
============================================================================================
示例10:sftp传输文件 (前提ssh可以连接)
--------------------------------------------------------------------------------------------
#注:ftp文件传输
#注:sftp 传输文件 本地和异地传输文件
#注:格式 sftp 用户名@主机名
[sanchuang@a ~]$ sftp B
Connected to B.
sftp> ls # 注:显示远程目录列表
2q aa adir bb bdir testdir testdir2 testhost
sftp> get bdir
Fetching /home/sanchuang/bdir/ to bdir
Cannot download non-regular file: /home/sanchuang/bdir/
sftp> mget bdir
Fetching /home/sanchuang/bdir/ to bdir
Cannot download non-regular file: /home/sanchuang/bdir/
sftp> get 2q # 注:get 远程路径 下载文件
Fetching /home/sanchuang/2q to 2q
/home/sanchuang/2q 100% 226 107.5KB/s 00:00
sftp> exit
============================================================================================
示例11:pssh pscp命令 (前提ssh可以连接)
--------------------------------------------------------------------------------------------
#批量处理
pssh
-h 指定主机文件列表,内容格式”[user@]host[:Port]”
-i 指定每个服务器的处理信息
[root@a ~]# yum install pssh -y # 注:没有的话需要安装epel源
[root@a ~]# cat ip.txt
192.168.0.31:2233
192.168.0.54:22
[root@a ~]# pssh -h ip.txt -i "/usr/sbin/ip a"
[1] 17:18:13 [FAILURE] 192.168.0.54:22 Exited with error code 255、
Permission denied (publickey,gssapi-keyex,gssapi-with-mic,password).
…… # 注:需要保证ssh能不能过去
[2] 17:18:13 [SUCCESS] 192.168.0.31:2233 # 注:返回SUCCESS表示执行成功
……
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
……
2: ens33: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP group default qlen
……
#-------------------------------------------------------------------------------------------
#ip.txt里面可以这样写
[root@a ~]# vim ip.txt
sanchuang@192.168.0.31:2233
sanchuang@192.168.0.54:2233
============================================================================================
示例12:pscp.pssh 批量传输文件 (前提ssh可以连接)
--------------------------------------------------------------------------------------------
[root@a ~]# pscp.pssh -h ip.txt pscptest /tmp
# 注:把当前目录下的pscptest文件传送到目标主机的/tmp目录下
[root@a ~]# vim ip.txt
sanchuang@192.168.0.31:2233
sanchuang@192.168.0.54:2233
[root@a ~]# pscp.pssh -h ip.txt pscptest /tmp
[1] 17:41:31 [FAILURE] sanchuang@192.168.0.54:2233 Exited with error code 1
[2] 17:41:31 [SUCCESS] sanchuang@192.168.0.31:2233
============================================================================================
示例13:fping 批量ping(前提ssh可以连接)
--------------------------------------------------------------------------------------------
#注:批量ping 使用fping命令
[root@a ~]# yum install fping -y
[root@a ~]# fping -g 192.168.0.1/24 # 注:-g 根据网段去ping
192.168.0.1 is alive
……
192.168.0.254 is unreachable
[root@a ~]# fping -f ip.txt # 注:-f根据文件指定ip去ping
192.168.0.31 is alive
192.168.0.54 is alive
[root@a ~]# vim ip.txt
192.168.0.31
192.168.0.54
三. ssh 服务补充#
3.1 ssh#
ssh --> secure shell
作用:远程登录和操作远程的服务器 --> 信息加密 --> 非常安全的远程登录协议
#注:远程登录远程操控 省成本
ssh 协议 属于应用层的协议
Linux:openssh --> centos7/8 自带
Windows 没有 ssh 协议
3.2 命令#
命令:
ssh
scp # 注:远程 copy
sftp
ssh-keygen
ssh-copy-id
3.3 登录方式#
登录方式:
Xshell # 注:不开源
putty # 注:开源
secureCRT # 注:开源
- 用户名和密码
/etc/passwd # 注:放用户名
/etc/shadow # 注:放密码
- 密钥
公钥和私钥
public key --> 公开 # 注:给别人
private key # 注:自己所有
3.4 安全加固措施#
安全加固措施:
修改端口号 22
nmap # 注:端口扫描
nc # 注:端口扫描
禁用 root
su # 注:su 切换到 root
密码复杂性
启用密钥 # 注:禁止密码认证
打补丁 或者 安装最新版本的 ssh 软件
iptables 防火墙
#注:免密通道(密钥登录)
3.5 免密通道#
免密通道:
单向信任 # 注:把密钥给其他主机
双向信任 # 注:双方互给公钥
#注:一般用 root 用户,为了安全起见用普通用户
3.6 ansible#
ansible:自动化运维的工具:批量管理和操作
#注:ansible 批量管理 批量部署的软件;底层用的 ssh 协议,推荐建立免密通道
#注:ansible 软件 用 Python 写的
3.7 日志文件:/var/log/secure#
日志文件:/var/log/secure
[root@cPen_centos8 ssh]# vim /etc/ssh/sshd_config
# Logging
#SyslogFacility AUTH
SyslogFacility AUTHPRIV # 注:日志类型 认证类型 AUTHPRIV 设置
#LogLevel INFO
日志文件:
/var/log/secure
[sanchuang@cPen_centos8 ~]$ ps aux|grep rsyslog # 注:外包日志的进程
ssh将自己的日志功能外包给rsyslog服务去帮它记录日志
[sanchuang@cPen_centos8 ~]$ vim /etc/rsyslog.conf
# The authpriv file has restricted access.
authpriv.* /var/log/secure
3.8 ssh 服务登录不了,如何排除?#
ssh 服务登录不了,如何排除?
检测网络是否通畅
ping
检测 ssh 服务是否启动,检查端口,selinux
ssh 的配置:是否禁用 root,是否禁用密码认证
检查防火墙 iptables
service firewalled stop
黑白名单 # 注:centos6、7 里面用,8 里面没有
3.9 ssh 免密通道#
ssh 免密通道
生成密钥对
ssh-keygen
ssh-keygen -t ecdsa
上传公钥
ssh-copy-id -i id_ecdsa.pub root@192.168.0.35
ssh-copy-id -p 2299 -i id_ecdsa.pub root@192.168.0.35
远程连接
ssh -p '2299' 'root@192.168.0.39'
免密通道的建立步骤:
[root@localhost .ssh]# ssh-keygen -t ecdsa
[root@localhost .ssh]# ssh-copy-id -p 2299 -i id_ecdsa.pub root@192.168.0.39
[root@localhost .ssh]# ssh -p '2299' 'root@192.168.0.39'
known_hosts:存放我们曾经ssh连接过的机器的公钥
scp 就是在2台机器之间底层使用ssh协议来拷贝文件或者文件夹
[root@cPen_centos8 ssh]# ssh root@192.168.0.24 # 注:远程登录
[root@cPen_centos8 ssh]# ssh root@192.168.0.24 df -Th # 注:远程执行命令
[root@cPen_python ssh]# scp echo.sh root@192.168.0.35:/root # 注:传文件 (源文件 远程)
[root@cPen_python ssh]# scp -r /boot root@192.168.0.35:/root # 注:传文件夹
[root@cPen_python ssh]# scp -r root@192.168.0.35:/etc/passwd # 注:拿文件夹
[root@cPen_python ssh]# ssh root@192.168.0.35 bash /root/echo.sh feng zhang wang
scp 就是在2台机器之间底层使用ssh协议来拷贝文件或者文件夹
---------------------------------------------------------------------------------------------------------------------------------
[root@cPen_centos8 ssh]# getenforce # 注:查看selinux
Disabled
[root@cPen_centos8 ssh]# setenforce 0 # 注:临时关闭selinux
setenforce: SELinux is disabled
---------------------------------------------------------------------------------------------------------------------------------
[sanchuang@cPen_centos8 ~]$ ifdown ens33
[sanchuang@cPen_centos8 ~]$ ifup ens33
#注:禁用root用户登录后,本地可以用root用户登录