Przekaż plik lokalnego portu lub gniazda do zdalnego pliku gniazda

24

Szybkie pytanie - uruchamiam dwa urządzenia z linuksem, jeden na moim pulpicie, a drugi na moim VPS. Ze względów bezpieczeństwa po stronie VPS zdecydowałem się na połączenia gniazd z MySQL ( /var/run/mysqld/mysql.sock). Wiem, że mogę tunelować w ten sposób: ssh -L 3307:127.0.0.1:3306 [email protected]jeśli skonfiguruję zdalny serwer sql do nasłuchiwania na jakimś porcie, ale chcę wiedzieć, czy mogę zrobić coś takiego: ssh -L /path/to/myremotesqlserver.sock:/var/run/mysqld/mysql.socktunelując dwa gniazda, a nie dwa porty?

Idealnym rozwiązaniem byłoby również przekierowanie portu lokalnego do pliku zdalnego gniazda, ale tam, gdzie to możliwe, staram się, aby serwery TCP nie działały na zdalnym urządzeniu.

(i tak, wiem, że tcp byłoby łatwiejsze).


źródło
Jeśli powodem, dla którego nie chcesz używać TCP na polu mySQL, są względy bezpieczeństwa (tj. Ataki zdalne itp.), Możesz oczywiście albo zaporę ogniową, a jeśli to nie wystarczy, zmów mySQL tylko do słuchania 127.0.0.1 dla połączeń TCP, możesz łatwo tunelować przez SSH. Jeśli nie, popieram poniższe rozwiązanie socat.
Mattias Ahnberg
lwn.net/Articles/609321 OpenSSH 6.7 przyniesie przekierowanie gniazd
Hubbitus
@Hubbitus jest teraz dostępna, jeśli tak, czy możesz podać przykładową odpowiedź?
CMCDragonkai 17.07.17
Ten komentarz był w formie odpowiedzi, ale został przez kogoś przekształcony w komentarz. I widzę, że już sugerujesz odpowiedź poniżej.
Hubbitus,

Odpowiedzi:

35

Przekaż lokalne gniazdo na żądanie

  • Skonfiguruj uwierzytelnianie klucza publicznego SSH
  • Zainstaluj socatna obu końcach
  • utwórz katalog lokalnie dla swoich gniazd, niedostępny dla innych użytkowników.
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'

następnie

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

skradzione z przekazywania gniazd domeny unix za pomocą ssh i socat

ijk
źródło
To jest niesamowite i powinno być przyjętą odpowiedzią.
John Smith Opcjonalnie
32

Chociaż w czasie, gdy pytanie zostało zadane, było to naprawdę niemożliwe, ale jest możliwe obecnie.

Możesz zarówno: UNIX => TCP i UNIX => UNIX forwarding.

Na przykład:

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

Jest to możliwe, ponieważ OpenSSH 6.7.

Igor Chubin
źródło
1
Udało mi się przekazać moje lokalne gniazdo do zdalnego gniazda serwera za pomocą powyższego i zdalnie uruchomić klienta dokera (można to zrobić bezpośrednio przez ssh, ale gdzie jest w tym zabawa :)ssh -L /home/user/docker.sock:/var/run/docker.sock dockerhost -N
sdkks 14.04.18
11

nie zrobiłem tego, ale spróbowałbym z socat . może coś takiego:

ssh [email protected] -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

ponownie, nigdy nie zrobiłem czegoś takiego.

Javier
źródło
Spróbuję i dam znać, jak to idzie. Korzystam z implementacji opartej na tcp.
W tej chwili nie mogę go uruchomić, ale i tak daje +1 +1, podoba mi się. Dam ci znać, jeśli to naprawię.
+1 wygląda jak przydatne narzędzie.
Warner
5

Od ssh 6.7 nie jest już potrzebne socat. Możesz przekazywać gniazda domeny unix bezpośrednio, takie jak:

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

Więcej informacji: https://medium.com/@dperny/forwarding-the-docker-socket-over-ssh-e6567cfab160

CMCDragonkai
źródło
Uznałem to również za przydatne do łączenia się z lokalnym gniazdem jako inny użytkownik. Pozwala mi to uruchamiać programy klienckie na procesie serwera, który rozłącza niektóre identyfikatory użytkowników (połączenia pochodzące z jego własnych programów uruchamiających zadania).
Warbo
Przekazywanie gniazda do tego samego komputera, ale innego katalogu kontrolowanego przez innego użytkownika, za pomocą sshd do uwierzytelnienia dostępu? Jaka jest twoja skrzynka?
CMCDragonkai
Uprawnienia do katalogu / dostęp nie stanowią problemu. Dany demon raczej odrzuca wszelkie próby nawiązania połączenia przez użytkowników w określonej grupie (rzekomo, aby zapobiec pomyleniu początkujących). Użycie ssh pozwala tym użytkownikom łączyć się (przez tunelowane gniazdo) tak, jakby byli użytkownikami spoza tej grupy, a zatem nie mogli się rozłączyć.
Warbo
Ciekawe, zabawne, jak masz na myśli demona nix, zajmuję się również problemami z tym związanymi. Zastanawiam się, dlaczego nix-daemon odrzuca połączenia do użytkowników w określonej grupie? Czy to kwestia konfiguracji zabezpieczeń? Lub związany z: nixos.org/nix/manual/#idm140737318362784 ?
CMCDragonkai
Zgodnie z komunikatem zatwierdzenia ma to zapobiec „przypadkowemu” użyciu.
Przywołałem
2

Kolejna modyfikacja odpowiedzi @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'

Odkurzacz

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
'

PROS

  1. Działa na openssh wcześniejszym niż 6.7 (jak CentOS 7)
  2. Zabija socat po zakończeniu ssh zamiast konieczności ponownego ssh na zdalnym serwerze
  3. Umożliwia niepubliczne logowanie ssh (w przeciwieństwie do rozwiązania ijk)

Cecha

  1. Ponieważ -fopcja nie jest używana, możesz albo użyć klucza publicznego i uruchomić się w tle za pośrednictwem, &albo możesz zalogować się interaktywnie i użyć Ctrl + Z i użyć tego samego $!do przechowywania pid.

CONS

  1. Nie można łatwo użyć -fopcji ssh, ponieważ w ten sposób stracisz pid ssh. Ta metoda polega na uruchomieniu na pierwszym planie i Ctrl + C, aby zabić.
  2. O wiele bardziej skomplikowane

Wyjaśnienie

  • socat ...& - uruchom socat w tle na zdalnym serwerze
  • pid=$! - przechowuj pid
  • trap kill\ $pid 0- działa kill $pidna zakończenie bash
  • while :; sleep... - usiądź w nieskończonej pętli
  • echo -ne \ \b- Echo, po którym następuje backspace. Nie udaje się to natychmiast po odłączeniu ssh. W przypadku a sleep 5oznacza to, że socatmoże działać do 5 sekund po ssh

Uwaga: Właściwie testowano przy użyciu docker, port 2375, /var/run/docker.sockoraz zmienną środowiskową DOCKER_HOST='tcp://localhost:2375', ale powinien działać dla mysql wszystko jedno

Aktualizacja

Korzystając z kontrolek SSH , możesz użyć -fflagi na mój sposób, po prostu dodaj następujące flagi

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

I dostaniesz

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'

Teraz możesz zakończyć wszystkie kontrolowane sesje za pomocą

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

Te -oopcje mogą być zapisane w .ssh/configpliku, lub można użyć zamiast -S (ale będziesz nadal potrzeba -o ControlMaster)

Andy
źródło
Używam skryptów w kontenerze Docker do wdrażania kodu na innych hostach. Twoja logika połączenia jest niesamowita, ale kończy się po zakończeniu sesji bash. Uniemożliwia to moje wywołanie w docker run ... connect.shcelu ustawienia tunelu, a następnie docker run ... deploy.sh. Próbowałem nohup, &i disownale wydają się przebić socatprzez zamknięcie stdouti wyzwalania kill. Jakieś pomysły na poprawki w celu wsparcia tej sprawy (tj. Wciąż blisko, gdy SSH przetrwa, ale przetrwa odrzucenie)?
claytond
DOBRZE. To faktycznie działa dobrze (w / -fi & disown) w terminalu. Najwyraźniej problem jest tworzony przez skrypt „wrapper”. Z chęcią przyjmę opinie, ale teraz szukam bardziej odpowiednich pytań i odpowiedzi.
claytond
@claytond Nie jestem pewien, co dokładnie robisz, ale tak, wszystkie inne polecenia są kończone, gdy kończy się pid 1 kontenera. To, co zwykle robiłbym w scenariuszu skryptu wdrażania, to użycie polecenia „deploy” i zapisanie punktu wejścia dla mojego kontenera obraz, który powie „jeśli $ 1 (polecenie) == deploay to” uruchom komendy ssh i komendy wdrażania, a następnie zakończ, co spowoduje zamknięcie połączenia ssh. Możesz także docker run ... connect.sh, a docker exec {container name/id} deploy.shwięc oni grają razem.
Andy
Masz rację. Używam execjuż na runkontenerze, a potok SSH nie trwał po execzakończeniu. Wyjaśniłem, że było to spowodowane dziwactwem w sposobie wykonywania skryptów. Jeśli przeniosłem wywołanie do własnego skryptu i zadzwoniłem nohup <script.sh> & disown, to przetrwa on ukończenie exec.
claytond
1

Opracowanie odpowiedzi Javiera działa dla mnie:

ssh -f [email protected] -L 9999:localhost:9999 "socat TCP-LISTEN:9999,fork,bind=localhost UNIX-CONNECT:/var/run/mysqld/mysql.sock"

Musisz być forkw stanie połączyć się wiele razy bez śmierci, po zamknięciu pierwszego połączenia. Ponadto sposób, w jaki socat pozwala określić adres do powiązania, odbywa się poprzez bindopcję, a nie jako adres przed portem.

Następnie po prostu połącz się localhost:9999tak, jak zwykle. Następnie, aby porzucić tunel:

ssh -f [email protected] "killall socat"

(lub coś podobnego, możesz zrobić bardziej skomplikowane rzeczy, które wymagają zachowania PID socat)

mpontes
źródło
1

Tak, możesz używać socat.

Najpierw wykonaj tunel TCP za pomocą SSH. Następnie użyj socat w następujący sposób:

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

Następnie daj uprawnienia nowemu utworzonemu gniazdu (może być chmod 777)

użytkownik190133
źródło
Jest to możliwe, ponieważ OpenSSH 6.6.
ysdx
3
chmod 777: nie nie nie nie nie! Nigdy nie biegaj chmod 777. To praktycznie nigdy nie jest wymagane! Nawet do „celów testowych”. Jeśli plik jest czytelny, to jest czytelny. Jeśli jest zapisywalny przez userlub groupktóry musi do niego napisać, to jest zapisywalny. Absolutnie nie ma potrzeby udzielania wszystkim uprawnień do zapisu, a zapomnienie chmodo czymś przy zdrowych zmysłach jest dokładnie tym, w jaki sposób hakowane są międzynarodowe korporacje. Po prostu nie rób tego. Zawsze. Napisałem wprowadzenie do uprawnień Unix . Proszę przeczytaj to!
Martin Tournoij