浅谈OpenSSH及SSH协议
OpenSSH
一、SSH协议
- ssh: secure shell,TCP连接,默认端口号22,安全的端口登录
- 软件实现:OpenSSH, dropbear
- 协议版本:当前使用ssh v2,基于DH算法做密钥交换,基于RSA或DSA实现身份认证
- 登录认证方式:基于password和基于key两种方式
二、OpenSSH
- 基于C/S结构
- client: ssh, scp, xshell, securecrt
- server: sshd
- ssh客户端:
- 路径:/etc/ssh/ssh_config
- 配置项:
StrictHostKeyChecking 首次登录检查Key,默认为"ask"提示,设为"no"不提示 - 语法:
ssh [user@]host [COMMAND]
默认以当前本机登录用户名登录远程主机
ssh [-l user] host [COMMAND] -l
指定用户登录远程主机
选项:
-p port:远程服务器监听的端口
-b:指定连接的源IP
-v:调试模式
-C:压缩方式
-X:支持x11转发
-Y:支持信任x11转发
-t:强制伪tty分配
//通过ssh直连remoteserver1实现间接连接至remoteserver2
ssh -t remoteserver1 ssh remoteserver2
OpenSSH远程验证
-
openssh实现远程主机验证的方式:
当用户远程连接ssh服务器时,会复制ssh服务器/etc/ssh/ssh_host*key.pub文件中的公钥到客户机的~./ssh/know_hosts中。下次连接时,会自动匹配相应私钥,不能匹配,将拒绝连接 -
ssh服务登录验证:基于用户/口令和基于密钥两种方式
- 基于用户/口令登录
- step 1 客户端发起ssh请求,服务器会把自己的公钥发送给用户
- step 2 用户会根据服务器发来的公钥对密码进行加密
- step 3 加密后的信息回传给服务器,服务器用自己的私钥解密,如果密码正确,则用户登录成功
- 基于密钥登录
- step 1 首先在客户端生成一对密钥
- step 2 并将客户端的公钥拷贝到服务端
- step 3 当客户端再次发送一个连接请求,包括ip, 用户名
- step 4 服务端得到客户端的请求后,会到authorized_keys中查找,如果有响应的IP和用户,就会随机生成一个字符串,例如:acdf
- step 5 服务端使用客户端拷贝过来的公钥进行加密,然后发送给客户端
- step 6 得到服务端发来的消息后,客户端会使用私钥进行解密,然后将解密后的字符串发送给服务端
- step 7 服务端接受到客户端发来的字符串后,跟之前的字符串进行对比,如果一致,就允许免密码登录
- 基于用户/口令登录
-
实现基于密钥登录
- 在客户端生成密钥对,-P ‘’:私钥不设置密码
ssh-keygen -t rsa [-P ''] [-f "~/.ssh/id_rsa"]
- 在客户端生成密钥对,-P ‘’:私钥不设置密码
[root@Centos7 ~]#ssh-keygen -t rsa -P '' -f ~/.ssh/id_rsa
Generating public/private rsa key pair.
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:GmCV/wiqDs4mJP/XWxuPRQ0UsCES7tC4DRi7NNtbJVo root@Centos7.server0
The key's randomart image is:
+---[RSA 2048]----+
| . +o. o.o. |
| + =.. . + |
| = * E.. . . |
| . * X.o. o |
| o +.=.So . . |
|.. .o o. .. |
|+. .. .. o . |
|+oo . .. * |
|o+.... ..o . |
+----[SHA256]-----+
- 把公钥文件传输至远程服务器对应用户的家目录
ssh-copy-id [-i [identity_file]] [user@]host
注意传输本机公钥到远程服务器直接可以ssh-copy-id [user@]host
,默认选择本机公钥
[root@Centos7 ~]#ssh-copy-id -i ~/.ssh/id_rsa.pub 172.20.54.2
/usr/bin/ssh-copy-id: INFO: Source of key(s) to be installed: "/root/.ssh/id_rsa.pub"
/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@172.20.54.2's password:
Number of key(s) added: 1
Now try logging into the machine, with: "ssh '172.20.54.2'"
and check to make sure that only the key(s) you wanted were added.
[root@Centos7 ~]#ssh 172.20.54.2
Last login: Thu Nov 7 10:08:32 2019 from 172.20.3.69
- 修改私钥的密码
ssh-keygen -p
[root@Centos7 ~]#ssh-keygen -p
Enter file in which the key is (/root/.ssh/id_rsa):
Enter new passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved with the new passphrase.
[root@Centos7 ~]#ssh 172.20.54.2
Enter passphrase for key '/root/.ssh/id_rsa':
Last login: Fri Nov 8 19:55:04 2019 from 172.20.54.1
- 使用验证代理,只需要输入一次密码,之后所有的ssh连接输入私钥密码的工作由代理完成。bash进程结束,代理工作结束;下次登录时,重新启动代理。
ssh-agent bash
启用代理
ssh-add
密码添加给代理
[root@Centos7 ~]#ssh-agent bash
[root@Centos7 ~]#ssh-add
Enter passphrase for /root/.ssh/id_rsa:
Identity added: /root/.ssh/id_rsa (/root/.ssh/id_rsa)
[root@Centos7 ~]#ssh 172.20.54.2
Last login: Fri Nov 8 19:55:46 2019 from 172.20.54.1
[root@Centos7 ~]#exit
logout
Connection to 172.20.54.2 closed.
[root@Centos7 ~]#ssh 172.20.54.2
Last login: Fri Nov 8 19:59:17 2019 from 172.20.54.1
加密文件传输工具:scp, rsysc, sftp, pssh
scp工具
- 来源于openssh-clients软件包
- scp遇到相同文件直接覆盖操作
- 语法:
scp [options] SRC... DEST/
scp [options] [user@]host:/sourcefile /destpath
:将远程主机文件复制到本地
scp [options] /sourcefile [user@]host:/destpath
:将本地文件复制到远程主机 - 常用选项:
-C: 压缩数据流
-r: 递归复制
-p: 保持原文件的属性信息
-q: 静默模式
-P PORT: 指明remote host的监听端口
rsync工具
-
基于ssh和rsh服务实现高效率的远程系统之间复制文件
-
使用安全的shell连接做为传输方式
-
比scp更快,只复制不同的文件
-
语法:
rsync -av /etc server1:/tmp
:复制目录和目录下文件
rsync -av /etc/ server1:/tmp
:只复制目录下文件 -
选项:
-n 模拟复制过程
-v 显示详细过程
-r 递归复制目录树
-p 保留权限
-t 保留时间戳
-g 保留组信息
-o 保留所有者信息
-l 将软链接文件本身进行复制(默认)
-L 将软链接文件指向的文件复制
-a 存档,相当于–rlptgoD,但不保留ACL(-A) 和SELinux属性(-X)
[root@Centos7 /data/ceshi]#rsync -av ./* 172.20.54.2:/data
sending incremental file list
test1
test2
test3
172.20.54.2/
172.20.54.2/test1
172.20.54.2/test2
172.20.54.2/test3
sent 415 bytes received 142 bytes 371.33 bytes/sec
total size is 0 speedup is 0.00
[root@Centos7 /data/ceshi]#echo >> test3
[root@Centos7 /data/ceshi]#rsync -av ./* 172.20.54.2:/data
sending incremental file list
test3
sent 221 bytes received 36 bytes 514.00 bytes/sec
total size is 1 speedup is 0.00
sftp工具
- 交互式文件传输工具
- 用法和传统的ftp工具相似
- 利用ssh服务实现安全的文件上传和下载
- 使用ls cd mkdir rmdir pwd get put等指令,可用?或help获取帮助信息
pssh工具
- pssh是一个python编写可以在多台服务器上执行命令的工具,也可实现文件复制
- 选项如下:
–version:查看版本
-h:主机文件列表,内容格式"[user@]host[:port]"
-H:主机字符串,内容格式"[user@]host[:port]"
-l:登录使用的用户名
-o:输出的文件目录
-O:SSH的选项
-v:详细模式
-A:手动输入密码模式
-x:额外的命令行参数使用空白符号,引号,反斜线处理
-X:额外的命令行参数,单个参数模式,同-x
-i:每个服务器内部处理信息输出
-P:打印出服务器返回信息 - 示例如下:
#通过pssh批量关闭seLinux
[root@Centos7 /etc/yum.repos.d]#pssh -H root@172.20.54.2 -i 'sed -ri "s/^SELINUX=.*/SELINUX=disabled/" /etc/selinux/config'
[1] 20:36:49 [SUCCESS] root@172.20.54.2
#批量发送指令
[root@Centos7 /etc/yum.repos.d]#pssh -H "root@172.20.54.2 yijie@172.20.54.2" -i hostname
[1] 20:46:00 [SUCCESS] root@172.20.54.2
Centos7.server0
[2] 20:46:00 [SUCCESS] yijie@172.20.54.2
Centos7.server0
#当不支持ssh的key认证时,通过 -A选项,使用密码认证批量执行指令
pssh -H yijie@172.20.54.2 -A -i hostname
#将标准错误和标准正确重定向都保存至本地主机的/data目录下
[root@Centos7 /etc/yum.repos.d]#pssh -H yijie@172.20.54.2 -o /data -e /data -i hostname
[1] 21:02:55 [SUCCESS] yijie@172.20.54.2
Centos7.server0
[root@Centos7 /etc/yum.repos.d]#ls /data
yijie@172.20.54.2
#获取每台服务器的uptime:
pssh -h ip.txt -i uptime
[1] 11:15:03 [SUCCESS] Mar.mars.he
11:15:11 up 4 days, 16:25, 1 user, load average: 0.00, 0.00, 0.00
[2] 11:15:03 [SUCCESS] Jan.mars.he
11:15:12 up 3 days, 23:26, 0 users, load average: 0.00, 0.00, 0.00
[3] 11:15:03 [SUCCESS] Feb.mars.he
11:15:12 up 4 days, 16:26, 2 users, load average: 0.08, 0.02, 0.0
#保存每台服务器运行的结果:
pssh -h IP.txt -i -o /tmp/pssh/ uptime
[1] 11:19:47 [SUCCESS] Feb.mars.he
11:19:55 up 4 days, 16:31, 2 users, load average: 0.02, 0.03, 0.00
[2] 11:19:47 [SUCCESS] Jan.mars.he
11:19:56 up 3 days, 23:30, 0 users, load average: 0.01, 0.00, 0.00
[3] 11:19:47 [SUCCESS] Mar.mars.he
11:19:56 up 4 days, 16:30, 1 user, load average: 0.00, 0.00, 0.00
pscp.pssh命令
- pscp.pssh功能是将本地文件批量复制到远程主机
- 语法:
pscp [-vAr] [-h hosts_file] [-H [user@]host[:port]] [-l user] [-p par] [-o outdir] [-e errdir] [-t timeout] [-O options] [-x args] [-X arg] local remote
- pscp-pssh选项
-v 显示复制过程
-r 递归复制目录 - 示例:
// 将本地curl.sh 复制到/app/目录
pscp.pssh -H 172.20.54.2 /root/test/curl.sh /app/
// 将本地curl.sh 复制到host.txt文件列表内的多个主机
pscp.pssh -h host.txt /root/test/curl.sh /app/
// 将本地多个文件批量复制到/app/目录
pscp.pssh -H 172.20.54.2 /root/f1.sh /root/f2.sh /app/
// 将本地目录批量复制到/app/目录
pscp.pssh -H 172.20.54.2 -r /root/test/ /app/
pslurp命令
- pslurp功能是将远程主机的文件批量复制到本地
- 语法
pslurp [-vAr] [-h hosts_file] [-H [user@]host[:port]] [-l user] [-p par][-o outdir] [-e errdir] [-t timeout] [-O options] [-x args] [-X arg] [-L localdir] remote local(本地名)
- pslurp选项
-L 指定从远程主机下载到本机的存储的目录,local是下载到本地后的名称
-r 递归复制目录 - 下载目标服务器的passwd文件至/app下,并更名为user
pslurp -H 192.168.1.10 -L /app /etc/passwd user
- 批量下载
host.txt
目标服务器的passwd文件至/app下,并更名为user
pslurp -H host.txt -L /app /etc/passwd user
SSH端口转发(又名“隧道”)
一、SSH 端口转发的功能
- SSH端口转发:SSH将其他TCP 端口的网络数据通过SSH 链接来转发,并且自动提供了相应的加密及解密服务
- SSH端口转发又名隧道(tunneling),SSH为其他TCP协议提供了一个安全的传输通道。
- 功能:
- 加密SSH Client 端至SSH Server 端之间的通讯数据
- 突破防火墙的限制完成一些之前无法建立的TCP 连接
二、SSH本地转发
-
语法:
ssh -L local_port:remote_host:remote_host_port ssh_server
local_port
:本地端口(防火墙外)
remote_host
:远程主机IP(防火墙内)
remote_host_port
:远程主机不安全的TCP协议端口(防火墙内)
ssh_server
:充当跳板机的ssh服务器IP(防火墙内) -
选项:
-f 后台启用
-N 不打开远程shell,处于等待状态
-g 启用网关功能 -
网络连接状态如图所示:
-
示例:
- 建立从本机到telnet服务器23端口的连接,监听本机2009端口,以sshsrv服务器为跳板
ssh -L 2009:telnetsvr:23 -Nf sshsrv
- 当访问本机的2009的端口时,被加密后转发到sshsrv的ssh服务,再解密被转发至telnetsrv的23端口
telnet 127.0.0.1 2009
- 信息在端口间的流向:
data <<==>> local_host:2009 <<==>> local_host:XXXXX <<==>> ssh_srv:22 <<==>> ssh_srv:YYYYY <<==>> telnet_srv:23
- 建立从本机到telnet服务器23端口的连接,监听本机2009端口,以sshsrv服务器为跳板
实验:建立SSH本地转发
- 分析:
建立从本机172.20.54.1
到telnet服务器172.20.54.3
的连接,中间将ssh服务器172.20.54.2
作为跳板,本地转发端口2019
ssh -L 2019:172.20.54.3:23 -Nf 172.20.54.2
本地建立连接
telnet 127.0.0.1 2019
本地转发连接远程telnet服务器 - 准备工作
yum -y install telnet-server
yum -y install telnet
systemctl strat telnet.socket
systemctl status telnet.socket
[root@Centos7 ~]#ssh -L 2019:172.20.54.3:23 -Nf 172.20.54.2
[root@Centos7 ~]#ss -ntl
State Recv-Q Send-Q Local Address:Port Peer Address:Port
LISTEN 0 128 127.0.0.1:2019 *:*
LISTEN 0 128 *:22 *:*
[root@Centos7 ~]#telnet 127.0.0.1 2019
Trying 127.0.0.1...
Connected to 127.0.0.1.
Escape character is '^]'.
Kernel 3.10.0-1062.4.1.el7.x86_64 on an x86_64
telnetserver login:
- 本地主机端口连接情况:本机连接至跳板机的ssh服务22端口
- 跳板机端口连接情况:跳板机一方面与本机以ssh服务22端口连接,一方面与远程服务器以telnet服务23端口连接
- 服务器端
- 数据流向:
data <<==>> 127.0.0.1:2019 <<==>> 172.20.54.1:35750 <<==>> 172.20.54.2:22 <<==>> 172.20.54.2:54276 <<==>> 172.20.54.3:23 - 关闭通道
ss -ntlp | grep 2019
kill -9 pid
三、SSH远程转发
- 语法:
ssh -R ssh_server_port:remote_host:remote_host_port ssh_server
ssh_server_port
:(防火墙外)
remote_host_port
:(防火墙内)
remote_host_port
:(防火墙内)
ssh_server
:(防火墙外) - 网络连接状态如图所示:
- 示例:
- 建立从ssh服务器到telnet服务器23端口的连接,监听ssh服务器2019端口,以ssh客户端为跳板
ssh -R 2019:telnetsv:23 -Nf ssh_server
- 当访问本机的2019端口时,将加密信息通过ssh服务转发请求到本机ssh客户端,再由本机解密后转发到telnetsrv的23端口
telnet testsv 2019
- 信息在端口间的流向:
Data <==> ssh_srv:2019 <==> ssh_srv:22 <==> local_host:XXXXX <==> local_host:YYYYY <==> telnet_srv:23
实验:建立SSH远程转发
- 建立从ssh服务器172.20.54.1到telnet服务器170.20.54.3的连接,中间将本机172.20.54.2作为跳板,远程转发端口2019
ssh -R 2019:172.20.54.3:23 -Nf 172.20.54.1
本机建立连接
- telnet 127.0.0.1 2019 远程ssh服务器连接远程telnet服务器
- ssh服务器端口连接情况:ssh服务器的22端口与主机相连
- 主机端口连接情况:一方面作为客户机与防火墙外的ssh服务器连接,另一方面与防火墙内的telnet服务器的23端口连接
- telnet服务器端口连接情况:telnet服务器的23端口与主机相连
- 关闭通道
ss -ntlp | grep 2019
kill -9 pid
四、SSH端口转发
-
当用浏览器访问internet时,本机的1080端口做为代理服务器,浏览器的访问请求被转发到ssh_server上,由ssh_server替之访问internet
-
示例:
ssh -D 2019 root@sshserver
建立本地2019端口至ssh_server的ssh连接,由ssh服务器访问172.20.54.3的httpd服务
在浏览器设置代理本地代理:ip:127.0.0.1 port:2019
实验:建立SSH端口转发
- 准备工作
- 在服务端安装 httpd
yum -y install httpd
echo "welcome test" > /var/www/html/index.html
SSH的X协议转发
- X协议:C/S结构,Client程序向Server发出请求,Server响应请求并展现相关图形界面
所有的图形应用程序都是X客户程序
能够通过TCP/IP连接远程X服务器
数据没有加密机制,可以通过ssh连接隧道安全传输 - OpenSSH的实现:
ssh -X user@remotehost COMMAND
完