Назад | Перейти на главную страницу

rsync через активное соединение ssh

Пытаясь написать сценарий как можно более чистым, мне интересно, есть ли какое-то решение для следующей ситуации:

Один сервер Linux с sshd и одно устройство Android с установленным клиентом dropbear ssh и rsync (без сервера).

Я пишу сценарий для удаленного запуска с помощью cron, который выполняет резервное копирование памяти Android на сервер Linux. Cron вызывает что-то вроде:

ssh remoteuser@linuxserver -i path_to_rsa_key runthisscript.sh

runthisscript.sh выполняет несколько действий с существующими данными, и, что я хочу сделать в середине сценария, это выполнить rsync с устройства Android обратно на сервер, используя уже открытое соединение ssh ( так как на андроиде нет sshd).

Я разработал другие решения, например, разбив мой серверный скрипт на несколько частей и вызывая их один за другим, с rsync (направление от Android к серверу) в середине, но я искал более элегантно реализованное решение (один скрипт, большинство проделанной работы на стороне сервера).

Идеи?

Вы можете взглянуть на аргумент --rsh / -e команды rsync.

Вы можете заменить rsh на cat или что-то подобное. Но вы должны добавить скрипт на стороне Android, который отправляет вывод вашего серверного скрипта в оболочку.

Сторона 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

helper.sh:

#!/bin/sh
host=$2
port=$1
shift 2
{
    echo exec "$@"
    socat 'STDIN' 'STDOUT'
} | socat '-' "TCP:$host:$port"

runthisscript.sh:

rsync -e './helper.sh 20000' --blocking-io <SRC> <DST>

Я предполагаю, что вы хотите иметь возможность подключаться из любого места, поэтому вы не можете гарантировать, на каком общедоступном IP-адресе будет находиться планшет (или даже если это позволит подключаться к планшету с сервера, так как он вряд ли будет общедоступным. адрес), в противном случае вам следует установить SSH deamon и ash rsync для подключения таким образом. В противном случае вам может быть нужен «обратный туннель».

Если ваш SSH-клиент на устройстве Android поддерживает обратную переадресацию портов, попробуйте использовать его для создания туннеля. Например, с openssh вы можете указать -R 2222:127.0.0.1:22 в командной строке, что будет означать, что сервер может подключаться к серверу SSHd на планшете (прослушивание порта 22 на 127.0.0.1, что касается планшета), подключившись к порту 2222 на 127.0.0.1 (это важно чтобы понять, что из кода в PoV сервера 127.0.0.1 - это сервер, 127.0.0.1 в командной строке относится к SSH клиент). Итак, если это сработает, вы можете в своем серверном скрипте запустить что-то вроде rsync user@127.0.0.1:/path/to/stuff/on/tablet /path/to/destination/on/server -e 'ssh -p 2222' -a --compress. В -e Опция используется здесь для указания нестандартного порта, к которому будет подключаться SSH.

Несколько более подробных примечаний к вышеизложенному (извините, это немного «свалка разума» и может быть плохо систематизирована, хотя, надеюсь, это поможет вам экспериментировать и / или искать полезные примеры в другом месте)

  • Это называется обеспечить регресс или удаленный туннель, потому что обычно перенаправляют от клиента к серверу (а не от сервера к клиенту, как вам здесь нужно). А местный туннель (от клиента к чему-то на стороне сервера) настраивается с помощью -L вариант вместо -R (по крайней мере, с OpenSSH, проверьте документацию вашего сервера для подтверждения).
  • Вы можете дать много -R и / или -L параметры в одной командной строке с OpenSSH, поэтому вы можете настроить более одного туннеля в любом / любом направлении, используя одно соединение 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, где это возможно. Прослушивание порта ниже 1024 заблокировано для непривилегированных пользователей по умолчанию в системах типа Uinx.
  • Если вы не хотите запускать демон 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. Адрес привязки относится к серверу, поэтому он не обязательно должен быть публично маршрутизируемым (фактически, адрес на фиктивном интерфейсе, который не видит даже остальная часть локальной сети, будет работать). Вы определенно необходимость GatewayPorts on, чтобы это работало с OpenSSH. Если вы этого не сделаете необходимость GatewayPorts на (т.е. если используется 127.0.0.1 на стороне сервера и нестандартный порт, который работает с реализацией SSHd вашего сервера без GatewayPorts yes или эквивалент), то оставьте его выключенным: так безопаснее.
  • Я использовал IPv4 во всем вышеперечисленном. Если ваш клиент и сервер поддерживают его и ваши сети на каждом конце настроены соответствующим образом, адресация IPv6 будет работать так же хорошо.

Настроенные таким образом туннели через SSH могут быть очень мощными, если вы поигрались с ними и выяснили, что это возможно и как это делать, если ваши клиентские и серверные реализации SSH / SSHd поддерживают все это.