Como funciona o SCP

Como funciona o SCP

A ferramenta WinSCP é capaz de realizar uma sudooperação na máquina remota scpcomo usuário sudo. Isso me leva a pensar que isso scptambém deve ser possível com a versão de linha de comando.

Nos bastidores, como o WinSCP está executando isso?

Eu não quero trabalharuma solução com um diretório temporário do usuário. Os arquivos podem ser tão grandes que preciso postar diretamente usando o sudousuário. Como resultado, o arquivo foi copiado, mas para o meu diretório local, não para o diretório sudo.

Uma solução pode ser porcanalizando manualmente sobre ssh:

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

O que eu acho que poderia ser personalizado para fazer o sudo da seguinte maneira:

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

O único problema é que fazendo desta forma, tenho muito trabalho para resolver que scpjá foi implementado usando base. Por este e outros motivos, também não quero utilizar esta solução.

Como posso deixar scplidar com uma cópia direta para remoto usando um sudopara alterar o usuário para obter acesso aos seus privilégios.

Responder1

O Scp funciona fazendo uma conexão ssh com o servidor remoto e, em seguida, usando essa conexão para executar outro scpcomando no sistema remoto. A instância scp local e a instância remota se comunicam por meio do link ssh para enviar ou receber arquivos.

OpenSSH scp em particular constrói uma string de comando scp para ser executada no sistema remoto. Em seguida, ele inicia o ssh para executar esse comando. O eventual comando ssh invocado é equivalente a isto:

/path/to/ssh [ssh options...] "scp [scp options...]"
  • /path/to/ssh normalmente é um caminho interno para o programa ssh.
  • [opções ssh...] é uma ou mais opções para o programa ssh.
  • "scp [opções scp...]" é um único argumento contendo o comando scp e seus argumentos para execução no sistema remoto.

OpenSSH scp não oferece muitas opções para alterar a forma do comando scp remoto. Não há como invocar algo diferente de "scp" ou inserir algo como "sudo" na frente da parte "scp".

Como você notou, o scp tem a opção de invocar algum outro programa em vez do ssh. Alguém que soubesse como poderia escrever um programa wrapper ssh e fazer com que o scp invocasse o wrapper em vez de invocar o ssh diretamente. O wrapper teria que examinar seus argumentos de linha de comando para encontrar aquele que contém o comando scp, alterar o comando conforme desejado e então invocar o ssh com os argumentos de linha de comando alterados.

Responder2

Como funciona o SCP

O funcionamento interno de scpdepende de duas formas não documentadas de scp, que é scp -fe scp -t. Eles são basicamente servidores remotos ouvindo stdin e gerando dados através de stdout. Esses processos usam um protocolo semelhante ao que o sftp faria. Mais informações podem ser encontradas em umBlog da Oracle.

Quando scpfor iniciado, ele iniciará primeiro uma sessão ssh para iniciar scp -tou scp -f. Seu scpprocesso local se comunicará com o scpprocesso remoto por meio de stdout e stdin canalizado para ssh (totalmente criptografado) e servirá como stdin/stdout para sua scpsessão remota.

Como personalizar

O scpcomando fornece uma opção -sque permite personalizar o programa usado para configurar a scpsessão remota. Espera-se que ele lide com todas as opções típicas do ssh. Para ajudar a depurar como isso pode parecer, configuramos um programa fictício que apenas despeja os parâmetros:

/tmp/scp-dump.sh:

echo $0 $*

Iremos executá-lo da seguinte forma:

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

E apropriadamente obtemos a seguinte saída:

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

Quebras de linha com barra invertida foram adicionadas para facilitar a leitura.

Isso nos permite modificar os parâmetros e comandos antes de enviá-los para o sshcomando.

Configurando o sudo

agora podemos escrever um programa para modificar os parâmetros conforme necessário, iniciar o ssh e usar um formulário modificado para iniciar scp -t. Basicamente, capturaremos os parâmetros, capturaremos aqueles que queremos usar internamente, apenas adicionaremos outros e faremos alterações.

/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

Agora podemos usar o formulário scp modificado:

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

Isso funciona bem para enviar um arquivo para o controle remoto. No entanto, quando recupero um arquivo remoto, ele trava de alguma forma. Quando interrompo a sessão (control-c), vejo que a transferência foi bem-sucedida, mas de alguma forma tenho um arquivo extra chamado "0". Será que alguém pode me ajudar com isso?

Melhor opção: sftp

No entanto, o sftp é muito melhor.

  1. tem a -Sopção - permitindo definir toda a linha de comando do ssh. Tive dificuldade em descobrir e fazer funcionar. Suspeito que não entendo como vincular corretamente o stdin/stdout de dentro de um wrapper shell-ssh.
  2. possui uma -sopção (minúscula) - permitindo definir apenas o subcomando responsável por configurar apenas o servidor remoto. Achei isso mais fácil de fazer funcionar.
  3. Você pode definir o caminho remoto, permissões de arquivo remoto, colocar/obter, etc., de acordo com as páginas de manual do sftp.

Neste caso simplesmente

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

Isso me deu o sftp>alerta " " feliz

Observe que o subprograma às vezes está localizado em caminhos diferentes, por exemplo /usr/libexec/openssh/sftp-server. Eu sugeriria analisar a Subsystem sftpstring " " de dentro do /etc/ssh/sshd_confarquivo?

informação relacionada