I’ve got a PHP communications server running using stream_socket_server() and stream_socket_accept(), a fairly complicated thing which uses SSL connections and certificates to be certain that the remote side is authorized to connect to the server. One of the things which is coming up in my logs are the failed connections. I’m trying to provide more details on these connections for security purposes.
I’m currently getting most of my error detail on the failed connections by setting an error handler for the stream_socket_accept() call:
public function on_ssa_error($errno, $errstr)
{
$this->ssa_error .= " ERROR [$errno]: $errstr\n";
}
public function on_select_read()
{
$this->ssa_error = "";
set_error_handler(array($this, "on_ssa_error"));
$rsocket = stream_socket_accept($this->ss, 0);
restore_error_handler();
if ($rsocket !== FALSE)
// Finish setting up the socket connection and start using it
else
// Report the error in $this->ssa_error
}
…when I have a failed connection, I tend to get errors like this:
ERROR [2]: stream_socket_accept(): SSL operation failed with code 1. OpenSSL Error messages: error:14094412:SSL routines:SSL3_READ_BYTES:sslv3 alert bad certificate
ERROR [2]: stream_socket_accept(): Failed to enable crypto
ERROR [2]: stream_socket_accept(): accept failed: Success
…which is partly useful in that it identifies the cause of the bad connection as a bad certificate, but I’d really like to have something indicating where the bad request came from, ideally the IP address or Mac Address of the source.
Is there any way to get the IP address of a failed connection using the stream_socket_xxx code? I know it’s possible to get the IP address of an accepted connection, but I’m stumped trying to figure out a way of getting it on a failed connection.
Related
Once upon a time, there was a normalish error in PHP land:
Warning: ftp_nlist(): data_accept: SSL/TLS handshake failed in [path] on line 29
But here's the catch, "line 29" is not the connection or login, note how it referenced the ftp_nlist() function:
$ftp = ftp_ssl_connect($cred['host'], $cred['port'], 180);
if (!ftp_login($ftp, $cred['user'], $cred['pass'])) {die("Login Failed");}
ftp_pasv($ftp, true);
$files = ftp_nlist($ftp, '');
OpenSSL is compiled and enabled in phpinfo() as suggested here:
ftp_login() : SSL/TLS handshake failed
Other posts I've seen all seem to reference error in the ftp_ssl_connect() or ftp_login() commands which work for me. What can I check when ftp_login() returns true?
Or... are there any logs to get more details on what is wrong?
I'm using php 5.3.29. The code does work properly on my desktop (php 7), but I'm hoping I don't have to upgrade the server to 7 for this to work
12-28-2017 update:
Upgrading to 5.6 resolved, so looks like Martin is on point.
Although this question is quite old, but in case someone else hits this problem:
If your ftp_ssl_connect and ftp_login works fine but functions like ftp_nlist, ftp_put, ftp_fput don't works the problem might be that your FTP server is using port 21 for Connection but different port ranges for data transfer, that explains why you can connect and login but you can't upload or download data, and you need to allow the Out-going connections to those port range in your firewall
The ftp_nlist opens a data connection. That connection needs TLS/SSL handshake too.
As the control connection handshake succeeded, the problem indeed cannot be with an absent TLS/SSL support in PHP. Neither the problem can be with anything like the server and PHP not being able to find a cipher to agree on.
When TLS/SSL handshake on data connection fails after handshake on control connection succeeded, it's quite usually because the client (PHP) did not reuse TLS/SSL session from control connection on the data connection (see Why is session reuse useful in FTPS?). Some servers do require that. PHP supports the reuse only since 5.6.26. See PHP Bug 70195. So make sure you use that version of PHP at least.
Our application is running since years without any glitch and one day we decided to use redis as our caching server for speedy delivery of data. Redis was installed/configured on new server and content were cached basis business requirement. The redis services were used at application end. Post production deployment, page started throwing numerous
warning: php_network_getaddresses: getaddrinfo failed: Name or service not known in /path/of/the/calling/script/file
What would be the reason and resolution ?
During development and testbed, we were using the different server, where I was able to make connection to redis server. But post production failover, I noticed, system was unable to resolve the address. It was unable to connect to caching.example.com
$redisServer = 'caching.example.com';
try {
$redis = new Redis();
$redis->connect($redisServer, 6379);
} catch (Exception $e) {
print_r($e);
}
Doing the root cause analysis, I did the host entry for caching.example.com on production server and it worked.
Basically/Theoretically If you are trying to access a remote URL, then file_get_contents() is your best bet. You can provide a full URL to that function, and it will fetch the content at that location using a normal HTTP request.
If you only want to send an HTTP request and ignore the response, you could use fsockopen() and manually send the HTTP request headers, ignoring any response. It might be easier with cURL though, or just plain old fopen(), which will open the connection but not necessarily read any response.
i used nusoap for calling a webservice like this:
<?php
require 'nusoap/lib/nusoap.php';
$client = new nusoap_client('http://webserviceSite.com/webservices/globalservices.asmx?wsdl', 'WSDL');
$error = $client->getError();
if ($error) {
die("client construction error: {$error}\n");
}
$answer = $client->call('GetCaptchaImage');
$error = $client->getError();
if ($error) {
print_r("res:".$client->response);
print("\n");
print_r("debug:".$client->getDebug());
die();
}
print_r($answer);
?>
but i got this error:
`"wsdl error: HTTP ERROR: Couldn't open socket connection to server http://webserviceSite.com/webservices/globalservices.asmx?wsdl prior to connect(). This is often a problem looking up the host name. "
plz help me.i cant understand this error
This error is exactly what it says: "Couldn't open socket connection to server". Prior SOAP communication client must be able to establish HTTP TCP connection (usually on port 80). This error means that your client is unable to make such connection. It may be caused by many factors: firewall between client and server, server don't like your client, web proxy on the way does not allow you to connect, no routing and so on.
From the box where you run your client you should be able to do:
telnet webserviceSite.com 80
and you should see something like:
Connected to webserviceSite.com.
Escape character is '^]'
Then if you type up few characters and hit enter you should get error page from remote server and connection should close. Unless you can get your client box to connect to remote http host reliably your soap call would fail.
I am using memcache in PHP but I am struggeling how to handle the error it throws at me.
I use the addServer method to add servers but while still in production I sometimes don't have it turned on and the connection obviously can't be established. This is all expected but instead of an exception I get a notice I can't get ride off.
Notice: MemcachePool::set(): Server 192.168.1.2 (tcp 11211, udp 0)
failed with: A connection attempt failed because the connected party
did not properly respond after a period of time, or established
connection failed because connected host has failed to respond.
(10060)
How can I catch/handle this notice/error?
You could either use a custom error handler so you can catch the notice when it happens and handle it appropriately, or check if the connection works after you execute addServer() and handle the failed connection there. For this check out this comment in the docs.
Sometimes my script, that sends push notifications crashes with error:
Warning: stream_socket_client() [function.stream-socket-client]: SSL
operation failed with code 1. OpenSSL Error messages:
error:14094410:SSL routines:SSL3_READ_BYTES:sslv3 alert handshake
failure
And sometimes everything is ok. I think this is not connected with certs or code. Cause I'm sending the same messages to the same devices and use the same algorithm. Any ideas ?
Regarding your question in the title - no, there's no guarantee that notifications will arrive.