underscore
underscore

Reputation: 6887

ssh or cURL to send data to remote server

I'm creating a app to sync my local mysql database to a remote mysql database, so I'm generating a dump file, sending it via the sFTP, then executing it on the server.

However, I am aware that there are other available methods like cURL. I like to send data to the remote server and execute it on the sever when it is accepted (TRUE), but I don't know much about security issues associated with using cURL in this regard. Can anyone advise on the cURL solution, else suggest any alternative methods?

Upvotes: 1

Views: 8051

Answers (4)

ChrisKnowles
ChrisKnowles

Reputation: 7120

This is a basic solution using ssh2 / libssh.

This code assumes that you already have a method of creating your database dump, and will just be reading it on the current server, with the aim of loading it on the remote server.

It connects to the remote host via SSH, writes your sql_dump to a file on the remote server, then executes a command to load it into the database.

I wouldn't recommend storing the username/password for connecting, this is simply a quick way to test the code. You would be better using ssh2_auth_pubkey_file to authenticate: http://php.net/manual/en/function.ssh2-auth-pubkey-file.php

// remote host authentication details. hostname/ip, user, pass
$host = 'REMOTE_HOST';
$user = 'REMOTE_USER';
$pass = 'REMOTE_PASS';

// check if we have ssh2 installed first
if (function_exists("ssh2_connect")) {

    //connect to remote host
    $connection = ssh2_connect($host, 22);

    // if connection successful, proceed
    if ($connection) {

        // authenticate on remote connection
        $auth = ssh2_auth_password($connection, $user, $pass);

        // if we have authenticated, proceed with remote commands
        if ($auth) {

            // load our dump file to a string
            $sql_str = file_get_contents('dump_file.sql');
            // bash command to cat our dump string to a file
            $write_remote_file_command = "cat <<'EOF' > /home/tmp_file.sql \n$sql_str \nEOF";
            // call our execute ssh function to execute above command
            executeSSHCommand($connection, $write_remote_file_command);

            // command to load our temp dump file into the database
            // - you may need to add additional commands to drop the existing db, etc
            $remote_load_command = "mysql -Uroot -p -h localhost database_name < /home/tmp_file.sql";
            // remotely execute load commands
            executeSSHCommand($connection, $remote_load_command);
        }
    }
}

// basic function to execute remote shell commands via our authenticated $connection
function executeSSHCommand($connection, $command) {

    $output = array();
    $ssh_data = "";

    $stream = ssh2_exec($connection, $command);

    if ($stream) {

        stream_set_blocking($stream, true);

        while ($buffer = fread($stream, 65536)) {

            $ssh_data .= $buffer;
        }

        fclose($stream);

        $output = explode(PHP_EOL, $ssh_data);

    } 

    return $output;
}

Upvotes: 0

neubert
neubert

Reputation: 16792

I use phpseclib, a pure PHP SFTP implementation, to do stuff like this. eg.

<?php
include('Net/SFTP.php');

$sftp = new Net_SFTP('www.domain.tld');
if (!$sftp->login('username', 'password')) {
    exit('Login Failed');
}

$sftp->put('filename.remote', 'filename.local', NET_SFTP_LOCAL_FILE);
?>

It has a number of advantages over libssh2, including speed and portability:

http://phpseclib.sourceforge.net/ssh/compare.html

Upvotes: 0

Jimbo
Jimbo

Reputation: 26584

Firstly, instead of generating the dump file, you should read the data from the file using file_get_contents(), fread() etc.

Store the result of this in a variable, then send that raw data over the pipeline (via cURL, if you wish), and have the code on the server-side generate the dump file instead.

Using cURL, you can specify a private certificate file for authentication - so the security of this is the same as using a certificate over ssh - it's not something you need to be worried about.

You can set the pem file with the following cURL option examples:

curl_setopt($ch, CURLOPT_SSLCERT, $pemfile);
curl_setopt($ch, CURLOPT_SSLCERTTYPE, 'PEM'); 
curl_setopt($ch, CURLOPT_SSLKEY, $keyfile); 

There are tutorials for the above all over the internet. Use private key authentication and your security issues are sorted. Just make sure you don't set CURLOPT_SSL_VERIFYPEER to false (you don't want any MiTM (man in the middle) attacks now, do you).

Upvotes: 3

Dave
Dave

Reputation: 3288

I use Curl for doing this.

I have an export script which generates json or xml (depends on what mood i'm in more than anything else) I then post this file to the remote server and the remote server uses ignore_user_abort so that processing can continue even if the parent internal system script times out / completes whatever.

Works like a charm syncing changes to a 2.6gb table between local web server and remote web server.

Upvotes: 1

Related Questions