PHP curl unable to access other servers via VPN - php

I have a server connected to my company via OpenVPN and I am trying to retrieve JSON from another server using PHP's curl command.
Running the most stripped back version of the code in PHP's interactive mode from the command line (php -a), works fine:
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, 'status.int.companyname.com');
curl_exec($ch);
{...expected json response after 2 seconds}
Howver when I run this from within Apache, the script will just hang.
Setting some timeouts and outputting the error
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 10);
curl_setopt($ch, CURLOPT_TIMEOUT, 10);
echo 'Error: '.curl_error($ch);
Gives the error as
Error: Resolving timed out after 10517 milliseconds
Initially I thought this was a DNS-related issue, but changing the URL to use the IP address or specifying the address to resolve to
curl_setopt($ch, CURLOPT_RESOLVE, [ 'status.int.companyname.com:80:10.10.0.5']);
yeilded a connection error:
Error: Connection timed out after 10001 milliseconds
My next thought was that Apache was using the wrong interface. The VPN is the default gateway, so works fine with everything else but I tried forcing it with
curl_setopt($ch, CURLOPT_INTERFACE, '10.33.0.105');
This made no difference. After reading around a few other posts, I tried adding the following in various combinations but it made no difference.
curl_setopt($ch, CURLOPT_DNS_USE_GLOBAL_CACHE, false);
curl_setopt($ch, CURLOPT_DNS_CACHE_TIMEOUT, 2);
curl_setopt($ch, CURLOPT_IPRESOLVE, CURL_IPRESOLVE_V4);
file_get_contents has the same problem
I don't inderstand it. Curl on the command line works and PHP in interactive mode work fine. It just doesn't work when the PHP script is executed via Apache.
Other things I've tried:
starting Apache after the VPN is connected
setting Apache to only bind to IPv4
Resolv.conf contains one nameserver, which is the correct one for the company VPN
The differences between the CLI and Apache versions of php.ini are as expected:
-disable_functions =
+disable_functions = pcntl_alarm,pcntl_fork,pcntl_waitpid,pcntl_wait,pcntl_wifexited,pcntl_wifstopped,pcntl_wifsignaled,pcntl_wifcontinued,pcntl_wexitstatus,pcntl_wtermsig,pcntl_wstopsig,pcntl_signal,pcntl_signal_dispatch,pcntl_get_last_error,pcntl_strerror,pcntl_sigprocmask,pcntl_sigwaitinfo,pcntl_sigtimedwait,pcntl_exec,pcntl_getpriority,pcntl_setpriority,
-expose_php = On
+expose_php = Off
-memory_limit = -1
+memory_limit = 128M
Has anyone seen this before? I've lost a few hours of my day on this now and it's driving me mad!
Thanks

Related

PHP - curl localhost connection refused

Explanation
I made a simple REST api in Java (GET).
Postman works (both localhost and IPv4)
curl from command line works (both localhost and IPv4)
External request from a different city works (IPv4)
Expected
To have PHP curl work on the localhost
Actual
For some reason PHP curl on IPv4 works, but localhost does not work
PHP curl output error
Failed to connect to localhost port 8080: Connection refused
curl error: 7
Code
$url = 'http://localhost:8080/api/user';
$curl = curl_init($url);
echo json_decode(curl_exec($curl));
I have tried (from the top of my head, no specific order)
curl_setopt ($curl, CURLOPT_PORT , 8080);
curl_setopt($curl, CURLOPT_POST, false);
curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, false);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
For those ones who are using Docker, Vargant and so on.
You got Failed to connect to localhost port 8080: Connection refused error, because you are trying to connect to localhost:8080 from inside virtual machine (eq. Docker), this host isn't available inside the Docker container, so you should add a proxy that can reach a port from the out.
To fix this issue add the next line of code after your curl_init():
curl_setopt($ch, CURLOPT_PROXY, $_SERVER['SERVER_ADDR'] . ':' . $_SERVER['SERVER_PORT']);
Here is a full example:
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $APIUrl);
if ($_SERVER['HTTP_HOST'] == 'localhost:8080') {
// Proxy for Docker
curl_setopt($ch, CURLOPT_PROXY, $_SERVER['SERVER_ADDR'] . ':' . $_SERVER['SERVER_PORT']);
}
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$response = curl_exec($ch);
if (curl_errno($ch)) {
$error = curl_error($ch);
}
curl_close($ch);
I'm not sure if this counts as an answer but I just restarted the linux VM and now its working...
Not sure if it's still usefull for you, but I've faced with almost same problem. I've started php server using php -S localhost:5500 or with VS-code extention, and try to connect via curl to same host, and it taken almost infinite time with no response. Solution was simple (if you understand russian, or can use translator you can find full article here).
So, from this article:
This script will not work with the default WPN-XM v0.8.6 setting because there is only one php -C gi process listening in the background, but your example requires (at least) two of them. php -C gi is already in use by the script making the curl request and therefore Nginx cannot redirect it to php -C gi. This means that you will first come across a blank page with a loading indicator and then remove the connection timeout.
The main problem is that php -C gi doesn't automatically spawn new processes (if needed). The issue is discussed here: https://github.com/WPN-XM/WPN-XM/issues/323
So the solution for me was to create another php server with a different port (for example 5500 and 5550) and everything started working.

CURL - Error code: 6 Couldn't resolve host 'http://www.yahoo.com' - XAMPP

Does anyone know what happen on the error as below when calling curl even call yahoo page:
Error code 6 :Couldn't resolve host 'http://www.yahoo.com'; No data of requested type
PHP
$sendurl = "http://www.yahoo.com";
$ch = curl_init($sendurl);
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 60);
$result = curl_exec($ch);
if(!$result){
echo $curl_errno($ch).":".curl_error($ch);
}
This error mean that curl can't resolve host name.
There is problem with DNS server on computer where you run this script.
If you run script on your local computer then check it just open www.yahoo.com in your browser.
If you run script on remote server, then you should login to server by SHH and check ping www.yahoo.com. Or ask your hosting support team about this issue.
I think you're missing options for allowing redirects and https. Check it in your browser -> you will get redirected to https URL.
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
curl_setopt($ch,CURLOPT_SSL_VERIFYPEER, false);

PHP curl call not working when the caller script is called from outside the LAN

So I am encountering a strange situation with a php curl request.
It works perfectly when the script is called from the same local network as the server which is running it but when somebody calls it from outside is not working anymore.
This is my code:
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, ROOT_DIR."directory/someScript.php");
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_TIMEOUT, 1);
$output = curl_exec($ch);
curl_close($ch);
When I run someScript.php manually even from outside the LAN it works just fine. The issue occurs only when it I try to run it by calling it with curl via another php script.
Anybody have any idea? The curl library is enabled. And both scripts are on the same server.
I am using port forwarding on port 80 to make the server visible in the Internet.
I decided to post the solution in case somebody else has the same problem.
In the end I found the cause for this. The problem was that I was calling the script using the external IP instead of the internal one. Further more because of this XAMPP redirected the call to its default page and because I didn't use the output I did not noticed that.

How to resolve cURL Error (7): couldn't connect to host?

I send an item code to a web service in xml format using cUrl(php). I get the correct response in localhost, but when do it server it shows
cURL Error (7): couldn't connect to host
And here's my code:
function xml_post($post_xml, $url)
{
$user_agent = $_SERVER['HTTP_USER_AGENT'];
$ch = curl_init(); // initialize curl handle
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_FAILONERROR, 1);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
curl_setopt($ch, CURLOPT_RETURNTRANSFER,1);
curl_setopt($ch, CURLOPT_TIMEOUT, 50);
curl_setopt($ch, CURLOPT_POSTFIELDS, $post_xml);
curl_setopt($ch, CURLOPT_USERAGENT, $user_agent);
// curl_setopt($ch, CURLOPT_PORT, $port);
$data = curl_exec($ch);
$curl_errno = curl_errno($ch);
$curl_error = curl_error($ch);
if ($curl_errno > 0) {
echo "cURL Error ($curl_errno): $curl_error\n";
} else {
echo "Data received\n";
}
curl_close($ch);
echo $data;
}
I send the item code to the tally and fetch the details from it. I tried using both the versions php 4+ and php5+, nothing works out Any solution.
CURL error code 7 (CURLE_COULDNT_CONNECT)
is very explicit ... it means Failed to connect() to host or proxy.
The following code would work on any system:
$ch = curl_init("http://google.com"); // initialize curl handle
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
$data = curl_exec($ch);
print($data);
If you can not see google page then .. your URL is wrong or you have some firewall or restriction issue.
“CURL ERROR 7 Failed to connect to Permission denied” error is caused, when for any reason curl request is blocked by some firewall or similar thing.
you will face this issue when ever the curl request is not with standard ports.
for example if you do curl to some URL which is on port 1234, you will face this issue where as URL with port 80 will give you results easily.
Most commonly this error has been seen on CentOS and any other OS with ‘SElinux’.
you need to either disable or change ’SElinux’ to permissive
have a look on this one
http://www.akashif.co.uk/php/curl-error-7-failed-to-connect-to-permission-denied
Hope this helps
If you have tried all the ways and failed, try this one command:
setsebool -P httpd_can_network_connect on
In PHP, If your network under proxy. You should set the proxy URL and port
curl_setopt($ch, CURLOPT_PROXY, "http://url.com"); //your proxy url
curl_setopt($ch, CURLOPT_PROXYPORT, "80"); // your proxy port number
This is solves my problem
In my case I had something like cURL Error (7): ... Operation Timed Out. I'm using the network connection of the company I'm working for. I needed to create some environment variables. The next worked for me:
In Linux terminal:
$ export https_proxy=yourProxy:80
$ export http_proxy=yourProxy:80
In windows I created (the same) environment variables in the windows way.
I hope it helps!
Regards!
Are you able to hit that URL by browser or by PHP script? The error shown is that you could not connect. So first confirm that the URL is accessible.
Check if port 80 and 443 are blocked. or enter - IP graph.facebook.com and enter it in etc/hosts file
you can also get this if you are trying to hit the same URL with multiple HTTP request at the same time.Many curl requests wont be able to connect and so return with error
This issue can also be caused by making curl calls to https when it is not configured on the remote device. Calling over http can resolve this problem in these situations, at least until you configure ssl on the remote.
In my case, the problem was caused by the hosting provider I was using blocking http packets addressed to their IP block that originated from within their IP block. Un-frickin-believable!!!
For a couple of days I was totally blocked on this. I'm very very new to networking/vms but was keen to try set it up myself instead of paying a hosting company to do it for me.
Context
I'm rebuilding the server side for an app that uses php routines to return various bits of data from internal sources as well as external APIs for a map based app. I have started an Oracle VM instance and have installed/set up Apache and php. All running totally fine, until one of my php routines tries to execute a cURL. I start implementing error logging to find that I don't even get a message - just '7', despite implementation being very similar to the above. My php routine accessing an internal file for data was running successfully so I was fairly sure it wasn't an Apache or php issue. I also checked my Apache error logs, nothing telling.
Solution
I nearly gave up - there's talk on disabling SELinux above and in other articles, I tried that and it did work for my purposes, but here's a really good article on why you shouldn't disable SELinux https://www.electronicdesign.com/technologies/embedded-revolution/article/21807408/dont-do-it-disabling-selinux
If temporarily disabling it works and like me you don't want to do this (but it confirms that SELinux is blocking you!), I found a neat little command that actually prints out any SELinux issues in a more readable fashion:
sealert -a /var/log/audit/audit.log
This returned the following:
found 1 alerts in /var/log/audit/audit.log
--------------------------------------------------------------------------------
SELinux is preventing php-fpm from name_connect access on the tcp_socket port 443.
Great, I now get a bit more information than just '7'. Reading further down, I can see it actually makes suggestions:
***** Plugin catchall_boolean (24.7 confidence) suggests ******************
If you want to allow httpd to can network connect
Then you must tell SELinux about this by enabling the 'httpd_can_network_connect' boolean.
Do
setsebool -P httpd_can_network_connect 1
This has been mentioned further above but now I have a bit more context and an explanation as to what it does. I run the command, and I'm in business. Furthermore, my SELinux is still set to enforcing, meaning my machine is more secure.
There are many other suggestions logged out, if you're blocked it might be worth logging out/checking out /var/log/audit/audit.log.

How to set a timeout on PHP5 curl calls? Published CURL options do not seem to work

We've written a script that pulls data from an external server. If the server goes down we don't want our server waiting for the data since we process a lot of data and we don't want it bogged down. To address this, we're trying to timeout our curl calls if they take more than a couple hundred milliseconds.
I found some documentation saying that CURLOPT_TIMEOUT_MS and CURLOPT_CONNECTTIMEOUT_MS should be available in my version of php and libcurl, but it does not seem to be timing out, even if I set the timeout to 1ms.
$url = "http://www.cnn.com;
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_HEADER,0); //Change this to a 1 to return headers
curl_setopt($ch, CURLOPT_USERAGENT, $_SERVER['HTTP_USER_AGENT']);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_TIMEOUT_MS, 1);
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT_MS, 1);
$data = curl_exec($ch);
curl_close($ch);
Does anyone know what we're doing wrong or another way to do this?
saw this in unresponsive dns server and curl multi timeouts not working:
"...We have had some times where a
site that we pull information has had
dns server become unresponsive. When
this happens the timeouts set in curl
(php bindings) do not work as
expected. It times out after 1min 14
sec with "Could not resolve host:
www.yahoo.com (Domain name not found)"
To make this happen in test env we
modify /etc/resolv.conf to have a
nameserver that does not exist
(nameserver 1.1.1.1). No mater what
they are set at
(CURLOPT_CONNECTTIMEOUT, CURLOPT_CONNECTTIMEOUT_MS
, CURLOPT_TIMEOUT, CURLOPT_TIMEOUT_MS)
they don't timeout when we cant get
to the DNS server. I use curl_multi
because i we have multiple sources
that we pull info from at the same
time. The example below makes one
call for example simplicity. And as a
side note curl_errno does not return
an error code even though there was an
error. Not sure why..."

Categories