PHP files on my server cannot connect to MySQL on a remote server using SSL with a private CA’s certificate.
Both servers are using:
Ubuntu server 22.04
MySQL 8.0
PHP 8.1
I have a php file on server1 which is trying to connect to MySQL on server2 using PDO:
$pdo = new PDO('mysql:host=<server2_ip>;dbname=<dbname>', '<user>', ‘<password>,
array(
PDO::MYSQL_ATTR_SSL_KEY =>'<path>/client-key.pem',
PDO::MYSQL_ATTR_SSL_CERT=>'<path>/client-cert.pem',
PDO::MYSQL_ATTR_SSL_CA =>'<path>/ca.pem'
)
);
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$pdo->exec('SET NAMES "utf8"');
A private SSL certificate was generated on server2 and shared with server1 using the method outlined in https://www.digitalocean.com/community/tutorials/how-to-configure-ssl-tls-for-mysql-on-ubuntu-18-04.
I can access the database on server2 from the command line on server1 using:
mysql -u <user> -h <server2_ip> -p
But when I try to connect to server2 using the php file on server1 I get the PDOExeption:
failed loading cafile stream
I searched for similar issues and I thought it might be caused by my privately generated certificates not being recognised by PHP. I tried manually adding my ca.pem file to /etc/ssl/certs using the method outlined in How do I add a Certificate Authority to PHP so the file() function trusts certificates signed by it? and updating
PDO::MYSQL_ATTR_SSL_CA =>'<path>/ca.pem'
to
PDO::MYSQL_ATTR_SSL_CA =>'/etc/ssl/certs/cacert.pem'
But this gave me the error:
SSL operation failed with code 1. OpenSSL Error messages: error:0200008A:rsa routines::invalid padding error:02000072:rsa routines::padding check failed error:1C880004:Provider routines::RSA lib error:06880006:asn1 encoding routines::EVP lib error:0A000086:SSL routines::certificate verify failed
The issue seems to be that PHP on server1 is having trouble recognising the private certificate authority I created on server2.
Is there any way to fix this?
BTW I have read similar stackoverflow issues that suggest adding the following to the PDO object:
PDO::MYSQL_ATTR_SSL_VERIFY_SERVER_CERT => false
This does allow me to connect to the server2 database from the server1 php file, but this prevents PHP from verifying the server certificates - doesn’t this defeat the purpose of SSL? If the server certificates are not being checked wouldn’t this leave me vulnerable to man-in-the-middle attacks?