ssh'ing 할 때 세션에서 세션으로 변경되는 서버에서 환경 변수를 어떻게 설정할 수 있습니까?


92

ssh서버에 들어갈 때 클라이언트에서 서버로 환경 변수를 전달하려면 어떻게해야합니까? 이 환경 변수는 ssh의 다른 호출간에 변경되므로 ssh 호출을 할 $HOME/.ssh2/environment때마다 덮어 쓰지 않습니다 . 어떻게해야합니까?


2
질문은 좀 더 구체적이어야합니다.
Ignacio Vazquez-Abrams

3
그 질문은 나에게 분명했다. 그러나 ssh매뉴얼 페이지에서 ~ / .ssh2 / environment를 수정하지 않으면 서버에 로그인 한 후 변수를 수동으로 설정하는 것 외에 다른 방법은 없습니다.
garyjohn

매번 다른 변수입니까? 아니면 다른 가치?
Dennis Williamson


1
다른 방법은 이미 더 유명하기 때문입니다. 나이가 든 상관 없습니다.
kenorb

답변:


110

물론 명령 내에서 환경 변수를 설정할 수 있지만 인용에주의해야합니다. 쉘은 로컬 명령 줄을 구문 분석하고 원격 쉘은 문자열에 이동합니다. 수신합니다.

변수가 클라이언트에있는 것과 동일한 값을 서버에서 얻으려면 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; 내 명령

심지어이 경우 LC_*옵션이 아닙니다, 당신은 정보 통과 할 수 TERM항상 복사 환경 변수를, (그러나 길이 제한이있을 수 있습니다). TERM알려진 쉘 유형을 지정하기 위해 원격 쉘이 변수를 제한하지 않는지 확인해야합니다 . 패스 -t원격 대화 형 쉘을 시작하지 않는 경우 ssh를하는 옵션을 선택합니다.

env TERM = "추가 정보 : $ TERM"ssh -t server.example.com 'MYVAR = $ {TERM % : *}; TERM = $ {TERM ## * :}; 수출 MYVAR; 내 명령

또 다른 가능성은 명령에서 변수를 직접 정의하는 것입니다.

ssh -t server.example.com '내 MYVAR = "추가 정보"; 내 명령

따라서 지역 변수를 전달하는 경우 :

ssh -t server.example.com 'export MYVAR =' " '$ LOCALVAR'" '; 내 명령

그러나 인용 문제에주의하십시오. 변수의 값은 원격 측에서 실행되는 쉘 스 니펫에 직접 보간됩니다. 위의 마지막 예는 $LOCALVAR작은 따옴표 ( ')를 포함하지 않는 것으로 가정합니다 .


2
고마워, 나는 바보 같은 LC_ * 변수가 ssh로 내보내지고 당신의 대답이 어디를 보았는지 지시했다. 난 그냥 ~ / 스푸핑 / 설정에서 그것을 해제해야
akostadinov

1
나는 원래 포스터의 상황에 있지만 전달하려는 변수는 TERM이므로 귀하의 답변에 약간 당황합니다. 최근 OpenSSH 버전에서 TERM 자동 전달 기능이 비활성화 되었습니까?
Doub

1
@Doub 기본값은 관리자가 원하는대로 AcceptEnv지시문 을 사용하여 서버 측의 모든 환경 변수를 거부하는 것 sshd_config입니다. 그러나 TERM서버 측에서 필터링 할 수있는 방법이 없다는 것을 알고있는 한 특별히 처리됩니다 (구성 설정에 관계없이 셸 환경에서 설정 됨). 이를 대체하는 프로필 스크립트가 없습니까 (예 : /etc/profile또는 ~/.profile또는 ~/.bashrc)?
Gilles

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"가 인쇄됩니다. 이 경우 TERM을 나열하십시오).
Doub

7
@Doub 아, 알겠습니다. TERM클라이언트가 서버에 tty를 할당하도록 요청한 경우에만 전송됩니다. 원격 측에 터미널이 없으면을 전송하는 데 쓸모가 없습니다 TERM. 당신이 명령을 지정하면 원격 측면에 단자가하려는 경우, 당신은 필요한 -t명령 줄 옵션 (또는 RequestTTY에서를 ~/.ssh/config).
Gilles

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
이것이 기본적으로 "아니오"로 설정되어 있다는 것을 아는 것이 매우 유용합니다!
jathanism

6

따라서 클라이언트에는 환경 변수가 있으며 원격 명령에서 사용할 수 있습니까? 나는 ssh가 마술처럼 그것을 통과시키는 방법이 없다고 생각하지만, 아마도 이런 식으로 할 수 있습니다. 사용하는 대신 다음과 같이 말합니다.

ssh remote.host my_command

당신은 이것을 할 수 있습니다 :

ssh remote.host env ENV_VAR=$ENV_VAR my_command

"아마"? 이 답변을 실제로 시도하기 전에 읽어보십시오. 나를 위해 작동하지 않았다.
tishma

1
수신 된 오류 등에 대해 자세히 관리 하시겠습니까?
pioto

1
@pioto 예를 들어 ENV_VAR에 공백이 있으면 인용 할 수 있습니다
.

Mac에서는 대화식 버전에 대해 -t 옵션이 있어야합니다. 그렇지 않으면 중단 된 것처럼 보입니다. $ ss -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를 제거하면 SSH가 정상으로 돌아가고 평소 로그인 쉘이 나타납니다.
Nick Sweeting

@NickSweeting $SHELL실제 쉘로 대체하려고 했습니까? 또한 서버에 / usr / bin / env가 있는지 확인하십시오. 그러나 해결책은 완벽하지 않습니다. 사용 scp하거나 인라인 명령을 원할 때 중단되는 것을 알았습니다 .
madprog

네, 제가 처음 시도한 것이 었습니다. 불행히도 작동하지 않아서 대신에 활성화 PermitUserEnvironment yes하고 사용 environment="..."했습니다 command="...".
Nick Sweeting

이것은 나를 위해 잘 작동합니다.
Mr. Tao

2

로컬 클라이언트에서 다음 ~/.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

홈 디렉토리 및 / etc에 cramfs가있는 장치에 대한 OpenSSH의 사용자 정의 빌드를 작성하고 있었으므로 (Cram FS는 읽기 전용) ~ / .ssh / environment는 전체 FS를 다시 빌드하지 않으면 작동하지 않으며 필드 배치되었습니다. 장치 (내장 시스템 따라서 CRAMFS 사용). sshd_config에서 authroized_keys 파일의 위치를 ​​지정할 수 있지만 어떤 이유로 든 environment =는 ~ / .ssh / authroized_keys의 환경 변수에 대해서만 작동합니다. / etc / profile을 편집하는 것은 옵션이 아니었고 비표준 디렉토리에 ssh를로드해야했습니다. child_set_env (... "MAIL"...) 뒤에 session.c에서 필요한 환경 변수를 추가하십시오 (이것은 내가 아는 해킹입니다 ...)하지만 누군가가 세션에 대해 하드 코딩 된 환경을 필요로하는 경우 소스에서 컴파일하면이 작업을 수행 할 수 있습니다. TGI-FLOSS


0

하나의 간단한 명령 :

ssh -t your_host_or_ip 'export some_var_name=whatever_you_want; bash'
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.