How to connect a PHP app to MySQL via pipes? - php

I have found glimpses of the fact that it is possible to connect PHP to MySQL via pipes in their documentation of MySQLi, but I cannot, for the life of me, find anyone explaining what is needed.
The host parameter claims:
When possible, pipes will be used instead of the TCP/IP protocol.
But when is it "possible"? I have my own machine, and I definitely have the necessary privileges to achieve this, I just don't know how. Connecting to the host localhost reports "Localhost via UNIX socket" when examining the host_info.
Trying to follow one (downvoted) comment from that page, and connecting to host ., with socket parameter set to mysql, causes a 2002 connection error.
How do I tell it to (always) connect via a pipe instead?

Today I had the same issue and it required much time to solve this on Windows.
I can establish a named pipe connection with the following code:
$connection = new mysqli('.', 'user', 'pass', 'database', null, '\\\\.\\pipe\\name_of_pipe');
The server, where I want to connect to, has the following configuration:
[mysqld]
skip-networking
enable-named-pipe
socket=name_of_pipe
Using '127.0.0.1', 'localhost' or NULL as hostname doesn't work. Also you must specify a path to the named pipe and not just the name of the pipe.
Unfortunately the PHP documentation is a little bit weak here...

Named Pipes only work under Windows.
Also
Whenever you specify "localhost" or "localhost:port" as server, the MySQL client library will override this and try to connect to a local socket (named pipe on Windows). If you want to use TCP/IP, use "127.0.0.1" instead of "localhost". If the MySQL client library tries to connect to the wrong local socket, you should set the correct path as in your PHP configuration and leave the server field blank.
It is not mentioned in the actual PHP documentation, but it should be still valid.

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.

Error connecting a remote server from a PHP page

I have a .php file which should receive and show data from a remote database. I run my program from PHPStorm (which is connected to the remote database through the "Database" right-hand pane) and a browser. Both ways I get an error which depends on the number of arguments I pass to pg_connect() function.
If I use
$dbconn = pg_connect("host=pg hostaddr=server.address.ru port=5432 dbname=studs user=... password=...")
than the error is
Unable to connect to PostgreSQL server: could not parse network address "server.address.ru": Unknown host in...
But I am sure that I wrote the address correctly (there are no typos in it). This way I am not sure about the correctness of the format of the passed arguments.
If I use
$dbconn = pg_connect("host=server.address.ru dbname=studs user=... password=...")
command, the error is
pg_connect(): Unable to connect to PostgreSQL server: could not connect to server: Connection timed out
I found a lot of information about this errors, but it mostly refers to localhosts and doesn't solve my problem. I guess, the problem can be in the way this connection is set in the function, but I do not know why it doesn't work properly. How can I solve it?
Thanks to #TangentiallyPerpendicular, I got on a right way of setting the connection. But since I have PostgreSQL remote connection, it wasn't just up to this answer.
What I did and how I set the connection (I work from PHPStorm so all the actions are based on this platform):
Open PuTTY and set an SSH connection (an SSH tunnel) between the server's DB port (for PostgreSQL it's usually 5432) and your local computer's PostgreSQL port (5432 most often too). You can do the same from a command line.
Open PHPStorm and in "Database" section (an icon on the right-hand side of the environment or "Data Sources and Drivers" in Settings) set general information ("General" section) and set another SSH tunnel ("SSH/SSL"). In SSH Configurations (the same "SSH/SSL" section) set a local port - it will be important in our connection! Let's say, this port is 20000. The port of the server you're connecting to is a usual one (usually 22 or 2222).
In the program the right use of function is $dbconn = pg_connect("host=localhost port=20000 dbname=studs user=... password=...") or die('Error: ' . pg_last_error());
The connection is set.
For those who has troubles setting an SSH tunnel with a remote PostgreSQL from PHP this can be useful too.

Connect PHP/phpMyAdmin to MySQL/MariaDB via named-pipe when skip-networking is enabled on Windows

Apache 2.4, PHP and MySQL or MariaDB Server are all running under Windows 10. phpMyAdmin is used in this environment.
my.ini has the configuration options skip-networking and enable-named-pipe set. So there is no way to connect via network.
HeidiSQL is connecting well using this configuration using . as hostname.
What options may be used for phpMyAdmin, to make him connect? I tried '.', 'localhost', '' and null. I also tried the options of my related posts.
How is this done using mysql::real_connect in PHP itself (which phpMyAdmin uses)? I think the docu is unclear for the socket parameter.
Related on stackoverflow:
PhpMyAdmin connect protocol PIPE
MySQL: Trying to connect via Named Pipe but getting "open_basedir restriction in effect"
My configuration (edit):
For mysql 80 you need to enter following named pipe for windows
$cfg['Servers'][$i]['socket'] = '\\.\pipe\MySQL80'
you should also check the phpmyadmn manual for connection and the mysql manual for more information on named pipes
To extent the answer:
The MySQL driver will always try to use sockets(linux) or named pipes(windows), when you add localhost as host, only when it can't use Sockets/named pipes, it will try to connect via TCP/IP, so under normal circumstances you don't need the line i wrote, only if you have a different name for the socket/named pipe you need to enter the socket/named pipe at that place.
so if you don't allow TCP/IP communnications for MySQL and the named pipe can't be established the connection would fail.

mysql_connect doesn't work on a certain host

I get this everytime I use mysql_connect() no matter what database I choose:
Warning: mysql_connect() [function.mysql-connect]: Can't connect to MySQL server on 'IP' (111) in filename.php on line 17
A MySQL error has occurred: Can't connect to MySQL server on 'IP' (111)
The exact same file works on my personal website fine. I have tried multiple databases hosted on different servers and it always gives that output.
The database itself is hosted on the same server, but using its full IP in mysql_connect(). Using localhost:port doesn't work either as it says:
Warning: mysql_connect() [function.mysql-connect]: Can't connect to local MySQL server through socket '/var/run/mysqld/mysqld.sock' (2) in filename.php on line 17
A MySQL error has occurred: Can't connect to local MySQL server through socket '/var/run/mysqld/mysqld.sock' (2)
But using the IP should work as it has worked calling it via the same file hosted on other servers.
This is the code:
$connect = mysql_connect($db_url,$db_user,$db_pass); // connects
if ($connect == false) exit("A MySQL error has occurred: " . mysql_error());
Now since the file works on other servers i am guessing it is something to do with the server it is on and might need something changed. I don't personally have root access to the server (just my part of the shared host). Is there anything I can do i php, editing the php.ini file or something I should pass on to someone with root access?
Edit: Ok it turns out that the server doesn't have access to outside databases, so thats why the IP didn't work. Thanks for all your answers but we have decided simply to change hosting provider. We need to be able to access an outside database.
This is on a hosting service? Check their documentation, there will be something that tells you where to find mysql. It isn't necessarily localhost.
For example, on startlogic.com, you use: yourdomain.startlogicmysql.com
Can you connect using mysqladmin using the same host, username and password?
mysqladmin -h $db_url -u $db_user -p $db_pass
Replace $db_xxxx with real values.
If that works from the same host as your php script, then sudo to the apache User and try the same test. One of those must be failing.
EDIT: nevermind on sudo part, I noticed that you don't have root access.
Something else to try: Use '127.0.0.1' instead of 'localhost'. I have had issues before where mysql stupidly assumed it could silently change 'localhost:' to '/var/run/mysqld/mysqld.sock'.
Your wording is not very clear, I hope you are not thinking you can connect to the same mysql server from any old web server just because you know the IP address and port number. If the web host is at all competent, they have probably firewalled mysql so it is only accessible through their own web servers.

How do I access another MySQL Database from another IP Address with PHP?

Ok, If you can answer this question, you deserve the nobel peace prize. Anyways, here's the situation.
I'm using Slicehost dot net, and I have 2 slices (two different IPs). One slice is my mail server and the other is my normal website. I'm running Ubuntu (8.04 or 8.10, something like that, it shouldn't matter). What I'm trying to do is access the MySQL database on the Mail server from the other slice. I'm trying to do that with PHP. I really appreciate any help.
mysql_connect()
$resource = mysql_connect('other-server-address.com', 'username', 'password');
The first parameter is the mysql server address.
Server Param
The MySQL server. It can also include
a port number. e.g. "hostname:port" or
a path to a local socket e.g.
":/path/to/socket" for the localhost.
If the PHP directive
mysql.default_host is undefined
(default), then the default value is
'localhost:3306'. In SQL safe mode,
this parameter is ignored and value
'localhost:3306' is always used.
Unless I'm misunderstanding... this setup is pretty common. Any trouble you're having might be related to the following:
Firewall settings
Grant access to the mysql user to connect from the other host
my.ini settings not allowing outside connections
Some other related SO questions:
Connecting to MySQL from other machines
How do I enable external access to MySQL Server?
php access to remote database
How to make mysql accept connections externally
Remote mysql connection
Assuming your mail server is at IP 192.168.1.20 and web server is 192.168.1.30
First of all you need to allow the web server to access the mysql database on your Mail server .
On 192.168.1.20 you run the mysql command and grant access on the database needed to your web server
mysql> grant all on mydb.* to 'someuser'#'192.168.1.30' identified by 'secretpass;
Your PHP code connects to that database with something like:
$conn = mysql_connect('192.168.1.20', 'someuser', 'secretpass');
mysql_connect() returns a link identifier if the connection is successful. Also you have to do is keep the references to both links.
When you want to use which ever link, simply include the link as an argument.
$link1 = mysql_connect($host1, $username1, $password1);
$link2 = mysql_connect($host2, $username2, $password2);
$r = mysql_query(QUERY, $link1);
Simple as that.

Categories