"Connection refused" error on socket_connect in php - php

I am trying to convert some code from perl to php.
Perl code looks like below:
my $handle = Connect($port, $host);
and I am trying to use socket to do the same thing in php.
I have tried socket_create and socket_connect,
socket_create and socket_bind, and fsocketopen.
As a result, I'm stuck with error messages saying "Connection refused" or "permission denied":
socket_connect() [function.socket-connect]: unable to connect [111]: Connection refused in
I am not sure if this is the problem I need to solve, or the problem of permission because the code in perl works fine (I did not write that code).
my php code looks like below:
$socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
if(!$socket){
die('Error: socket_create()');
}
if(!socket_connect($socket,$host,$port)) {
die('Error: socket_connect()');
}
I'm not the one who manages the server, so I will need to ask someone else for the access if it is a permission issue. What should I ask for specifically?
Or should I use some other function to connect to the server? I am new to perl, so I am not sure if socket_connect is the equivalent function to use or not.
Thanks.

If your perl code is able to establish the connection, no additional permissions should be needed to do the same in php. Connection refused means the remote host doesn't let you in (you probably connect to wrong address/port). Permission denied is more surprising, a lot of people have this kind of problem while running httpd scripts with SELinux enabled. If you're one of them, refer to the SELinux manpage:
SELinux policy can be setup such that httpd scripts are not allowed to connect out to the network. This would prevent a hacker from breaking into you httpd server and attacking other machines. If you need scripts to be able to connect you can set the httpd_can_network_connect boolean on:
setsebool -P httpd_can_network_connect 1
I have a few concers to your examples though. Connect from your Perl snippet doesn't seem to be the standard socket connect; I don't know which module it belongs to, but are you sure there is no magic behind the call? As socket_connect takes address in dotted-quad notation (for IPv4), make sure you're not passing a hostname (you would need to make a DNS lookup first). At the very end check if it's really a TCP socket you need, not UDP.

Related

How to create a tunnel to a remote AWS database after being connected in ssh to the Bastion host, all using in PHP

I am trying to create a tunnel using ssh2_tunnel() to a remote AWS database, after being connected in ssh to the bastion host, via php, that has access to this remote MySql db.
Here is my actual code :
<?php
$ssh = ssh2_connect('domainofbastionhost', 22);
if (ssh2_auth_password($ssh,'myuserofthebastion','mypassofthebastion'){
$tunnel = ssh2_tunnel($ssh,'xxxx.xxx.xxx.rds.amazonaws.com',3306);
$stream_set_blocking($tunnel,true);
//Everything works fine up to here
$db = new PDO('mysql:host=xxxx.xxx.xxx.rds.amazonaws.com;port=3306;dbname=myawsdbname','myusertoaccessmyawsdb','mypasstoaccessmyawsdb');
}
?>
Due to this $db line, I get on my localhost page "Uncaught PDOException: SQLSTATE[HY000] [2002] Connection timed out ....".
I have tried to connect to the db from the bastion host (by ssh) through my shell, everything works fine, I am greeted by the "Trying 'IPOFTHEAWSDB'... Connected to 'canonical domain name of the db'. Escape character is '^]'. ] 5.5.5-xx.x.xx-MariaDB-xxxxxxmysql_native_password", which means everything works fine. I even tried to connect directly to the aws db, and I get disconnected, which means that my bastion host is clearly whitelisted to access the db.
I think the problem is that when I want to create my new PDO object, I am not whitelisted to access the resource, which means I have to use that $tunnel variable somewhere. I have seen a few examples online of some users using, instead of my $db line :
$db = new PDO('mysql:unix_socket=/var/run/mysqld/mysqld.sock;dbname=myawsdbname,'myusertoaccessmyawsdb','mypasstoaccessmyawsdb');
But this is not working, as I don't have access to this mysql.sock resource as it should be on the bastion host. It's using my own mysqld.sock from my local machine. But where is the $tunnel stream really stored ? I am not sure.
I am quite confused as if it is possible to do so, and if so, how.
If you know anything or find anything, please tell me, it would mean a lot.
ssh2_tunnel() returns a raw socket resource, which is not going to be usable by any MySQL client libraries. It does not create a tunnel like the ssh CLI binary does. Also Unix sockets and TCP are very different beasts, so I would suggest not trying to follow that thread any further.
I would suggest not attempting to establish the tunnel in the context of a PHP script at all, as every request will open another connection and tunnel, potentially creating a lot of overhead on the bastion's SSH server.
To create an SSH tunnel on the command line:
ssh -N -L 3306:your.rds.instance:3306 your_user#bastion.host
Now you should be able to connect via 127.0.0.1:3306 in your PHP script.
To close the connection/turn off the tunnel issue ssh -O exit your_user#bastion.host.
However, I would not suggest using SSH tunnels for anything intended to be unattended. This is because I have found SSH tunnels to be finnicky, and they do not re-establish themselves after an interruption unless you're using a wrapper script, which is another layer of kludge. So I would suggest this approach for local dev/remote access only.
For a persistent connection that you might want to use to connect services/websites over, I would suggest some form of VPN depending on your particular requirements. I believe you can also apply security groups to your RDS instances to simply whitelist connections from certain public IP addresses/networks, but use with caution.

PHP cant connect to memcached server [duplicate]

I m running centos 6. Using apache for handling php and nginx to handle scripts images and css
i have installed memcached server.
PORT="11211"
USER="memcached"
MAXCONN="4096"
CACHESIZE="512"
OPTIONS="-l 127.0.0.1"
i have also installed the module for php.
i created a new php file
$memcache = new Memcache;
$memcache->connect('127.0.0.1', 11211) or die ("Could not connect");
i checked the memcached status and it is running.
I am always getting "Could not connect".
I tried to change the value to 'localhost' from '127.0.0.1' - still not working.
$memcache = new Memcache();
$memcache->addServer('127.0.0.1', 11211) or die ("Could not connect");
var_dump($memcache->getExtendedStats());
$memcache->set('key', 'hello world', false, 60);
echo $memcache->get('key');
//$memcache->connect('127.0.0.1', 11211) or die ("Could not connect");
Output
array(1) { ["127.0.0.1:11211"]=> bool(false) }
What does connect and addServer do differently? Which is best way to do?
But i am not getting the Hello World
More updates on the code and on this problem..
phpinfo is showing memcached.
var_dump($memcache->get('key')); gives
bool(false)
why should i use addServer instead of connect?
More update on the code
$memcache = new Memcache;
$memcache->addServer('localhost', 11211);
echo $memcache->getServerStatus('localhost', 11211);
output : 1
//$memcache->set('key', 'hello world') or die("failed to store data");
output : failed to store data
few more details
getsebool httpd_can_network_memcache
it returns off
Should it return on?
Notice: Memcache::connect(): Server 127.0.0.1 (tcp 11211, udp 0) failed with: Permission denied (13)
As flushed out in the comments, it appears you are running Security-Enhanced Linux (SELinux) which adds an extra layer of security at the kernel level. In my experience and usage, I found that SELinux adds a force field around certain services so that they cannot access particular assets on the system. For example, if I want to serve html content from /home/src/web, I have to tell the system that it is ok for the httpd service to access content in the /home/src/web path. To do this I would issue the following command:
$ -> setsebool -P httpd_enable_homedirs 1
Basically, to allow cross-communication between services, you have to allow such access via a policy, much like "pinholing" a firewall to allow access to a specific port, except with SELinux you are not granting access to a port, rather you are granting access to another part of the system, or service. Fortunately for us, there are several built in policies which we can use the above setsebool construct, rather than trying to define our own policies, which can be a pain. For a more complete explanation of SELinux check out the wikipedia page.
Now to answer your specific questions:
why should i use addServer instead of connect?
addserver() will allow you to add multiple ips (or hostnames) to a list from which it is assumed that cached values are present, i.e. a pool of memcache servers. Whereas the connect() will only allow you to connect to the single, specified server.
getsebool httpd_can_network_memcache, it returns off, Should it return on?
Yes, it appears that turning on this specific setting will allow you to connect to a memcache server, with SELinux enabled, however on my production servers I still have it set to off, but have the following set:
$ -> setsebool -P httpd_can_network_connect 1
I believe, that either setting will accomplish the objective, however with the above setting, if you have a memcache server on another host, httpd can still access it.
Here is a decent write-up on pinholing SELinux to allow httpd service access to other services.

PHP Client can't connect to RabbitMQ server on localhost

OS: CentOS 6.4
I am trying to connect to the RabitMQ server using the php client as follows,
$connection = new AMQPConnection('10.1.150.109', 5672, 'guest', 'guest');
$channel = $connection->channel();
But when I ran the script from the browser, it gives me this,
exception 'PhpAmqpLib\Exception\AMQPRuntimeException' with message 'Error Connecting to server(13): Permission denied ' in /var/www/html/event/vendor/videlalvaro/php-amqplib/PhpAmqpLib/Wire/IO/StreamIO.php:27
netstat show this,
tcp 0 0 :::5672 :::* LISTEN 10776/beam
In this post, this guy gives the answer implicitly, Client can't connect to RabbitMQ server on localhost. But he has not described the procedure which he followed to fix the issue.
I thank you in advanced for anyone who can help me in this regard.
Since I don't like the accepted answer, here's one I think is better.
Disabling SELinux is a hack. It may work but it's probably not a good idea. What isn't immediately obvious from the question (or the other question it references) is HOW the php client is being run. I.e. from the command line or via a browser.
SELinux by default won't allow httpd (i.e. apache) to connect to port 5672.
In my case, running the php script from the command line works - the connection is accepted. However, running it from a browser fails because of this SELinux policy.
I imagine that "reconfiguring the listen address from 0.0.0.0 to 127.0.0.1" is a reference to the hostname parameter, which in my case is set to "localhost" rather than an explicit IP address. (For sure 0.0.0.0 is going to fail!)
You can enable httpd to access port 5672 in SELinux: https://serverfault.com/questions/563872/selinux-allow-httpd-to-connect-to-a-specific-port
what happens if you
telnet 10.1.150.109 5672

socket_bind() unable to bind address

I'm trying to create a Web Socket Server for a small project I am working on.
I have set up the server (located at home) and have port forwarded 80 and 22. I read this tutorial: here
And whenever I ssh into my server to run "startDarmon.php" I get the following error:
PHP Warning: socket_bind(): unable to bind address [98]: Address already in use in
/var/www/server/socket.class.php on line 48
2013-02-23 14:15:38 System: Socket bound to localhost:8000.
2013-02-23 14:15:38 System: Start listening on Socket
This is what i think is preventing my client from connecting to the server. So in the startDarmon.php file I have:
$WebSocket = new socketWebSocket('MY_IP_NOT_LAN_IP',8000);
And inside my client file, I have:
var host = "ws://MY_IP_NOT_LAN:8000/server/startDaemon.php";
Does anyone have any suggestions to why this is not allowing me to establish a connection?
I'm guessing the issue is on the Linux server.
Run the netstat -a -p -n command under root (e.g. with sudo) to understand which process is using that port. Then perhaps do a setsockopt(2) with SO_REUSEADDR
(see socket(7) for more).
The TCP protocol has some specified delays in minutes (eg keepalive, etc etc...). See e.g. tcp(7)
I do suggest reading a good book on Linux system programming like Advanced Linux Programming and perhaps some material on network programming.
You can reuse an address using the setting below:
if ( ! socket_set_option($sock, SOL_SOCKET, SO_REUSEADDR, 1))
{
echo socket_strerror(socket_last_error($sock));
exit;
}
Another application is already using the port that you are trying to use.You can run
lsof -i:port_no
to make the port free.

Connection to secure FTP Server from PHP

This question is in line with this question, I am trying to connect to secure FTP Server and it is not able to connect, wierd part is that I am able to do ssh and connect to the server but when I try to do it from php code using few different approaches but it is not working
Approaches:
FTP Wrappers
ftp_connect & ftp_login
ftp_ssl_connect
ssh2_sftp
ssh2-scp-send & ssh2-scp-receive -- Have not tried this approach yet but recommended in comments portion and so would work on this and will post updates later.
Code for Approach 1:
$ftp_server = "ftp://username:password#192.168.1.1:21/{$log_file_name}";
$opts = array('ftp' => array('overwrite' => TRUE));
$context = stream_context_create($opts);
$put_file = file_put_contents($ftp_server, $response, LOCK_EX,$context);
Here also am not able to connect to secure FTP Server, any suggestions as to why it is not able to connect ?
Code for Approach 2:
ftp_server = 'www.server.com';
$conn_id = ftp_connect($ftp_server) or die ("Cannot connect to host");
//Program dies out here and give error message "Cannot connect to host",
//but why ftp_login does not work here, Any Suggestions ?
$ftp_user_name = "login";
$ftp_user_pass = "password";
// login with username and password
$login_result = ftp_login($conn_id, $ftp_user_name, $ftp_user_pass);
// check connection and login result
if ((!$conn_id) || (!$login_result))
{ echo "FTP connection has encountered an error!";
echo "Attempted to connect to $ftp_server for user $ftp_user_name....";
//exit;
} else
{
echo "Connected to $ftp_server, for user $ftp_user_name".".....";
}
Code for Approach 3:
Here am using same code as approach 1 but instead of ftp_connect, am using ftp_ssl_connect
Code for Approach 4:
$connection = ssh2_connect('www.server.com', 22);
ssh2_auth_password($connection, 'login', 'password');
$sftp = ssh2_sftp($connection);
//exit();
$stream = fopen("ssh2.sftp://$sftp/path/to/file", 'r');
Can anyone advise why am I not able to connect to secure FTP Server using above approaches but still am able to do so using ssh ?
Are there any other approaches to connect to secure FTP Server using php ?
UPDATE:
Q1. I tried again using ftp_connect but it just died out and why does it dies out, what are the scenarios in which ftp_connect dies out ?
Q2. Do we have only this approaches to connect to the server or are there any other which we can implement ?
Q3. Is this php language related that it does not support secure FTP Connection ? OR there is any other way of doing this using php, if yes than do provide different approaches as it would be very helpful.
UPDATE 1:
I was trying to google more on the issue and it seems that if ftp_connect does not work than firewall could be one of the reason for it. I am not totally sure if that is the case but I am researching more on it and post an update in here if I find anything useful.
Possible Solution :
Problem
If I remove the "or die" then you get the error:
When running from a webpage:
Warning: ftp_login() expects parameter 1 to be resource, boolean given in /var/www/ftp_test.php on line 28
var_dump($conn_id); returns bool(false).
From command line /usr/bin/php /var/www/ftp_test.php
var_dump($conn_id); returns resource(4) of type (FTP Buffer).
Script completes.
Solution 1
This could be one solution :
Try to turn off selinux and here is the way or Search : How to disable selinux for turning it off temporarily or permanently.
Solution 2
If you don't want to turn off selinux completely, you might get what you need by just setting the httpd_can_network_connect using the setsebool command.
Verify that it was previously set to "off":
getsebool httpd_can_network_connect
Set it to "on":
setsebool httpd_can_network_connect=1
Turn selinux back on:
setenforce 1
Check to be sure php ftp_connect still works when running under httpd.
Set the policy (-P) to "on" so it persists over a reboot:
setsebool -P httpd_can_network_connect=1
Solution 3
There could also be issue with company firewall. Make sure it is configured properly and has access rights set properly.
Solution 4
Another approach is to use cURL : libcurl as it can be used to connect and communicate to many different types of servers with many different types of protocols
Solution 5
There is open source project called PHP Secure Communication Library (phpspeclib) which can be also used to establish secure connection to FTP Server.
Many cheap webhoster will not give you ssh (hence no ftp via ssh aka
sftp) but only ssl-secured ftp aka ftps (see here). You might
have that problem. As others suggested, use filezilla or
another ftp client to test your credits and chosen security method
beforehand.
ftp_ssl_connect() at least under windows will be a long journey,
since you have to compile your own php binaries, see here.
As this php contributor rightfully points out, no secure
connection is secure, as long as you don't know, who you are talking
too, aka „peer certification“ through valid certificates.
phpseclib is probably your best bet. But I haven't figure out, how to
ensure, it uses peer verification (guessing, the truth is in
openssl.conf ...)
So even at the time of writing, I wonder more than ever, if
peer-validated ftps (ftp with ssl/tls authentification) is possible... also see my question here.
As for ´ftp via ssh´ alias ´sftp´: No direct advice, but note, that many cheap 'non-dedicated server' webhosts do not support it (which is bad). Company firewalls might block the relevant ports.
As for 'ftp using ssl/tls' alias 'ftps': Your answer is here. Don't waste time on ftp_ssl_connect() :-)
(Yes, it's poorly documented on the php site, to say the least)
This page has what you seek (I think)
http://kevin.vanzonneveld.net/techblog/article/make_ssh_connections_with_php/
and here are the manual pages
http://php.net/manual/en/book.ssh2.php
I, too, encountered quite a lot of issues when dealing with encrypted connections.
First thing is to check the protocol you are looking to use. Secure FTP is most commonly refearing to FTP over SHH but can also mean SCP, SFTP or FTPS.
One way to figure out is to check connecting using a client like filezilla.
If the protocol is handled via a PHP module, the best approach is indeed, to use it. In this case, you need to make sure that, in addition to the protocol-related one, the OPENSSL module is installed for php.
There are some cases where the module support still won't work. In this case, using the libcurl module is one option. This is the case for instance when you need to use a client certificate.
Unfortunately, here again, you may encounter some problems due to the partial support of libcurl in the php module. One scenario I experimented is when the server certificate is judged invalid by the module.
The last solution I usually use is to run the curl binary from an exec statement, for the later case using the "-k" switch.
I tried the phpseclib library and it works in Windows and Linux.
If you are using composer, just add in your require section :
"phpseclib/phpseclib": "0.3.*#dev"
And then, you can do this : http://phpseclib.sourceforge.net/sftp/examples.html#put

Categories