From 6214417384aa24ff1444e63bdd8bb3b7853180c9 Mon Sep 17 00:00:00 2001 From: lordrobincbz Date: Wed, 11 Dec 2024 14:44:09 +0100 Subject: [PATCH] feat:(config.inc.php/docker-entrypoint.sh): Add support for mTLS to a remote server/cluster/service --- README.md | 9 ++++- apache/config.inc.php | 28 +++++++++++++++ apache/docker-entrypoint.sh | 64 +++++++++++++++++++++++++++++++++ fpm-alpine/config.inc.php | 28 +++++++++++++++ fpm-alpine/docker-entrypoint.sh | 63 ++++++++++++++++++++++++++++++++ fpm/config.inc.php | 28 +++++++++++++++ fpm/docker-entrypoint.sh | 63 ++++++++++++++++++++++++++++++++ 7 files changed, 282 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 8fbece68..dfa22790 100644 --- a/README.md +++ b/README.md @@ -185,7 +185,14 @@ docker run --name phpmyadmin -d -e PMA_HOSTS='sslhost,nosslhost' -e PMA_SSLS='1, * ``PMA_SOCKET`` - define socket file for the MySQL connection * ``PMA_SOCKETS`` - define comma separated list of socket files for the MySQL connections * ``PMA_SSL`` - when set to 1, defines SSL usage for the MySQL connection -* ``PMA_SSLS`` - comma separated list of `0` and `1` defining SSL usage for the corresponding MySQL connections +* ``PMA_SSL_VERIFY`` - when set to 1, enables SSL certificate verification for the MySQL connection. +* ``PMA_SSL_VERIFIES`` - comma-separated list of `0` and `1` to enable or disable SSL certificate verification for multiple MySQL connections. +* ``PMA_SSL_CA_BASE64`` - in the context of mTLS security, allows setting your CA file as a base64 string inside the default `config.inc.php`. +* ``PMA_SSL_CAS_BASE64`` - in the context of mTLS security, allows setting multiple CA files as a comma-separated list of base64 strings inside the default `config.inc.php`. +* ``PMA_SSL_CERT_BASE64`` - in the context of mTLS security, allows setting your CERT file as a base64 string inside the default `config.inc.php`. +* ``PMA_SSL_CERTS_BASE64`` - in the context of mTLS security, allows setting multiple CERT files as a comma-separated list of base64 strings inside the default `config.inc.php`. +* ``PMA_SSL_KEY_BASE64`` - in the context of mTLS security, allows setting your KEY file as a base64 string inside the default `config.inc.php`. +* ``PMA_SSL_KEYS_BASE64`` - in the context of mTLS security, allows setting multiple KEY files as a comma-separated list of base64 strings inside the default `config.inc.php`. * ``PMA_USER`` and ``PMA_PASSWORD`` - define username and password to use only with the `config` authentication method * ``PMA_ABSOLUTE_URI`` - the full URL to phpMyAdmin. Sometimes needed when used in a reverse-proxy configuration. Don't set this unless needed. See [documentation](https://docs.phpmyadmin.net/en/latest/config.html#cfg_PmaAbsoluteUri). * ``PMA_CONFIG_BASE64`` - if set, this option will override the default `config.inc.php` with the base64 decoded contents of the variable diff --git a/apache/config.inc.php b/apache/config.inc.php index 9f5d2ac7..693a715d 100644 --- a/apache/config.inc.php +++ b/apache/config.inc.php @@ -28,7 +28,15 @@ 'PMA_UPLOADDIR', 'PMA_SAVEDIR', 'PMA_SSL', + 'PMA_SSL_VERIFY', + 'PMA_SSL_CA', + 'PMA_SSL_KEY', + 'PMA_SSL_CERT', 'PMA_SSLS', + 'PMA_SSL_VERIFIES', + 'PMA_SSL_CAS', + 'PMA_SSL_KEYS', + 'PMA_SSL_CERTS' ]; foreach ($vars as $var) { @@ -66,11 +74,19 @@ $verbose = [$_ENV['PMA_VERBOSE']]; $ports = [$_ENV['PMA_PORT']]; $ssls = [$_ENV['PMA_SSL']]; + $ssl_verifies = [$_ENV['PMA_SSL_VERIFY']]; + $ssl_cas = [$_ENV['PMA_SSL_CA']]; + $ssl_keys = [$_ENV['PMA_SSL_KEY']]; + $ssl_certs = [$_ENV['PMA_SSL_CERT']]; } elseif (! empty($_ENV['PMA_HOSTS'])) { $hosts = array_map('trim', explode(',', $_ENV['PMA_HOSTS'])); $verbose = array_map('trim', explode(',', $_ENV['PMA_VERBOSES'])); $ports = array_map('trim', explode(',', $_ENV['PMA_PORTS'])); $ssls = array_map('trim', explode(',', $_ENV['PMA_SSLS'])); + $ssl_verifies = array_map('trim', explode(',', $_ENV['PMA_SSL_VERIFIES'])); + $ssl_cas = array_map('trim', explode(',', $_ENV['PMA_SSL_CAS'])); + $ssl_keys = array_map('trim', explode(',', $_ENV['PMA_SSL_KEYS'])); + $ssl_certs = array_map('trim', explode(',', $_ENV['PMA_SSL_CERTS'])); } if (! empty($_ENV['PMA_SOCKET'])) { @@ -84,6 +100,18 @@ if (isset($ssls[$i - 1]) && $ssls[$i - 1] === '1') { $cfg['Servers'][$i]['ssl'] = $ssls[$i - 1]; } + if (isset($ssl_verifies[$i - 1]) && $ssl_verifies[$i - 1] === '1') { + $cfg['Servers'][$i]['ssl_verify'] = $ssl_verifies[$i - 1]; + } + if (isset($ssl_cas[$i - 1])) { + $cfg['Servers'][$i]['ssl_ca'] = $ssl_cas[$i - 1]; + } + if (isset($ssl_keys[$i - 1])) { + $cfg['Servers'][$i]['ssl_key'] = $ssl_keys[$i - 1]; + } + if (isset($ssl_certs[$i - 1])) { + $cfg['Servers'][$i]['ssl_cert'] = $ssl_certs[$i - 1]; + } $cfg['Servers'][$i]['host'] = $hosts[$i - 1]; if (isset($verbose[$i - 1])) { $cfg['Servers'][$i]['verbose'] = $verbose[$i - 1]; diff --git a/apache/docker-entrypoint.sh b/apache/docker-entrypoint.sh index 5c2e85af..655072f8 100755 --- a/apache/docker-entrypoint.sh +++ b/apache/docker-entrypoint.sh @@ -29,6 +29,45 @@ if [ ! -z "${PMA_USER_CONFIG_BASE64}" ]; then echo "${PMA_USER_CONFIG_BASE64}" | base64 -d > /etc/phpmyadmin/config.user.inc.php fi +if [ ! -z "${PMA_SSL_CA_BASE64}" ]; then + mkdir -p /etc/phpmyadmin/ssl + echo "Adding the custom pma-ssl-ca from base64." + echo "${PMA_SSL_CA_BASE64}" | base64 -d > /etc/phpmyadmin/ssl/pma-ssl-ca.pem + export "PMA_SSL_CA"="/etc/phpmyadmin/ssl/pma-ssl-ca.pem" +fi + +if [ ! -z "${PMA_SSL_KEY_BASE64}" ]; then + mkdir -p /etc/phpmyadmin/ssl + echo "Adding the custom pma-ssl-key from base64." + echo "${PMA_SSL_KEY_BASE64}" | base64 -d > /etc/phpmyadmin/ssl/pma-ssl-key.key + export "PMA_SSL_KEY"="/etc/phpmyadmin/ssl/pma-ssl-key.key" +fi + +if [ ! -z "${PMA_SSL_CERT_BASE64}" ]; then + mkdir -p /etc/phpmyadmin/ssl + echo "Adding the custom pma-ssl-cert from base64." + echo "${PMA_SSL_CERT_BASE64}" | base64 -d > /etc/phpmyadmin/ssl/pma-ssl-cert.pem + export "PMA_SSL_CERT"="/etc/phpmyadmin/ssl/pma-ssl-cert.pem" +fi + +if [ ! -z "${PMA_SSL_CAS_BASE64}" ]; then + echo "Adding multiples custom pma-ssl-ca from base64." + PMA_SSL_CAS=$(generate_ssl_files "${PMA_SSL_CAS_BASE64}" "CA" "pem") + export "PMA_SSL_CAS" +fi + +if [ ! -z "${PMA_SSL_KEYS_BASE64}" ]; then + echo "Adding multiples custom pma-ssl-key from base64." + PMA_SSL_KEYS=$(generate_ssl_files "${PMA_SSL_KEYS_BASE64}" "CERT" "cert") + export "PMA_SSL_KEYS" +fi + +if [ ! -z "${PMA_SSL_CERTS_BASE64}" ]; then + echo "Adding multiples custom pma-ssl-cert from base64." + PMA_SSL_CERTS=$(generate_ssl_files "${PMA_SSL_CERTS_BASE64}" "KEY" "key") + export "PMA_SSL_CERTS" +fi + # start: Apache specific settings if [ -n "${APACHE_PORT+x}" ]; then echo "Setting apache port to ${APACHE_PORT}." @@ -50,6 +89,31 @@ get_docker_secret() { fi } +# This function generates SSL files from a base64 encoded string. +# Arguments: +# 1. base64_string: A comma-separated string of base64 encoded SSL files. +# 2. prefix: A prefix to be used in the output file names. +# 3. extension: The file extension to be used for the output files. +# The function creates a directory for the SSL files, decodes each base64 string, +# writes the decoded content to a file, and returns a comma-separated list of the generated file paths. +# +generate_ssl_files() { + local base64_string="${1}" + local output_dir="/etc/phpmyadmin/ssl" + mkdir -p "${output_dir}" + IFS=',' read -ra FILES <<< "${base64_string}" + local counter=1 + local ssl_files="" + for file in "${FILES[@]}"; do + local output_file="${output_dir}/pma-ssl-${2}-${counter}.${3}" + echo "${file}" | base64 -d > "${output_file}" + ssl_files="${ssl_files}${output_file}," + counter=$((counter + 1)) + done + ssl_files="${ssl_files%,}" + echo "${ssl_files}" +} + get_docker_secret PMA_USER get_docker_secret PMA_PASSWORD get_docker_secret MYSQL_ROOT_PASSWORD diff --git a/fpm-alpine/config.inc.php b/fpm-alpine/config.inc.php index 9f5d2ac7..693a715d 100644 --- a/fpm-alpine/config.inc.php +++ b/fpm-alpine/config.inc.php @@ -28,7 +28,15 @@ 'PMA_UPLOADDIR', 'PMA_SAVEDIR', 'PMA_SSL', + 'PMA_SSL_VERIFY', + 'PMA_SSL_CA', + 'PMA_SSL_KEY', + 'PMA_SSL_CERT', 'PMA_SSLS', + 'PMA_SSL_VERIFIES', + 'PMA_SSL_CAS', + 'PMA_SSL_KEYS', + 'PMA_SSL_CERTS' ]; foreach ($vars as $var) { @@ -66,11 +74,19 @@ $verbose = [$_ENV['PMA_VERBOSE']]; $ports = [$_ENV['PMA_PORT']]; $ssls = [$_ENV['PMA_SSL']]; + $ssl_verifies = [$_ENV['PMA_SSL_VERIFY']]; + $ssl_cas = [$_ENV['PMA_SSL_CA']]; + $ssl_keys = [$_ENV['PMA_SSL_KEY']]; + $ssl_certs = [$_ENV['PMA_SSL_CERT']]; } elseif (! empty($_ENV['PMA_HOSTS'])) { $hosts = array_map('trim', explode(',', $_ENV['PMA_HOSTS'])); $verbose = array_map('trim', explode(',', $_ENV['PMA_VERBOSES'])); $ports = array_map('trim', explode(',', $_ENV['PMA_PORTS'])); $ssls = array_map('trim', explode(',', $_ENV['PMA_SSLS'])); + $ssl_verifies = array_map('trim', explode(',', $_ENV['PMA_SSL_VERIFIES'])); + $ssl_cas = array_map('trim', explode(',', $_ENV['PMA_SSL_CAS'])); + $ssl_keys = array_map('trim', explode(',', $_ENV['PMA_SSL_KEYS'])); + $ssl_certs = array_map('trim', explode(',', $_ENV['PMA_SSL_CERTS'])); } if (! empty($_ENV['PMA_SOCKET'])) { @@ -84,6 +100,18 @@ if (isset($ssls[$i - 1]) && $ssls[$i - 1] === '1') { $cfg['Servers'][$i]['ssl'] = $ssls[$i - 1]; } + if (isset($ssl_verifies[$i - 1]) && $ssl_verifies[$i - 1] === '1') { + $cfg['Servers'][$i]['ssl_verify'] = $ssl_verifies[$i - 1]; + } + if (isset($ssl_cas[$i - 1])) { + $cfg['Servers'][$i]['ssl_ca'] = $ssl_cas[$i - 1]; + } + if (isset($ssl_keys[$i - 1])) { + $cfg['Servers'][$i]['ssl_key'] = $ssl_keys[$i - 1]; + } + if (isset($ssl_certs[$i - 1])) { + $cfg['Servers'][$i]['ssl_cert'] = $ssl_certs[$i - 1]; + } $cfg['Servers'][$i]['host'] = $hosts[$i - 1]; if (isset($verbose[$i - 1])) { $cfg['Servers'][$i]['verbose'] = $verbose[$i - 1]; diff --git a/fpm-alpine/docker-entrypoint.sh b/fpm-alpine/docker-entrypoint.sh index 0d98e270..7a4c8f72 100755 --- a/fpm-alpine/docker-entrypoint.sh +++ b/fpm-alpine/docker-entrypoint.sh @@ -29,6 +29,44 @@ if [ ! -z "${PMA_USER_CONFIG_BASE64}" ]; then echo "${PMA_USER_CONFIG_BASE64}" | base64 -d > /etc/phpmyadmin/config.user.inc.php fi +if [ ! -z "${PMA_SSL_CA_BASE64}" ]; then + mkdir -p /etc/phpmyadmin/ssl + echo "Adding the custom pma-ssl-ca from base64." + echo "${PMA_SSL_CA_BASE64}" | base64 -d > /etc/phpmyadmin/ssl/pma-ssl-ca.pem + export "PMA_SSL_CA"="/etc/phpmyadmin/ssl/pma-ssl-ca.pem" +fi + +if [ ! -z "${PMA_SSL_KEY_BASE64}" ]; then + mkdir -p /etc/phpmyadmin/ssl + echo "Adding the custom pma-ssl-key from base64." + echo "${PMA_SSL_KEY_BASE64}" | base64 -d > /etc/phpmyadmin/ssl/pma-ssl-key.key + export "PMA_SSL_KEY"="/etc/phpmyadmin/ssl/pma-ssl-key.key" +fi + +if [ ! -z "${PMA_SSL_CERT_BASE64}" ]; then + mkdir -p /etc/phpmyadmin/ssl + echo "Adding the custom pma-ssl-cert from base64." + echo "${PMA_SSL_CERT_BASE64}" | base64 -d > /etc/phpmyadmin/ssl/pma-ssl-cert.pem + export "PMA_SSL_CERT"="/etc/phpmyadmin/ssl/pma-ssl-cert.pem" +fi + +if [ ! -z "${PMA_SSL_CAS_BASE64}" ]; then + echo "Adding multiples custom pma-ssl-ca from base64." + PMA_SSL_CAS=$(generate_ssl_files "${PMA_SSL_CAS_BASE64}" "CA" "pem") + export "PMA_SSL_CAS" +fi + +if [ ! -z "${PMA_SSL_KEYS_BASE64}" ]; then + echo "Adding multiples custom pma-ssl-key from base64." + PMA_SSL_KEYS=$(generate_ssl_files "${PMA_SSL_KEYS_BASE64}" "CERT" "cert") + export "PMA_SSL_KEYS" +fi + +if [ ! -z "${PMA_SSL_CERTS_BASE64}" ]; then + echo "Adding multiples custom pma-ssl-cert from base64." + PMA_SSL_CERTS=$(generate_ssl_files "${PMA_SSL_CERTS_BASE64}" "KEY" "key") + export "PMA_SSL_CERTS" +fi get_docker_secret() { local env_var="${1}" @@ -42,6 +80,31 @@ get_docker_secret() { fi } +# This function generates SSL files from a base64 encoded string. +# Arguments: +# 1. base64_string: A comma-separated string of base64 encoded SSL files. +# 2. prefix: A prefix to be used in the output file names. +# 3. extension: The file extension to be used for the output files. +# The function creates a directory for the SSL files, decodes each base64 string, +# writes the decoded content to a file, and returns a comma-separated list of the generated file paths. +# +generate_ssl_files() { + local base64_string="${1}" + local output_dir="/etc/phpmyadmin/ssl" + mkdir -p "${output_dir}" + IFS=',' read -ra FILES <<< "${base64_string}" + local counter=1 + local ssl_files="" + for file in "${FILES[@]}"; do + local output_file="${output_dir}/pma-ssl-${2}-${counter}.${3}" + echo "${file}" | base64 -d > "${output_file}" + ssl_files="${ssl_files}${output_file}," + counter=$((counter + 1)) + done + ssl_files="${ssl_files%,}" + echo "${ssl_files}" +} + get_docker_secret PMA_USER get_docker_secret PMA_PASSWORD get_docker_secret MYSQL_ROOT_PASSWORD diff --git a/fpm/config.inc.php b/fpm/config.inc.php index 9f5d2ac7..693a715d 100644 --- a/fpm/config.inc.php +++ b/fpm/config.inc.php @@ -28,7 +28,15 @@ 'PMA_UPLOADDIR', 'PMA_SAVEDIR', 'PMA_SSL', + 'PMA_SSL_VERIFY', + 'PMA_SSL_CA', + 'PMA_SSL_KEY', + 'PMA_SSL_CERT', 'PMA_SSLS', + 'PMA_SSL_VERIFIES', + 'PMA_SSL_CAS', + 'PMA_SSL_KEYS', + 'PMA_SSL_CERTS' ]; foreach ($vars as $var) { @@ -66,11 +74,19 @@ $verbose = [$_ENV['PMA_VERBOSE']]; $ports = [$_ENV['PMA_PORT']]; $ssls = [$_ENV['PMA_SSL']]; + $ssl_verifies = [$_ENV['PMA_SSL_VERIFY']]; + $ssl_cas = [$_ENV['PMA_SSL_CA']]; + $ssl_keys = [$_ENV['PMA_SSL_KEY']]; + $ssl_certs = [$_ENV['PMA_SSL_CERT']]; } elseif (! empty($_ENV['PMA_HOSTS'])) { $hosts = array_map('trim', explode(',', $_ENV['PMA_HOSTS'])); $verbose = array_map('trim', explode(',', $_ENV['PMA_VERBOSES'])); $ports = array_map('trim', explode(',', $_ENV['PMA_PORTS'])); $ssls = array_map('trim', explode(',', $_ENV['PMA_SSLS'])); + $ssl_verifies = array_map('trim', explode(',', $_ENV['PMA_SSL_VERIFIES'])); + $ssl_cas = array_map('trim', explode(',', $_ENV['PMA_SSL_CAS'])); + $ssl_keys = array_map('trim', explode(',', $_ENV['PMA_SSL_KEYS'])); + $ssl_certs = array_map('trim', explode(',', $_ENV['PMA_SSL_CERTS'])); } if (! empty($_ENV['PMA_SOCKET'])) { @@ -84,6 +100,18 @@ if (isset($ssls[$i - 1]) && $ssls[$i - 1] === '1') { $cfg['Servers'][$i]['ssl'] = $ssls[$i - 1]; } + if (isset($ssl_verifies[$i - 1]) && $ssl_verifies[$i - 1] === '1') { + $cfg['Servers'][$i]['ssl_verify'] = $ssl_verifies[$i - 1]; + } + if (isset($ssl_cas[$i - 1])) { + $cfg['Servers'][$i]['ssl_ca'] = $ssl_cas[$i - 1]; + } + if (isset($ssl_keys[$i - 1])) { + $cfg['Servers'][$i]['ssl_key'] = $ssl_keys[$i - 1]; + } + if (isset($ssl_certs[$i - 1])) { + $cfg['Servers'][$i]['ssl_cert'] = $ssl_certs[$i - 1]; + } $cfg['Servers'][$i]['host'] = $hosts[$i - 1]; if (isset($verbose[$i - 1])) { $cfg['Servers'][$i]['verbose'] = $verbose[$i - 1]; diff --git a/fpm/docker-entrypoint.sh b/fpm/docker-entrypoint.sh index 0d98e270..7a4c8f72 100755 --- a/fpm/docker-entrypoint.sh +++ b/fpm/docker-entrypoint.sh @@ -29,6 +29,44 @@ if [ ! -z "${PMA_USER_CONFIG_BASE64}" ]; then echo "${PMA_USER_CONFIG_BASE64}" | base64 -d > /etc/phpmyadmin/config.user.inc.php fi +if [ ! -z "${PMA_SSL_CA_BASE64}" ]; then + mkdir -p /etc/phpmyadmin/ssl + echo "Adding the custom pma-ssl-ca from base64." + echo "${PMA_SSL_CA_BASE64}" | base64 -d > /etc/phpmyadmin/ssl/pma-ssl-ca.pem + export "PMA_SSL_CA"="/etc/phpmyadmin/ssl/pma-ssl-ca.pem" +fi + +if [ ! -z "${PMA_SSL_KEY_BASE64}" ]; then + mkdir -p /etc/phpmyadmin/ssl + echo "Adding the custom pma-ssl-key from base64." + echo "${PMA_SSL_KEY_BASE64}" | base64 -d > /etc/phpmyadmin/ssl/pma-ssl-key.key + export "PMA_SSL_KEY"="/etc/phpmyadmin/ssl/pma-ssl-key.key" +fi + +if [ ! -z "${PMA_SSL_CERT_BASE64}" ]; then + mkdir -p /etc/phpmyadmin/ssl + echo "Adding the custom pma-ssl-cert from base64." + echo "${PMA_SSL_CERT_BASE64}" | base64 -d > /etc/phpmyadmin/ssl/pma-ssl-cert.pem + export "PMA_SSL_CERT"="/etc/phpmyadmin/ssl/pma-ssl-cert.pem" +fi + +if [ ! -z "${PMA_SSL_CAS_BASE64}" ]; then + echo "Adding multiples custom pma-ssl-ca from base64." + PMA_SSL_CAS=$(generate_ssl_files "${PMA_SSL_CAS_BASE64}" "CA" "pem") + export "PMA_SSL_CAS" +fi + +if [ ! -z "${PMA_SSL_KEYS_BASE64}" ]; then + echo "Adding multiples custom pma-ssl-key from base64." + PMA_SSL_KEYS=$(generate_ssl_files "${PMA_SSL_KEYS_BASE64}" "CERT" "cert") + export "PMA_SSL_KEYS" +fi + +if [ ! -z "${PMA_SSL_CERTS_BASE64}" ]; then + echo "Adding multiples custom pma-ssl-cert from base64." + PMA_SSL_CERTS=$(generate_ssl_files "${PMA_SSL_CERTS_BASE64}" "KEY" "key") + export "PMA_SSL_CERTS" +fi get_docker_secret() { local env_var="${1}" @@ -42,6 +80,31 @@ get_docker_secret() { fi } +# This function generates SSL files from a base64 encoded string. +# Arguments: +# 1. base64_string: A comma-separated string of base64 encoded SSL files. +# 2. prefix: A prefix to be used in the output file names. +# 3. extension: The file extension to be used for the output files. +# The function creates a directory for the SSL files, decodes each base64 string, +# writes the decoded content to a file, and returns a comma-separated list of the generated file paths. +# +generate_ssl_files() { + local base64_string="${1}" + local output_dir="/etc/phpmyadmin/ssl" + mkdir -p "${output_dir}" + IFS=',' read -ra FILES <<< "${base64_string}" + local counter=1 + local ssl_files="" + for file in "${FILES[@]}"; do + local output_file="${output_dir}/pma-ssl-${2}-${counter}.${3}" + echo "${file}" | base64 -d > "${output_file}" + ssl_files="${ssl_files}${output_file}," + counter=$((counter + 1)) + done + ssl_files="${ssl_files%,}" + echo "${ssl_files}" +} + get_docker_secret PMA_USER get_docker_secret PMA_PASSWORD get_docker_secret MYSQL_ROOT_PASSWORD