SCP 작동 방식

SCP 작동 방식

WinSCP 도구는 sudo원격 시스템에서 scpsudo 사용자로 작업을 수행할 수 있습니다. 따라서 명령줄 버전에서도 이것이 가능해야 한다고 생각하게 됩니다 scp.

WinSCP는 이를 어떻게 실행하고 있나요?

나는 일하고 싶지 않다사용자 준비 디렉터리가 있는 솔루션. 파일이 너무 커서 사용자를 사용하여 직접 게시해야 할 수도 있습니다 sudo. 결과적으로 파일은 복사되었지만 sudo 디렉토리가 아닌 내 로컬 디렉토리에 복사되었습니다.

한 가지 해결책은 다음과 같습니다.SSH를 통해 수동으로 파이핑:

tar zcvf -  MyBackups | ssh user@server "cat > /path/to/backup/foo.tgz"

다음과 같이 sudo를 수행하도록 사용자 정의할 수 있을 것 같습니다.

cat local.txt | ssh user@server "sudo -u sudouser cat > ~/remote_file"

다만 문제는 이렇게 하면 scp이미 base를 이용해 구현한 것을 해결해야 한다는 부담이 크다는 점이다. 이런저런 이유로 저는 이 솔루션을 사용하고 싶지 않습니다.

어떻게 하면 사용자를 변경하여 해당 권한에 액세스할 수 있는지 scp를 사용하여 원격으로 직접 복사를 처리 할 수 있습니다.sudo

답변1

scp는 원격 서버에 SSH 연결을 만든 다음 해당 연결을 사용하여 scp원격 시스템에서 다른 명령을 실행하는 방식으로 작동합니다. 로컬 scp 인스턴스와 원격 인스턴스는 SSH 링크를 통해 통신하여 파일을 보내거나 받습니다.

특히 OpenSSH scp는 원격 시스템에서 실행될 scp 명령 문자열을 구성합니다. 그런 다음 ssh를 시작하여 해당 명령을 실행합니다. 호출되는 최종 ssh 명령은 다음과 동일합니다.

/path/to/ssh [ssh options...] "scp [scp options...]"
  • /path/to/ssh는 일반적으로 ssh 프로그램에 대한 내장 경로입니다.
  • [ssh options...]는 ssh 프로그램에 대한 하나 이상의 옵션입니다.
  • "scp [scp 옵션...]"은 scp 명령과 원격 시스템에서 실행할 인수를 포함하는 단일 인수입니다.

OpenSSH scp는 원격 scp 명령의 형식을 변경하는 옵션을 많이 제공하지 않습니다. "scp" 이외의 다른 항목을 호출하거나 "scp" 부분 앞에 "sudo"와 같은 항목을 삽입할 수 있는 방법은 없습니다.

아시다시피 scp에는 ssh가 아닌 다른 프로그램을 호출할 수 있는 옵션이 있습니다. ssh 래퍼 프로그램을 작성하고 ssh를 직접 호출하는 대신 scp가 래퍼를 호출하도록 하는 방법을 아는 사람이 있습니다. 래퍼는 명령줄 인수를 검사하여 scp 명령이 포함된 항목을 찾고 원하는 대로 명령을 변경한 다음 변경된 명령줄 인수로 ssh를 호출해야 합니다.

답변2

SCP 작동 방식

의 내부 작동은 문서화되지 않은 두 가지 형식 인 및 에 scp따라 달라집니다 . 이들은 기본적으로 stdin을 수신하고 stdout을 통해 데이터를 생성하는 원격 서버입니다. 이러한 프로세스는 sftp가 수행하는 것과 유사한 프로토콜을 사용합니다. 자세한 내용은 다음에서 확인할 수 있습니다.scpscp -fscp -t오라클 블로그.

시작 되면 scp먼저 SSH 세션을 시작하여 scp -t또는 scp -f. 그런 다음 로컬 scp프로세스는 SSH로 파이프된(완전히 암호화됨) stdout 및 stdin을 통해 원격 프로세스와 통신 하고 원격 세션 scp에 대한 stdin/stdout 역할을 합니다 .scp

사용자 정의 방법

이 명령은 원격 세션을 설정하는 데 사용되는 프로그램을 사용자 정의할 수 있는 scp옵션을 제공합니다 . 에 대한 일반적인 모든 옵션을 처리할 것으로 예상됩니다 . 디버깅을 돕기 위해 매개변수만 덤프하는 더미 프로그램을 설정했습니다.-sscpssh

/tmp/scp-dump.sh:

echo $0 $*

다음과 같이 실행하겠습니다.

scp -S /tmp/scp-dump.sh /tmp/dump.txt [email protected]:/tmp

그리고 적절하게 다음과 같은 출력을 얻습니다.

/home/me/dump.sh \
    -x -oForwardAgent=no \
    -oPermitLocalCommand=no \
    -oClearAllForwardings=yes \
    -l me -- server.com scp -t /tmp

가독성을 위해 백슬래시를 사용한 줄 바꿈이 추가되었습니다.

이를 통해 매개변수와 명령을 명령으로 보내기 전에 수정할 수 있습니다 ssh.

sudo 설정

이제 필요에 따라 매개변수를 수정하고, ssh를 시작하고, 수정된 형식을 사용하여 시작하는 프로그램을 작성할 수 있습니다 scp -t. 기본적으로 매개변수를 캡처하고, 내부적으로 사용하려는 매개변수를 트랩하고 추가 매개변수만 추가하고 변경합니다.

/tmp/scp-sudo.sh:

add_ssh_option() {
  local option
  if [ $# = 2 ]; then
    option="$1 \"$2\""
  else
    option="$1"
  fi
  if [ -z "${ssh_options}" ]; then
    ssh_options=${option}
  else
    ssh_options="${ssh_options} ${option}"
  fi
}

parse_options() {
  ssh_options=
  local option
  while [ $# > 0 ] ; do
    case $1 in
      -oSudoUser=* )
        SSH_SUDO_USER=${option##*=}
        shift
        ;;
      -l ) ssh_user=$2 ; shift 2 ;;
      -i ) add_ssh_option "$1" "$2" ; shift 2 ;;
      -- ) shift ; break ;;
      -* ) add_ssh_option "${1}" ; shift ;;
      *  ) break ;;
    esac
  done
  ssh_host=$1
  shift
  ssh_command="$*"
}

parse_options "$@"
# To avoid intererence with Standard-In, we change this to
# Strict:
add_ssh_option "-oStrictHostKeyChecking=yes"

if [ -z "${SSH_SUDO_USER}" ]; then
  # As before without sudo
  cat | ssh $ssh_options -l $ssh_user $ssh_host $ssh_command
  exit $?
else
  # Send standard-in to the customized "scp -t" sink.
  cat | ssh $ssh_options -l $ssh_user $ssh_host sudo -i -u ${SSH_SUDO_USER} $ssh_command
  exit $?
fi

이제 수정된 scp 형식을 사용할 수 있습니다.

scp -oSudoUser=other \
    -i /tmp/me-id_rsa \
    /tmp/scp-sudo.sh \
    /tmp/dump.txt \
    [email protected]:/tmp

이것은 원격으로 파일을 보내는 데 적합합니다. 그러나 원격 파일을 검색하면 어떻게든 작동이 멈춥니다. 세션을 중단하면(control-c) 전송이 성공한 것을 알 수 있지만 이름이 "0"인 추가 파일이 있습니다. 누구든지 저를 도와줄 수 있는지 궁금하세요?

더 나은 옵션: sftp

그러나 sftp가 훨씬 좋습니다.

  1. -S여기 에는 전체 SSH 명령줄을 설정할 수 있는 옵션이 있습니다 . 그것을 파악하고 실행하는 데 어려움을 겪었습니다. Shell-Ssh 래퍼 내에서 stdin/stdout을 올바르게 바인딩하는 방법을 이해하지 못하는 것 같습니다.
  2. (소문자) 옵션이 있어 -s원격 서버 설정만 담당하는 하위 명령만 설정할 수 있습니다. 나는 이것을 작동시키는 것이 더 쉽다는 것을 알았습니다.
  3. sftp 매뉴얼 페이지에 따라 원격 경로, 원격 파일 권한을 설정하고 넣기/가져오기 등을 수행할 수 있습니다.

이 경우 우리는 단순히

sftp -s "sudo -u sudo-user -- /usr/libexec/openssh/sftp-server" [email protected]

그것은 나에게 행복한 " sftp>" 프롬프트를 주었다

서브프로그램이 다른 경로에 있는 경우도 있습니다(예: ) /usr/libexec/openssh/sftp-server. 파일 Subsystem sftp내에서 " " 문자열을 구문 분석하는 것이 좋습니다 /etc/ssh/sshd_conf.

관련 정보