Автоматическая очистка неиспользуемых юникс-сокетов

Вопрос или проблема

Фон: Я перенаправляю локальный unix-сокет на удалённый unix-сокет через SSH (-R /tmp/remote:/tmp/local), чтобы удалённый клиент мог к нему подключиться. И (при достаточно свежей версии ssh) это работает.

Проблема в том, что /tmp/remote сохраняется после завершения соединения ssh, которое его создало, что означает, что последующие попытки перенаправить локальный сокет будут терпеть неудачу, пока /tmp/remote не будет каким-то образом удалён. В ssh теперь есть StreamLocalBindUnlink, который звучит многообещающе, но на самом деле работает в обратном направлении (с -L, удаляя локальный сокет). Нет StreamRemoteBindUnlink.

Таким образом, я остаюсь с (некрасивым, небезопасным) решением использования перенаправления unix-тcp и обёрточного скрипта для клиента, который связывает unix-сокет с TCP-сокетом – socat автоматически очищает за собой. Я рассматривал возможность использования .bash_logout, но это ненадёжно и даже uglier.

Есть ли способ автоматически очищать неиспользуемые unix-сокеты?

Ответ или решение

Автоматическая очистка неиспользуемых UNIX-сокетов может представлять определенную сложность, особенно в контексте пересылки сокетов через SSH. Ваша ситуация с /tmp/remote, который остается после завершения соединения, потребует более элегантного решения, чем использование перехватчиков или нестабильных скриптов.

Решение 1: Использование параметров SSH в сочетании с дополнительной логикой

  1. Создание обертки для SSH-подключения: Вместо прямого использования SSH для пересылки сокета, вы можете создать обертку, которая будет отслеживать состояние соединения и автоматически удалять сокет после разрыва.

    Пример скрипта, который вы можете использовать:

    #!/bin/bash
    
    SOCKET="/tmp/remote"
    REMOTE_SOCKET="/tmp/local" # Убедитесь, что этот путь доступен на удаленной машине
    
    # Оберните вызов SSH
    ssh -R "$SOCKET:$REMOTE_SOCKET" user@remote_host -N &
    
    # Сохраняем PID
    SSH_PID=$!
    
    # Удаляем сокет при завершении SSH-процесса
    wait $SSH_PID
    rm -f "$SOCKET"

    Этот скрипт будет запускать SSH-сессию, а затем ждать ее завершения. Если соединение разорвется, скрипт автоматически удалит сокет.

Решение 2: Использование inotify для наблюдения за сокетом

Альтернативным решением может быть использование inotify для отслеживания состояния файлов в /tmp и автоматического удаления несуществующих или неиспользуемых сокетов.

  1. Установка inotify-tools:

    Убедитесь, что inotify-tools установлены:

    sudo apt-get install inotify-tools
  2. Создание скрипта для наблюдения:

    Создайте скрипт, который будет отслеживать сокет и удалять его, если он не используется.

    #!/bin/bash
    
    SOCKET="/tmp/remote"
    
    while true; do
       # Проверяем, доступен ли сокет
       if [ ! -e "$SOCKET" ]; then
           echo "Сокет не найден"
           break
       fi
    
       # Используем inotify для ожидания изменений
       inotifywait -e delete_self "$SOCKET" && rm -f "$SOCKET"
    done

Рекомендации

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

Также рассмотрите возможность использования более безопасных методов связи (например, TLS) вместо простого пересылки через TCP/UNIX-сокеты, если это возможно в вашем контексте.

Заключение

Автоматическая очистка неиспользуемых UNIX-сокетов требует некоторого планирования и разработки, но с помощью вышеперечисленных методов можно значительно упростить этот процесс. Надеюсь, одно из предложенных решений подойдет для вашей ситуации.

Оцените материал
Добавить комментарий

Капча загружается...