Existe uma maneira de enviar argumentos personalizados para um servidor rsync?

5

Eu tenho um servidor de backup que os clientes usam com o rsync sobre o SSH. O servidor está configurado para executar um script de shell personalizado que envolve a chamada do lado do servidor rsync. O lado do cliente não tem conhecimento disso e pode emitir qualquer linha de comando rsync válida.

Eu gostaria de passar alguns argumentos do cliente para esse script de shell. Algo como

$ rsync -av -customarg1 value1 -customarg2 value2 file1 file2 user@server

O rsync do lado do cliente rejeita quaisquer argumentos que não conhece, assim como ssh (via rsync -e ). O melhor que eu tenho é passar argumentos como falsas especificações de arquivos do lado do servidor que o script extrai da linha de comando do lado do servidor antes de executá-lo para iniciar o servidor rsync. ou seja, um comando como

$ rsync -av file1 file2 user@server:some/path\;customarg1=value1\;customarg2=value2

forneceria dois argumentos e então se comportaria como se o comando fosse

$ rsync -av file1 file2 user@server:some/path

(Isso usa o fato de que o SSH define várias variáveis de ambiente, incluindo $SSH_ORIGINAL_COMMAND , que contém o comando emitido pelo cliente ssh (ou seja, o comando rsync server lançado pelo cliente rsync), independentemente do servidor ssh configurado execute (ou seja, o script de shell personalizado))

    
por starfry 20.07.2016 / 18:08

3 respostas

5

Talvez você possa usar a opção -M (versão longa --remote-option ), que não parece ser verificada pelo cliente rsync. -M-xxxx é passado para o remoto com o -M removido como -xxxx . Você pode brincar facilmente com isso usando -M-M-xxxx , que é ignorado pelo cliente e remoto:

rsync -av -M-M-myvar=val /tmp/test/ remote:test/

Se o front-end do seu servidor reconhecer e remover os sinalizadores resultantes antes de chamar o rsync, você obtém o que precisava.

Você pode jogar mais com --rsync-path , o que permite que você execute qualquer script. Ele obterá os argumentos remotos concatenados. Por exemplo

rsync -a -M-myvar=val --rsync-path='echo hello >/tmp/out; ./mysync' /tmp/test/ remote:test/

será executado no controle remoto como

echo hello >/tmp/out
./mysync --server -logDtpre.iLsfx -myvar=val . test/
    
por 20.07.2016 / 19:41
3

Isso não é exatamente bonito, mas tudo pode estar escondido em um script:

O SSH pode enviar variáveis de ambiente arbitrárias através do túnel; tanto o cliente quanto o servidor precisam ser configurados para permitir isso. O cliente é feito facilmente com a opção -o ; o servidor que você teria que fazer no seu arquivo sshd_config . Aceitar as arbitrárias é uma má ideia, mas algo assim deve funcionar:

BACKUP_PROVIDER_VAR1=val1 rsync -e 'ssh -o SendEnv=BACKUP_PROVIDER_*' …

Você precisaria então colocar um AcceptEnv LANG LC_* BACKUP_PROVIDER_* no seu sshd_config (que, até onde eu sei, pode ser limitado a apenas um determinado usuário / grupo com um Match ). Na verdade, você provavelmente não precisa de LANG ou LC_* de seus clientes de backup, portanto, você só deseja suas próprias versões personalizadas de env.

    
por 20.07.2016 / 19:08
0

Desde o rsync versão 3.1.0, um argumento --remote-option (ou sua forma abreviada -M ) está disponível para passar argumentos para o servidor. Por exemplo, dando ao cliente o comando:

$ rsync -av -M --customarg1=value1 -M --customarg2=value2 file1 file2 user@server:some/path

resultará no comando do servidor recebendo os argumentos prefixados com -M , mas sem o -M , na variável SSH_ORIGINAL_COMMAND . Assim:

rsync --server -vnlogDtpre.iLsfxC --customarg1=value1 --customarg2=value1 . some/path

Os argumentos personalizados precisam ser processados e removidos da linha de comando antes de invocar o rsync do lado do servidor (caso contrário, terminará com um erro porque não os reconhece). Uma maneira de fazer isso é com uma correspondência de expressão regular:

rsync_cmd="$SSH_ORIGINAL_COMMAND"
[[ "$rsync_cmd" =~ --customarg1=([a-zA-Z0-9]+) ]] && customarg1=${BASH_REMATCH[1]}
[[ "$rsync_cmd" =~ --customarg2=([a-zA-Z0-9]+) ]] && customarg2=${BASH_REMATCH[1]}
rsync_cmd=$(sed -re 's/--(customarg1|customarg2)=[a-zA-Z0-9]+//g' <<< $rsync_cmd)

(o exemplo de correspondência regex permite que o parâmetro seja alfanumérico)

Uma ressalva para isso é que ele não funciona se o cliente rsync receber a opção -s (ou --protect-args ) porque isso faz com que os argumentos sejam passados internamente entre o cliente e o servidor rsync - eles não são expostos para o shell, não estão incluídos em $SSH_ORIGINAL_COMMAND e, portanto, não podem ser manipulados.

Um método alternativo é usar --rsync-path para passar os argumentos personalizados. Este método funciona com versões mais antigas do rsync que não possuem -M , bem como com a opção --protect-args :

$ rsync --rsync-path='rsync --customarg1=value1 --customarg2=value2' -av file1 file2 user@server:some/path
    
por 21.07.2016 / 12:52

Tags