file_get_contents doesn't work with SSH Tunnel - php

I have created an tunnel(SSH) in order to access URL's that are blocked from my local PC. This works really well, I can for example access from the browser this url http://localhost:8888 and I will get the intended content. This URL also works with the REST Client that I'm using for testing. However, if I call it from PHP:
file_get_contents('http://localhost:8888')
I get this error each time: failed to open stream: Connection refused
So my guess is that file_get_contents doesn't work well with SSH tunnels. Is there maybe an alternative function that I could use for this purpose ?

I solved this problem using php-ssh2 package.
Instalation on Ubuntu 16
sudo apt-get install php-ssh2
Usage with user name and password:
$conn = ssh2_connect($ip, 22);
ssh2_auth_password($conn, $user,$pass);
ssh2_scp_recv($conn, '/remote_path', '/local_path');
Usage with id_rsa (after ssh-copy-id)
I recommend use this method because of we probably do not want paste plain password in source code.
$conn = ssh2_connect($ip, 22);
ssh2_auth_pubkey_file($conn, $user,
"/home/{$user}/.ssh/id_rsa.pub",
"/home/{$user}/.ssh/id_rsa", 'secret')
ssh2_scp_recv($conn, '/remote_file', '/local_file');
Additional info
Old name of this package: libssh2-php
Docs:
http://php.net/manual/en/function.ssh2-scp-recv.php
Connected question:
How to SFTP with PHP?
Is there also possibility of use:
file_get_contents("ssh2.sftp://{$user}:{$pass}#{$ip}:22{$remote_path}"))
but I do not know how to use it with id_rsa.pub.

Related

PHP FTP can't connect when containerized

I'm trying to containerize my PHP script.
But for some reason it's unable to connect to my FTP server when it's running in the container.
Running the script locally on my machine runs without any issues.
Dockerfile:
FROM php:8.1-cli
EXPOSE 8080
COPY . /var/www/html/
WORKDIR /var/www/html
ENTRYPOINT php -f serve.php
PHP Script:
$connection = ftp_connect(FTP_HOST, 21, 90);
ftp_pasv($connection, true);
if(ftp_login($connection, FTP_USERNAME, FTP_PASSWORD))
{
$stream = fopen('data://text/plain,','r');
ftp_fput($connection, $filename, $stream);
}
ftp_close($connection);
After 90 seconds it gives the following warning:
ftp_fput(): Connection timed out in /var/www/html/ftp.php on line 16
I tried bashing into the container and installing an FTP client.
It gives me a similar timeout error - I can connect to the host, but running any commands results in a stall.
I also have tried running the container on a VPS to eliminate any local firewall/network issues.
But the issue is the same.
Please let me know if any additional information is needed to solve the issue.
Mind the documentation of PHP's ftp_pasv function (emphasis mine):
Please note that ftp_pasv() can only be called after a successful login or otherwise it will fail.
Also note that you do not check the status return value of your ftp_pasv call, so you won't notice if that call actually succeeds (which is most likely won't). Because of that, your script will attempt to establish an active FTP connection. That won't work in a container (unless started with --network=host), because the container runs in a private network which is NATed by your host machine.
Solution: Login first, enabling passive mode second (and also, always check your error return values; many of the older functions from the PHP standard library do not throw exceptions, but rely on error return values):
if (ftp_login($connection, FTP_USERNAME, FTP_PASSWORD))
{
if (ftp_pasv($connection, true) === false) {
throw new \Exception("could not enable passive mode")
}
$stream = fopen('data://text/plain,','r');
ftp_fput($connection, $filename, $stream);
}

How to get file from SFTP server

I've been working at this for the last 2 days to no avail. I've also searched on StackOverflow for a solution but I couldn't find one that works for me.
I'm trying to pull a .csv file from a SFTP server. I found out you cannot do this with a default installation of PHP. I found 2 solutions.
1) Enable the ssh2_sftp extension in my PHP. I couldn't get this to work. I downloaded the required files, put them in my php/ext folder as directed, and modified the line in php.ini as required. Wouldn't work.
2) Use phpseclib. Couldn't get this to work as you need to use composer with it and composer wont load my php.ini because I have curl enabled?
Are there any other solutions for logging into a sftp server?
Appreciate the help.
Since it sounds like you have root access on the machine you're working with, why not use scp? It's a native php function so long as you have shell_exec enabled, and the user www-data (or whatever you call your httpd user) has shell access.
<?php
$connection = ssh2_connect('your_remote_server', 22); //remote connection
ssh2_auth_password($connection, 'username', 'password'); //authentication
ssh2_scp_recv($connection, '/remoteServer/whatever/yourFile.csv', '/localServer/yourNewFilename.csv'); //remote file -> local file
?>
NOTE
I have used this, but I also store the "username" and "password" in a MySQL database using bcrypt with a minimum cost of 12. More about that Here

PHP SSH2 PECL extension issues

Before I begin, I'm aware of phpseclib and from what I've ready it's the way you should normally go. Unfortunately I'm working on an older script, and I'm trying to avoid the time needed to set up phpseclib, test on local environment, put on production, test on production, refactor my script, etc. I'm hoping someone can help resolve my issue with ssh2.
I've used the following script to ssh a file to a client's server. It has worked fine for years.
<?php
$url = 'their.url.com';
$userName = 'name';
$password = 'pass';
$conn = ssh2_connect($url, 22);
$auth = ssh2_auth_password($conn, $userName, $password);
// Determine whether this is a file path that needs to be opened or not
$localFilePath = 'test123.txt';
$openFile = fopen($localFilePath, "r");
$fileName = 'test.txt';
// Their server path
$remoteFilePath = "/Orders/".$fileName;
if ($auth === true) {
// Transfer file
$sftp = ssh2_sftp($conn);
file_put_contents("ssh2.sftp://".$sftp.$remoteFilePath, $openFile);
}
WHAT HAPPENED:
My client moved his stuff to a different server. It broke the connection, he freaked out, etc., etc. He gave me updated credentials to the new server, and I have confirmed the protocal is SFTP - SSH File Transfer Protocal.
THE ISSUE:
The file transfer is no longer working after updating the ssh combo url/credentials.
WHAT I'VE TRIED:
I tried a test file transfer using Linux (not PHP) and it worked. I also ssh'd in using Filezilla and transferred a file that way, no problem. so I have confirmed that the host/user/pass combo is correct.
I dumped out the result of the file_put_contents, and it is false.
I dumped out $conn, $auth, and $sftp, and what "ssh2.sftp://".$sftp.$remoteFilePath looks like, and the results are (in order)
resource(27) of type (SSH2 Session)
bool(true)
resource(30) of type (SSH2 SFTP)
ssh2.sftp://Resource id #30/Orders/test.txt
Note that test.txt is a very tiny file to rule out file size issues.
I have also uninstalled and reinstalled the ssh2 PECL extension.
I am convinced this is due to an issue on their end, because this script has always worked before, I'm just baffled as to why things are failing now that they're on their new server, and I'm not sure what to do further to diagnose the problem. I can't think of any change that's been made to my server that would affect this.
Any ideas would be greatly appreciated.
Why not just use the ssh2.sftp:// stream directly?
file_put_contents("ssh2.sftp://{$userName}:{$password}#{$url}:22/{$remoteFilePath}", $openFile);
It should work without all the ssh connection, authentication, moving to sftp, etc..

Couchbase PHP Connect Hello World! on Mac

I installed the Couchbase Server and its PHP SDK through brew install libcouchbase on Mac. The server admin console is running/working fine on http://127.0.0.1:8091/. I added a hello.php file with the below code in /Library/WebServer/Documents/hello.php.
<?php
$cb = #new Couchbase("http://127.0.0.1:8091/",'username','password');
if($cb->getResultCode() != COUCHBASE_SUCCESS){
throw Exception('Cannot connect to couchbase!');
} else {
echo "Hello World!";
}
When I go to http://127.0.0.1:8091/hello.php, I get an error saying Not found.. What is the problem?
When I go to http://127.0.0.1:8091/hello.php, I get the below error
Not found.. What is the problem?
You are going to the wrong port. Port 8091 is the Couchbase Server Console interface. It looks like you are trying to deploy your hello.php script using the Apache server shipped with OS X which uses the default http port (80). The script is also located in the wrong folder. I believe /Library/WebServer/Documents/ is for static content only.
Given the problem you have ran into it make me suspect that you are trying to learn too many new things at once. You should try running the script outside of a Apache first and get it working there.
php hello.php
It is also worth pointing out that you are using the older 1.X version of the Couchbase PHP SDK, you will want to use the new 2.X version.
I assume you've anonymized the code above, but be sure in place of where you have 'username' you have the bucket name and similarly for the bucket password or empty string if no password. Also, check the docs as the connect string you're using is not necessarily the preferred..
Note for debugging these kinds of things you can set LCB_LOGLEVEL to a higher level as mentioned in the documentation. The way you set an envvar varies based on how you're deploying PHP, but you can easily just test it at the command line.

file_get_contents - Connection timed out

<?php
$a = file_get_contents('http://www.google.com');
echo $
Why is the browser returning this error?
Warning: file_get_contents(http://www.google.com) [function.file-get-contents]: failed to open stream: Connection timed out in /home/test.php on line 2
Mostly probably your server cannot connect to an external resource, for example, because of firewall restrictions.
file_get_contents does not work well at all with getting remote files and should not be used. It does not deal with slow network connections or redirects, and does not return error codes. You should use curl instead to fetch remote files.
There is an example in the manual for curl_exec: http://us3.php.net/manual/en/function.curl-exec.php
I had the same problem, couldn't download using file_get_contents(), but using curl on the command line for the same URL worked fine. Turned out it tried to connect over IPv6 which failed.
I solved it by disabling IPv6 in my kernel parameters.
It might be server side issue, might be your server cannot communicate with other server remotely. You have to communicate with server administrator.
For some reason file_get_contents() fails intermittently on some websites that support IPv6 (maybe 20% of the time, the command times-out). Although disabling IPv6 resolves the issue, that is not the best solution as more sites move to IPv6.
I wrote a simple PHP gethtml() function that works around the issue using wget. This will automatically use IPv6 when IPv4 is not available. A minor drawback is that it uses an external command, but I think it is preferable to disabling IPv6.
If wget is not already installed on your distribution, you can install it as follows:
sudo apt install wget
PHP Function Example:
$myhtml = gethtml("http://example.com");
//use instead of file_get_contents() due to inconsistent IPv6 performance
function gethtml($url){return shell_exec("wget --prefer-family=IPv4 -qO- ".$url);}

Categories