Mysql connection over SSL with PHP mysqli - php

I'm trying to setup PHP mysqli connection to MariaDB database for two VPS servers and need to encrypt the communications due to it being over public network.
Currently I can connect from the client server to database server via commandline mysql client normally and I have checked via tcpdump that the connection is encrypted. However for some reason I can't figure out the PHP part. It's relatively basic nginx + php5-fpm + mariadb setup but mysql is working on non default port.
Debian Jessie, Php5 5.6.7, Mariadb 10.0.16, nginx 1.6.2
Here's the test script:
<?php
$DB_NAME = '';
$DB_HOST = '111.111.111.111';
$DB_USER = 'username';
$DB_PASS = 'password';
$mysqli = mysqli_init();
if (!$mysqli) {
die('mysqli_init failed');
}
//have tried witha and without the following with multiple variations
$mysqli->ssl_set(NULL, NULL, NULL,'/etc/mysql/ssl/',NULL);
if (!$mysqli->real_connect($DB_HOST, $DB_USER, $DB_PASS, $DB_NAME, 11111, NULL,MYSQLI_CLIENT_SSL )) {
die('Connect Error (' . mysqli_connect_errno() . ') '
. mysqli_connect_error());
}
$query = "SHOW STATUS LIKE 'ssl_cipher'";
$result = $mysqli->query($query) or die($mysqli->error.__LINE__);
if($result->num_rows > 0) {
while($row = $result->fetch_assoc()) {
print_r($row);
}
}
else {
echo 'NO RESULTS';
}
mysqli_close($mysqli);
?>
Main error I'm getting without the ssl_set:
2015/07/11 15:58:34 [error] 2857#0: *374 FastCGI sent in stderr: "PHP message: PHP Warning: mysqli::real_connect(): SSL operation failed with code 1. OpenSSL Error messages:
error:14090086:SSL routines:SSL3_GET_SERVER_CERTIFICATE:certificate verify failed in /srv/www/test.php on line 15
PHP message: PHP Warning: mysqli::real_connect(): Cannot connect to MySQL by using SSL in /srv/www/test.php on line 15
PHP message: PHP Warning: mysqli::real_connect(): [2002] (trying to connect via tcp://192.168.130.123:42139) in /srv/www/test.php on line 15
PHP message: PHP Warning: mysqli::real_connect(): (HY000/2002): in /srv/www/test.php on line 15".....
Any ideas would be appreciated. This is really killing me.

Maybe this problem occurs due to the changes made in PHP 5.6. I guess you are using self-signed certificates? If your DB enables peer_name validation by DEFAULT, there is no way to disable this in PHP. So when generating you certificates you have to use the right "Common Name" for each one:
CA: hostname
Server: FQND, e.g. hostname.example.com
Client: somename
The important part is the server certificate where the Common Name has to be the same as the host you are connecting to.

What it looks like is this
SSL3_GET_SERVER_CERTIFICATE:certificate verify failed
My guess is that you don't have the correct CA set up. Some DB systems (like Amazon Web Services RDS) have their own CA file. You're using the capath argument so make sure the PEM files are in that path. If they are, the next thing I would do is switch to the third argument of ssl_set and specify the PEM file directly
$mysqli->ssl_set(NULL, NULL, '/path/to/ca.pem', NULL, NULL);

Related

php script fails to connect to MySQL with SSL

The script below runs on a Centos server and is trying to connect to a MySQL database on another server which requires SSL parameters. The credentials used in the script work fine using and Microsoft Access DSN connection.
<?php
ini_set ('error_reporting', E_ALL);
ini_set ('display_errors', '1');
error_reporting (E_ALL|E_STRICT);
$pdo = new PDO('mysql:host=99.99.199.199;dbname=dummy1', 'user1', 'pwd1',
array(
PDO::MYSQL_ATTR_SSL_KEY =>'/etc/mysql/ssl/ck.pem',
PDO::MYSQL_ATTR_SSL_CERT=>'/etc/mysql/ssl/cc.pem',
PDO::MYSQL_ATTR_SSL_CA =>'/etc/mysql/ssl/c1.pem'
));
$statement = $pdo->query("SHOW TABLES;");
$row = $statement->fetch(PDO::FETCH_ASSOC);
echo htmlentities($row['_message']);
?>
The code above gives SSL operation failed with code 1 - here is the full message:
Fatal error: Uncaught PDOException: PDO::__construct(): SSL operation
failed with code 1. OpenSSL Error messages: error:14090086:SSL
routines:ssl3_get_server_certificate:certificate verify failed in
/var/www/vhosts/zzzzz.org/httpdocs/zzodbc/dgodbc1.php:10
Stack trace: #0 /var/www/vhosts/zzzzz.org/httpdocs/zzodbc/dgodbc1.php(10): PDO->__construct('mysql:host=99.9...', 'odbc_guil...', 'pwd1',
Array) #1 {main} Next PDOException: SQLSTATE[HY000] [2002] in
/var/www/vhosts/zzzzz.org/httpdocs/zzodbc/dgodbc1.php:10 Stack trace:
#0 /var/www/vhosts/zzzzz.org/httpdocs/zzodbc/dgodbc1.php(10): PDO->__construct('mysql:host=99.9...', 'odbc_guil...', 'pwd1',
Array) #1 {main} thrown in
/var/www/vhosts/zzzzz.org/httpdocs/zzodbc/dgodbc1.php on line 10
I have verified that the credentials, including the SSL parameters with a DSN connection. I have checked that the SSL Keys are correctly located in the /etc/mysql/ssl directory.
Any help to suggest what I'm doing wrong would be good. Thanks.
I may have been going at this in the wrong way....
Since these keys work with ODBC then I think I should be using using odbc_connect and sending the same string as I use with MS access such as
$user = "user";
$pass = "pwd";
$connection = "Driver={MySQL ODBC 5.1 Driver};Server=46.51.178.163;Database=db1;sslca=/etc/mysql/ssl/c1.pem;sslkey=/etc/mysql/ssl/ck.pem;sslcapath=/etc/mysql/ssl/;sslcert=/etc/mysql/ssl/cc.pem";
$con = odbc_connect($connection, $user, $pass);
But to get this to work I need to install a MySQL connector on the server which I'm grappling with at the moment.
I have solved this problem -thanks for all who have helped. This is what I have learned:
SSL keys are connection type specific - so I had keys that worked with ODBC and it was wrong to expect them to work with PDO
ODBC drivers ( php extensions ) need to be installed on the server - they aren't automatically present. Here is an excellent video showing how to do this.
You need command line access to the server to install the driver ( and also to upload the SSL keys to a secure location ) - they are in /etc/mysql/ssl.
I installed the driver in /usr/lib/odbc2/lib rather than in the long folder name in the video. I also installed the in the /usr tree because when I tried the locations in the video I got file not found errors. The two driver files are libmyodbc5a.so and libodbc5w.so. Only the ...5w.so file seems to be required.
Once these files are in place then you need to add an entry to odbcinst.ini in the /etc folder. I used nano so the command line nano odbcinst.ini brings up the file which had a model entry for PostgresSQL. If the server is 64 bit then these are the entries I made in odbcinst.ini:
[mysql537]
Driver64 = /usr/lib/odbc2/lib/libmyodbc5w.so
Setup64 = /usr/lib/odbc2/lib/libmyodbc5w.so
UsageCount = 1
You must have the ...64 paths otherwise the driver isn't found ( i.e Driver64 = NOT Driver= ). I made this mistake first off.
Provided the driver files are found at the paths in odbcinst.ini then things should work. (I thought I needed entries in odbc.ini but I now believe you only need something here if you are using a DSN).
the folder odbc2 was one I created inside /etc/lib which already exists. I did that to avoid any permission issues by creating a new folder.
Here is the code that works ( the connection string is exactly the same as the string used in a Microsoft Access connection ):
<?php
ini_set ('error_reporting', E_ALL);
ini_set ('display_errors', '1');
error_reporting (E_ALL|E_STRICT);
$user = "odbcmmm";
$pass = "999999999";
$connection = "Driver={mysql537};Server=99.99.199.199;Database=db_name;UID=odbc_db_name;PWD=password;sslca=/etc/mysql/ssl/c1.pem;sslkey=/etc/mysql/ssl/ck.pem;sslcapath=/etc/mysql/ssl/;sslcert=/etc/mysql/ssl/cc.pem";
$con = odbc_connect($connection, $user, $pass);
$sql="SELECT Id from stk_item";
$rs=odbc_exec($con,$sql);
if (!$rs) {
exit("Error in SQL");
}
I hope this is useful.

Warning: mysqli::__construct(): (HY000/2002): No such file or directory in [duplicate]

This question already has answers here:
Warning: mysql_connect(): [2002] No such file or directory (trying to connect via unix:///tmp/mysql.sock) in
(17 answers)
Closed 2 years ago.
I'm totally stuck having spent a couple of days trying to figure this out...
I have set up an Apache web server (version 2.4.34) on my Mac OS running Mojave (10.14.3) and have installed the current version of MySQL Community Server (8.0.15). Both running perfectly as I can determine (from command line). I have PHP 7.1.23 installed. When I create a .php file with the following code and put it in my Sites directory and then in Safari go to http://localhost/~dave/hello.php I get this error:
"Warning: mysqli::__construct(): (HY000/2002): No such file or
directory in /Users/dave/Sites/hello.php on line 7 Connection failed:
No such file or directory".
Code in hello.php:
<?php
$servername = "localhost";
$username = "dave";
$password = "*****";
//Create connection
$conn = new mysqli($servername, $username, $password);
//Check connection
if ($conn->connect_error) {
die("Connection failed: " . $conn->connect_error);
}
echo "Connected successfully";
?>
I have tried everything I can think of, including those suggestions in the other two similar posts (this one: My database user exists, but I still get an (HY000/2002): No such file or directory and this one: PHP Warning: mysqli::__construct(): (HY000/2002): No such file or directory (Debian GNU/Linux 9)), and I cannot connect to MySQl with php. In particular, I checked with the php info page and the socket for mysqli is given as var/mysql/mysql.sock. In the relevant table in mysql the value for socket is given as /tmp/mysql.sock. I tried changing the php.ini.default file by adding each of these sockets (in place of the empty value) and neither worked (still generates the same error). I thought that the 2002 MySQL socket error might be the problem, so I made a symlink by doing this:
sudo mkdir /var/mysql
sudo ln -s /tmp/mysql.sock /var/mysql/mysql.sock
but all that did was generate a new error:
Warning: mysqli::__construct(): The server requested authentication
method unknown to the client [caching_sha2_password] in
/Users/dave/Sites/hello.php on line 7
Warning: mysqli::__construct(): (HY000/2054): The server requested
authentication method unknown to the client in
/Users/dave/Sites/hello.php on line 7 Connection failed: The server
requested authentication method unknown to the client
So I removed the symlink...and returned to the original error.
I also tried replacing "localhost" with the IP address 127.0.0.1 as well as "localhost:3306" as other question threads have suggested. Nothing worked here either.
Please help, I am new to this kind of use of the computer/web design and I'm out of obvious (googleable/understandable) options.
Use 127.0.0.1 instead of localhost.
I got some help from some local tech guys in my area and it turns out that fixing the socket error was the first step, like I tried to do above. I eventually did it this way, using the solution by noun:
Warning: mysql_connect(): [2002] No such file or directory (trying to connect via unix:///tmp/mysql.sock) in
The second error message was then generated (same one as in my question, here again):
mysqli::__construct(): The server requested authentication method unknown to the client [caching_sha2_password] in /Users/dave/Sites/hello.php on line 7
Warning: mysqli::__construct(): (HY000/2054): The server requested authentication method unknown to the client in /Users/dave/Sites/hello.php on line 7
This was fixed by the SQL-based solution (June 9 2018 answer) to this question:
php mysqli_connect: authentication method unknown to the client [caching_sha2_password]
This SQL statement was simply run in MySQL from the terminal. After restarting the Apache server I reloaded the .php file in Safari and this resulted in a successful mysqli connection to MySQL with PHP. I also tried a PDO connection and this also worked.

how to connect to MySQL databases using php in zend server

I am trying to connect to my MySQL version 8.0.11 database in zend server version 7.2.10 using php but I could not connect it
Warning: mysqli::__construct(): Unexpected server respose while doing caching_sha2 auth: 109 in C:\Program Files (x86)\Zend\Apache24\htdocs\connectdatabase.php on line 7
Warning: mysqli::__construct(): MySQL server has gone away in C:\Program Files (x86)\Zend\Apache24\htdocs\connectdatabase.php on line 7
Warning: mysqli::__construct(): (HY000/2006): MySQL server has gone away in C:\Program Files (x86)\Zend\Apache24\htdocs\connectdatabase.php on line 7
Connection failed :MySQL server has gone away
I am getting the following warnings when i try to run my code.
i have searched and tried ALTER USER 'username'#'hostname' IDENTIFIED WITH mysql_native_password BY "userpassword" command but it does not work for me
<?php
$servername = "localhost";
$username = "root";
$password = "hello";
$conn = new mysqli($servername,$username,$password);
if(mysqli_connect_error())
{
die("Connection failed :" . mysqli_connect_error());
}
echo "CONNECTED SUCCESSFULLY";
?>
Try with caching_sha2_password:
ALTER USER 'username'#'hostname'IDENTIFIED WITH caching_sha2_password BY 'userpassword';

mysqli_real_connect() getting SSL3_GET_SERVER_CERTIFICATE:certificate verify failed

We just upgraded to php 5.6 from php 5.4, and everything was working fine with our MySQL connecting using MySQLi and SSL.
Our connection looks like:
mysqli_real_connect($db, $host, $username, $password, $database, $port, $socket, MYSQLI_CLIENT_SSL);
mysqli_set_charset($db, "utf8");
Howerver, now when we try and connect to MySQL over SSL using php 5.6 we are getting:
Warning: mysqli_real_connect(): SSL operation failed with code 1.
OpenSSL Error messages: error:14090086:SSL
routines:SSL3_GET_SERVER_CERTIFICATE:certificate verify failed in
/MySQLConnection.php on line 29
Warning: mysqli_real_connect(): Cannot connect to MySQL by using SSL
in /MySQLConnection.php on line 29
Warning: mysqli_real_connect(): [2002] (trying to connect via
tcp://mysql1.ourdomain.com:3306) in /MySQLConnection.php on line 29
Warning: mysqli_real_connect(): (HY000/2002): in /MySQLConnection.php
on line 29
I tried setting:
mysqli_options($db, MYSQLI_OPT_SSL_VERIFY_SERVER_CERT, false);
But that does not help.
UPDATE
I added:
$mysql_certs_path = "/full/path/to/certs/mysql";
mysqli_ssl_set($db, $mysql_certs_path . "/client-key.pem", $mysql_certs_path . "/client-cert.pem", $mysql_certs_path . "/ca-cert.pem", null, null);
And still getting:
Warning: mysqli_real_connect(): SSL operation failed with code 1.
OpenSSL Error messages: error:14090086:SSL
routines:SSL3_GET_SERVER_CERTIFICATE:certificate verify failed in
/MySQLConnection.php on line 31
Warning: mysqli_real_connect(): Cannot connect to MySQL by using SSL in /MySQLConnection.php on line 31
#jww, I have written a post that shares exactly the problems #Justin is facing here. According to my post, the CN of the certificate issued by Google Cloud SQL has the pattern:
CN=project-name:instance-id
Had something similar to this happen to me. When I upgraded PHP to 5.6, it worked. But when I entered:
sudo apt-get install php5-mysqlnd
On Ubuntu 15.04, the SSL to AWS RDS stopped working, even though it worked with the libmysql driver. Running:
sudo apt-get install php5-mysql
Installed the old drivers and it started working again. Near as I can figure out, it's failing the peer-name validation for connecting to RDS. I do not know how to fix that, and because it uses PHP streams for its connection, the settings don't seem to matter that you pass in.
This is a known bug:
https://bugs.php.net/bug.php?id=68344
So I wrote this method, modified from here: How to know if MySQLnd is the active driver?
public function getMySQLIType()
{
$mysqlType = [
'mysql' => false,
'mysqli' => false,
'mysqlnd' => false,
];
if (function_exists('mysql_connect')) {
$mysqlType['mysql'] = true;
}
if (function_exists('mysqli_connect')) {
$mysqlType['mysqli'] = true;
}
if (function_exists('mysqli_get_client_stats')) {
$mysqlType['mysqlnd'] = true;
}
return $mysqlType;
}
If the array returns true for mysqlnd, I disable SSL. If returns false, then I enable it. Thus far, it works. Yes, this is a hack fix but I do not know how to legitimately fix this issue.

I want to access another server database in PHP

I am really a beginner in PHP and Mysql. I made a database on static IP 192.168.1.211 which is based on CentOS(only Command prompt) and on this IP there is no other software like easyPHP, and I am working on static IP 192.168.1.20 based on Windows 7. I also installed easyPHP and Dreamweaver... using Dreamweaver I made one .php file and I tried to use the database which is on 192.168.1.20..
using below code
<?php
$server2 = '192.168.1.211';
$con = mysqli_connect(server2,'root','password','vvani');
if (mysqli_connect_errno())
{
echo "Failed to connect to MySQL: " . mysqli_connect_error();
}
?>
but I get an error as shown below
Notice: Use of undefined constant server2 - assumed 'server2' in C:\Program Files\EasyPHP-DevServer-13.1VC9\data\localweb\test\welcome.php on line 4
Warning: mysqli_connect(): php_network_getaddresses: getaddrinfo failed: No such host is known. in C:\Program Files\EasyPHP-DevServer-13.1VC9\data\localweb\test\welcome.php on line 4
Warning: mysqli_connect(): (HY000/2002): php_network_getaddresses: getaddrinfo failed: No such host is known. in C:\Program Files\EasyPHP-DevServer-13.1VC9\data\localweb\test\welcome.php on line 4
Failed to connect to MySQL: php_network_getaddresses: getaddrinfo failed: No such host is known.
How can I access the database on 192.168.1.211 from 192.168.1.20 in PHP code?
I also tried hard to find a solution from Google, but I am not getting a perfect solution.
Just read errors and correct it..
<?php
$server2 = '192.168.1.211';
$con = mysqli_connect($server2,'root','password','vvani'); // here, $server2 is variable, not constant
if (mysqli_connect_errno())
{
echo "Failed to connect to MySQL: " . mysqli_connect_error();
}
Change server2 to $server2. If that still doesn't work then it's possible the other server does not allow requests in such a way so you will have to update the MySQL settings on that server to allow external access to the port (or otherwise forward it).
Thanks Elon Than and Explosion Pills,
I changed server2 to $server2, but I get new warning
Warning: mysqli_connect(): (HY000/1130): Host '192.168.1.20' is not allowed to connect to this MySQL server in C:\Program Files\EasyPHP-DevServer-13.1VC9\data\localweb\test\welcome.php on line 4
And I research on it and I try to give remotely access to database on another server.
Follow some few steps and solved problem.
# mysql -u root -p
mysql> GRANT ALL ON Database.* TO <un>#'localhost' IDENTIFIED BY 'password';
Thanks again.

Categories