Вопрос или проблема
Фон: Я перенаправляю локальный 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 в сочетании с дополнительной логикой
-
Создание обертки для 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
и автоматического удаления несуществующих или неиспользуемых сокетов.
-
Установка
inotify-tools
:Убедитесь, что
inotify-tools
установлены:sudo apt-get install inotify-tools
-
Создание скрипта для наблюдения:
Создайте скрипт, который будет отслеживать сокет и удалять его, если он не используется.
#!/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-сокетов требует некоторого планирования и разработки, но с помощью вышеперечисленных методов можно значительно упростить этот процесс. Надеюсь, одно из предложенных решений подойдет для вашей ситуации.