Durante lo ssh, come posso impostare una variabile d'ambiente sul server che cambia da sessione a sessione?


92

Quando sshentro in un server, come posso passare una variabile d'ambiente dal client al server? Questa variabile di ambiente cambia tra diverse invocazioni di ssh, quindi non voglio sovrascrivere $HOME/.ssh2/environmentogni volta che faccio una chiamata ssh. Come posso fare questo?


2
La tua domanda deve essere un po 'più specifica.
Ignacio Vazquez-Abrams,

3
La domanda era abbastanza chiara per me. Tuttavia, dalla sshpagina man, non vedo altro modo di farlo se non l'impostazione manuale della variabile dopo aver effettuato l'accesso al server, a meno che non modifichi ~ / .ssh2 / environment.
garyjohn,

Ogni volta è una variabile diversa? O un valore diverso?
Dennis Williamson,


1
Al contrario, poiché questo è già più popolare. Non importa che sia più vecchio.
Kenorb,

Risposte:


110

Ovviamente, puoi impostare la variabile d'ambiente all'interno del comando, tuttavia dovrai fare attenzione al preventivo: ricorda che la tua shell analizzerà la tua riga di comando locale, e quindi la shell remota proverà sulla stringa riceve.

Se vuoi che una variabile ottenga sul server lo stesso valore che ha sul client, prova l' SendEnvopzione:

ssh -o SendEnv = MYVAR server.example.com mycommand

Ciò richiede supporto dal server, comunque. Con OpenSSH, il nome della variabile deve essere autorizzato in /etc/sshd_config.

Se il server consente solo determinati nomi di variabili specifici, è possibile aggirare il problema; ad esempio, una configurazione comune consente LC_*attraverso, ed è possibile effettuare le seguenti operazioni:

ssh -o SendEnv = LC_MYVAR server.example.com 'MYVAR = $ LC_MYVAR; disinserito LC_MYVAR; esportazione MYVAR; myCommand'

Se even LC_*non è un'opzione, è possibile passare informazioni nella TERMvariabile d'ambiente, che viene sempre copiata (tuttavia potrebbe esserci un limite di lunghezza). Dovrai comunque assicurarti che la shell remota non limiti la TERMvariabile per designare un tipo di terminale noto. Passare l' -topzione a ssh se non si avvia una shell interattiva remota.

env TERM = "informazioni aggiuntive: $ TERM" ssh -t server.example.com 'MYVAR = $ {TERM%: *}; TERM = $ {TERM ## *:}; esportazione MYVAR; myCommand'

Un'altra possibilità è quella di definire la variabile direttamente nel comando:

ssh -t server.example.com 'export MYVAR = "informazioni aggiuntive"; myCommand'

Pertanto, se si passa una variabile locale:

ssh -t server.example.com 'export MYVAR =' "'$ LOCALVAR'" '; myCommand'

Tuttavia, fai attenzione ai problemi di quotazione: il valore della variabile verrà interpolato direttamente nello snippet di shell eseguito sul lato remoto. L'ultimo esempio sopra presuppone che $LOCALVARnon contenga virgolette singole ( ').


2
Grazie mille, ero furioso che le stupide variabili LC_ * fossero esportate su ssh e la tua risposta mi ha indicato dove cercare. Devo solo disabilitarlo in ~ / .ssh / config
akostadinov il

1
Sono nella situazione del poster originale, ma la variabile che volevo inoltrare è TERM, quindi sono un po 'perplesso dalla tua risposta. Questo inoltro automatico di TERM è stato disabilitato dalle recenti versioni di OpenSSH?
Doub

1
@Doub L'impostazione predefinita è di rifiutare tutte le variabili di ambiente sul lato server, con le AcceptEnvdirettive sshd_configcome desiderato dall'amministratore. Ma TERMviene trattato in modo speciale, per quanto ne so non c'è modo di filtrarlo sul lato server (è impostato nell'ambiente della shell indipendentemente da qualsiasi impostazione di configurazione). Sei sicuro che non ci sia uno script del profilo che lo ignori (come /etc/profileo ~/.profileo ~/.bashrc)?
Gilles,

2
@Gilles: l'ho testato di nuovo e, a meno che non aggiunga esplicitamente TERM alla mia direttiva AcceptEnv, il TERM non viene trasmesso. Non apro una shell, ma eseguo direttamente un comando, ad esempio: "ssh -o SendEnv = TERM shell.example.com env". Che stampa tutte le variabili di ambiente e TERM appare solo se si trova in SendEnv sul client e AcceptEnv sul server. Se eseguo "ssh -o SendEnv = TERM shell.example.com echo \ $ {TERM}" senza accettare AcceptEnv o SendEnv, stampa "stupido", che non sono sicuro da dove provenga (env neanche elenco TERM in quel caso).
Doub

7
@Doub Oh, capisco. TERMviene trasmesso solo se il client richiede al server di allocare un tty. Se non ci sono terminali sul lato remoto, sarebbe inutile trasmettere TERM. Quando si specifica un comando, se si desidera disporre di un terminale sul lato remoto, è necessaria l' -topzione della riga di comando (o RequestTTYin ~/.ssh/config).
Gilles,

12

Se è possibile amministrare l'host di destinazione, è possibile configurare sshd per consentire il passaggio delle variabili di ambiente locale all'host di destinazione.

Dalla pagina man sshd_config:

 PermitUserEnvironment
     Specifies whether ~/.ssh/environment and environment= options in
     ~/.ssh/authorized_keys are processed by sshd.  The default is
     "no".  Enabling environment processing may enable users to bypass
     access restrictions in some configurations using mechanisms such
     as LD_PRELOAD.

la configurazione di sshd vive in genere su /etc/ssh/sshd_config


7
È molto utile sapere che questo è impostato su "no" per impostazione predefinita!
jatanismo

6

Quindi, sul tuo client, hai qualche variabile d'ambiente e vuoi che sia disponibile per il comando remoto? Non penso che ci sia un modo per far passare magicamente ssh, ma probabilmente puoi fare qualcosa del genere. Invece di usare, dire:

ssh remote.host my_command

Puoi farlo:

ssh remote.host env ENV_VAR=$ENV_VAR my_command

"probabilmente"? Vorrei leggerlo prima di provare davvero questa risposta. Non ha funzionato per me.
tishma,

1
Vuoi elaborare eventuali errori ricevuti, ecc.?
pioto,

1
@pioto Potrebbe essere un preventivo, ad esempio se ENV_VAR ha degli spazi
Martin C. Martin

Su Mac devi avere l'opzione -t per una versione interattiva, altrimenti sembra bloccata. Quindi potrebbe funzionare: $ ssh -t remote.host env ENV_VAR = $ ENV_VAR my_command
muenalan

3

La risposta di @setset (che non ha funzionato per me) mi ha portato a questa risposta:

Puoi aggiungere questo comando al tuo ~/.ssh/authorized_keysfile:

command="/usr/bin/env VARIABLE=<something> $SHELL" ssh-rsa <key>

export VARIABLE=<something>stava uscendo immediatamente e la connessione SSH è stata chiusa (bloccandomi fuori dal server), mentre /usr/bin/env ... $SHELLeseguirà la shell predefinita con un ambiente modificato.


Questo si blocca quando eseguo l'accesso per me. Quando lo rimuovo SSH ritorna normale e ottengo la mia solita shell di accesso.
Nick Sweeting,

@NickSweeting Hai provato forse la sostituzione $SHELLcon un guscio vero e proprio? Controlla anche che / usr / bin / env esista sul server. Tuttavia la soluzione non è perfetta: ho notato che si blocca quando volevo usare scpo un comando in linea.
madprog,

Sì, è stata la prima cosa che ho provato. Sfortunatamente non è mai riuscito a farlo funzionare, alla fine è stato abilitato PermitUserEnvironment yese utilizzato environment="..."invece di command="...".
Nick Sweeting,

Questo funziona bene per me.
Sig. Tao,

3

Sul tuo client locale, nel tuo ~/.ssh/configpuoi aggiungere SetEnv, ad es

Host myhost
  SetEnv FOO=bar

Nota: controllare man ssh_config.

Quindi sul server, assicurarsi di consentire al client di passare determinate variabili di ambiente nel /etc/ssh/sshd_configfile di configurazione:

AcceptEnv LANG LC_* FOO BAR*

Nota: controllare man sshd_config.


1

Potresti provare a invocare un comando personalizzato, supponendo che tu abbia una configurazione di accesso ssh senza password. Sul server, modifica la voce ~ / .ssh / authorized_keys che corrisponde alla chiave del tuo client:

command="export VARIABLE=<something>" ssh-rsa <key>

Guarda questo link nella sezione Comando forzato per qualche dettaglio in più.


1
Ho provato questo, ma non funziona. Esegue il comando ed esce, quindi non c'è sessione interattiva. È quello il comportamento normale? In tal caso, ciò potrebbe essere utile se tutto ciò che si desidera fare è consentire a una chiave specifica di attivare un comando specifico, ma se si desidera passare le informazioni utilizzate in una sessione (come indicato dalla domanda), è inutile a tale scopo . Non c'è sessione.
iconoclasta,

1

Stavo realizzando una build personalizzata di OpenSSH per un dispositivo con un cramfs nella directory home e / etc (Cram FS è di sola lettura) quindi ~ / .ssh / environment non funzionava non senza ricostruire l'intero FS e questi erano distribuiti sul campo dispositivi (sistemi integrati, quindi l'uso di CRAMFS). È possibile specificare in sshd_config la posizione del file authroized_keys ma per qualche motivo environment = funziona solo con variabili d'ambiente in ~ / .ssh / authroized_keys. La modifica del profilo / etc / non era un'opzione e ho dovuto caricare ssh in una directory non standard. In session.c dopo child_set_env (... "MAIL" ...) aggiungi solo le variabili di ambiente di cui hai bisogno (questo è un hack che conosco ...) ma solo se qualcuno ha bisogno di alcuni enc codificati per una sessione, se lo sei compilando dalla fonte puoi farlo. TGI-FLOSS


0

solo un semplice comando:

ssh -t your_host_or_ip 'export some_var_name=whatever_you_want; bash'
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.