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?
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).
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.
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
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;
}
Related
I'm trying to store data to ipfs via PHP, I use curl to communicate with API , it works fine on my local node, but I want to use an external node from infura.io
but for some reason, ipfs.infura.io is refusing my connection via php
even a simple command like ... I've tried it on my localhost as well as a couple of servers
here is a simple endpoint that you can open in the browser and get the output
https://ipfs.infura.io:5001/api/v0/pin/add?arg=QmeGAVddnBSnKc1DLE7DLV9uuTqo5F7QbaveTjr45JUdQn
but when I try to open it via php i get
Failed to connect to ipfs.infura. io port 5001: Connection refused
or when using another method like file_get_contents
file_get_contents(ipfs.infura.io:5001/api/v0/pin/add?arg=QmeGAVddnBSnKc1DLE7DLV9uuTqo5F7QbaveTjr45JUdQn): failed to open stream: Connection refused
i've tried it on local host and multiple server , i get the same result even via ssh command line
any idea why is this happening ?
here is a simplified version n of my code
$curl = curl_init();
curl_setopt($curl, CURLOPT_URL,"https://ipfs.infura.io:5001/api/v0/pin/add?arg=QmeGAVddnBSnKc1DLE7DLV9uuTqo5F7QbaveTjr45JUdQn");
curl_setopt($curl, CURLOPT_FOLLOWLOCATION, 1);
curl_setopt($curl, CURLOPT_FAILONERROR, true);
$res = curl_exec($curl);
if (curl_errno($curl)) {
$error_msg = curl_error($curl);
echo ('error ...');
echo ($error_msg);
exit();
}
curl_close($curl);
echo($res);
In order to connect ipfs node, you need to have a client library. client libraries automatically format API responses to match the data types used in the programming language and also handles other specific communication rules.
In javascript,
import { create as ipfsHttpClient } from "ipfs-http-client";
const client = ipfsHttpClient("https://ipfs.infura.io:5001/api/v0");
then this client makes request:
const added = await client.add(file, {
progress: (prog) => console.log(`received:${prog}`),
In php, you can use this package: https://github.com/cloutier/php-ipfs-api
Check this to interact with infura: https://github.com/digitalkaoz/php-ipfs-api
This library requires the cURL module:
$ sudo apt-get install php5-curl
$ composer require cloutier/php-ipfs-api
$ composer install
$ export IPFS_API=http://somehost:5001/api/v0
to use this Driver from the commandline simply provide the option (or leave it away since its the default):
$ bin/php-ipfs version --driver=IPFS\\Driver\\Http
$ bin/php-ipfs version
Client this Driver is intended for programmatically usage:
$driver = $container[IPFS\Driver\Cli::class];
//$driver = $container[IPFS\Driver\Http::class];
$client = new IPFS\Client($driver);
$response = $client->execute((new \IPFS\Api\Basics())->version());
var_dump($response);
In PHP, I cannot even get the SFTP connection to work. I have tried to use the native SFTP functionality (ssh_connect), and it fails to connect. I have also tried to use phpseclib, but it fails as well. Neither of my aforementioned attempts have provided much in the way of log info.
The native code:
if (!function_exists('ssh2_connect')) {
echo "dll not loaded properly"; //never see this, so I know it works
return false;
}
$connection = ssh2_connect('sftp.example.com', 22);
ssh2_auth_password($connection, 'username', 'password');
$sftp = ssh2_sftp($connection);
phpseclib library code:
include('Net/SFTP.php');
$sftp = new Net_SFTP('sftp.example.com');
if (!$sftp->login('username', 'password')) {
exit('Login Failed');
}
I have also tried to track all of the transactions via Fiddler to see if I at least see a connection being made, and I do see an error in the browser (below) that from googling may mean that a connection was made to the server, but no responses.
[Fiddler] ReadResponse() failed: The server did not return a complete response for this request. Server returned 17139 bytes.
Why am I able to connect to the URL with the username and password via FIleZilla, but not from within php? Do I need some other DLLs in PHP's /ext folder (e.g. php_openssl.dll, etc.)?
Thanks,
Sean
I need to check if my hosting server can reach certain IPs that I need to work with.
I have a shared hosting plan and, although I have access to SSH, the PING function is not available.
I've tried several php scripts but to no avail. Most of them relied on executing PING via shell.
Is there any way I can check this without using PING? I tried using the CURL function (in PHP) but it doesn't seem to work with IPs.
Any help would be very much appreciated.
Try this, it connects to port 22, which is the reserved port for ssh:
<?php
//
// By: Spicer Matthews <spicer#cloudmanic.com>
// Company: Cloudmanic Labs, LLC
// Date: 5/19/2011
// Description: This is a client to the echo server. It will send 10 test commands, and echo the server response.
// Run it from the command line "php client.php".
//
set_time_limit(0);
$address = '127.0.0.1';
$port = '22';
$fp = fsockopen($address, $port, $errno, $errstr, 300);
if(! $fp)
{
http_response_code(204);
}
else
{
http_response_code(404);
}
?>
The response codes may need to be changed, as necessary.
I want to append data to a file that is on another server.
Was wondering if the code below will work:
$fp = fopen('http://192.168.2.34:1234/Planet/data.txt', 'a+');
fwrite($fp, $successString);
fwrite($fp, '/n');
fclose($fp);
I'll spoil it: no, it won't work. There needs to be a service that handles the HTTP connection on the other end, which may then itself write something to a file. You cannot access files on remote hard disks directly over HTTP. And thank god for it.
One of the options for writing a file to a remote sever using something like the above would be using FTP access with allow_url_fopen enabled in php.ini and like follows:
<?php
$file = fopen ("ftp://ftp.example.com/incoming/outputfile", "w");
if (!$file) {
echo "<p>Unable to open remote file for writing.\n";
exit;
}
/* Write the data here. */
fwrite ($file, $_SERVER['HTTP_USER_AGENT'] . "\n");
fclose ($file);
?>
Source: http://php.net/manual/en/features.remote-files.php
However the source also states:
Note: You might get the idea from the example above that you can use this technique to write to a remote log file. Unfortunately that would not work because the fopen() call will fail if the remote file already exists. To do distributed logging like that, you should take a look at syslog().
Therefore you cannot append using the above method, if you are sending a system log message to a remote server use syslog() as this is designing for that purpose.
Of the top of my head, you could potentially use something like SSH if on a linux machine or cygwin if on a Windows machine on either side to append to a file using PHP. But you would need SSH access to the remote machine.
if (!function_exists("ssh2_connect")) die("function ssh2_connect doesn't exist"); // log in at server1.example.com on port 22 if(!($con
= ssh2_connect("server1.example.com", 22))){
echo "fail: unable to establish connection\n"; } else {
// try to authenticate with username root, password secretpassword
if(!ssh2_auth_password($con, "root", "secretpassword")) {
echo "fail: unable to authenticate\n";
} else {
// allright, we're in!
echo "okay: logged in...\n";
// execute a command
if (!($stream = ssh2_exec($con, "EXECUTE SSH COMMAND HERE TO APPEND" ))) {
echo "fail: unable to execute command\n";
} else {
// collect returning data from command
stream_set_blocking($stream, true);
$data = "";
while ($buf = fread($stream,4096)) {
$data .= $buf;
}
fclose($stream);
}
} }
Source: http://kevin.vanzonneveld.net/techblog/article/make_ssh_connections_with_php/
p.s. The reason you cannot do what you are asking in your example above in that scenario, is that if it were possible, ANYONE would be able to write to files on any server. As you can imagine this would be a great security risk!
You cannot do this; you'd probably get an error message like this:
PHP Warning: fopen(http://example.com/data.txt): failed to open stream: HTTP wrapper does not support writeable connections
I appreciate any help that can be offered on the subject. At the end of an online enrollment, I am taking customer data (several fields), putting them in a CSV file and trying to submit to another client over SSL protocol but have no idea how this is done. I am also storing the information on a local database and am hoping the process is somewhat similar.
I have already been sent links to view the SSH2 instructions from php.net SSN2
but to be honest this is like reading Chinese to me. I do not understand the instructions and am not looking to install any extensions, modify the PHP.ini file or anything of the sort (especially since we do not own the server the information is being sent through).
Is there a simple, secure way of transmitting this file to the SSL protocol provided to us?
Thanks!
Perhaps you could use ftp_ssl_connect for that matter, which is used to open a secure SSL-FTP connection, and to upload a file is just a straight forward process, just create the connection to the server, and put the file up there. A basic example could be:
//Create your connection
$ftp_conn = ftp_ssl_connect( $host, $you_can_provide_a_port );
//Login
$login_result = ftp_login($ftp_conn, $user, $pass);
if( $login_result )
{
//Set passive mode
ftp_pasv( $ftp_conn, true );
// Transfer file
$transfer_result = ftp_put( $ftp_conn, $dest_file_path, $source_file_path, FTP_BINARY );
//Verify if transfer was successfully made
if( $transfer_result)
{
echo "Success";
}
else
{
echo "An error occured";
}
}
For reference purposes http://www.php.net/manual/en/function.ftp-ssl-connect.php
The only way I've managed to do ftp over SSL using php was to use php's exec() function to execute a curl command. PHP's curl library would not work because at the time, the skip-pasv-ip option did not exist and it was something that was absolutely required. Something like:
curl --user <username:password> --disable-epsv --ftp-pasv --ftp-skip-pasv-ip --ftp-ssl --sslv2 --cert <path/to/certificate> -T <path/to/uploadfile> <hostname>
You may need to modify the curl options to suit your needs.