A ferramenta WinSCP é capaz de realizar uma sudo
operação na máquina remota scp
como usuário sudo. Isso me leva a pensar que isso scp
també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 sudo
usuá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 scp
já foi implementado usando base. Por este e outros motivos, também não quero utilizar esta solução.
Como posso deixar scp
lidar com uma cópia direta para remoto usando um sudo
para 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 scp
comando 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 scp
depende de duas formas não documentadas de scp
, que é scp -f
e 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 scp
for iniciado, ele iniciará primeiro uma sessão ssh para iniciar scp -t
ou scp -f
. Seu scp
processo local se comunicará com o scp
processo remoto por meio de stdout e stdin canalizado para ssh (totalmente criptografado) e servirá como stdin/stdout para sua scp
sessão remota.
Como personalizar
O scp
comando fornece uma opção -s
que permite personalizar o programa usado para configurar a scp
sessã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 ssh
comando.
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.
- tem a
-S
opçã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. - possui uma
-s
opção (minúscula) - permitindo definir apenas o subcomando responsável por configurar apenas o servidor remoto. Achei isso mais fácil de fazer funcionar. - 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 sftp
string " " de dentro do /etc/ssh/sshd_conf
arquivo?