Featured image of post 使用 Docker + Proxy 部署 phpMyAdmin 來管理 MySQL 或 MariaDB

使用 Docker + Proxy 部署 phpMyAdmin 來管理 MySQL 或 MariaDB

在使用 Cloudflare Tunnel 、 Traefik、 Nginx 等 Proxy 程式組態 SSL 的環境下, phpMyAdmin 會出現警告提示,這篇文章將說明如何修正這個問題。

最後更新
約 646 字

前言

在 Docker 中部署 phpMyAdmin 後,如果再用 Proxy 套上 SSL,會因為 phpMyAdmin 的安全性檢查而出現 HTTPS 警告提示。

雖然網站本身已經使用 HTTPS 連線,但是因為 Proxy 的關係,phpMyAdmin 會認為是使用 HTTP 連線,所以會出現警告提示。

錯誤訊息如下:

1
2
3
There is a mismatch between HTTPS indicated on the server and client.
This can lead to a non working phpMyAdmin or a security risk.
Please fix your server configuration to indicate HTTPS properly.

phpMyAdmin 判斷 HTTPS 的方法

Source Code: phpmyadmin/src/Config.php

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
/**
 * Checks if protocol is https
 *
 * This function checks if the https protocol on the active connection.
 */
public function isHttps(): bool
{
    if ($this->get('is_https') !== null) {
        return (bool) $this->get('is_https');
    }

    $url = $this->get('PmaAbsoluteUri');

    $is_https = false;
    if (! empty($url) && parse_url($url, PHP_URL_SCHEME) === 'https') {
        $is_https = true;
    } elseif (strtolower(Core::getenv('HTTP_SCHEME')) === 'https') {
        $is_https = true;
    } elseif (strtolower(Core::getenv('HTTPS')) === 'on') {
        $is_https = true;
    } elseif (strtolower(substr(Core::getenv('REQUEST_URI'), 0, 6)) === 'https:') {
        $is_https = true;
    } elseif (strtolower(Core::getenv('HTTP_HTTPS_FROM_LB')) === 'on') {
        // A10 Networks load balancer
        $is_https = true;
    } elseif (strtolower(Core::getenv('HTTP_FRONT_END_HTTPS')) === 'on') {
        $is_https = true;
    } elseif (strtolower(Core::getenv('HTTP_X_FORWARDED_PROTO')) === 'https') {
        $is_https = true;
    } elseif (strtolower(Core::getenv('HTTP_CLOUDFRONT_FORWARDED_PROTO')) === 'https') {
        // Amazon CloudFront, issue #15621
        $is_https = true;
    } elseif (Util::getProtoFromForwardedHeader(Core::getenv('HTTP_FORWARDED')) === 'https') {
        // RFC 7239 Forwarded header
        $is_https = true;
    } elseif (Core::getenv('SERVER_PORT') == 443) {
        $is_https = true;
    }

    $this->set('is_https', $is_https);

    return $is_https;
}

解決方法

最簡單的解決方法是修改 phpMyAdmin 的設定檔 $cfg['PmaAbsoluteUri'],讓它知道使用的是 HTTPS 連線。 在 Docker 中,可以透過環境變數來設定。

config.user.inc.php 的內容需要以 base64 編碼後放入 docker-compose.ymlenvironment.PMA_USER_CONFIG_BASE64 中。 內容需要是完整的 PHP 檔案,即從 <?php 開始,到 ?> 結束。

Base64 編碼可以使用線上工具 IT-Tools: Base64 string encoder/decoder 來進行。

例子:

1
2
3
4
  phpmyadmin:
    image: phpmyadmin
    environment:
      - PMA_USER_CONFIG_BASE64={BASE64_ENCODED_CONTENT}

忽略 SQL 連接的 SSL 警告

設定忽略 phpMyAdmin 連接到 SQL 伺服器時的 SSL 警告。如果 SQL 伺服器是在本機,可以安全地設定忽略警告。

值是一個陣列,可以設定多個 SQL 主機,如下所示:

1
$cfg['MysqlSslWarningSafeHosts'] = ['127.0.0.1', 'localhost', '172.17.0.1'];

手動指定 phpMyAdmin 的絕對 URI

設定 phpMyAdmin 的絕對 URI,在 Docker 配合 Cloudflare 套 SSL 的環境下,設定正確的 Uri 可以排除登入頁面的錯誤資訊。 最後需要加 /

1
$cfg['PmaAbsoluteUri'] = 'https://{phpMyAdmin_URL}';

其他自訂設定可以參考 phpMyAdmin 官方檔案


使用 Hugo 建立
主題 StackJimmy 設計