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

Перенаправить локальный порт или файл сокета в удаленный файл сокета

Быстрый вопрос - я запускаю два Linux-сервера, один на моем собственном рабочем столе, а другой на моем VPS. По соображениям безопасности на стороне VPS я выбрал сокетные соединения с MySQL (/var/run/mysqld/mysql.sock). Я знаю, что могу туннелировать вот так: ssh -L 3307:127.0.0.1:3306 user@site.com если я настроил удаленный сервер sql для прослушивания какого-либо порта, но я хочу знать, могу ли я сделать что-то вроде: ssh -L /path/to/myremotesqlserver.sock:/var/run/mysqld/mysql.sock тем самым туннелируя два сокета, а не два порта?

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

(и да, я знаю, что tcp будет проще).

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

Вы можете использовать оба варианта: UNIX => TCP и UNIX => пересылка UNIX.

Например:

ssh \
  -R/var/run/mysql.sock:/var/run/mysql.sock \
  -R127.0.0.1:3306:/var/run/mysql.sock \
  somehost

Это возможно, начиная с OpenSSH 6.7.

Перенаправить локальный сокет по запросу

  • Настройка аутентификации с открытым ключом SSH
  • Установить socat на обоих концах
  • создайте каталог для ваших сокетов локально, недоступный для других пользователей.
export SOCKET_DIR=~/.remote-sockets
mkdir -p $SOCKET_DIR
socat "UNIX-LISTEN:$SOCKET_DIR/mysqld.sock,reuseaddr,fork" \
EXEC:'ssh user@server socat STDIO UNIX-CONNECT\:/var/run/mysqld/mysqld.sock'

затем

mysql -S $SOCKET_DIR/mysqld.sock -u mysqluser -p

украдено из пересылка сокетов домена unix с помощью ssh и socat

я этого не делал, но я бы попробовал с сокат. может быть что-то вроде:

ssh xxx@yyy.zzz -L 9999:localhost:9999 "socat TCP-LISTEN:localhost:9999 UNIX-CONNECT:/var/run/mysqld/mysql.sock"
socat UNIX-LISTEN:/path/to/local/socket TCP:localhost:9999

опять же, я никогда не делал ничего подобного.

Начиная с версии ssh 6.7, socat больше не требуется. Вы можете напрямую пересылать сокеты домена unix, например:

ssh -nNT -L $(pwd)/docker.sock:/var/run/docker.sock user@someremote

Больше информации: https://medium.com/@dperny/forwarding-the-docker-socket-over-ssh-e6567cfab160

Еще одна модификация ответа @mpontes '/ @ javier, что

ssh user@remoteserver -L 9999:localhost:9999 'socat TCP-LISTEN:9999,fork,bind=localhost UNIX-CONNECT:/var/run/mysqld/mysql.sock& pid=$!; trap "kill $pid" 0; while echo -ne " \b"; do sleep 5; done'

Очиститель

ssh user@remoteserver -L 9999:localhost:9999 '
  socat TCP-LISTEN:9999,fork,bind=localhost UNIX-CONNECT:/var/run/mysqld/mysql.sock&
  pid=$!
  trap "kill $pid" 0
  while echo -ne " \b"; do
    sleep 5
  done
'

ЗА

  1. Работает на openssh до 6.7 (например, CentOS 7)
  2. Убивает socat при завершении ssh вместо повторной отправки ssh на удаленный сервер
  3. Разрешает непубличный вход по ssh (в отличие от решения ijk)

Характерная черта

  1. Поскольку -f опция не используется, вы можете использовать открытый ключ и работать в фоновом режиме через & или вы можете войти в систему в интерактивном режиме и использовать Ctrl + Z и использовать то же $! для хранения pid.

МИНУСЫ

  1. Не могу легко использовать -f ssh, так как в этом случае вы потеряете pid ssh. Этот метод основан на запуске на переднем плане и Ctrl + C для уничтожения.
  2. Гораздо сложнее

Объяснение

  • socat ...& - запустить socat в фоновом режиме на удаленном сервере
  • pid=$! - сохранить pid
  • trap kill\ $pid 0 - бегать kill $pid при завершении bash
  • while :; sleep... - сидеть в бесконечном цикле
  • echo -ne \ \b - Эхо-пробел, за которым следует возврат. Это не удается, как только отключается ssh. С sleep 5, это означает, что socat может работать до 5 секунд после ssh

Примечание: Фактически протестировано с использованием докера, порт 2375, /var/run/docker.sock, и переменная среды DOCKER_HOST='tcp://localhost:2375', но все равно должно работать на mysql

Обновить

С помощью Элементы управления SSH, вы можете использовать -f флаг, используя мой способ, просто добавьте следующие флаги

-f -o ControlPath=~/.ssh/%C -o ControlMaster=auto

И ты получишь

ssh -f -o ControlPath=~/.ssh/%C -o ControlMaster=auto user@remoteserver -L 9999:localhost:9999 'set -m; socat TCP-LISTEN:9999,fork,bind=localhost UNIX-CONNECT:/var/run/mysqld/mysql.sock& pid=$!; trap "kill $pid" 0; while echo -ne " \b"; do sleep 5; done'

Теперь вы можете завершить все контролируемые сеансы, используя

ssh -o ControlPath=~/.ssh/%C -O exit remoteserver

В -o варианты можно сохранить в вашем .ssh/config файл, или вы можете использовать вместо этого -S (но вам все равно понадобится -o ControlMaster)

Разрабатывая ответ Хавьера, это работает для меня:

ssh -f xxx@yyy.zzz -L 9999:localhost:9999 "socat TCP-LISTEN:9999,fork,bind=localhost UNIX-CONNECT:/var/run/mysqld/mysql.sock"

Тебе нужно fork для того, чтобы иметь возможность подключаться несколько раз без потери связи после закрытия первого подключения. Кроме того, socat позволяет указать адрес для привязки через bind вариант, а не как адрес перед портом.

После этого просто подключитесь к localhost:9999 как обычно. Затем, чтобы снести туннель:

ssh -f xxx@yyy.zzz "killall socat"

(или что-то подобное, вы можете сделать более сложные вещи, которые включают сохранение PID socat)

Да, вы можете использовать socat.

Сначала сделайте TCP-туннель с SSH. Затем используйте socat следующим образом:

socat unix-listen: /var/run/mysqld/mysqld.sock,fork,unlink-early tcp: 127.0.0.1: 3306

Затем дайте разрешения для нового созданного сокета (может быть chmod 777)