尝试编写尽可能干净的脚本,我想知道是否有针对以下情况的解决方案:
一台运行 sshd 的 Linux 服务器和一台 android 设备,安装了 dropbear ssh 客户端和 rsync(无服务器)。
我正在编写一个脚本,使用 cron 远程运行该脚本,将 android 内存备份到 linux 服务器。cron 调用类似以下内容的命令:
ssh remoteuser@linuxserver -i path_to_rsa_key runthisscript.sh
runthisscript.sh 使用现有数据执行一些操作,而我想要在脚本中间做的是从 android 设备 rsync 回服务器,利用已经打开的 ssh 连接(因为 android 上没有运行 sshd)。
我已经开发了其他解决方案,例如将我的服务器脚本分成几个部分并一个接一个地调用它们,中间使用 rsync(android 到服务器方向),但我正在寻找一个更优雅的解决方案(单个脚本,大部分工作在服务器端完成)。
有想法吗?
答案1
您可以看看 rsync 的 --rsh/-e 参数。
您可以用 cat 或类似程序替换 rsh。但您必须在 android 端添加一个脚本,将服务器脚本的输出发送到 shell。
Android端:
socat 'EXEC:/bin/bash' 'TCP-LISTEN:20000' &
ssh remoteuser@linuxserver -i path_to_rsa_key -R 20000:127.0.0.1:20000 runthisscript.sh
帮助器.sh:
#!/bin/sh
host=$2
port=$1
shift 2
{
echo exec "$@"
socat 'STDIN' 'STDOUT'
} | socat '-' "TCP:$host:$port"
运行此脚本.sh:
rsync -e './helper.sh 20000' --blocking-io <SRC> <DST>
答案2
我假设您希望能够从任何地方进行连接,因此您无法保证平板电脑将位于哪个公共 IP 地址上(或者即使这允许从服务器连接到平板电脑,因为它不太可能是公共地址),否则您应该安装 SSH 守护程序和 ash rsync 以这种方式进行连接。否则,“反向隧道”可能就是您所寻找的。
如果您的 Android 设备上的 SSH 客户端支持反向端口转发,那么请考虑使用它来构建隧道。例如,使用 openssh,您可以-R 2222:127.0.0.1:22
在命令行中指定,这意味着服务器上的内容可以通过连接到 127.0.0.1 上的端口 2222 连接到平板电脑上的 SSHd 服务器(就平板电脑而言,监听 127.0.0.1 上的端口 22)(重要的是要意识到,从服务器的 PoV 上的代码来看,127.0.0.1 是服务器,命令行中的 127.0.0.1 是相对于 SSH客户)。如果可行,您可以在服务器脚本中运行类似 的命令。此处使用的选项用于指定 SSH 连接的非标准端口。rsync [email protected]:/path/to/stuff/on/tablet /path/to/destination/on/server -e 'ssh -p 2222' -a --compress
-e
关于上述内容的一些更详细的说明(抱歉,这有点像“思维倾泻”,可能组织得不太好,但希望它能帮助你在其他地方进行实验和/或查找有用的例子):
- 这被称为撤销或者偏僻的隧道,因为更常见的是设置从客户端到服务器的重定向(而不是您在此处需要的从服务器到客户端的重定向)。当地的隧道(客户端到服务器端)是使用选项
-L
而不是设置的-R
(至少对于 OpenSSH,请检查服务器的文档以进行确认)。 - 您可以在 OpenSSH 的同一个命令行上提供许多
-R
和/或-L
选项,因此您可以使用单个 SSH 连接在任意方向设置多个隧道。 - 你可能需要
GatewayPorts yes
在服务器中指定或类似内容,sshd_config
以使反向隧道正常工作。请查看 SSHd 实现的文档以了解详细信息。 - 平板电脑从哪里调用并不重要:端口转发创建的隧道将始终(通过 SSH 连接)指向其 SSH 客户端。您甚至可以使用转发将其指向其他本地资源,
-R 8888:192.168.42.42:80
这意味着与服务器上的 127.0.0.1:8888 的连接将通过 SSH 隧道,并命中平板电脑当前所在网络上的任何机器上的端口 80,无论该机器响应的是 192.168.42.42(这甚至可能是完全不同位置的另一台远程机器)。 - 您将需要平板电脑上的 rsync 客户端,以便服务器能够通过隧道通过 SSH 运行它。
- 上述示例使用非标准端口,因为 SSHd 可能会在服务器上的所有接口上监听端口 22。如果您以 root 身份连接到服务器,则使用低于 1024 的端口号(即 222 而不是 2222)更安全,但您应尽可能避免以 root 身份连接到远程资源。在 Uinx-a 类系统上,默认情况下会阻止非特权用户监听低于 1024 的端口。
- 如果您不想在平板电脑上运行 SSH 守护程序,则可以改为在守护程序模式下运行 rsync 实例。端口转发将类似于
537:127.0.0.1:537
或(如果您已经在服务器上以服务器模式运行 rsync,因此端口 537 已被占用,则类似于5537:127.0.0.1:537
和添加-p 5537
到 rsync 命令以告诉它服务器不在标准位置)。 - 如果你的服务器的 SSHd 没有监听端口 22全部服务器的接口/地址,那么您可以使用 22 而不是非标准端口,方法是指定隧道应连接到特定接口,方法是将该地址添加到部分的开头
-R
,如下所示:-R 192.168.1.1:22:127.0.0.1:22
。绑定地址与服务器相关,因此不需要是可公开路由的地址(实际上,即使本地 LAN 的其余部分看不到的虚拟接口上的地址也可以使用)。你确实需要GatewayPorts
启用才能与 OpenSSH 配合使用。如果没有需要GatewayPorts
开启(即,如果使用 127.0.0.1 服务器端和非标准端口,并且它与您服务器的 SSHd 实现兼容GatewayPorts yes
或等效)则将其关闭:这样更安全。 - 以上所有情况我都假设 IPv4。如果您的客户端和服务器都支持 IPv4,并且两端的网络配置正确,那么 IPv6 寻址同样有效。
一旦您使用过这种方式配置的 SSH 隧道,并弄清楚了它的功能和操作方法,那么它就会非常强大,假设您的客户端和服务器 SSH/SSHd 实现都支持它。