Safe way to synchronize ressources between servers

2019-09-04 16:26发布

问题:

I need to synchronize ressources from a master server to a slave server. I use rsync because it can synchronize folder recursively using incremental file list. I have been able to make it work the simpliest way using ssh-keys. Everything is fine but it doesn't work through php shell_exec function. Here is what I have done so far, and where I am getting stuck. Help would be appreciated!

Master and slave servers are on ubuntu 14.04.4

Creation of the ssh-key folder within user's home directory.

mkdir ~/.ssh
chmod 0700 ~/.ssh

Creation of a private / public ssh key with no passphrase

ssh-keygen -f ~/.ssh/id_rsa -q -P ""

Unsure slave server can receive master public ssh key

// log in slave server
mkdir ~/.ssh
chmod 0700 ~/.ssh
touch ~/.ssh/authorized_keys
chmod 0644 ~/.ssh/authorized_keys

Copy public key to the slave server (where I want to synchronize ressources)

// log in master server
su ssh-copy-id -i ~/.ssh/id_rsa.pub [slave user]@[slave host]

Test synchronisation of an existing folder... let's say www/js/

rsync -avz -e "ssh -i ~/.ssh/id_rsa -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null" --progress ~/www/js/ [slave user]@[slave host]:~/www/js/

Yay, all works fine.

I log on slave server, remove www/js folder recursively.

I log on master server

I create a simple php script to test if it work within as a "shell command"

test.php

var_dump(shell_exec('rsync -avz -e "ssh -i ~/.ssh/id_rsa -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null" --progress ~/www/js/ [slave user]@[slave host]:~/www/js/'));

The synchronization doesn't work from php. Probably because php runs width www-data user? How can I make it work safely from pĥp?

回答1:

As suggested by symcbean, my previous answer was is a security risk. Making www-data able to access remote hosts without password may be really dangerous. A better approach is to set up a linux user, lets say "wwwsync", that will handle rsync with remote hosts, and let www-data execute rsync "under wwwsync user". That way, we can control / secure rsync by setting up what wwwsync user can and cannot do.

Creation of a linux user that will handle synchronization (let's say wwwsync), and create the ssh-key folder within user's home directory.

// log as root user    
adduser wwwsync
// log as wwwsync
su wwwsync
// create ssh folder for ssh key creation
mkdir ~/.ssh
chmod 0700 ~/.ssh

Creation of a private / public ssh key with no passphrase

ssh-keygen -f ~/.ssh/id_rsa -q -P ""

Unsure slave server can receive master public ssh key

// log in slave server
mkdir ~/.ssh
chmod 0700 ~/.ssh
touch ~/.ssh/authorized_keys
chmod 0644 ~/.ssh/authorized_keys

Copy public key to the slave server (where I want to synchronize ressources)

// log in master server as wwwsync
su ssh-copy-id -i ~/.ssh/id_rsa.pub [slave user]@[slave host]

Make www-data user (php) able to perform rsync under wwwsync user

// log in as root
su root
// edit sudo configuration
sudo visudo
// add this line at the bottom of the file
www-data ALL=(wwwsync) NOPASSWD: /usr/bin/rsync

This line will then work properly from php

shell_exec('rsync -H -u wwwsync -avz -e "ssh -i ~/.ssh/id_rsa -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null" --progress ~/www/js/ [slave user]@[slave host]:~/www/js/')

Next important step : Make sure that wwwsync has rights and permissions properly set, according to your needs, so www-data won't synchronize unwanted ressources to your remote servers.



回答2:

** edit : this answer is not a secure. Please see my other answer **


I finally found out how to make it work

copy private ssh-key to www-data's home folder. Then php will be able to rsync through shell_exec function

www-data's home folder is /var/www/ (in my case Ubuntu 14)

create .ssh folder if not present

mkdir /var/www/.ssh
chown www-data /var/www/.ssh
chmod 0700 /var/www/.ssh

copy ssh key and set proper rights

cp ~/.ssh/id_rsa /var/www/.ssh
chown www-data /var/www/.ssh/id_rsa
chmod 0600 /var/www/.ssh/id_rsa

This line now works for me :

shell_exec('rsync -avz -e "ssh -i ~/.ssh/id_rsa -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null" --progress [absolute_path]/www/js/ [slave user]@[slave host]:~/www/js/');

If it helps someone...

But since I know a lot in security but can't say I'm a specialist, I wonder if that is secure ?