Можно ли использовать символические ссылки, чтобы всегда удалять один слой дерева каталогов?

Вот решение с использованием OpenSSH >= 6.7 + socat:

  1. OpenSSH >= 6.7 может использовать перенаправление сокетов домена Unix

    Это означает, что конечной точкой обратного туннеля будет слушающий сокет UNIX вместо традиционного прослушивающего сокета TCP. Затем вы можете более легко управлять флотилией RPI с помощью простой схемы именования :имя сокета будет выбранным RPI (и фиксированным именем ), например OfficeDevice1991. Это может быть даже уникальное свойство из RPI, если это действительное имя файла (, поскольку имена сокетов unix соответствуют соглашениям об именах файлов ). Например, его имя хоста, MAC-адрес его карты Ethernet или Wi-Fi...

    SSH может обрабатывать сокеты unix для туннелей, а не для подключения к себе. Ему понадобится помощь ProxyCommand, чтобы иметь возможность работать как клиент сокета unix -. socat может обрабатывать многие виды соединений, включая сокеты unix.

    ОБНОВЛЕНИЕ:
    Существует также особая проблема для обработки :файла сокета unix, который не удаляется при чистом выходе, и при этом он не был бы удален в любом случае, например, после сбоя. Для этого требуется опция StreamLocalBindUnlink=yes. Сначала я не обнаружил, что, как следует из названия, этот параметр должен быть установлен на узле, создающем сокет unix. Так что в итоге он устанавливается на клиенте с локальным форвардом(-L)или же на сервере (вsshd_config)с удалённым форвардом(-R). ОП нашел это там . В этом решении используется удаленная переадресация.

    Конфигурация на VPS:

    mkdir /rpi-access
    

    (от имени пользователя root )отредактируйте файл sshd_config(/etc/ssh/sshd_config). Требуется эта дополнительная опция:

    StreamLocalBindUnlink yes
    

    В зависимости от параметров по умолчанию может также потребоватьсяAllowStreamLocalForwarding yes

    ОБНОВЛЕНИЕ2:
    Также установите в sshd_configпараметры ClientAliveIntervalи ClientAliveCountMax, что позволит обнаруживать отключение в разумные сроки,например:

    ClientAliveInterval 300
    ClientAliveCountMax 2
    

    Устаревшие соединения ssh должны быть обнаружены раньше на VPS (~10 мин с примером ), после чего соответствующий процесс sshd завершится.

    Использование в RPI:

    ssh -fN -R /rpi-access/OfficeDevice1991:localhost:22 -i /privatekeyfile useraccount@ip
    

    В файле конфигурации это будет похоже на это:

    Host ip
    User useraccount
    RemoteForward /rpi-access/OfficeDevice1991:localhost:22
    IdentityFile /privatekeyfile
    

    Повторяю еще раз :параметр StreamLocalBindUnlink yes, установленный на sshdна стороне VPS важен :только что созданный сокет не удаляется даже при обычном выходе. Этот параметр обеспечивает удаление сокета, если он существует до использования, что позволяет повторно использовать его для дальнейших повторных подключений. Это также означает, что нельзя рассматривать простое наличие сокета как означающее, что RPI подключен (, но см. далее ).

    Теперь это можно делать на VPS:

    ssh -o 'ProxyCommand=socat UNIX:/rpi-access/%h -' rpiuseraccount@OfficeDevice1991
    

    В качестве файла конфигурации, учитывая, например, что имена RPI начинаются с OfficeDevice:

    Host OfficeDevice*
        User rpiuseraccount
        ProxyCommand socat UNIX:/rpi-access/%h -
    
  2. Чтобы сохранить ссылку, просто используйте цикл

    RPI может запускать цикл, переподключающий ssh ​​к VPS всякий раз, когда соединение прекращается. Для этого нельзя использовать фоновый режим (нет-f). Также следует использовать механизм поддержания активности. TCPKeepAlive (уровень системы )или ServerAliveInterval (уровень приложения ). Я думаю, что TCPKeepAlive полезен только на стороне сервера (, принимающей соединение ), поэтому давайте лучше использовать ServerAliveInterval.

    Его значение (, а также ServerAliveCountMax ), вероятно, следует адаптировать в зависимости от различных критериев :брандмауэр, сбрасывающий неактивные соединения через определенное время, желаемая задержка восстановления, не генерирующий бесполезный трафик,... давайте скажем 300 здесь.

    OfficeDevice1991 RPI:

    #!/bin/sh
    while : ; do
        ssh  -N -o ConnectTimeout=30 -o ServerAliveInterval=300 -R /rpi-access/OfficeDevice1991:localhost:22 -i /privatekeyfile useraccount@ip
        sleep 5 # avoid flood/DDoS in case of really unexpected issues
    done
    

    Даже если удаленная сторона еще не обнаружила предыдущую ошибку подключения и еще некоторое время работает старое подключение ssh,StreamLocalBindUnlink yesв любом случае принудительно обновит сокет unix до нового соединения.

  3. это уже обработано 1.

    Не нужно customcommandsearch. При правильных настройках в 1. простое использование ssh OfficeDevice1991приведет к подключению к OfficeDevice1991.

    При необходимости на VPS, только от имени rootпользователя, эта команда:

    fuser /rpi-access/*
    

    может показать, какие RPI подключены в настоящее время (, кроме тех, которые недавно потеряли соединение перед обнаружением ). Он не будет отображать устаревшие файлы сокетов unix, потому что к ним не привязан процесс.

0
26.04.2020, 13:58
1 ответ

Вы можете использовать rsyncс некоторым сценарием, который запускается при создании нового элемента в первом каталоге. что-то вроде rsync --avu delete /dirA /dirBЭто полезно:Как синхронизировать папки Для скрипта вы можете использовать inotifyдля отслеживания действий по созданию/удалению в каталоге

0
19.03.2021, 02:26

Теги

Похожие вопросы