Mysql

無法使用 SSL 和 SHA256 密碼驗證連接到遠端 mysql 數據庫

  • October 5, 2018

我可以通過來自 Web 伺服器的 cli 的安全連接成功連接,但在通過 php 腳本測試連接時收到錯誤消息。

來自 Web 伺服器 cli 的 mysql 狀態

mysql  Ver 14.14 Distrib 5.7.21, for Linux (x86_64) using  EditLine wrapper

Connection id:      9
Current database:   
Current user:       test@db.test.com
SSL:            Cipher in use is DHE-RSA-AES256-SHA
Current pager:      stdout
Using outfile:      ''
Using delimiter:    ;
Server version:     5.7.21-0ubuntu0.16.04.1 (Ubuntu)
Protocol version:   10
Connection:     0.0.0.0 via TCP/IP
Server characterset:    utf8mb4
Db     characterset:    utf8mb4
Client characterset:    utf8mb4
Conn.  characterset:    utf8mb4
TCP port:       3306
Uptime:         3 days 4 hours 53 min 35 sec

Threads: 1  Questions: 17  Slow queries: 0  Opens: 107  Flush tables: 1  Open tables: 26  Queries per second avg: 0.000

來自 Web 伺服器 cli 的 SSL 變數

+---------------+-----------------+
| Variable_name | Value           |
+---------------+-----------------+
| have_openssl  | YES             |
| have_ssl      | YES             |
| ssl_ca        | ca.pem          |
| ssl_capath    |                 |
| ssl_cert      | server-cert.pem |
| ssl_cipher    |                 |
| ssl_crl       |                 |
| ssl_crlpath   |                 |
| ssl_key       | server-key.pem  |
+---------------+-----------------+

來自 Web 伺服器 cli 的授權

+-------------------------------------------------------------+
| Grants for test@0.0.0.0                             |
+-------------------------------------------------------------+
| GRANT USAGE ON *.* TO 'test'@'0.0.0.0'              |
| GRANT SELECT ON `testDB`.* TO 'test'@'0.0.0.0' |
+-------------------------------------------------------------+

使用來自 Web 伺服器 cli 的 utf8mb4 的字元集

+--------------------------+------------------------+
| Variable_name            | Value                  |
+--------------------------+------------------------+
| character_set_client     | utf8mb4                |
| character_set_connection | utf8mb4                |
| character_set_database   | utf8mb4                |
| character_set_filesystem | binary                 |
| character_set_results    | utf8mb4                |
| character_set_server     | utf8mb4                |
| character_set_system     | utf8                   |
| collation_connection     | utf8mb4_unicode_520_ci |
| collation_database       | utf8mb4_unicode_520_ci |
| collation_server         | utf8mb4_unicode_520_ci |
+--------------------------+------------------------+

遠端數據庫的使用者權限

+------------------+-------------+-----------------------+----------+
| user             | host        | plugin                | ssl_type |
+------------------+-------------+-----------------------+----------+
| test             | 0.0.0.0     | sha256_password       | X509     |
+------------------+-------------+-----------------------+----------+

Web 伺服器上的證書權限

apache@web:~$ ls -al /etc/mysql-client
total 20
drwxr-xr-x  2 root root 4096 Mar 24 02:30 .
drwxr-xr-x 99 root root 4096 Mar 30 20:04 ..
-r-xr-xr-x  1 root root 1107 Mar 24 02:30 ca.pem
-r-xr-xr-x  1 root root 1107 Mar 24 02:30 client-cert.pem
-r-xr-xr-x  1 root root 1679 Mar 24 02:30 client-key.pem

Web 伺服器上的 PHP 測試腳本

$dsn = 'mysql:host=db.test.com;port=3306;dbname=testDB;charset=utf8mb4';
$dbuser = 'test';
$dbpass = 'sha256-hash';

$dboptions = array (
   PDO::MYSQL_ATTR_SSL_KEY    =>'/etc/mysql-client/client-key.pem',
   PDO::MYSQL_ATTR_SSL_CERT   =>'/etc/mysql-client/client-cert.pem',
   PDO::MYSQL_ATTR_SSL_CA     =>'/etc/mysql-client/ca.pem',
   PDO::MYSQL_ATTR_SSL_VERIFY_SERVER_CERT => false 
);

   try {
       $conn = new PDO($dsn,$dbuser,$dbpass,$dboptions);
       if($conn){
               echo "Connection established";
       }
   } catch (PDOException $e) {
       echo 'Connection failed: ' . $e->getMessage();
   }

從 Web 伺服器到數據庫伺服器的成功網路連接

Connection to 0.0.0.0 3306 port [tcp/mysql] succeeded!

來自 Web 伺服器的錯誤消息

apache@web:~$ php -f test.php
Connection failed: SQLSTATE[HY000] [2002]

我的幾個問題是:

  • php腳本中使用的數據庫密碼應該設置為明文密碼字元串還是sha256雜湊?我都試過了,都沒有工作。
  • 由於證書位於具有全域權限的 /etc 中,並且 php 腳本具有明確的文件路徑,因此是否需要在 Web 伺服器上創建數據庫使用者帳戶?例如,我在 Web 伺服器上的“測試”使用者僅真正用於從命令行測試 mysql 連接。我看不到 apache 是如何依賴於測試使用者的。
  • 我應該看看任何 php.ini 設置嗎?我測試過的唯一一個是更改“open_basedir”以包含 /etc/mysql-client 目錄,但這也沒有做任何事情。
  • 有人知道錯誤 #77595是否已修復嗎?
  • 有沒有人真正使用 PHP 通過 SSL 獲得 sha256_password 身份驗證才能實際工作?

更新#1

據說Bug #77595已在 php7.2.3 中修復,所以我用 ubuntu18.04 啟動了一個新的虛擬機,它的預設包是 php7.2.3,仍然沒有運氣。var_dump 中唯一有用的錯誤字元串是

"PDO::__construct(): SSL operation failed with code 1. OpenSSL Error 
messages: error:0906D06C:PEM routines:PEM_read_bio:no start line"

從命令行登錄 mysql 仍然可以使用相同的證書,只是 php 不喜歡它們。我從 mysql 伺服器對它們進行了 scp,因此不太可能出現格式化錯誤。

對於這個問題,我沒有明確的答案。我的假設是 yaSSL 發生了一些事情。我最終使用了 Percona,它實現了 openSSL。

引用自:https://serverfault.com/questions/906090