SSH命令工具研究报告

0 什么是SSH

Secure Shell(安全外壳协议,简称SSH)是一种加密的网络传输协议,可在不安全的网络中为网络服务提供安全的传输环境。SSH通过在网络中创建安全隧道来实现SSH客户端与服务器之间的连接。虽然任何网络服务都可以通过SSH实现安全传输,SSH最常见的用途是远程登录系统,人们通常利用SSH来传输命令行界面和远程执行命令。

1 使用SSH登录远程计算机

SSH是我们常用的远程加密登录系统的网络协议,一个典型的使用场景是在Linux系统上登录远程的Linux服务器,本文主要介绍在Linux中使用 OpenSSH 的进行远程登录,并分析其背后的原理。

以下命令中,remote$是指远程计算机,local$是指本地计算机,笔者使用的Linux发行版为Manjaro,你可以根据你自己的系统执行相应的命令。

1.0 配置SSH Server

  • 从软件源安装OpenSSH:
remote$ pacman -S openssh 

OpenSSH 是 SSH 协议的免费开源实现。OpenSSH提供了服务端后台程序和客户端工具,用来加密远程控制和文件传输过程中的数据,并由此来代替原来的类似服务。

  • 设置开机启动SSH服务:
remote$ systemctl enable sshd.service
  • 立即启动SSH服务:
remote$ systemctl start sshd.service
  • 重新启动SSH服务:
remote$ systemctl restart sshd.service

1.1 使用SSH Client访问远程计算机

  • 使用用户名和密码登录远程计算机:
local$ ssh user@remote -p port

user 是远程机器上的用户名,默认为当前用户

remote 是远程机器的地址,可以是 IP、域名、或别名

port 是 SSH Server 监听的端口,默认值为 22

  • 如果想为以上配置输入别名,那么在 ~/.ssh/config 里面追加以下内容,其中alias是由你指定的别名:
Host alias
    HostName remote
    User user
    Port port

这时使用账户和密码登录SSH Server,不但麻烦,还不够安全。下面将介绍使用SSH钥匙进行免密码登录。

1.2 设置免密码登录

  • 在SSH Client生成SSH钥匙:
local$ ssh-keygen

生成的钥匙默认保存在~/.ssh中,其中公钥放在了~/.ssh/id_rsa.pub,私钥放在了 ~/.ssh/id_rsa

  • 将生成的公钥告诉SSH Server:
local$ ssh-copy-id -i ~/.ssh/id_rsa.pub user@host

这时,再登录SSH Server,就只需一条简单的命令:

local$ ssh alias

使用钥匙登录SSH Server,不但更加方便,安全性也提高了,这是为什么呢?下面介绍一下SSH钥匙登录的原理。

2 原理介绍

2.1 密码登录

当使用SSH通过密码登录时,过程如下:

SSH命令工具研究报告_第1张图片
从上图中,可以看到我们使用SSH进行登陆时,主要分为以下几步:

1.用户使用ssh user@host命令对SSH Server发起登陆;
2.SSH Server将自己的公钥返回给SSH Client;
3.SSH Client使用公钥对用户输入的密码进行加密;
4.SSH Client将加密后的密码发送给SSH Server;
5.SSH Server使用私钥对密码进行解密;
6.最后,SSH Server判断解密后的密码是否与用户密码一致,一致就同意登陆,否则反之。
这个过程乍一看没有任何问题,但是在实际工作中,却是存在风险漏洞的。由于SSH不像https协议那样,SSH协议的公钥是没有证书中心(CA)公证的,也就是说,都是自己签发的。这就导致如果有人截获了登陆请求,然后冒充SSH Server,将伪造的公钥发给用户,那么用户很难辨别真伪,用户再通过伪造的公钥加密密码,再发送给冒充主机,此时冒充的主机就可以获取用户的登陆密码了,那么SSH的安全机制就荡然无存了,这也就是我们常说的中间人攻击。

而使用SSH钥匙,就能够防范中间人攻击了。

2.2 密钥登录

SSH命令工具研究报告_第2张图片

上图就是SSh免密登陆原理图,从上图可以看出,SSH免密登陆的前提是使用ssh-keygen生成公私钥匙对,然后通过ssh-copy-id -i ~/.ssh/id_rsa.pub user@host命令将公钥分发至SSH Server。接下来的每次免密登陆步骤如下:

  1. 用户使用ssh user@host命令对SSH Server发起登陆;
  2. SSH Server对用户返回一个随机串;
  3. SSH Client使用私钥对这个随机串进行加密,并将加密的随机串返回至SSH Server;
  4. SSH Server使用分发过来的公钥对加密随机串进行解密;
  5. 如果解密成功,就证明用户的登陆信息是正确的,则允许登陆;否则反之。

通过ssh-copy-id -i ~/.ssh/id_rsa.pub user@host命令分发的公钥都会被保存至SSH Server的~/.ssh/authorized_keys文件中。

2.3 非对称加密

2.3.1 对称加密与非对称加密

  • 对称加密:加密和解密使用的是同一个密钥,加解密双方必须使用同一个密钥才能进行正常的沟通。

  • 非对称加密:需要两个密钥来进行加密和解密,公开密钥(public key,简称公钥)和私有密钥(private key,简称私钥) ,公钥加密的信息只有私钥才能解开,私钥加密的信息只有公钥才能解开。

需要注意的一点,这个公钥和私钥必须是一对的,如果用公钥对数据进行加密,那么只有使用对应的私钥才能解密,所以只要私钥不泄露,那么我们的数据就是安全的。

  • 对于加密:公钥加密,私钥加密。毕竟公钥可以公开,但是私钥只有你自已知道,你也同样希望只有你自已才能解密
  • 对于签名:私钥加密,公钥解密。好比你的签名只有你自已签的才是真的,别人签的都是假的。

2.3.2 RSA算法

SSH协议支持多种加密算法,经常使用的RSA 算法即是一种非对称加密算法,它的原理基于一个十分简单的数论事实:将两个大素数相乘十分容易,但是想要对其乘积进行因式分解却极其困难,因此可以将乘积公开作为加密密钥。这种算法非常可靠,密钥越长,它就越难破解。根据已经披露的文献,目前被破解的最长RSA密钥是768个二进制位。也就是说,长度超过768位的密钥,还无法破解(至少没人公开宣布)。因此可以认为,1024位的RSA密钥基本安全,2048位的密钥极其安全。

3 参数速查表

最后,附上SSH常见命令参数表,以便日后查询使用。

参数

-a
    禁止转发认证代理的连接.
    
-A
    允许转发认证代理的连接. 可以在配置文件中对每个主机单独设定这个参数.
    代理转发须谨慎. 某些用户能够在SSH Server上绕过文件访问权限 (由于代理的 UNIX 域 socket), 他们可以通过转发的连接访问本地代理. 攻击者不可能从代理获得密钥内容, 但是他们能够操作这些密钥, 利用加载到代理上 的身份信息通过认证.
    
-b bind_address
    在拥有多个接口或地址别名的机器上, 指定收发接口.
    
-c blowfish|3des|des
    选择加密会话的密码术. 3des 是默认算法. 3des (triple-des) 用三支不同的密钥做加密-解密-加密三次运算, 被认为比较可靠. blowfish 是一种快速的分组加密术(block cipher), 非常安全, 而且速度比 3des 快的多. des 仅支持 客户端, 目的是能够和老式的不支持 3des 的协议第一版互操作. 由于其密码算法上的弱点, 强烈建议避免使用.
    
-c cipher_spec
    另外, 对于协议第二版, 这里可以指定一组用逗号隔开, 按优先顺序排列的密码术. 详见 Ciphers
    
-e ch|^ch|none
    设置 pty 会话的 escape 字符 (默认字符: `~' ) . escape 字符只在行首有效, escape 字符后面跟一个点 (`.' ) 表示结束连接, 跟一个 control-Z 表示挂起连接(suspend), 跟 escape 字符自己 表示输出这个字符. 把这个字符设为 ``none 则禁止 escape 功能, 使会话完全透明.

-f
    要求 在执行命令前退至后台. 它用于当 准备询问口令或密语, 但是用户希望它在后台进行. 该选项隐含了 -n 选项. 在远端机器上启动 X11 程序的推荐手法就是类似于 ssh -f host xterm 的命令.
    
-g
    允许远端主机连接本地转发的端口.
    
-i identity_file
    指定一个 RSA 或 DSA 认证所需的身份(私钥)文件. 默认文件是协议第一版的 $HOME/.ssh/identity 以及协议第二版的 $HOME/.ssh/id_rsa 和 $HOME/.ssh/id_dsa 文件. 也可以在配置文件中对每个主机单独指定身份文件. 可以同时使用多个 -i 选项 (也可以在配置文件中指定多个身份文件).
    
-I smartcard_device
    指定智能卡(smartcard)设备. 参数是设备文件, 能够用它和智能卡通信, 智能卡里面存储了用户的 RSA 私钥.
    
-k
    禁止转发 Kerberos 门票和 AFS 令牌. 可以在配置文件中对每个主机单独设定这个参数.
    
-l login_name
    指定登录SSH Server的用户. 可以在配置文件中对每个主机单独设定这个参数.
    
-m mac_spec
    另外, 对于协议第二版, 这里可以指定一组用逗号隔开, 按优先顺序排列的 MAC(消息验证码)算法 (message authentication code). 详情以 MACs 为关键字查询.
    
-n
    把 stdin 重定向到 /dev/null (实际上防止从 stdin 读取数据). 在后台运行时一定会用到这个选项. 它的常用技巧是远程运行 X11 程序. 例如, ssh -n shadows.cs.hut.fi emacs 将会在 shadows.cs.hut.fi 上启动 emacs, 同时自动在加密通道中转发 X11 连接. 在后台运行. (但是如果 要求口令或密语, 这种方式就无法工作; 参见 -f 选项.)
    
-N
    不执行远程命令. 用于转发端口. (仅限协议第二版)
    
-o option
    可以在这里给出某些选项, 格式和配置文件中的格式一样. 它用来设置那些没有命令行开关的选项.
    
-p port
    指定SSH Server的端口. 可以在配置文件中对每个主机单独设定这个参数.
    
-q
    安静模式. 消除所有的警告和诊断信息.
    
-s
    请求远程系统激活一个子系统. 子系统是 SSH2 协议的一个特性, 能够协助 其他应用程序(如 sftp)把SSH用做安全通路. 子系统通过远程命令指定.
    
-t
    强制分配伪终端. 可以在远程机器上执行任何全屏幕(screen-based)程序, 所以非常有用, 例如菜单服务. 并联的 -t 选项强制分配终端, 即使 没有本地终端.
    
-T
    禁止分配伪终端.
    
-v
    冗详模式. 使 打印关于运行情况的调试信息. 在调试连接, 认证和配置问题时非常有用. 并联的 -v 选项能够增加冗详程度. 最多为三个.
    
-x
    禁止 X11 转发.
    
-X
    允许 X11 转发. 可以在配置文件中对每个主机单独设定这个参数.
    应该谨慎使用 X11 转发. 如果用户在SSH Server上能够绕过文件访问权限 (根据用户的X授权数据库), 他就可以通过转发的连接访问本地 X11 显示器. 攻击者可以据此采取行动, 如监视键盘输入等.
    
-C
    要求进行数据压缩 (包括 stdin, stdout, stderr 以及转发 X11 和 TCP/IP 连接 的数据). 压缩算法和 gzip(1) 的一样, 协议第一版中, 压缩级别 ``level 用 CompressionLevel 选项控制. 压缩技术在 modem 线路或其他慢速连接上很有用, 但是在高速网络上反而 可能降低速度. 可以在配置文件中对每个主机单独设定这个参数. 另见 Compression 选项.
    
-F configfile
    指定一个用户级配置文件. 如果在命令行上指定了配置文件, 系统级配置文件 (/etc/ssh/ssh_config ) 将被忽略. 默认的用户级配置文件是 $HOME/.ssh/config
    
-L port:host:hostport
    将本地机(客户机)的某个端口转发到远端指定机器的指定端口. 工作原理是这样的, 本地机器上分配了一个 socket 侦听 port 端口, 一旦这个端口上有了连接, 该连接就经过安全通道转发出去, 同时SSH Server和 host 的 hostport 端口建立连接. 可以在配置文件中指定端口的转发. 只有 root 才能转发特权端口. IPv6 地址用另一种格式说明: port/host/hostport
    
-R port:host:hostport
    将SSH Server(服务器)的某个端口转发到本地端指定机器的指定端口. 工作原理是这样的, SSH Server上分配了一个 socket 侦听 port 端口, 一旦这个端口上有了连接, 该连接就经过安全通道转向出去, 同时本地主机和 host 的 hostport 端口建立连接. 可以在配置文件中指定端口的转发. 只有用 root 登录SSH Server 才能转发特权端口. IPv6 地址用另一种格式说明: port/host/hostport
    
-D port
    指定一个本地机器 ``动态的 应用程序端口转发. 工作原理是这样的, 本地机器上分配了一个 socket 侦听 port 端口, 一旦这个端口上有了连接, 该连接就经过安全通道转发出去, 根据应用程序的协议可以判断出SSH Server将和哪里连接. 目前支持 SOCKS4 协议, 将充当 SOCKS4 服务器. 只有 root 才能转发特权端口. 可以在配置文件中指定动态端口的转发.
    
-1
    强制 只使用协议第一版.
    
-2
    强制 只使用协议第二版.
    
-4
    强制 只使用 IPv4 地址.
    
-6
    强制 只使用 IPv6 地址.

你可能感兴趣的:(SSH命令工具研究报告)