php fsockopen - php

I have a simple php script on a server that's using fsockopen to connect to a server.
<?php
$fp = fsockopen("smtp.gmail.com", 25, $errno, $errstr, 30);
if (!$fp) {
echo "$errstr ($errno)<br />\n";
} else {
echo fgets($fp, 1024);
fclose($fp);
}
?>
The problem is the the script times out and fails to connect. If i change the port from 25 to 80 for example it works without problems on any host. So the problem seems to be only the port 25 no matter what host i use, i tried a lot of them and all work for port 80 and others but for 25 fails.
Connections are not blocked form firewall as if i telnet from shell it successfully connects to any port on any host.
Any idea what could be the problem as it's really weird?
LE: If i run the same php script from the shell, php scriptname.php it works so only when i run it by http it fails. I have apache with SuPHP so the problem is around here somewhere

Interesting...
Some firewalls can block specific program's connections to specific ports.
Please check it again, try to stop firewall completely. Also try to stop any anti-spyware.

Like maxnk mentioned firewalling is the most likely issue, either on the server, or by your ISP. Port 25 is frequently firewalled as a method to prevent spam.
Just as a quick test, since you mentioned gmail, you might want to try connecting to port 587 instead. Gmail listens for smpt on this alternate port in addition to port 25 to help users bypass overly restrictive firewalls.

I've run into some strange issues with PHP's socket handling, too. It ended up being a problem with the system it was running on. Have you tried running your code on a different machine?

I think the connection problem is with your machine. I just copied your code into a script on my machine(linux suse) and ran it with php -f test_script. I got the following message
220 mx.google.com ESMTP j8sm1814228gvb.0

CentOS can have SELinux enabled which can cause connection weirdness. Have you checked your error logs?

Related

Lost UDP packages with PHP socket_sendto

I have a PHP CMS system, that's sending a UDP package to switch off a device on the local network.
$sock = socket_create(AF_INET, SOCK_DGRAM, SOL_UDP);
if (!$sock) {
echo "COULD NOT CREATE SOCKET";
}
$result = socket_sendto($sock, "Ausgang1AUS", 11, 0, "192.168.20.49", 30303);
socket_close($sock);
if ($result) echo "UDP SENT ".$result." BYTES";
This has been working perfectly on our old (dedicated) linux server.
Now since switching to a new (virtual) linux server, these packages never reach their target.
I get no error in PHP (just my "UDP SENT 11 BYTES", but the packages just do not arrive anywhere in the local network.
It DOES work if I send the UDP to the server itself (using it's own IP).
It DOES work if I run this script on another machine in the local network.
It DOES work if I send UDP via netcat, e.g.
echo "Ausgang1AUS" | nc -u 192.168.20.49 30303. So it shouldn't be a general blocking problem.
Firewall and SELinux are both disabled on the machine.
Does anyone have an idea whats happening? Could it be some PHP setting or some user privilege? Is there any tool I could use to find out whats's happening to the UDP package?
I'm pretty lost at the moment...
Edit:
Seems to have nothing to do with php socket_sendto in the end, but connect to the LENGTH of the data sent. So #stark was right, using echo (thus introducing a newline) changed the length from 11 bytes to 12 bytes, and suddenly packages do arrive.
I posted a new question on SuperUser
Is this virtual Linux server running on a Windows VM? There was a recent Windows update that introduced a bug in hypervisor which is causing UDP packets under 12 bytes to fail checksum validation.
There's a Github issues here where other users are reporting the same issue on WSL2.
https://github.com/microsoft/WSL/issues/8610
You can see there's a workaround posted in that thread that might help in your situation, at least until Microsoft manage to fix the issue:
ethtool -K eth0 tx off

how to use php sockets to write string

So Im trying to get my head wrapped around this....
I open the port
$remip = $_SERVER['SERVER_ADDR']; //Grab my server address
$fp = fsockopen($remip, 80, $errno, $errstr, 10);//Godaddy hosting only 80 and 443 ports work
//fsockopen(ip address , port, IDK, IDK, timeout delay)
so now the ports open or if not maybe some error checking to be sure
if (!$fp) { echo "$errstr ($errno)<br>\n"; exit; } //Not sure what this echos out but its clear how it stops errors
So now that the port is open any ip/client can connect on this port????
Ill assume I can now connect....
So on my client I open a socket to my server ip address port tcp connection.....
The php file includes something like
else {$out = "hello, 80\r\n"; //out specifies the string to be written , bytes to write
fwrite($fp, $out); //$fp is the handle
fclose($fp)}//close the connection
at this point ill assume that my client gets the hello written to it ..
finish up by closing the connection
Im entirely new to this so Im attempting to understand some sample code here...
So how long is this socket open for? If i want to keep this port open do i need to do a cron job to launch this file periodically.
Im 100% sure that I have got something wrong here so please set me straight.
I think you have a misconception of what fsockopen does. In your example your fsockopen does not actually open port 80 (as in opening a server socket), but it opens a client socket that connects to port 80 on the server itself. It actually does open a (client) port which gets a (not completely) random number.
After you connected using fsockopen you can send HTTP commands to the webserver such as GET /index.php
What you need to use is socket_listen() and socket_bind(). There are a few places in the docs that show you how to get PHP listening on a socket: http://www.php.net/manual/en/function.socket-listen.php
I suggest you read and try them out by simply testing then with a unix tool called netcat (nc <ip_address> <port> command normally)

fsockopen issue when opening port to sphinx only in php

I have an issue when connecting php and only php to the sphinx daemon. I have tested the sample sphinx php example test.php and narrowed it down to being a connection problem.
I have the follow piece of code which shows the problem,
<?php
$fp = #fsockopen ( '127.0.0.1', '9312', $errno, $errstr,300 );
if(!$fp) {
echo "$errstr ($errno)";
}
?>
Whenever it runs from command line or browser I get the following error,
Connection refused (111)
I have verified the following,
searchd is indeed running and on port 9312
searchd can be connected to using telnet
searchd can be connected to using test.py in the sphinx api
php can connect to port 80
It is running on a Westhost VPS which seems to be the issue since it works fine on my local test machine. I have existing code which was using Python to run searches against the index without any issues so this one has me well and truly stumped.
Some additional info,
PHP 5.2.5
Sphinx 0.9.9-release
Anyone have any ideas how I could diagnose and fix this issue further?
Maybe you could use cmd: netstat -an
To see what ip:port is Sphinx Server running, then use that ip and port in fsocketopen() function

PHP can't connect to localhost XMPP server on port 5222

I've set up an ejabberd install locally on my Windows box, where I also have Apache, PHP and MySQL. I've also confirmed that it works great using Digsby, and have kicked the tires a bit by creating some users, sending some messages, etc. All good.
However, PHP can't open a stream using stream_socket_client to port 5222. Even at its simplest level:
stream_socket_client("tcp://localhost:5222", $errno, $errstr, 30, STREAM_CLIENT_CONNECT);
Returns a timeout error. However, again, connecting with an IM client to localhost on port 5222 works fine. (Using stream_socket_client to open a simple connection to localhost on port 80 also works.)
Any ideas? I'm stuck!
selinux needs to be off, or allow apache to talk to xmpp
Many servers don't listen on the loopback device by default, or only listen on ::1 or 127.0.0.1 and have localhost pointing to the other. Check by doing:
% netstat -an | grep 5222
and checking the output for a LISTEN line that shows where your server is listening.
Finally, try using the IP address of your box explicitly as the connection hostname.
Sometimes you just need to peek on the line to see exactly what is going on. Windump(tcpdump) is your friend in these cases.

Port checking from php

I'm trying to connect to gmail pop server from a phplist installation and it fails, but i'm not sure whether my webhost opened port 995 or not. They say they have opened it, but i'm in doubt. Is there a way i can check it from a php script? They are running php 5.2.0 on a windows server, though i'm not sure what OS is that. phpinfo() says "Windows NT DEDI514 5.2 build 3790"
You can put code in a php script to open a connection to a specific hostname (or IP address) and port.
If you know the expected response, you should be able to tell if you are getting a connection. If you get something like "Connection refused", then either you are being blocked, or the destination host is not accepting connections on that port.
This example uses IP address 192.0.2.0 and port 995. Replace these with whatever you want to test.
<?php
echo "\nOpening connection\n\n";
$fp = fsockopen("192.0.2.0", 995, $errno, $errstr);
if (!$fp) {
echo "ERROR: $errno - $errstr\n";
} else {
echo fread($fp, 1024);
fclose($fp);
}
?>
You can also send data to the server using
fwrite($fp, "blah blah blah\r\n");
There is more information about fsockopen here.
I think you'll need to ping or traceroute to a machine that will respond on that port.
This article should have much more than you want to know, but there's an example script at the bottom that you can modify to test.
http://www.planet-source-code.com/vb/scripts/ShowCode.asp?lngWId=8&txtCodeId=1786
There are some other scripts here:
http://www.theworldsend.net/
I can't vouch for any of these personally, but they look like what you need.
And, of course, if you can ssh or telnet into your server, you can do all this much more easily using the ping and traceroute commands.
Maybe safe mode is active? This prevents calling services on other servers.
Edit:
All filesystem and stream functions are affected by the safe mode settings!
The open_basedir setting affects fopen()!

Categories