Laravel + MySQL + SSL-Mode - SQLSTATE[HY000] [3159] - mysql

On Linode I've setup a MySQL Database Cluster and an Ubuntu server with Apache and PHP 8.1.
When I SSH onto the Ubuntu server I'm able to connect to the cluster:
mysql --host=lin-xxx-mysql-primary-private.servers.linodedb.net --user=xxx --password --ssl-mode=required
However, when I run php artisan migrate I get the following error:
Illuminate\Database\QueryException
SQLSTATE[HY000] [3159] Connections using insecure transport are prohibited while --require_secure_transport=ON. (SQL: select * from information_schema.tables where table_schema = xxxrch and table_name = migrations and table_type = 'BASE TABLE')
at vendor/laravel/framework/src/Illuminate/Database/Connection.php:712
708▕ // If an exception occurs when attempting to run a query, we'll format the error
709▕ // message to include the bindings with SQL, which will make this exception a
710▕ // lot more helpful to the developer instead of just the database's errors.
711▕ catch (Exception $e) {
➜ 712▕ throw new QueryException(
713▕ $query, $this->prepareBindings($bindings), $e
714▕ );
715▕ }
716▕ }
+33 vendor frames
34 artisan:37
Illuminate\Foundation\Console\Kernel::handle()
I have not setup any certificates/pem files which other answers reference, but it still works from the mysqlclient.
What would I add to my .env to config\database.php to get this working?

Here's how I addressed this:
Download the cert from the Linode dashboard.
Place it in resources\certificates
In config/database.php I added:
'sslmode' => env('DB_SSLMODE', 'prefer'),
'options' => extension_loaded('pdo_mysql') && env('APP_ENV') !== 'testing' && env('APP_ENV') !== 'local' ? array_filter([
PDO::MYSQL_ATTR_SSL_CA => resource_path('certificates/certificate.crt'),
PDO::MYSQL_ATTR_SSL_VERIFY_SERVER_CERT => true,
]) : [],
One thing that's important to note is that this will not work for phpunit tests.
This answer was helpful: https://stackoverflow.com/a/70468831/1343140

Related

SQL/Laravel is not quoting text fields when building a query

UPDATED
I am new to Laravel and tried to test this demo https://github.com/laravel-json-api/laravel on my local Mac after installing ddev, Docker and MAMP. The problem is that the code (that I didn't write, I just downloaded without making any changes) is executing a SELECT trying to find a user with that email address but, apparently, Laravel builds the SQL sentence removing the quotes when adding the content for the field "email".
This is the error message that I get on the browser:
SQLSTATE[HY000] [2002] No such file or directory (SQL: select * from `users` where `email` = frankie#example.com limit 1)
I use MySQL 5.7.32 and the DB collation is utf8_general_ci.
The error show in the browser when the exception is caught is:
/var/www/html/vendor/laravel/framework/src/Illuminate/Database/Connection.php
* #param array $bindings
* #param \Closure $callback
* #return mixed
*
* #throws \Illuminate\Database\QueryException
*/
protected function runQueryCallback($query, $bindings, Closure $callback)
{
// To execute the statement, we'll simply call the callback, which will actually
// run the SQL against the PDO connection. Then we can calculate the time it
// took to execute and log the query SQL, bindings and time in our memory.
try {
$result = $callback($query, $bindings);
}
// If an exception occurs when attempting to run a query, we'll format the error
// message to include the bindings with SQL, which will make this exception a
// lot more helpful to the developer instead of just the database's errors.
catch (Exception $e) {
throw new QueryException(
$query, $this->prepareBindings($bindings), $e
);
}
return $result;
}
/**
* Log a query in the connection's query log.
*
* #param string $query
* #param array $bindings
* #param float|null $time
* #return void
*/
public function logQuery($query, $bindings, $time = null)
{
$this->event(new QueryExecuted($query, $bindings, $time, $this));
if ($this->loggingQueries) {
*Arguments
"SQLSTATE[HY000] [2002] No such file or directory (SQL: select * from `users` where `email` = frankie#example.com limit 1)"*
This is the database.php config for the demo project:
database.php demo:
'mysql' => [
'driver' => 'mysql',
'host' => env('DB_HOST', '127.0.0.1'),
'port' => env('DB_PORT', '8889'),
'database' => env('DB_DATABASE', 'forge'),
'username' => env('DB_USERNAME', 'forge'),
'password' => env('DB_PASSWORD', ''),
'unix_socket' => '/Applications/MAMP/tmp/mysql/mysql.sock',
'charset' => 'utf8mb4',
'collation' => 'utf8mb4_unicode_ci',
'prefix' => '',
'strict' => true,
],
MySQL listens on port 8889
Anyone has experienced a similar situation?
Thanks
Your problem is not the quotes, there's something wrong with the SQL server internally.
Regarding the quotes:
When using the standard eloquent methods, query parameters will be sent to the server using prepared statements. This is very save and the no need four adding quotes. Internally the server handles the parameters correctly.
Whenever an error occurred, the server outputs the pure, unquoted data of received from the prepared statement. This indeed is a bit misleading, but it's not an error.
I closed this question as it is not related to how Laravel builds the SQL sentence. It is about an error trying to connect to MySQL from any PHP code on MAMP. See my new question here Error: 200 Connection refused on PHP connecting to MySQL running on MAMP
Such an error may occur when accidentaly we are passing in fields that don't match our Model's fields

Prestashop: 'Link to database cannot be established'

This is our first time moving a Prestashop Installation from one Domain to another and it has been one hell of a learning curve.
Steps we have taken so far:
Copied the database:
0) New database name: gamingco_ps, user gamingco_ps1
Changed ps_configuration
Changed the ps_shop_url (Domain/Domain SSL)
Amended htcacess to stop any redirects
CPANEL removed all temporary redirects
Changed the /home/gamingco/public_html/app/config/parameters.php :
<?php return array (
'parameters' =>
array (
'database_host' => 'localhost',
'database_port' => '',
'database_name' => 'gamingco_ps',
'database_user' => 'gamingco_ps1',
'database_password' => '{Password}',
'database_prefix' => 'pswy_',
'database_engine' => 'InnoDB',
'mailer_transport' => 'smtp',
'mailer_host' => '127.0.0.1',
'mailer_user' => NULL,
'mailer_password' => NULL,
'secret' => 'dva3atuoqjpqhb8xmjtfwjszkpbwaifombdlbg46qwygbi7e4mpyfgui',
'ps_caching' => 'CacheMemcache',
'ps_cache_enable' => false,
'ps_creation_date' => '2021-01-27',
'locale' => 'en-US',
'use_debug_toolbar' => true,
'cookie_key' => 'zml9yqgynwgixtb1e4c0xh8q8gjeynsp7arnovqw5dhpcthcyfpu89bx',
'cookie_iv' => 'qsembkbmpfbnk5bf3hhxjg3sw1laaa06',
'new_cookie_key' => 'def00000acce4699cd116debb37dc5533dfd6ff201153a61ac3446801d772207548a0f44596a7a01939e9f753e4290f3735373a25516e62b2118322ec7f7cd64e3b347ee',
),
);
We are now receiving error 500 without debug mode and with debugmode we are met with:
Link to database cannot be established: SQLSTATE[28000] [1045] Access denied for user 'gamingco_ps1'#'localhost' (using password: YES)
at line 136 in file classes/db/DbPDO.php
131. public function connect()
132. {
133. try {
134. $this->link = $this->getPDO($this->server, $this->user, $this->password, $this->database, 5);
135. } catch (PDOException $e) {
136. throw new PrestaShopException('Link to database cannot be established: ' . $e->getMessage());
137. }
138.
139. $this->link->exec('SET SESSION sql_mode = \'\'');
140.
141. return $this->link;```
DbPDOCore->connect - [line 330 - classes/db/Db.php]
DbCore->__construct - [line 241 - classes/db/Db.php] - [4 Arguments]
DbCore::getInstance - [line 47 - config/alias.php]
pSQL - [line 1336 - classes/shop/Shop.php] - [1 Arguments]
ShopCore::findShopByHost - [line 337 - classes/shop/Shop.php] - [1 Arguments]
ShopCore::initialize - [line 118 - config/config.inc.php]
require - [line 27 - index.php] - [1 Arguments]
I gone through all the steps again and I cannot seem to identify where the error maybe.
Error is pretty straighforward here, Prestashop cannot connect to database.
Things to check:
Make sure your var/cache/prod directory does not contain any cache file from previous installation as it can lead to old DB connection with old credentials.
Double check DB data in parameters.php, carefully look for data correctness (case sensitive, correct DB host / port etc.)
If none of above helps, try connecting your box from ssh and check direct db connection from there with :
mysql -u{username} -p{password} {database name}
and post the result.

How to connect mysql database using laravel

I'm trying to connect the MySQL database in Laravel, having some issues.
This is MySQL credentials in the .env file in Laravel.
DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=welcome
DB_USERNAME=krishna
DB_PASSWORD=Krish_123
I'm trying to migrate it's shown some error like bellow.
siva#siva-Latitude-3490:~/Desktop/laravel-practies-project$ php artisan migrate
Illuminate\Database\QueryException
could not find driver (SQL: select * from information_schema.tables where table_schema = welcome and table_name = migrations and table_type = 'BASE TABLE')
at vendor/laravel/framework/src/Illuminate/Database/Connection.php:671
667| // If an exception occurs when attempting to run a query, we'll format the error
668| // message to include the bindings with SQL, which will make this exception a
669| // lot more helpful to the developer instead of just the database's errors.
670| catch (Exception $e) {
> 671| throw new QueryException(
672| $query, $this->prepareBindings($bindings), $e
673| );
674| }
675|
+34 vendor frames
35 artisan:37
Illuminate\Foundation\Console\Kernel::handle(Object(Symfony\Component\Console\Input\ArgvInput), Object(Symfony\Component\Console\Output\ConsoleOutput))

Cannot connect to Google Cloud MySQL using SSL with PDO on Google Compute

Just figured this out and wanted to share.
I am able to connect to MySQL using SSL with the PHP PDO from my local machine. The same code fails when run from a Google Compute Engine instance. I know the certs and IP address are setup correctly because connecting via the MySQL command line client using SSL on the instance works perfectly.
MySQL command line works on Compute:
mysql --ssl-ca=server-ca.pem --ssl-cert=client-cert.pem --ssl-key=client-key.pem \
--host=111.111.111.111 --user=someuser --password
PHP PDO does not work on Compute:
<?php
new PDO ('mysql:host=111.111.111.111;port=3306;dbname=mydatabase',
'someuser',
'somepassword,
array(
PDO::MYSQL_ATTR_SSL_KEY => '/somedir/ssl/client-key.pem',
PDO::MYSQL_ATTR_SSL_CERT => '/somedir/ssl/client-cert.pem',
PDO::MYSQL_ATTR_SSL_CA => '/somedir/ssl/ca-cert.pem'
)
);
PDO gives this error on Compute:
PHP Fatal error: Uncaught exception 'PDOException' with message 'SQLSTATE[HY000] [2026] SSL connection error: ASN: bad other signature confirmation'
Remove the CA cert from the PDO connection.
Remove this key/value from the array:
PDO::MYSQL_ATTR_SSL_CA => '/somedir/ssl/ca-cert.pem'
Like so:
<?php
new PDO ('mysql:host=111.111.111.111;port=3306;dbname=mydatabase',
'someuser',
'somepassword,
array(
PDO::MYSQL_ATTR_SSL_KEY => '/somedir/ssl/client-key.pem',
PDO::MYSQL_ATTR_SSL_CERT => '/somedir/ssl/client-cert.pem'
)
);
PDO with SSL will silently fail back to an insecure connection under certain conditions. To test that SSL is working run this query on the connection:
SHOW STATUS LIKE 'Ssl_cipher';
It should return something like:
Ssl_cipher => DHE-RSA-AES256-SHA
Otherwise the it will return an empty value.
Just add one more PDO attribute (as per comments by Desislav Kamenov in http://php.net/manual/en/ref.pdo-mysql.php) into your array so that your PDO becomes ...
new PDO ('mysql:host=111.111.111.111;port=3306;dbname=mydatabase',
'someuser',
'somepassword',
array(
PDO::MYSQL_ATTR_SSL_KEY => '/somedir/ssl/client-key.pem',
PDO::MYSQL_ATTR_SSL_CERT => '/somedir/ssl/client-cert.pem',
PDO::MYSQL_ATTR_SSL_CA => '/somedir/ssl/ca-cert.pem',
PDO::MYSQL_ATTR_SSL_VERIFY_SERVER_CERT => false
)
);

Laravel failing to connect to DB after 4.2 upgrade

I just upgraded my Laravel install from 4.1.(something) to 4.2.7 using the steps recommended here: http://laravel.com/docs/upgrade
Now I'm getting this error on every page:
PDOException (2002)
SQLSTATE[HY000] [2002] Can't connect to local MySQL server through socket '' (111)
MySQL is not running locally, but it's not supposed to be. I don't have any configuration for connecting to local MySQL, my development SQL server is remote. Why is it trying to connect to local?
Is there some config change that isn't mentioned in the upgrade guide? Everything was peachy in 4.1.
From my app/config/database.php file:
'default' => 'mysql',
...
'connections' => array(
'mysql' => array(
'driver' => 'mysql',
'host' => 'myrealdb.us-east-1.rds.amazonaws.com',
'database' => 'myrealdbname',
'username' => 'myrealuser',
'password' => 'myrealpass',
'charset' => 'utf8',
'collation' => 'utf8_unicode_ci',
'prefix' => '',
'database_port' => '3306',
'unix_socket' => '',
),
...
);
I tried php artisan clear-compiled and php artisan dump-autoload just in case. No effect.
Edit: I submitted a fix for this that has been merged into the 4.2 branch. You shouldn't have to worry about this error anymore.
I got it! This appears to be a change in the way Laravel uses the database configuration, I hope this answer helps others.
The short version is: if your connection is configured like mine (in the question), delete the unix_socket entry from the array.
Previously, I always copied and edited the default entries in the connections array, leaving in the unix_socket parameter as empty. Apparently now there's a check that assumes if unix_socket is present, it should use a socket DSN string. The empty string in my config passed the check. You can see how this happens in /vendor/laravel/framework/src/Illuminate/Database/Connectors/MySqlConnector.php. The functions getDsn, getSocketDsn, and getHostDsn tell the story.
Pasted because this will eventually change:
protected function getDsn(array $config)
{
return isset($config['unix_socket']) ? $this->getSocketDsn($config) : $this->getHostDsn($config);
}
...
protected function getSocketDsn(array $config)
{
extract($config);
return "mysql:unix_socket={$config['unix_socket']};dbname={$database}";
}
...
protected function getHostDsn(array $config)
{
extract($config);
return isset($config['port'])
? "mysql:host={$host};port={$port};dbname={$database}"
: "mysql:host={$host};dbname={$database}";
}