SSH에서 변수 전달

SSH에서 변수 전달

SSH 원격에 변수를 전달하려고 하는데 작동하지 않습니다. 내 코드는 다음과 같습니다

#!/bin/bash
set -x
conexion="[email protected]"
parameter="$1"
ssh -T $conexion <<'ENDSSH' 
clear
echo "$parameter"
ENDSSH

나는 다음을 실행한다:

./script.sh try

그것은 나에게 말했다:

parameter: Undefined variable.

도움이 필요하세요?

답변1

변수(환경 변수) 전달이 ssh가능하지만 일반적으로 제한됩니다.

클라이언트에게 보내달라고 말해야 합니다. OpenSSH를 예로 들면 다음과 같습니다.

ssh -o SendEnv=parameter host cmd...

그러나 이를 수락하려면 서버도 필요합니다( AcceptEnvOpenSSH의 구성 지시문 사용). 변수를 허용하는 것은 상당한 보안 위험을 초래하므로 일부 SSH 배포에서는 특정 네임스페이스(예: LC_*일부 OpenSSH 배포)에서 특정 변수를 허용하지만 일반적으로 기본적으로 수행되지 않습니다.

또한 를 호출하기 전에 변수를 내보내야 합니다 ssh. 예를 들면 다음과 같습니다.

LC_parameter="$parameter" ssh -o SendEnv=LC_parameter host csh << 'END'
echo $LC_parameter:q
END

위에서는 쉘 변수의 내용을 환경 변수 $parameter bash로 전달하고 , 이를 승인하면 환경 변수로 사용자의 로그인 쉘에 전달한 다음 명령에 전달합니다 ( 그런 다음 확장할 수 있음). ) .LC_parametersshsshsshdcsh

host그러나 언급한 대로 컴퓨터 관리자가 구성에 AcceptEnv LC_parameter또는 를 추가하지 않는 한 AcceptEnv LC_*(때때로 기본적으로 수행됨) 이 작업은 작동하지 않습니다 sshd.

예제의 오류 메시지 Undefined variable는 원격 사용자의 로그인 셸이 csh또는 임을 나타냅니다 tcsh. 예상치 못한 상황을 피하기 위해 쉘을 명시적으로 호출하는 것이 더 좋습니다( ssh host csh또한 tty가 요청되지 않았으므로 요청하지 않아도 됨을 의미합니다 -T). $LC_parameter:q구문에 유의하세요 . 이는 변수에 개행 문자가 포함된 경우 작동하지 않는 csh것과는 반대로 변수의 내용을 문자 그대로 전달하는 방법 입니다."$LC_parameter"

변수를 사용하는 LC_*것이 옵션이 아닌 경우 다음을 사용할 수도 있습니다.고객쉘( bash귀하의 경우)은 변수를 확장합니다. 순진한 접근 방식은

ssh host csh << END
echo "$variable"
END

그러나 이는 변수의 내용이 원격 쉘에 의해 해석되기 때문에 위험합니다. 예시를 $variable포함 `reboot`하거나 제시 하면 "; reboot; : "나쁜 결과를 낳게 됩니다.

따라서 먼저 원격 셸의 구문에서 변수가 올바르게 참조되는지 확인해야 합니다. 여기서는 csh안정적으로 수행하기 어려운 곳 을 피하고 대신 sh//를 사용합니다 .bashksh

sh 참조를 위해 도우미 함수를 사용하십시오.

shquote() {
  awk -v q=\' -v b='\\' '
    BEGIN{
      for (i=1; i<ARGC; i++) {
        gsub(q, q b q q, ARGV[i])
       printf "%s ", q ARGV[i] q
      }
      print ""
      exit
    }' "$@"
}

다음과 같이 호출됩니다 ssh.

ssh host sh << END
parameter=$(shquote "$parameter")
echo "\$parameter"
END

로컬 셸이 아닌 원격 셸에서 $확장이 수행되도록 세 번째 항목을 어떻게 이스케이프하는지 살펴보세요 .$parameter

답변2

환경 변수 전달과 같은 다른 트릭 외에도 LC_*다음을 수행할 수 있습니다.

PARAMETER="123"
ssh user@host PARAMETER="$PARAMETER" bash -s <<- 'EOF'
    echo $PARAMETER
EOF

이 방법의 장점은 원격 호스트 (이름이 다음으로 시작하지 않는 경우), 로컬 호스트(대상 또는 대상) export PARAMETER의 구성에 이름을 추가할 필요가 없다는 것입니다 .AcceptEnvLC_/etc/ssh/sshd_configSendEnv-o/etc/ssh/ssh_config

답변3

ENDSSH네 번째 줄에서 따옴표를 제거하면 도움이 될 것입니다.

제공: 질문에 대한 @Archemar의 의견.

경고하다이 답변의 설명에서 @StéphaneChazelas가 언급했듯이 이 솔루션을 사용하면 $parameter여기 문서의 변수가 로컬 셸에 의해 확장됩니다. 즉, 변수의 내용이 원격 셸에 의해 셸 코드로 해석됩니다. 이는 명령 주입 취약점이 발생함을 의미합니다.따라서 이것은 일반적으로 권장되지 않습니다.

답변4

큰따옴표 안에 작은따옴표를 삽입합니다.

$ file_name="one two"
$ ssh remote ls "'$file_name'"
ls: cannot access 'one two': No such file or directory

작은따옴표를 제거하지 않고 변수가 먼저 대체됩니다. 이런 방식으로 콘텐츠는 작은따옴표로 묶어 ssh로 전송됩니다.

관련 정보