SSH를 사용하여 파일을 업로드한 다음 사용자에게 제어 권한을 다시 부여합니다.

SSH를 사용하여 파일을 업로드한 다음 사용자에게 제어 권한을 다시 부여합니다.

SSH를 사용하여 원격 서버에 연결할 때 스크립트가 내용을 확인하고 stdin으로 돌아오기 전에 개인 스크립트를 배포하는 스크립트를 만들려고 합니다. 이 모든 작업은 하나의 SSH 연결 내에서 이루어집니다. 그렇지 않으면 여러 번 수행해야 합니다. 인증을 위해..).

작동하는 스크립트가 있습니다.

#!/bin/zsh
HOST="$1"

# Install ZSH if it's not already installed
ssh "$HOST" <<- EOF
    if [ ! -x /bin/zsh ]; then
        if [ -x "/usr/bin/dnf" ]; then
            sudo dnf install -y zsh >/dev/null
        elif [ -x "/usr/bin/apt-get" ]; then
            sudo DEBIAN_FRONTEND=noninteractive apt-get install -y zsh >/dev/null
        fi
    fi
EOF

# Copy ZSH configuration to remote host
tar -cz -f - -C "$HOME" --exclude="*.zwc" {.zshrc,.zshenv,.config/zsh/{p10k.zsh,plugins}} | ssh "$HOST" 'tar -xz -f - -C "$HOME"'

# Login with ZSH in a login shell
ssh -t "$HOST" 'SHELL=/bin/zsh /bin/zsh -l'

하지만 이를 위해 여러 연결을 사용합니다. 하나의 연결만 어떻게 사용할 수 있나요?

POC를 시도했습니다

#!/bin/zsh
HOST="$1"

# redirect 3 to standard output
exec 3>&1

ssh -t $HOST >&3 <&1 &

# doesn't work, doesnt execute on remote host
echo "hostname"
# this as well
echo "hostname" >&1

# works, give back the tty of the remote server to the user
exec 1<&0

wait
echo "THE END"

하지만 tty가 반환될 때까지 원격 서버에서 명령을 실행할 수 없습니다. 그리고 파일을 보내는 방법도 모르겠습니다.

이 모든 작업을 수행할 수 있는 방법이 있나요?

답변1

동일한 스트림을 통해 셸 코드, tar 파일 및 사용자 입력을 보내는 것은 잠재적으로 암호나 키 암호 문구를 요구 ssh -t하지만 ssh매우 서투르고 취약합니다.

conf 파일이 너무 크지 않고 환경 변수를 수용할 수 있고 원격 sshd의 AcceptEnv LC_*구성에 하나가 있는 경우(일반적인 경우) 다음 base64 중 하나로 인코딩된 tgz 파일을 전달할 수 있습니다.

#! /bin/zsh -
HOST=${1?}

LC_ZC=$(
  tar -cz -f - -C ~ --exclude="*.zwc" {.zshrc,.zshenv,.config/zsh/{p10k.zsh,plugins}} |
    base64
) exec ssh -o SendEnv=LC_ZC -t "$HOST" '
  if ! command -v zsh; then
    if command -v dnf; then
      sudo dnf install -y zsh
    elif command -v apt-get; then
      sudo DEBIAN_FRONTEND=noninteractive apt-get install -y zsh
    fi
  fi > /dev/null

  echo "$LC_ZC" | base64 -d | tar -zxf - -C ~
  unset -v LC_ZC
  SHELL=/bin/zsh exec /bin/zsh -l'

(또한 원격 시스템에 있는 사용자의 로그인 쉘이 POSIX와 유사하다고 가정합니다.)

그렇지 않은 경우 가장 쉬운 방법은 아마도 여러 호출을 사용하는 것이지만 ssh모두 연결 다중화 기능을 사용하여 동일한 로그인 세션을 공유하는 것입니다( ControlMaster// 매뉴얼 페이지의 지침 및/또는 이 사이트의 예를 참조하십시오).ControlPathControlPersist

최신 버전의 openssh를 사용하는 또 다른 방법은 -R remote_socket:local_socketUnix 도메인 소켓을 사용하여 tar 파일을 전송하는 것입니다( zsh/net/socket예: zsh 모듈 사용).

관련 정보