O problema é que o sftp é executado como o ID do usuário - primeiro, o sftp ssh do cliente no host de destino como o usuário especificado, em seguida, executa o sftp-server. Como o sftp-server está sendo executado como um usuário comum, ele não tem como "entregar" um arquivo (alterar o proprietário de um arquivo).
No entanto, se você for capaz de usar scp e atribuir um par de chaves para cada usuário, você pode contornar isso. Isso envolve adicionar uma chave do usuário ao arquivo ~ / .ssh / authorized_keys do root, com um parâmetro "command=" para forçá-lo a executar um script que limpe e altere os argumentos do programa scp do lado do servidor. Usei essa técnica antes para configurar uma caixa de depósito scan anônima que permitia que qualquer pessoa enviasse um arquivo e garantisse que ninguém pudesse recuperar arquivos enviados e também evitar substituições.
Se você estiver aberto a essa técnica, me avise e atualizarei este post com uma receita rápida.
Editar: com base nos comentários, aqui está minha receita que usei originalmente para configurar uma caixa de depósito anônima. Mas deve funcionar para este propósito também.
Se você quiser que o John escreva para fazer o upload de arquivos para /var/www/webstuff
, e tiver arquivos gravados nele de propriedade do usuário id apache
, então:
1) Gere um par de chaves ssh:
ssh-keygen -t rsa -f john-scp-key
2) Edite o arquivo de chave pública "john-scp-key.pub" e insira uma instrução "command=" no começo da seguinte forma:
command="/usr/local/bin/strictscp ^/var/www/webstuff" ssh-rsa AAAA..... (reset
of key follows)
3) Adicione o conteúdo do arquivo john-scp-key.pub
to ~apache/.ssh/authorized_keys
(crie o arquivo se ele não existir, certificando-se de que tanto o diretório .ssh quanto as authorized_keys sejam de propriedade de apache
, e não graváveis por grupo ou mundo)
4) Crie o script /usr/local/bin/strictscp
da seguinte forma:
#!/bin/sh
read cmd arg1 arg2 <<EOT
$SSH_ORIGINAL_COMMAND
EOT
if [ "$cmd" = scp -a "$arg1" = -t ] && echo "$arg2" |grep "$1" >/dev/null 2>&1
then
eval $cmd $arg1 $arg2
fi
5) Agora, forneça o arquivo de chave privada john-scp-key
para John e peça-lhe que copie os arquivos para o seu servidor da Web da seguinte forma:
scp -i john-scp-key some_file.html apache@yourserver:/var/www/webstuff/
A maneira como isso funciona é quando você usa scp para copiar um arquivo para um servidor, o cliente scp usa ssh para executar "scp -t / path / name" no servidor. Ao usar um par de chaves, você pode substituir o comando executado e forçar um comando específico a ser executado quando essa chave for usada. O comando original que foi solicitado, juntamente com seus argumentos, está na variável de ambiente "$ SSH_ORIGINAL_COMMAND". Então, apontamos COMMAND=
para um script que verifica os argumentos permitidos (nesse caso, ele verifica se o terceiro argumento é o diretório específico ao qual queremos gravar as coisas), de modo que essa chave só seja boa para o propósito pretendido e possa pode ser usado para executar comandos arbitrários no servidor.
Você pode bloquear o script strictscp
um pouco mais, verificando se o arquivo de destino existe ou não, e também pode adicionar um comando chgrp
ao final para definir a propriedade do grupo do arquivo (supondo que apache
é um membro desse grupo).
Espero que isso ajude - se você tiver algum problema com isso, avise-me e veremos se posso melhorar ainda mais essa resposta.