Contents

从Linux中的远程SSH会话中获取数据

1. 简介

远程访问系统比以往任何时候都更加普遍。但是,由于协议和环境的不同限制,一般和剪贴板数据共享可能并不总是在客户端和服务器机器之间开箱即用。

在本教程中,我们将讨论如何从 Linux 中的远程 SSH 会话本地传输数据。首先,我们简要阐明什么是 SSH 以及我们如何使用它。接下来,我们将解释如何重定向交互式和非交互式会话的输出。最后,我们以重定向到剪贴板的具体情况结束。

我们使用 GNU Bash 5.1.4 在 Debian 11 (Bullseye) 上测试了本教程中的代码。它是 POSIX 兼容的,应该可以在任何这样的环境中工作。

2. SSH 协议

Secure Shell (SSH) 是一种用于安全信息传输的加密网络协议。 出于我们的目的,我们假设 SSH 密钥已经:

  • 生成
  • 复制 到我们的远程服务器blogdemo.com
  • 在我们的本地和远程机器上配置

这意味着默认密钥访问是现成的,我们将在ssh (Secure Shell) 客户端命令中跳过身份验证。

由于身份验证是主要障碍,通过配置密钥访问,使用ssh变得微不足道。

3. SSH 远程执行模式

从广义上讲,我们可以使用ssh运行一个或多个命令并退出或启动交互式会话并等待输入。对于我们的需求,后一种情况更为复杂。让我们简要讨论一下它们。

3.1. 交互的

在交互式 SSH 会话模式下,我们在提示符下输入命令,但所有命令都在远程机器上执行

$ hostname
personal.local
$ ssh itcodingman@blogman
$ hostname
blogdemo.com

在这里,我们使用主机名 来输出当前机器的主机名。之后,我们在服务器blogdemo.com上与用户x进入远程交互式 SSH 会话,其中我们显示同一命令返回的主机名是远程系统的主机名。

SSH 协议通过在远程机器上执行默认 shell 来实现这一点,它接管了整个 SSH 会话。退出这个交互式会话会终止 shell 以及ssh客户端进程,并将控制权返回给我们启动它的终端。

3.2. 脚本

SSH 协议的众多功能之一是远程命令执行:

$ hostname
personal.local
$ ssh itcodingman@blogman 'hostname'
blogdemo.com

基本上,我们跳过ssh的交互功能,只执行提供的一个或多个命令,返回输出。请注意命令是如何作为参数提供的。

我们将详细研究这两种执行模式。让我们继续使用非交互式脚本模式。

4. 非交互式 SSH 输出重定向

由于ssh在输入和输出方面的行为与任何其他 Linux 命令一样,一旦我们捕获其中一个流,我们就可以随意处理它。

4.1.管道 SSH 输出

与其他流一样,我们可以通过管道传输 ssh输出

$ ssh itcodingman@blogman 'ip address' | grep global
inet 10.0.6.66/24 brd 10.0.6.255 scope global eth0

在这里,我们通过ip 获取远程机器的网络信息。随后,我们将其通过管道传递给grep (全局正则表达式打印),以仅过滤掉全局 IP。

当然,我们可以在没有直接管道的情况下达到这个效果。

4.2. 子shell中的SSH

实际上,我们可以使用子shell 来获取 SSH 返回的数据

$ REMOTE_HOSTNAME="$(ssh itcodingman@blogman 'hostname')"
$ ping "${REMOTE_HOSTNAME}"
PING blogdemo.com (203.0.113.66) 56(84) bytes of data.
64 bytes from 203.0.113.66 (203.0.113.66): icmp_seq=1 ttl=666 time=66.6 ms

我们首先将远程主机名存储在REMOTE_HOSTNAME变量中。之后,我们使用以主机名作为参数的*ping *命令。

当然,如果不过滤交互式ssh环境中的孤立数据,这些解决方案很少有用。

5. 交互式 SSH 输出重定向

由于 SSH 会话的完整输出只有在ssh客户端终止后才可用于管道,因此我们必须想出一个解决方案来立即从交互式会话中获取当前数据。

5.1. 流复制

在不完全重定向的情况下从stdout 获取数据的一种方法是tee 命令

$ echo '-----' > stdout.txt
$ ssh itcodingman@blogman | tee stdout.txt
$ hostname
blogdemo.com
$ exit
## $ cat stdout.txt
$ hostname
blogdemo.com
$ exit

首先,我们创建一个文件stdout.txt并用五个破折号填充它。之后,我们启动一个 SSH 会话,通过管道连接到tee。请注意tee如何将 SSH 会话中的所有信息同时重定向到 stdout 和stdout.txt

当然,这里的问题是冗长和缺少过滤器。接下来,我们将检查一些更细化的方法。

5.2. nc

从实时 SSH 会话中提取信息的另一种方法是将其发送出去。我们可以使用nc (Netcat) 将信息从会话传输回客户端。为此,我们首先需要在客户端本身上启动一个单独的服务器:

$ nc -l -p 36661

-l标志在*-p*之后的端口启动侦听服务器。之后,在一个单独的终端中,我们建立一个反向 SSH 隧道 会话

$ ssh itcodingman@blogman -R localhost:36660:localhost:36661

我们读取*-R*(反向隧道)标志参数如下:将任何数据重定向到远程主机的端口 36660 到端口 36661 的当前客户端**计算机。这允许我们通过SSH 服务器上的nc向我们在客户端打开的nc服务器发送数据:

$ echo "$(date)" | nc localhost 36660

在这里,我们将当前date 发送到localhost的 36660 端口,也就是 SSH 服务器。但是,由于反向隧道,此信息实际上是传输到客户端的端口 36661。

事实上,回到带有我们的nc服务器的客户端,我们可以在 Netcat 命令下方看到当前日期。从广义上讲,这个过程只是建立了一个到客户端的反向连接,服务器用它来提供数据

有替代nc来实现相同的目标。此外,我们将讨论的其他选项提供了一个有价值的奖励功能:剪贴板访问。

6. SSH剪贴板

SSH 协议标准 没有指定剪贴板机制。但是,我们通常可以使用本地可用的所有可用选项进行复制和粘贴

例如,我们可以从启动 SSH 会话的 GUI 终端窗口中选择、复制和粘贴文本。或者,我们可以采用以下方法之一。

6.1. X 选择

如果我们想通过命令行发送到剪贴板,我们可以使用xselxclip 命令:

$ ssh itcodingman@blogman 'hostname' | xsel --input
$ xsel --output
blogdemo.com

基本上,我们将ssh输出通过管道传送到xsel命令。重要的是,如果没有在本地运行X Server ,我们将无法使用像xselxclip这样的工具。

另一方面,只有在以下情况下,才能通过xclip远程使用 X11:

  • 在本地机器上安装并运行 X Server
  • 添加或取消注释X11Forwarding yes到*/etc/ssh/sshd_config*

要使用xclip,我们使用*-X*(X11 转发)标志启动ssh客户端:

$ ssh -X itcodingman@blogman
$ echo "$(date)" | xclip -i

在我们使用xclip获取远程机器上的数据输入后,我们可以使用本地机器上的输出:

$ xclip -o
Sun 10 Oct 2021 10:00:00 AM EST

重要的是,此数据仅在 SSH 会话期间可用,在.

6.2. nc剪贴板

当然,我们可以使用上面的 Netcat 解决方案,但要通过管道连接到xsel

$ nc -l -p 36661 | xsel --input

我们在nc服务器上接收到的任何数据都直接进入剪贴板,我们可以通过客户端上的xsel来恢复。但是,还有其他选项将所有这些功能组合在一个专门的包中。

6.3. lemonade

一个这样的选择是lemonade 命令——一个单一的工具,它允许我们:

  • 在客户端启动监听器
  • 将数据从 SSH 会话发送到客户端
  • 在服务器上执行预定义的操作

事实上,**我们使用这个工具的方式与nc非常相似。**首先,我们在终端中启动lemonade服务器:

$ lemonade start

之后,在一个单独的终端中,我们像以前一样通过ssh连接到我们的服务器。唯一的变化是反向隧道端口 - 都是 2489,lemonade的默认值:

$ ssh itcodingman@blogman -R localhost:2489:localhost:2489

最后,我们在服务器上使用lemonade将数据发送回客户端:

$ echo "$(date)" | lemonade copy

重要的是,使用copy命令到lemonade,我们将 SSH 会话数据直接移动到本地剪贴板。然后,我们不仅可以通过图形界面粘贴这些数据,还可以通过客户端上的命令行粘贴这些数据:

$ lemonade paste
Sun 10 Oct 2021 10:00:00 AM EST

请注意,该工具与其他工具一样,应安装在 server 和 client 上。此外,lemonade还有其他有用的功能,例如在客户端打开浏览器、重定向到给定的 URL。

6.4. 剪辑

我们可以使用*clippy *实现上述所有功能。此外,Clippy 实现了更高的安全性以及直接使用该工具启动 SSH 会话的能力。这简化了反向隧道配置:

$ clippy ssh itcodingman@blogman
$ echo "$(date)" | clippy set

与其他方法类似,我们通过客户端上的相同工具获取数据:

$ clippy get
Sun 10 Oct 2021 10:10:00 AM EST

Clippy 还支持在桌面上执行任意命令,而不仅仅是像 SSH 那样的命令行。