sshするとき、セッションごとに変化する環境変数をサーバーに設定するにはどうすればよいですか?


92

sshサーバーにアクセスするときに、クライアントからサーバーに環境変数を渡すにはどうすればよいですか?この環境変数はsshの異なる呼び出し間で変化するため$HOME/.ssh2/environment、ssh呼び出しを行うたびに上書きしたくありません。これどうやってするの?


2
あなたは質問をより具体的にする必要があります。
イグナシオバスケス-エイブラムス

3
質問は私には十分明確でした。ただし、sshmanページからは、〜/ .ssh2 / environmentを変更しない限り、サーバーにログインしてから変数を手動で設定する以外、その方法はありません。
ゲイリージョン

それは毎回異なる変数ですか?または別の値?
デニスウィリアムソン


1
これはすでに一般的であるため、他の方法でラウンド。古くても構いません。
ケノーブ

回答:


110

もちろん、コマンド内で環境変数を設定できますが、引用に注意する必要があります。シェルがローカルコマンドラインを解析し、リモートシェルが文字列itを取得することに注意してください受け取ります。

変数がクライアント上にあるのと同じ値をサーバー上で取得したい場合は、SendEnvオプションを試してください:

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

ただし、これにはサーバーからのサポートが必要です。OpenSSHでは、変数名をで認証する必要があり/etc/sshd_configます。

サーバーが特定の特定の変数名のみを許可している場合、それを回避できます。たとえば、一般的なセットアップではLC_*通過が許可され、次のことができます。

ssh -o SendEnv = LC_MYVAR server.example.com 'MYVAR = $ LC_MYVAR; 設定解除LC_MYVAR; MYVARをエクスポートします。mycommand '

さらにLC_*オプションがない場合は、TERM環境変数に情報を渡すことができます。環境変数は常にコピーされます(ただし、長さに制限がある場合があります)。リモートシェルがTERM既知の端末タイプを指定するために変数を制限しないことを確認する必要があります。-tリモートの対話型シェルを起動していない場合は、sshにオプションを渡します。

env TERM = "追加情報:$ TERM" ssh -t server.example.com 'MYVAR = $ {TERM%:*}; TERM = $ {TERM ## *:}; MYVARをエクスポートします。mycommand '

別の可能性は、コマンドで変数を直接定義することです:

ssh -t server.example.com 'export MYVAR = "追加情報"; mycommand '

したがって、ローカル変数を渡す場合:

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

ただし、引用の問題に注意してください。変数の値は、リモート側で実行されるシェルスニペットに直接補間されます。上記の最後の例で$LOCALVARは、単一引用符(')が含まれていないことを想定しています。


2
ありがたいことに、私は愚かなLC_ *変数がsshにエクスポートされており、あなたの答えがどこを見るべきかを教えてくれました。〜/ .ssh / configでそれを無効にする必要があります
-akostadinov

1
私は元のポスターの状況にいますが、私が転送したかった変数はTERMですので、あなたの答えには少し困惑しています。このTERMの自動転送は、最近のOpenSSHバージョンによって無効にされていますか?
ダウ

1
@Doubデフォルトでは、サーバー側のすべての環境変数を拒否し、管理者の希望どおりにAcceptEnvディレクティブを入力sshd_configします。しかしTERM、サーバー側でフィルター処理する方法がない限り、特別に扱われます(構成設定に関係なく、シェルの環境で設定されます)。それを上書きするプロファイルスクリプト(/etc/profileor ~/.profileまたはor など~/.bashrc)がないことを確認しますか?
ジル

2
@Gilles:もう一度テストしましたが、AcceptEnvディレクティブに明示的にTERMを追加しない限り、TERMは渡されません。シェルを開くのではなく、コマンドを直接実行します。たとえば、「ssh -o SendEnv = TERM shell.example.com env」です。これはすべての環境変数を出力し、TERMはクライアントのSendEnvとサーバーのAcceptEnvにある場合にのみ表示されます。AcceptEnvまたはSendEnvを使用せずに「ssh -o SendEnv = TERM shell.example.com echo \ $ {TERM}」を実行すると、「dumb」と表示されますが、どこから来たのかわかりません(envはその場合はTERMをリストしてください)。
ダウ

7
@Doubああ、なるほど。TERMクライアントがサーバーにttyの割り当てを要求した場合にのみ送信されます。リモート側に端末がない場合、送信することは役に立たないでしょうTERM。このコマンドを指定する場合は、リモート側の端子を持つようにしたい場合は、あなたが必要とする-tコマンドラインオプション(またはRequestTTY中を~/.ssh/config)。
ジル

12

ターゲットホストを管理できる場合は、ローカル環境変数をターゲットホストに渡すことができるようにsshdを構成できます。

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.

sshd構成は通常、 /etc/ssh/sshd_config


7
これがデフォルトで「no」に設定されていることを知ることは非常に便利です!
ジャタニズム

6

クライアントに環境変数があり、それをリモートコマンドで使用できるようにしますか?sshを魔法のように渡す方法はないと思いますが、おそらくこのようなことをすることができます。使用する代わりに、次のように言います。

ssh remote.host my_command

あなたはこれを行うことができます:

ssh remote.host env ENV_VAR=$ENV_VAR my_command

"恐らく"?この答えを実際に試す前に、それを読んでほしい。うまくいかなかった。
ティシュマ

1
受信したエラーなどについて詳しく説明してください。
ピオト

1
@piotoはENV_VARがそれにスペースを持っている場合例えば、引用する可能性があります
マーティンC.マーティンを

Macでは、インタラクティブバージョンの場合は-tオプションが必要です。$ ssh -t remote.host env ENV_VAR = $ ENV_VAR my_command
muenalan

3

@emptysetの応答(私にとってはうまくいきませんでした)は、私にこの答えを導きました:

このコマンドを~/.ssh/authorized_keysファイルに追加できます。

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

export VARIABLE=<something>すぐに終了し、SSH接続が閉じられました(サーバーからロックアウトされました)。一方/usr/bin/env ... $SHELL、変更された環境でデフォルトのシェルを実行します。


これは、私のためにログインするときにハングします。削除すると、SSHが通常に戻り、通常のログインシェルが表示されます。
ニックスウィー

@NickSweetingおそらく$SHELL実際のシェルに置き換えようとしましたか?また、サーバーに/ usr / bin / envが存在することも確認してください。しかし、解決策は完璧ではありませんscp。使用したいときやインラインコマンドを実行したときにハングすることに気付きました。
madprog

はい、それが私が最初に試したものでした。残念ながら、それが動作するようになったことはありません、有効になってしまったPermitUserEnvironment yesと使用してenvironment="..."の代わりにcommand="..."
ニックスウィー

これは私にとってうまく機能しています。
タオ氏

3

あなたのローカルクライアント上で、~/.ssh/configあなたが追加することができますSetEnv、例えば

Host myhost
  SetEnv FOO=bar

注:を確認してくださいman ssh_config

次に、サーバーで、クライアントが構成/etc/ssh/sshd_configファイル内の特定の環境変数を渡すことを許可します。

AcceptEnv LANG LC_* FOO BAR*

注:を確認してくださいman sshd_config


1

パスワードなしのsshログイン設定があると仮定して、カスタムコマンドの呼び出しを試みることができます。サーバーで、クライアントからのキーに対応する〜/ .ssh / authorized_keysエントリを編集します。

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

詳細については、「強制コマンド」セクションのこのリンクを参照してください。


1
これを試しましたが、うまくいきません。コマンドを実行して終了するため、対話型セッションはありません。それは通常の動作ですか?もしそうなら、特定のキーが特定のコマンドをトリガーすることを許可するだけなら、それは有用かもしれませんが、セッションで使用される情報(質問の状態として)渡したい場合、その目的には役に立たないでしょう。セッションはありません。
iconoclast

1

ホームディレクトリにcramfsがあり、/ etc(Cram FSは読み取り専用)のデバイス用にOpenSSHのカスタムビルドを行っていたため、〜/ .ssh / environmentは、FS全体を再構築しないと機能しません。デバイス(組み込みシステムCRAMFSの使用)。sshd_configでauthroized_keysファイルの場所を指定できますが、何らかの理由で、environment =は〜/ .ssh / authroized_keysの環境変数に対してのみ機能します。/ etc / profileの編集はオプションではなく、非標準のディレクトリにsshをロードする必要がありました。session.cのchild_set_env(... "MAIL" ...)の後に、必要な環境変数を追加します(これは私が知っているハックです...)が、誰かがセッションのためにハードコードされたenvを必要とする場合にのみこれを行うことができるソースからコンパイルします。TGI-FLOSS


0

たった1つの簡単なコマンド:

ssh -t your_host_or_ip 'export some_var_name=whatever_you_want; bash'
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.