Estou trabalhando com duas instâncias do Ubuntu na AWS (que uso uma chave pem para acessá-las).
Eu configurei o rsync para ambas as instâncias e funciona se eu usar o usuário padrão que é ubuntu@ipaddress. No entanto, se eu tentar usar o rsync com outro usuário (estou digitando, sudo su - jenkins
por exemplo, ou mesmo digitando sudo
antes do comando rsync), recebo o seguinte erro.
Permission denied (publickey).
rsync: connection unexpectedly closed (0 bytes received so far) [Receiver]
rsync error: unexplained error (code 255) at io.c(226) [Receiver=3.1.0]
Passos que tomei:
Eu tentei criar uma chave ssh (usando ssh-keygen) enquanto estava logado como jenkins
e adicionei-a ao authorized_keys
arquivo em ambos /home/ubuntu/.ssh/authorized_keys
(de onde estou executando o rsync) e até mesmo $JENKINS_HOME/.ssh/authorized_keys
(onde tentei executar o rsync de lá também).
Até tentei usar a chave pem para fazer a mesma coisa e também não funcionou.
Aqui está o que estou tentando executar
rsync -avuh --delete -e ssh jenkins@ipaddress:/var/lib/jenkins/* /var/lib/jenkins
E aqui está o arquivo-chave
rsync -avuh --delete -e 'ssh -i path/to/key.pem' [email protected]:/var/lib/jenkins/* /var/lib/jenkins
PS: A única razão pela qual não quero executá-lo com o usuário do Ubuntu é porque entro failed: Permission denied (13)
em muitas coisas (já que os arquivos são de propriedade do Jenkins).
Objetivo final:
Estou tentando manter o backup da instância de backup do Jenkins constantemente com a instância primária, fazendo um cronjob:
*/30 * * * * /usr/bin/rsync -avuh --delete -e ssh root@jenkinsprimary:/var/lib/jenkins/* /var/lib/jenkins
Responder1
Você tem que diferenciar 2 coisas:
- Quemestabelece a conexão SSH.
- qualusuário remoto possui os arquivosque você deseja copiar.
Visão geral
(srcmachine) (rsync) (destmachine)
srcuser -- SSH --> destuser
|
| sudo su jenkins
|
v
jenkins
Digamos que você queira sincronizar novamente:
- De:
- Máquina:
srcmachine
- Do utilizador:
srcuser
- Diretório:
/var/lib/jenkins
- Máquina:
- Para:
- Máquina:
destmachine
- Usuário:
destuser
paraestabelecer a conexão SSH. - Diretório:
/tmp
- Proprietário dos arquivos finais:
jenkins
.
- Máquina:
Solução
rsync --rsync-path 'sudo -u jenkins rsync' -avP --delete /var/lib/jenkins destuser@destmachine:/tmp
Explicações
--rsync-path=PROGRAM specify the rsync to run on the remote machine
O truque é dizer para rodar rsync
na máquina remota com outro usuário ( jenkins
) diferente daquele que estabelece a conexão SSH ( destuser
).
Requisitos
Acesso SSH
(srcmachine) (rsync) (destmachine)
srcuser -- SSH --> destuser
[~/.ssh/id_rsa] [~/.ssh/authorized_keys] <-- "id_rsa.pub" inside
[~/.ssh/id_rsa.pub]
Não se esqueça de restringir as permissões em ~/.ssh
:
chmod 700 ~/.ssh
sudoer para odestuser
O destuser
deve ter o privilégio de fazer sudo -u jenkins rsync
.
Em geral, definimos the destuser
como membro do sudoers
. Para fazer isso, no root
@ destmachine
:
cat > /etc/sudoers.d/destuser << EOF
destuser ALL=(ALL) NOPASSWD:ALL
EOF
Para testá-lo antes rsync
, você pode fazer login no destuser
@ destmachine
e executar isto:
sudo su jenkins
echo $USER
Se retornar:
jenkins
isso significa que você está logado como jenkins
usuário e que seu rsync
comando também funcionará, porque o privilégio escalade jenkins
funciona.
Nota sobre uma solução ruim: estabeleça a conexão SSH com o usuário de destinojenkins
Por que simplesmente não fazemos isso?
(srcmachine) (rsync) (destmachine)
srcuser -- SSH --> jenkins
[~/.ssh/id_rsa] [~/.ssh/authorized_keys] <-- "id_rsa.pub" inside
[~/.ssh/id_rsa.pub]
porque jenkins
é uma conta de "serviço", o que significa que ela executa um serviço que expõe uma porta ( 80
ou algo assim) para acesso HTTP externo, e isso significa que é POSSÍVEL que haja uma violação de segurança através do serviço Jenkins sobre HTTP para obter acesso .
É por isso que temos www-data
usuários e similares para executar os diferentes serviços. Caso sejam hackeados nas portas que expõem, eles não poderão fazer muito:
- tudo é somente leitura para eles.
- exceto escrever em
/var/log/THE_SERVICE
.
Portanto, permitir o acesso SSH para o jenkins
usuário expõe um ataque de superfície (e o mesmo acontece com o acesso SSH como root
!!).
Além disso, se você quiser sincronizar novamente como outro usuário ( root
, www-data
, etc.), você terá que copiar sua chave pública SSH para essas contas (problemático).
Boa solução: Você deve definirAcesso SSH o mínimo possível às contas de usuário( destuser
) quePODE escalarpara a conta de "serviço" desejada ( jenkins
, root
, etc.).
Responder2
Tive um problema semelhante com o rsyncing como outro usuário. Resolvi executando o próximo comando:
rsync -avu -e "ssh -i my-key -o StrictHostKeyChecking=no -l user-i-want-to-use-in-rsync" ./local_dir remote_host:remote-host-dir
Observe que talvez você precise brincar com as teclas para poder executar o rsync como outro usuário.
Responder3
sudo -u jenkins -i rsync ...
comsem citações.
A -i
opção faz o sudo
comando ser executado com o ambiente do usuário incluindo chaves ssh .profile
, .bash_profile
etc.
Do sudo
homem:
-i, --login
Execute o shell especificado pela entrada do banco de dados de senha do usuário de destino como um shell de login. Isso significa que arquivos de recursos específicos de login, como
.profile
,.bash_profile
ou.login
serão lidos pelo shell. Se um comando for especificado, ele será passado ao shell para execução por meio da-c
opção do shell. Se nenhum comando for especificado, um shell interativo será executado.sudo
tenta mudar para o diretório inicial desse usuário antes de executar o shell. O comando é executado em um ambiente semelhante àquele que um usuário receberia no login. Observe que a maioria dos shells se comporta de maneira diferente quando um comando é especificado em comparação com uma sessão interativa; consulte o manual do shell para obter detalhes. A seção Ambiente de comando nosudoers(5)
manual documenta como a-i
opção afeta o ambiente no qual um comando é executado quando a política sudoers está em uso.
Responder4
Eu tenho um problema semelhante.
Eu resolvo isso usando o cron. Mas o cron deve ser executado com usuário específico (ex: jenkins)
Basta fazer o cron job:
$ crontab -u jenkins -e
em seguida, preencha o cron com sua necessidade.
*/2 * * * * sh /home/user/scp.sh 2>&1 >> /home/user/errmail.log