Быстрый вопрос - я запускаю два 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.
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
'
-f
опция не используется, вы можете использовать открытый ключ и работать в фоновом режиме через &
или вы можете войти в систему в интерактивном режиме и использовать Ctrl + Z и использовать то же $!
для хранения pid.-f
ssh, так как в этом случае вы потеряете pid ssh. Этот метод основан на запуске на переднем плане и Ctrl + C для уничтожения.socat ...&
- запустить socat в фоновом режиме на удаленном сервереpid=$!
- сохранить pidtrap kill\ $pid 0
- бегать kill $pid
при завершении bashwhile :; 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)