Ssh'ing yaparken, oturumdan oturuma değişen sunucudaki bir ortam değişkenini nasıl ayarlayabilirim?


92

Bir sshsunucuya girdiğimde , bir ortam değişkenini istemciden sunucuya nasıl iletebilirim? Bu ortam değişkeni, farklı ssh çağrıları arasında değişir, bu yüzden $HOME/.ssh2/environmenther ssh araması yaptığımda üzerine yazmak istemiyorum . Bunu nasıl yapabilirim?


2
Sorunuz biraz daha spesifik olmalı.
Ignacio Vazquez-Abrams,

3
Soru bana yeterince açıktı. Ancak, sshman sayfasında, ~ / .ssh2 / ortamını değiştirmediyseniz, sunucuya giriş yaptıktan sonra değişkeni manuel olarak ayarlamaktan başka bir yol görmüyorum.
garyjohn

Her seferinde farklı bir değişken mi? Ya da farklı bir değer?
Dennis Williamson,


1
Diğer taraftan, bu zaten daha popüler olduğu için. Daha büyük olması önemli değil.
kenorb

Yanıtlar:


110

Elbette, ortam değişkenini komutun içinde ayarlayabilirsiniz, ancak alıntı yapma konusunda dikkatli olmanız gerekir: kabuğunuzun yerel komut satırınızı ayrıştırdığını ve ardından uzak kabuğun dizeye gideceğini unutmayın alır.

Bir değişkenin, istemcide sahip olduğu sunucuda aynı değeri elde etmesini istiyorsanız, SendEnvseçeneği deneyin :

ssh -o SendEnv = MYVAR sunucusu.example.com komutum

Bu olsa da, sunucudan destek gerektirir. OpenSSH ile değişken ismi yetkilendirilmiş olmalıdır /etc/sshd_config.

Sunucu yalnızca belirli değişken adlarına izin veriyorsa, bunun üzerinde çalışabilirsiniz; örneğin, ortak bir kurulum olanak sağlar LC_*ve aşağıdakileri yapabilirsiniz:

ssh -o SendEnv = LC_MYVAR sunucusu.example.com 'MYVAR = $ LC_MYVAR; LC_MYVAR'ın ayarlanmamış; ihracat MYVAR; mycommand'

Bir LC_*seçenek olmasa bile , bilgileri TERMdaima değiştirilen ortam değişkeninde iletebilirsiniz (bununla birlikte bir uzunluk sınırı olabilir). Uzak kabuğun TERMbilinen bir terminal türünü belirtmek için değişkeni kısıtlamadığından emin olmanız gerekir . Geçiş -tUzak etkileşimli kabuk başlayan değilseniz ssha seçeneği.

env TERM = "ek bilgi: $ TERM" ssh -t server.example.com 'MYVAR = $ {TERM%: *}; SÜRESİ = $ {SÜRE ## *:}; ihracat MYVAR; mycommand'

Diğer bir olasılık değişkeni doğrudan komutta tanımlamaktır:

ssh -t server.example.com 'verme MYVAR = "ek bilgi"; mycommand'

Böylece, yerel bir değişkeni geçiyorsanız:

ssh -t server.example.com 'verme MYVAR =' "'$ LOCALVAR'" '; mycommand'

Bununla birlikte, alıntı yapma hususlarına dikkat edin: değişkenin değeri doğrudan uzak tarafta yürütülen kabuk snippet'ine dahil edilir. Yukarıdaki son örnekte $LOCALVAR, herhangi bir tek tırnak ( ') bulunmadığı varsayılmaktadır .


2
Çok teşekkürler, aptal LC_ * değişkenlerinin ssh'a aktarılması ve cevabın nereye bakmamı istediği konusunda öfkelendim. Sadece ~ / .ssh / config
akostadinov

1
Orijinal posterin durumundayım ama iletmek istediğim değişken TERM, bu yüzden cevabınıza biraz şaşırdım. TERM'nin bu otomatik iletimi en son OpenSSH sürümleri tarafından devre dışı bırakılmış mı?
Doub

1
@Doub Varsayılan, sunucu tarafındaki tüm ortam değişkenlerini , yönetici tarafından istenen şekilde AcceptEnvyönergeleri ile reddetmektir sshd_config. Ancak TERM, bildiğim kadarıyla sunucu tarafında filtrelemenin bir yolu yok (herhangi bir yapılandırma ayarından bağımsız olarak kabuk ortamında ayarlanır). Bunu geçersiz kılan bir profil komut dosyası olmadığından emin misiniz (gibi /etc/profileveya ~/.profileveya ~/.bashrc)?
Gilles

2
@Gilles: Tekrar test ettim ve açıkça AcceptEnv yönergesine TERM eklemediğim sürece, TERM geçilmez. Bir kabuk açmıyorum, ancak doğrudan bir komutu çalıştırıyorum, örneğin: "ssh -o SendEnv = TERM shell.example.com env". Bu tüm ortam değişkenlerini yazdırır ve TERM yalnızca istemcide SendEnv'de ve sunucuda AcceptEnv'de ise görünür. AcceptEnv veya SendEnv ile "ssh -o SendEnv = TERM shell.example.com echo \ $ {TERM}" çalıştırıyorsam, nereden geldiğinden emin değilim "aptal" yazıyor (env, hatta Bu durumda TERM'i listeler).
Doub

7
@Doub Oh, anlıyorum. TERMyalnızca istemci sunucudan bir tty ayırmasını isterse iletilir. Uzak tarafta terminal yoksa, iletmenin faydası olmaz TERM. Bir komut belirttiğinizde, uzak tarafta bir terminal kullanmak istiyorsanız, -tkomut satırı seçeneğine (veya RequestTTYiçeri ~/.ssh/config) ihtiyacınız vardır.
Gilles

12

Hedef ana bilgisayarı yönetebilirseniz, sshd'yi yerel ortam değişkenlerinizi hedef ana bilgisayara iletmeye izin verecek şekilde yapılandırabilirsiniz.

Sshd_config man sayfasından:

 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.

sshd yapılandırması tipik olarak /etc/ssh/sshd_config


7
Bunun varsayılan olarak "hayır" olarak ayarlandığını bilmek çok faydalıdır!
jathanizm

6

Yani, müşterinizde, bazı ortam değişkenleriniz var ve bunun uzaktan kumanda için de kullanılabilir olmasını mı istiyorsunuz? Ssh'ı sihirli bir şekilde geçmenin bir yolu olduğunu sanmıyorum, ama muhtemelen böyle bir şey yapabilirsin. Kullanmak yerine, şunu söyleyin:

ssh remote.host my_command

Bunu yapabilirsiniz:

ssh remote.host env ENV_VAR=$ENV_VAR my_command

"muhtemelen"? Keşke bu cevabı gerçekten denemeden önce okudum. Benim için işe yaramadı.
tishma

1
Alınan herhangi bir hata hakkında ayrıntılı bilgi vermek ister misiniz?
pioto,

1
@pioto Alıntı yapıyor olabilir, örneğin eğer ENV_VAR içinde boşluklar varsa
Martin C. Martin

Mac'te etkileşimli bir sürüm için -t seçeneğine sahip olmalısınız, aksi takdirde takılmış görünüyor. Yani bu işe yarayabilir: $ ssh -t remote.host env ENV_VAR = $ ENV_VAR my_command
muenalan

3

@ emptyset'in yanıtı (benim için çalışmadı) bu cevaba yol açtı:

Bu komutu ~/.ssh/authorized_keysdosyanıza ekleyebilirsiniz :

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

export VARIABLE=<something>hemen çıkıyordu ve SSH bağlantısı kapatıldı (beni sunucudan kilitledi), /usr/bin/env ... $SHELLvarsayılan kabuğunuzu değiştirilmiş bir ortamla çalıştırırdı.


Bu sadece benim için giriş yaparken kilitleniyor. Kaldırdığımda SSH normale döner ve normal giriş kabuğumu alırım.
Nick Sweeting,

@NickSweeting belki $SHELLgerçek bir kabukla değiştirmeyi denedin mi? Ayrıca sunucuda / usr / bin / env dosyasının olup olmadığını kontrol edin. Ancak çözüm mükemmel değil: Kullanmak istediğimde scpveya satır içi bir komut kullandığımda asıldığını fark ettim .
madprog

Evet, ilk denediğim şey buydu. Maalesef hiç işe yaramadı, yerine etkinleştirme PermitUserEnvironment yesve kullanmaya başladı . environment="..."command="..."
Nick Sweeting

Bu benim için iyi çalışıyor.
Bay Tao,

2

Yerel istemci üzerinde Gözlerinde farklı ~/.ssh/configekleyebilir SetEnv, örneğin

Host myhost
  SetEnv FOO=bar

Not: Kontrol Et man ssh_config.

Ardından sunucuda, istemcinin /etc/ssh/sshd_configconfig dosyanızda belirli ortam değişkenlerini geçmesine izin verdiğinizden emin olun :

AcceptEnv LANG LC_* FOO BAR*

Not: Kontrol Et man sshd_config.


1

Parola olmadan ssh oturum açma kurulumunuz olduğunu varsayarak özel bir komut çağırmayı deneyebilirsiniz. Sunucuda, müşteriden gelen anahtara karşılık gelen ~ / .ssh / yetkili_ anahtarlar girişinizi düzenleyin:

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

Bak bu bağlantıyı bölümünde Komut Zorla biraz daha ayrıntı için.


1
Bunu denedim, ama işe yaramadı. Komutu çalıştırır ve çıkar, bu nedenle etkileşimli oturum yoktur. Bu normal davranış mı? Öyleyse, yapmak istediğiniz tek şey belirli bir komutun belirli bir komutu tetiklemesine izin vermekse faydalı olabilir, ancak bir oturumda kullanılan bilgileri (soruların olduğu gibi) iletmek istiyorsanız, o zaman bu amaç için işe yaramaz . Oturum yok.
iconoclast

1

Ana dizinde cramfs ve / etc (Cram FS salt okunur) olan bir aygıt için özel bir OpenSSH derlemesi yapıyordum, bu nedenle ~ / .ssh / ortam tüm FS'yi yeniden oluşturmadan çalışmayacaktı ve bunlar sahaya dağıtıldı. cihazlar (Gömülü Sistemler Dolayısıyla CRAMFS kullanımı). Sshd_config dosyasında authroized_keys dosyasının konumunu belirleyebilirsiniz, ancak bir nedenden dolayı environment = yalnızca ~ / .ssh / authroized_keys içindeki ortam değişkenleri için çalışır. / Etc / profile dosyasını düzenlemek bir seçenek değildi ve ssh'i standart olmayan bir dizine yüklemek zorunda kaldım. Child_set_env (... "MAIL" ...) 'den sonraki session.c' de sadece ihtiyacınız olan ortam değişkenlerini ekleyin (Bu, bir hack ... olduğunu biliyorum), fakat sadece bir kişinin oturumu için biraz kodlanmış envs isteyin. kaynaktan derleyerek bunu yapabilirsiniz. TGI-FLOSS'un


0

sadece basit bir komut:

ssh -t your_host_or_ip 'export some_var_name=whatever_you_want; bash'
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.