PHP Exec SCP does not copy the file to the remote server - php

I need a file from a server to another server (I own both) using PHP. I have the following script:
<?php
exec('scp /home/pat/file1.tst pat#myserver.com:/home/pat/file1.txt');
I get this error:
Disallowed system call: SYS_pipe
What is that error? and how can I fix it?

PHP environment does not allow exec on your server.

This is kinda late, I know, but you might have better luck with phpseclib's pure PHP SCP implementation:
https://raw.github.com/phpseclib/phpseclib/master/phpseclib/Net/SCP.php
Example of how to use it:
<?php
include('Net/SCP.php');
include('Net/SSH2.php');
$ssh = new Net_SSH2('www.domain.tld');
if (!$ssh->login('username', 'password')) {
exit('bad login');
}
$scp = new Net_SCP($ssh);
$scp->put('abcd', str_repeat('x', 1024*1024));
?>

Related

Copy csv from remote sftp server copy to my server's wordpress directory

I'm looking for a solution to how I can copy a csv file that is on a remote sftp server and have it available on my server. I'm then using a plugin to pull the data from this csv into my wordpress database.
I have tried to do this with this PHP script:
https://phpseclib.com/docs/sftp
Do I need to install something on my server to get this running? Sorry, but I'm not very backend and a bit of a noob. There's probably a way easier approach to this..
I get a 500 error when I run this PHP file in the browser.
<?php
function getData(){
use phpseclib3\Net\SFTP;
$sftp = new SFTP('server-domain', port); //default port is 22
if (!$sftp->login('username', 'password')) {
throw new Exception('Login failed');
}
$sftp->get(‘remote-server-file.csv’, 'my-server-file.csv' ); // return content of the file
getData();
?>

use ppk file to connect to sftp in PHP

I am having trouble connecting to an SFTP server using a .ppk file that are provided.
I have tried this ppk file in Filezilla and it works.
According to one of the comments in another question it is better to use phpseclib but i didnt find any instructions on how to download files from SFTP using a ppk file. Any directions or suggestions?
Here is the code I'm not sure if that will help or not.
include('Net/SSH2.php');
include('Crypt/RSA.php');
include('Net/SFTP.php');
DEFINE('SERVER','sample.sftp.com');
DEFINE('USER','sampleUserName');
DEFINE('KEY','sample_key_22733_priv.ppk');
$sftp = new Net_SFTP(SERVER);
//I guess this password is useless here
//and i will have to use my ppk file here but i don't know how
if (!$sftp->login(USER, 'password')) {
exit('Login Failed');
}
var_dump($sftp->nlist());
phpseclib works perfectly fine with PPK files, assuming they're RSA keys and not DSA keys. Just initialize a Crypt_RSA object and then call loadKey(file_get_contents('path/to/key.ppk')) on that object.
To download files do $sftp->get('/path/to/filename.ext').
Here's your orig code modified to include all this:
<?php
include('Net/SSH2.php');
include('Crypt/RSA.php');
include('Net/SFTP.php');
DEFINE('SERVER','sample.sftp.com');
DEFINE('USER','sampleUserName');
DEFINE('KEY','sample_key_22733_priv.ppk');
$rsa = new Crypt_RSA();
$rsa->loadKey(file_get_contents(KEY));
$sftp = new Net_SFTP(SERVER);
//I guess this password is useless here
//and i will have to use my ppk file here but i don't know how
if (!$sftp->login(USER, $rsa)) {
exit('Login Failed');
}
echo $sftp->get('/path/to/filename.ext');
Update:
As #neubert confirmed, PPK files are supported but you do need to make sure they are RSA as I explained, but you do not need them in OpenSSH format
Convert your PPK to an OpenSSH RSA key. You can convert this using the PuTTYgen executable: http://www.chiark.greenend.org.uk/~sgtatham/putty/download.html
Once you have it in an RSA key, you can use this with phpseclib: http://phpseclib.sourceforge.net/ssh/auth.html#rsakey

How do I make this script copy files to local disk?

I have copied and tried many PHP scripts from SO posts. I am trying to download files from a server running Centos. Via psftp (putty) I can login manually and copy files. But I want to automate the process, hence the need for a script.
On a similar server running on Windows am able to download files by ftp via a simple Perl script. On the Centos server I get connection refused with the Perl script. So I tried several php scripts. Are the scripts below (from SO posts) for the job? or what is wrong with the scripts?
script 1
#!/usr/bin/php
<?php
include('Net/SSH2.php');
$sftp = new Net_SFTP('xx.xx.xxx.xxx');
if (!$sftp->login('myuser', 'mypasswd')) {
exit('Login Failed');
}
// outputs the contents of filename.remote to the screen
echo $sftp->get('gateway_data*');
?>
Script 2
#!/usr/bin/php
<?php
include('Net/SSH2.php');
username='myuser';
password='mypasswd';
// Create SCP connection using a username and password
$scp = new SCP(
'xx.xx.xxx.xxx',
new SSH2Password($username, $password)
);
#################################
$sftp = ssh2_sftp($conn);
// Create a new local folder
ssh2_sftp_mkdir($sftp, './data');
// Retrieve a list of files
$files = scandir('ssh2.sftp://' . $sftp . '/data/gateway_data*');
################################################################
?>
In the first of PHP script you have posted you're doing echo $sftp->get('gateway_data*'); whereas in the Perl script you're doing cp gateway_data_301.txt. Try doing that in the PHP script. eg. echo $sftp->get('gateway_data_301.txt');.
As is it is unclear what you're expecting to happen. Unless the file name /actually/ has a wild card in it then are you expecting it to download every file that starts off with gateway_data* and just concatenate them in the output? Personally, I think just returning false or NULL would be better than that.
You can use your script 2 in PHP. However something is missing there. You are only opening the source directory. You must write a loop over all files in that folder.
// Retrieve a list of files
$files = scandir('ssh2.sftp://' . $sftp . '/data/gateway_data*');
foreach ($files as $key => $value) {
See the example of how to send a file with SFTP using SFTPConnection.

Uploading files using SCP using phpseclib

I need to create 2 functions: one to upload files using SFTP and another using SCP. I'm using phpseclib and the put method; I believe I have the SFTP function done.
Now, I'm trying to do the SCP function. Per http://adomas.eu/phpseclib-for-ssh-and-scp-connections-with-php-for-managing-remote-server-and-data-exchange/, it seems like the following are the things I need to do:
In case of SCP:
1. Including the needed file: include('/path/to/needed/file/Net/SFTP.php');
2. Creating object and making connection:
$sftp = new Net_SFTP('host');
if (!$sftp->login('user', 'password')) { exit('Login Failed'); }
3. Reading contents of a file: $contents=$sftp->get('/file/on/remote/host.txt');
4. Copying file over sftp with php from remote to local host: $sftp->get('/file/on/remote/host.txt', '/file/on/local/host.txt');
5. Copying file over sftp with php from local to remote host: $sftp->put('/file/on/remote/host.txt', '/file/on/local/host.txt');
6. Writing contents to remote file: $sftp->get('/file/on/remote/host.txt', 'contents to write');
I need to do #5, but it looks like what I did for SFTP. SFTP and SCP aren't the same, right? Is the same code correct? If not, how do I do SCP?
As noted by neubert, phpseclib has SCP support now through the Net_SCP class.
You instantiate an Net_SCP object by passing it a Net_SSH2 or Net_SSH1 object in the constructor, and can then use the get() and put() methods to download or upload files via SCP.
Here's a simple example script showing me SCPing a file from my local machine to a remote AWS instance.
<?php
set_include_path(get_include_path() .
PATH_SEPARATOR .
'/home/mark/phpseclib');
require_once('Crypt/RSA.php');
require_once('Net/SSH2.php');
require_once('Net/SCP.php');
$key = new Crypt_RSA();
if (!$key->loadKey(file_get_contents('my_aws_key.pem')))
{
throw new Exception("Failed to load key");
}
$ssh = new Net_SSH2('54.72.223.123');
if (!$ssh->login('ubuntu', $key))
{
throw new Exception("Failed to login");
}
$scp = new Net_SCP($ssh);
if (!$scp->put('my_remote_file_name',
'my_local_file_name',
NET_SCP_LOCAL_FILE))
{
throw new Exception("Failed to send file");
}
?>
phpseclib recently added SCP support:
https://github.com/phpseclib/phpseclib/blob/master/phpseclib/Net/SCP.php
Yes, the SCP is completely different protocol to the SFTP.
The phpseclib now supports the SCP in recent versions (since version 0.3.5, released in June 2013).
Alternatively, use the PHP PECL SSH2 functions for SCP upload/download:
https://www.php.net/manual/en/ref.ssh2.php

PHP SSH2 and Amazon EC2 .pem's

I've been looking for a way to use PHP's SSH2 to create a sort of terminal. To connect to Amazon in a normal terminal, you would use something like ssh -i path_to/key.pem ec2.ip-555-xxx.com. In PHP on the other hand, SSH2 has a function ssh2_auth_pubkey_file . But have run into a bit of a wall here, as Amazon only provides me with 1 private key (.pem) file, and the function has arguments for both private and public keys. Ultimately I'd like to have a client upload a .pem file to the server and be able to connect to a local or remote SSH server with PHP SSH2 on Amazon using that .pem file.
.pem is the server certificate for the apache web server, it has nothing to do with ssh. See: https://serverfault.com/questions/9708/what-is-a-pem-file-and-how-does-it-differ-from-other-openssl-generated-key-file-f
Seems it might also be a combo file with public and private keys in it. In any case it will not work for ssh directly, you will need to convert it to normal files.
You have it backward anyway - amazon will not give you the private key, quite the opposite - you give amazon the public key. You generate the private/public key pair locally, then upload the public key into the .ssh/authorize_keys files.
Personally, I'd recommend phpseclib, a pure PHP SSH2 implementation be used:
<?php
include('Net/SSH2.php');
$key = new Crypt_RSA();
//$key->setPassword('whatever');
$key->loadKey(file_get_contents('privatekey'));
$ssh = new Net_SSH2('www.domain.tld');
if (!$ssh->login('username', $key)) {
exit('Login Failed');
}
echo $ssh->exec('ls -la');
?>
This is how you get the private and public keys from .pem within php
$eKey = file_get_contents('/pathto/key.pem');
$key_private = openssl_get_privatekey($eKey);
$keyDet=openssl_pkey_get_details($key_private);
$key_public = openssl_pkey_get_public(array($keyDet['key'],""));
$keyPDet=openssl_pkey_get_details($key_public);

Categories