Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Rsync via PHP exec() with SSH passwordless ssh login

Tags:

php

apache

rsync

If I run the command via php exec(): It does not work. But if I use bash, it runs perfect. Any idea what the problem might be.? I was thinking maybe it is executing rsync as apache and not allowing ssh login.

exec('rsync -au /var/www/html/f1/ [email protected]:/var/www/html/f2/');
like image 869
DaedBaet Avatar asked Feb 01 '12 01:02

DaedBaet


4 Answers

PHP generally runs in Apache under mod_php. Usually Apache is running as its own user account, independent from the real-world people who use the server.

So, the ~/.ssh files which store the passwordless-SSH key under your user account's home directory are not available to PHP inside Apache, since it doesn't have your homedir. Even if Apache shared your home directory, it still wouldn't have permissions to read those files.

like image 100
Borealid Avatar answered Oct 20 '22 02:10

Borealid


My investigation of this stuff brings me to that: I can run rsync in php which in turn runs under apache. But I must to take into consideration some points:

  • The home directories must exist for an user under which account a web server is launched at local computer (probably, http) and for a remote user under which account you are connecting to the remote host.
  • The private authentication key (possibly with empty password) must be accessible for the http user. Corresponding public key must be added to the remote

    ~/.ssh/authorized_keys 
    

    file. Here ~ is the home dir of the remote user at the remote host.

  • A local configuration file

    ~/.ssh/config
    

    must be created. Here ~ is the home dir of the http user at the local host. The config file must be accessible for the http user only. It may contain something like this:

    Host *
        User=www-data
        IdentityFile=~/.ssh/nopass_rsa
        Compression=no
        Ciphers=arcfour
        StrictHostKeyChecking=no
        UserKnownHostsFile=/dev/null
    

    Here User is a user name at the remote host, IdentityFile is a key file. Next two parameters (Compression and Ciphers) allow to increase throughput slightly. And the last two parameters allow to skip host-key checking.

  • If you are dealing with ~/.ssh directory of the local http user and ~ is root directory for the web-server at the same time then there is the security trouble: you (or anybody else) can access your keyfiles simply typing

    www.your-domain.com/.ssh/ 
    

    in browser. So denying access to this directory in a web-browser's config will be a good idea.

My example of php-code:

exec('rsync -auq remote.host.com:/archive/ ./backup_bd/');

which just works...

I think, I answered your question.

like image 34
Serge Roussak Avatar answered Oct 20 '22 02:10

Serge Roussak


Here's how you specify where should SSH pick up your keys:

exec('rsync -e "ssh -i /home/you/.ssh/id_dsa" ...')

I assume that Apache runs under user that can read your id_dsa or id_rsa.

like image 2
sanmai Avatar answered Oct 20 '22 02:10

sanmai


store the command in a shell script, since it has no dynamic parts, and then use exec() to execute the shell script.

# on command line    
echo 'rsync -au /var/www/html/f1/ [email protected]:/var/www/html/f2/' > sync_files

# On command line
chmod +x sync_files

<?php
// in php
exec('sync_files');
?>
like image 1
Andre Honsberg Avatar answered Oct 20 '22 04:10

Andre Honsberg