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


24

Швидке запитання - я запускаю два вікна 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 було б простіше).


Якщо ви не хочете використовувати TCP у вікні mySQL, це через проблеми безпеки (тобто віддалені атаки тощо), можна, звичайно, або зробити брандмауер, і якщо це недостатньо добре, змушуйте mySQL прослуховувати лише 127.0.0.1 для його TCP-з'єднань, ви можете легко пройти тунель через SSH. Якщо ні, я підтримую рішення socat нижче.
Маттіас Анберг

lwn.net/Articles/609321 OpenSSH 6.7 принесе переадресацію розетки
Hubbitus

@Hubbitus ця функція доступна зараз, якщо так, чи можете ви надати приклад відповіді?
CMCDragonkai

Цей коментар був у формі відповіді, але хтось перетворювався на коментар. І я бачу, ви вже пропонуєте відповідь нижче.
Губбіт

Відповіді:


35

Надішліть місцеву розетку на вимогу

  • Установіть автентифікацію відкритого ключа 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


Це приголомшливо і це має бути прийнятою відповіддю.
Джон Сміт Необов’язковий

32

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

Ви можете обидва: 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.


1
Мені вдалося переслати мій локальний сокет на віддалений серверний сокет, використовуючи вище, і запустити докер-клієнт віддалено (це можна зробити безпосередньо в ssh, але де в цьому весело :)ssh -L /home/user/docker.sock:/var/run/docker.sock dockerhost -N
sdkks

11

я цього не робив, але спробував би з 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

знову ж таки, я ніколи нічого подібного не робив.


Я підкажу і дам вам знати, як це йде. Я використовував реалізацію на основі tcp.

Наразі я не можу змусити його працювати, але +1 все одно для ідеї, мені це подобається. Я дам вам знати, якщо я це виправлю.

+1 виглядає як корисна утиліта.
Warner

5

Більше socat більше не потрібен, оскільки ssh 6.7. Ви можете пересилати Unix доменні розетки безпосередньо так:

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

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


Я також вважаю це корисним для підключення до локального сокета як іншого користувача. Це дозволило мені запускати клієнтські програми проти серверного процесу, який відключає певні ідентифікатори користувача (з'єднання, що надходять від його власних запуску завдань).
Варбо

Переслати сокет на ту саму машину, але інший каталог, керований іншим користувачем, використовуючи sshd для автентифікації доступу? Яка ваша корисна скринька?
CMCDragonkai

Дозволи / доступ до каталогу не є проблемою. Швидше, конкретний демон демонструє будь-які спроби підключення, зроблені користувачами певної групи (нібито, щоб запобігти плутанині новачків). Використання ssh дозволяє тим користувачам підключитися (через тунельований сокет) так, ніби вони були користувачем, що не в цій групі, і, отже, не відключатися.
Варбо

Цікаво, смішно, як ви маєте на увазі нікс-демон, я також маю справу з питаннями щодо цього. Мені цікаво, чому nix-daemon перериває зв’язки з користувачами певної групи? Це річ конфігурації безпеки? Або пов’язані з: nixos.org/nix/manual/#idm140737318362784 ?
CMCDragonkai

Відповідно до повідомлення про зобов’язання, це запобігати "випадковому" використанню. Я підніс це сюди
Варбо,

2

Ще одна модифікація відповіді @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. Працює з opensh раніше, ніж 6,7 (як CentOS 7)
  2. Вбиває socat під час припинення ssh замість того, щоб повторно виконувати ssh на віддалений сервер
  3. Дозволяє непублічний ssh ​​логін (на відміну від ijk рішення)

Особливість

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

КОНС

  1. Неможливо легко скористатися параметром -fssh, оскільки таким чином ти втратиш приріст ssh. Цей метод залежить від запуску на передньому плані та Ctrl + C для вбивства.
  2. Набагато складніше

Пояснення

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

Примітка: На насправді протестовані з використанням докер, порт 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)


Я використовую сценарії всередині контейнера Docker для розгортання коду для інших хостів. Ваша логіка підключення дивовижна, але закінчується, коли закінчується сеанс bash. Це не дозволяє мені закликати docker run ... connect.shналаштовувати тунель, за яким слід docker run ... deploy.sh. Я спробував nohup, &і, disownале вони, здається, зламаються socat, закриваючи stdoutі спрацьовуючи kill. Будь-які ідеї для налаштувань на підтримку цього випадку (тобто все ще близькі, коли SSH є, ​​але переживає відмову)?
claytond

ДОБРЕ. Це на самому ділі працює відмінно (ш / -fі & disown) в терміналі. Мабуть, проблема створюється сценарієм "обгортка". Я вітаю вклад, але я дивлюся на більш відповідні запитання та відповіді зараз.
claytond

@claytond Не впевнений, що саме ви робите, але так, усі інші команди припиняються, коли закінчується підписка 1 контейнера. Що я зазвичай робив у сценарії розгортання сценарію, це використовувати команду "розгорнути" та написати вхідну точку для мого контейнера зображення, на якому буде сказано "якщо $ 1 (команда) == deploay, то" запустіть команди ssh та команди розгортання, а потім закінчіть, що закриє ssh-з'єднання. Ви також можете docker run ... connect.sh, і docker exec {container name/id} deploy.sh, щоб вони грали разом.
Енді

Ти правий. Я фактично використовую execвже runконтейнер, і SSH труба не зберігалася після execзакінчення. Я уточнив, що це було пов'язано із химерністю із виконанням сценаріїв. Якщо я перемістив виклик до власного сценарію і зателефонував nohup <script.sh> & disown, він переживе завершення exec.
claytond

1

Розуміючи відповідь Хав'єра, це працює для мене:

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, як тільки ви закриєте перше з'єднання. Крім того, спосіб socat дозволяє вам вказати адресу для прив'язки через bindопцію, а не як адресу перед портом.

Після цього просто підключіться до localhost:9999звичайного способу, як би ви хотіли. Потім, щоб зняти тунель:

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

(або щось подібне, ви можете зробити більш детальні речі, які передбачають збереження PID соца)


1

Так, ви можете використовувати socat.

Спочатку зробіть тунель TCP з SSH. Потім використовуйте socat так:

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

Потім надайте дозволи новому створеному сокету (може бути chmod 777)


Це можливо, оскільки OpenSSH 6.6.
ysdx

3
chmod 777: nonononono! Ніколи не бігати chmod 777. Це практично ніколи не потрібно! Навіть не для "тестування". Якщо файл читабельний, то він читабельний. Якщо це можна записати через те userчи інше, groupщо потрібно писати до нього, то це можна записати. Існує абсолютно нульова потреба, щоб дати всім права на написання, і забути chmodце повернути на щось розумне - це саме те, як багатонаціональні компанії зламаються. Просто не роби цього. Колись. Я написав вступ дозволів Unix . Прочитайте, будь ласка!
Мартін Турноїй
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.