Inoltra la porta locale o il file socket al file socket remoto


24

Domanda rapida: eseguo due box Linux, uno il mio desktop e l'altro il mio VPS. Per motivi di sicurezza sul lato VPS ho optato per connessioni socket a MySQL ( /var/run/mysqld/mysql.sock). So di poter eseguire il tunneling in questo modo: ssh -L 3307:127.0.0.1:3306 user@site.comse ho impostato il server sql remoto per l'ascolto su una porta, ma quello che voglio sapere è che posso fare qualcosa del genere: in ssh -L /path/to/myremotesqlserver.sock:/var/run/mysqld/mysql.sockquesto modo il tunneling di due socket, anziché due porte?

Una soluzione perfettamente accettabile sarebbe anche quella di inoltrare una porta locale al file socket remoto, ma dove possibile sto cercando di non avere server tcp in esecuzione sul box remoto.

(e sì, so che TCC sarebbe più facile).


Se il motivo per cui non si desidera utilizzare TCP nella casella mySQL è dovuto a problemi di sicurezza (ad esempio attacchi remoti, ecc.), È possibile ignorare entrambi i firewall e, se ciò non è abbastanza buono, fare in modo che mySQL ascolti solo 127.0.0.1 per le sue connessioni TCP, puoi facilmente tunnel attraverso SSH. In caso contrario, sostengo la soluzione socat di seguito.
Mattias Ahnberg,

lwn.net/Articles/609321 OpenSSH 6.7 porterà l'inoltro socket
Hubbitus,

@Hubbitus questa funzione è ora disponibile, in tal caso, puoi fornire una risposta di esempio?
CMCDragonkai,

Quel commento era in forma di risposta, ma convertito in commento da qualcuno. E ora vedo che già suggerisci la risposta qui sotto.
Hubbitus,

Risposte:


35

Inoltra un socket locale su richiesta

  • Configurare l'autenticazione con chiave pubblica SSH
  • Installa socatad entrambe le estremità
  • crea una directory localmente per i tuoi socket, inaccessibile ad altri utenti.
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'

poi

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

rubato dall'inoltro dei socket di dominio unix con ssh e socat


Questo è fantastico e dovrebbe essere la risposta accettata.
John Smith Opzionale il

32

Anche allora, quando la domanda è stata posta, era davvero impossibile, ma è possibile al giorno d'oggi.

È possibile entrambi: UNIX => TCP e UNIX => inoltro UNIX.

Per esempio:

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

È possibile da OpenSSH 6.7.


1
Sono riuscito a inoltrare il mio socket locale al socket del server remoto usando sopra ed eseguire il client docker in remoto (potrebbe essere fatto direttamente da ssh, ma dove è il divertimento :)ssh -L /home/user/docker.sock:/var/run/docker.sock dockerhost -N
sdkks

11

non l'ho fatto, ma proverei con socat . forse qualcosa del tipo:

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

di nuovo, non ho mai fatto nulla di simile.


Ci proverò e ti farò sapere come va. Ho usato l'implementazione basata su tcp.

Non riesco a farlo funzionare al momento ma +1 comunque per l'idea, mi piace. Ti farò sapere se lo aggiusto.

+1 sembra un'utilità utile.
Warner,

5

Non è più necessario socat da ssh 6.7. Puoi inoltrare socket di dominio unix direttamente come:

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

Maggiori informazioni: https://medium.com/@dperny/forwarding-the-docker-socket-over-ssh-e6567cfab160


Ho anche trovato questo utile per la connessione a un socket locale come utente diverso. Questo mi ha permesso di eseguire programmi client su un processo server che disconnette determinati ID utente (connessioni provenienti dai propri corridori di lavoro).
Warbo,

Inoltro di un socket alla stessa macchina, ma directory diversa controllata da un utente diverso, usando sshd per autenticare l'accesso? Qual è il tuo caso d'uso?
CMCDragonkai,

Le autorizzazioni / l'accesso alla directory non sono un problema. Piuttosto, un demone particolare elimina qualsiasi tentativo di connessione fatto dagli utenti in un determinato gruppo (presumibilmente per evitare che i neofiti vengano confusi). L'uso di ssh consente a quegli utenti di connettersi (tramite il socket sintonizzato) come se fossero utenti non appartenenti a quel gruppo e quindi non disconnettersi.
Warbo,

Interessante, divertente come intendi il demone-nix, mi occupo anche di problemi al riguardo. Mi chiedo perché nix-daemon sta abbandonando le connessioni agli utenti di un determinato gruppo? È una cosa di configurazione della sicurezza? O correlato a: nixos.org/nix/manual/#idm140737318362784 ?
CMCDragonkai,

Secondo il messaggio di commit è per impedire l'uso "accidentale". L'ho portato qui
Warbo il

2

Un'altra modifica della risposta di @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'

addetto alle pulizie

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
'

PROFESSIONISTI

  1. Funziona su openssh prima della 6.7 (come CentOS 7)
  2. Uccide socat sulla terminazione ssh invece di dover re-ssh nel server remoto
  3. Consente l'accesso ssh non pubblico (diversamente dalla soluzione ijk)

caratteristica

  1. Poiché l' -fopzione non viene utilizzata, è possibile utilizzare una chiave pubblica ed eseguire in background tramite &oppure è possibile accedere in modo interattivo e utilizzare Ctrl + Z e utilizzare lo stesso $!per memorizzare il pid.

CONS

  1. Non puoi usare facilmente l' -fopzione ssh, poiché perderai il pid di ssh in quel modo. Questo metodo si basa sull'esecuzione in primo piano e Ctrl + C per uccidere.
  2. Molto più complicato

Spiegazione

  • socat ...& - eseguire socat in background sul server remoto
  • pid=$! - memorizza il pid
  • trap kill\ $pid 0- eseguire kill $pidsu bash terminazione
  • while :; sleep... - sedersi in un ciclo infinito
  • echo -ne \ \b- Spazio eco seguito da backspace. Questo fallisce non appena l'ssh viene disconnesso. Con a sleep 5, questo significa che socatpuò funzionare fino a 5 secondi dopo ssh

Nota: In realtà testati utilizzando finestra mobile, la porta 2375, /var/run/docker.socke la variabile ambiente DOCKER_HOST='tcp://localhost:2375', ma dovrebbe funzionare per mysql tutti uguali

Aggiornare

Usando i controlli SSH , puoi usare la -fbandiera a modo mio, basta aggiungere le seguenti bandiere

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

E otterrai

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'

Ora puoi terminare tutte le sessioni controllate usando

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

Le -oopzioni possono essere salvate nel tuo .ssh/configfile oppure puoi usare -S invece (ma avrai comunque bisogno -o ControlMaster)


Sto usando gli script all'interno di un contenitore Docker per distribuire il codice ad altri host. La tua logica di connessione è sorprendente ma termina quando termina la sessione bash. Questo impedisce al mio di chiamare docker run ... connect.shper impostare il tunnel seguito da docker run ... deploy.sh. Ho provato nohup, &e disownma sembrano rompersi socatchiudendo stdoute attivando il kill. Qualche idea per le modifiche a supporto di questo caso (vale a dire ancora vicino quando SSH fa ma sopravvive a un rinnegamento)?
Claytond,

OK. Questo funziona davvero bene (w / -fand & disown) in un terminale. Apparentemente il problema è stato creato dallo script "wrapper". Gradirei un contributo, ma sto cercando domande e risposte più appropriate ora.
Claytond,

@claytond Non so esattamente cosa stai facendo, ma sì, tutti gli altri comandi vengono terminati quando termina il pid 1 di un contenitore. Quello che normalmente farei nel tuo scenario di script di distribuzione è usare il comando "deploy" e scrivere un punto di accesso per il mio contenitore immagine che dirà "if $ 1 (il comando) == deploay then" esegui i comandi ssh, i comandi deploy, e poi end, che chiuderà la connessione ssh. Puoi anche docker run ... connect.she docker exec {container name/id} deploy.sh, quindi, giocano insieme.
Andy,

Hai ragione. In realtà sto usando execsu un runcontenitore già e il tubo SSH non persisteva dopo la execfine. Ho chiarito che era dovuto a una stranezza con il modo in cui gli script venivano eseguiti. Se ho spostato la chiamata sul suo stesso script e nohup <script.sh> & disownho chiamato , sopravvive al completamento di exec.
Claytond,

1

Elaborando la risposta di Javier, questo funziona per me:

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

È necessario forkper poter connettersi più volte senza morire dopo aver chiuso la prima connessione. Inoltre, il modo in cui socat consente di specificare un indirizzo a cui associarsi è tramite l' bindopzione, non come indirizzo prima della porta.

Dopo questo, connettiti localhost:9999normalmente come faresti. Quindi per demolire il tunnel:

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

(o qualcosa di simile, puoi fare cose più elaborate che comportano mantenere il PID di socat)


1

Sì, puoi usare socat.

Prima fai il tunnel TCP con SSH. Quindi usa socat in questo modo:

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

Quindi concedere le autorizzazioni al nuovo socket creato (potrebbe essere chmod 777)


Questo è possibile da OpenSSH 6.6.
ysdx,

3
chmod 777: nonononono! Mai e poi mai correre chmod 777. Non è praticamente mai richiesto! Nemmeno per "scopi di test". Se il file è leggibile, è leggibile. Se è scrivibile da parte del usero groupche hanno bisogno di scrivere ad esso, allora è scrivibile. Non c'è assolutamente bisogno di dare a tutti i permessi di scrittura, e dimenticarsene chmodè qualcosa di sensato come le multinazionali vengono hackerate. Basta non farlo. Mai. Ho scritto un'introduzione delle autorizzazioni Unix . Per favore, leggilo!
Martin Tournoij,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.