I'm trying to delete a folder and all the files that in it, in a SSH server.
The thing is that I don't know how ssh2 works. I changed the connection to ssh2, but maybe those function doesn't works in a ssh server, I don't know...
My code:
$ftpuser = '***';
$ftppass = '***';
$dir = 'files/someFolder/';
$connection = ssh2_connect('**.***.***.***',22);
if(!$connection) {
error_log("Couldn't connect to $ftp_server");
exit;
}
$login_result = ssh2_auth_password($connection, $ftpuser, $ftppass);
ftp_chdir($connection, $dir);
$folders_files = ftp_nlist($connection, '.');
foreach ($folders_files as $folder_file) {
ftp_delete($connection, $folder_file);
}
ftp_rmdir($connection, $dir);
There are some errors:
PHP Warning: ftp_chdir(): supplied resource is not a valid FTP Buffer resource in...
PHP Warning: ftp_nlist(): supplied resource is not a valid FTP Buffer resource in...
PHP Warning: Invalid argument supplied for foreach() in...
PHP Warning: ftp_rmdir(): supplied resource is not a valid FTP Buffer resource in...
What the hell is going on here?
You're mixing the ssh2_* functions and the ftp_* functions. They're not interchangeable.
That said I'd recommend using phpseclib, a pure PHP SFTP implementation. An example:
<?php
include('Net/SFTP.php');
$sftp = new Net_SFTP('www.domain.tld');
if (!$sftp->login('username', 'password')) {
exit('Login Failed');
}
$sftp->delete('dirname.remote', true); // deletes a directory and all its contents
?>
The fact that it can recursively delete stuff should be particularly useful to you. ie. if files/someFolder/ contains a folder A that itself contains another folder, folder B, you probably won't be able to delete it with your method whereas with phpseclib's deletion approach can delete it.
You must be inside a non-existent directory.
This code will help you understand what you are doing wrong.
echo "Current directory: " . ftp_pwd($connection) . "\n";
// try to change the directory to somedir
if (ftp_chdir($connection, "files/someFolder/")) {
echo "Current directory is now: " . ftp_pwd($connection) . "\n";
} else {
echo "Couldn't change directory\n";
}
Related
I'm having trouble copying a file from my laravel project to another server. This is what I'm doing.
$connection = ssh2_connect($this->ftpHostname, $this->ftpPort);
if (!$connection) {
throw new \Exception("Couldn't connect to {$this->ftpHostname}:{$this->ftpPort}");
}
$loginResult = ssh2_auth_password($connection, 'usrname', 'pswrd');
if (!$loginResult) {
throw new \Exception("Username or Password not accepted for {$this->ftpHostname}:{$this->ftpPort}");
}
$sftp = ssh2_sftp($connection);
$fullFilePath = storage_path() .'/'.$this->argument('local-file');
$remoteFilePath = "ssh2.sftp://{$sftp}/{$this->argument('remote-folder')}/SomeFolder/{$this->argument('remote-filename')}.txt";
$copyResult = copy($fullFilePath, $remoteFilePath);
But it's giving me this error
[ErrorException]
copy(): Unable to open ssh2.sftp://Resource id #621/My Folders/Upload only/sample.txt on remote host
I'm really new in ssh how do I solve this?
Cast $sftp to an int before using it in the ssh2.sftp:// fopen wrapper.
$remoteFilePath = "ssh2.sftp://" . (int)$sftp . "/{$this->argument('remote-folder')}/SomeFolder/{$this->argument('remote-filename')}.txt";
From ssh2_sftp
The example code above fails unless you cast the $stftp to (int) or use intval()
$stream = fopen("ssh2.sftp://$sftp/path/to/file", 'r'); // Fails
$stream = fopen("ssh2.sftp://" . (int)$sftp . "/path/to/file", 'r'); // joy
Since copy() will be using the fopen wrappers to interpret your ssh2.sftp:// uri, that should help.
I have to connect to a server via ssh, but to access it I need to first connect to another ssh server. I use standard password access to them.
So my steps are:
ssh root#serverdomain1.com
then when connected in serverdomain1 I do in terminal:
ssh myuseraccount#serverdomain2.com
in php, I tried to use ssh2_exec('ssh serverdomain2.com'); but no results. Then I tried also ss2_tunnel($connection, ...). but nothing worked.
This doesn't work:
$ssh = ssh2_connect('serverdomain1.com', 22);
if (ssh2_auth_password($ssh, $user,$pass)) {
$stream = ssh_exec($ssh, "ssh serverdomain2.com");
stream_set_blocking($stream, true);
$stream_out = ssh2_fetch_stream($stream, SSH2_STREAM_STDIO);
echo stream_get_contents($stream_out); // <== doesn't work!!!
}
This also doesn't work:
$ssh = ssh2_connect('serverdomain1.com', 22);
if (ssh2_auth_password($ssh, $user,$pass)) {
$tunnel = ssh2_tunnel($ssh, 'serverdomain2.com', 22);
if (!$tunnel) {
echo('no tunnel<br/>');
}
else {
fwrite($tunnel, "echo 1\n");
while (!feof($tunnel)) {
echo fgets($tunnel, 128);
}
}
}
The echo result for tunnel:
"SSH-2.0-OpenSSH_6.6.1p1 Ubuntu-2ubuntu2.4 Protocol mismatch."
How can I do that with SSH2 from PHP?
I recently published a project that allows PHP to obtain and interact with a real Bash shell, through SSH if needed. Get it here: https://github.com/merlinthemagic/MTS
The project lets you keep bouncing from server to server using ssh.
After downloading you would simply use the following code:
//first you get a shell on the first server:
$shellObj = \MTS\Factories::getDevices()->getRemoteHost('ip_address1')->setConnectionDetail('username1', 'password1')->getShell();
//then build on that first shell, the following way.
\MTS\Factories::getDevices()->getRemoteHost('ip_address2')->setConnectionDetail('username2', 'password2')->getShell($shellObj);
//any command executed on the shell will run only on the second host you connected to.
$return1 = $shellObj->exeCmd("hostname");
echo $return1;//hostname of the second host you connected to
//
Make sure that RSSH, PECL, SSH2 libraries installed on your server
You can check this using phpinfo
Here is my working code to access the server using ssh2. Hope it will help!
<?php
$host = 'SERVER_HOST_ADDR';
$port = SERVER_PORT;
$username = 'SERVER_USERNAME';
$password = 'SERVER_PASSWORD';
$remoteDir = './home/'; //DIR_PATH
$localDir = '/var/www/html/'; //LOCAL_DIR_PATH
// Make our connection
$connection = ssh2_connect($host);
// Authenticate
if (!ssh2_auth_password($connection, $username, $password)) {
throw new Exception('Unable to connect.');
}
// Create our SFTP resource
if (!$sftp = ssh2_sftp($connection)) {
throw new Exception('Unable to create SFTP connection.');
}
/**
* Now that we have our SFTP resource, we can open a directory resource
* to get us a list of files. Here we will use the $sftp resource in
* our address string as I previously mentioned since our ssh2://
* protocol allows it.
*/
$files = array();
$dirHandle = opendir("ssh2.sftp://$sftp/$remoteDir");
// Properly scan through the directory for files, ignoring directory indexes (. & ..)
while (false !== ($file = readdir($dirHandle))) {
if ($file != '.' && $file != '..') {
$files[] = $file;
}
}
echo "<pre>";print_r($files);
?>
I want to download file from SFTP so i created page which looks like it.
<?php
$username = "XYZ";
$password = "ABC";
$url ='FTP.abc.COM';
// Make our connection
$connection = ssh2_connect($url);
// Authenticate
if (!ssh2_auth_password($connection, $username, $password)) throw new Exception('Unable to connect.');
// Create our SFTP resource
if (!$sftp = ssh2_sftp($connection)) throw new Exception('Unable to create SFTP connection.');
$localDir = '/path/to/your/local/dir';
$remoteDir = '/path/to/your/remote/dir';
// download all the files
$files = scandir('ssh2.sftp://' . $sftp . $remoteDir);
if (!empty($files))
{
foreach ($files as $file) {
if ($file != '.' && $file != '..')
{
ssh2_scp_recv($connection, "$remoteDir/$file", "$localDir/$file");
}
}
}
?>
When i will call this page from browser. It will show error look like it.
Fatal error: Call to undefined function ssh2_connect() in page.php on line 6
if this method is correct then what should i edit in this page?
and if there is another method then suggest me that method. Thanks in advance.
You'll probably have better success with phpseclib, a pure PHP SFTP implementation. eg.
<?php
include('Net/SFTP.php');
$sftp = new Net_SFTP('www.domain.tld');
if (!$sftp->login('username', 'password')) {
exit('Login Failed');
}
// outputs the contents of filename.remote to the screen
echo $sftp->get('filename.remote');
// copies filename.remote to filename.local from the SFTP server
$sftp->get('filename.remote', 'filename.local');
?>
It has a number of advantages over libssh2:
http://phpseclib.sourceforge.net/ssh/compare.html
SSH2 functions are not standard functions in PHP. You have to install them first. See http://php.net/manual/en/ref.ssh2.php for more details.
I have CSVs that I want to upload to the 'incoming' folder in the SFTP server. I am using phpseclib to do this. The connection is already there but it does not output anything.
I'm not sure if what I did was correct since I haven't dealt with SFTP before. Here's what my code looks like:
$file = "leads.csv";
$server = "41.160.150.200";
//$server = "ft.bayport.co.za";
$port = "22";
$username = "";
$password = "";
//username and password removed for security reasons
set_include_path(get_include_path() . PATH_SEPARATOR . 'phpseclib');
include 'Net/SFTP.php';
define('NET_SFTP_LOGGING', NET_SFTP_LOG_COMPLEX); // or NET_SFTP_LOG_SIMPLE
$sftp = new Net_SFTP($server);
// Check SFTP Connection
if (!$sftp->login($username, $password)) {
echo 'Login Failed.';
echo $sftp->getSFTPLog();
}else{
echo 'Connected to SFTP.';
echo $sftp->pwd();
// Upload CSVs to SFTP incoming folder
echo $upload = $sftp->put("incoming/".$file, "./bayport/".$file, NET_SFTP_LOCAL_FILE);
}
I would really appreciate any help. Thanks!
Now I know what's the problem with the script.
The remote directory URL was wrong. "incoming/" should be "/incoming/"
I have a little problem with this pice of code. The script connects, but it wont give me the folders that are located in root ... i am missing something?
$ftp_server = "ftp.something.com";
$ftp_user = "user";
$ftp_pass = "pass";
// set up a connection or die
$conn_id = ftp_connect($ftp_server) or die("Couldn't connect to $ftp_server");
// try to login
if (#ftp_login($conn_id, $ftp_user, $ftp_pass))
{
echo "Connected as $ftp_user#$ftp_server\n";
}
else
{
echo "Couldn't connect as $ftp_user#$ftp_server\n";
}
$contents = ftp_nlist($conn_id, ".");
var_dump($contents);
ftp_close($conn_id);
die;
It outputs
Connected as $ftp_user#$ftp_server;
and
boolean false
Why it won't list the files?
i could solve this very fast with
file_exists("ftp//user:pass#host.com")
... but the easy part is not what im looking for, i would not learn anything
ftp_nlist() returns false when an error occurs. I'm guessing you need to use passive transfer:
// after ftp_login(...)
ftp_pasv($conn_id, true);
Generell, I'd recommend troubleshooting this by using a a CLI tool like ftp or a GUI-client like Filezilla. The log/output is very, very helpful.
HTH
Don't be panic. Its easy to solve. After ftp_login() just use the code given in the below.
ftp_set_option($ftp_conn, FTP_USEPASVADDRESS, false); // set ftp option
ftp_pasv($ftp_conn, true); //make connection to passive mode
This code solved my problem.
I would also just suggest confirming who and where you are to make sure that permissions and the actual results you expect are true (a little sanity check once in a while is healthy).
echo shell_exec('whoami')." is who i am </br>";
and after you connect as user then
echo "Current directory is now: " . ftp_pwd($conn_id) . "</br>";
if you can do these things from command line as this user and list contents of the directory then you should be well on your way.
For me, adding the following above your connection works:
putenv('TMPDIR=/tmp/');