Test the SSL connection (#441)

This commit is contained in:
William Desportes
2025-01-15 00:05:15 +01:00
parent 9fca4e0022
commit ab37078704
8 changed files with 244 additions and 8 deletions
+1 -1
View File
@@ -15,7 +15,7 @@ jobs:
fail-fast: false
matrix:
database-image: ["mariadb:10.6", "mariadb:10.11", "mariadb:latest", "mysql:5.7", "mysql:latest"]
configuration: ["default", "one-host", "one-socket-host", "config-mount-dir", "fs-import-export", "different-apache-port", "run-as-www-data"]
configuration: ["default", "one-host", "one-socket-host", "config-mount-dir", "fs-import-export", "different-apache-port", "run-as-www-data", "one-ssl-host"]
steps:
- uses: actions/checkout@v4
+1 -1
View File
@@ -22,7 +22,7 @@ testing-%:
docker compose -p "phpmyadmin_$@" -f ./testing/docker-compose/docker-compose.$@.yml up --build --abort-on-container-exit --exit-code-from=sut
docker compose -p "phpmyadmin_$@" -f ./testing/docker-compose/docker-compose.$@.yml down
run-tests: testing-default testing-one-host testing-one-socket-host testing-config-mount-dir testing-fs-import-export testing-different-apache-port testing-run-as-www-data
run-tests: testing-default testing-one-host testing-one-socket-host testing-config-mount-dir testing-fs-import-export testing-different-apache-port testing-run-as-www-data testing-one-ssl-host
logs:
docker compose -f ./testing/docker-compose/docker-compose.testing-default.yml logs
+5
View File
@@ -4,6 +4,7 @@ def pytest_addoption(parser):
parser.addoption("--url")
parser.addoption("--username")
parser.addoption("--password")
parser.addoption("--root-password")
parser.addoption("--server")
parser.addoption("--sqlfile")
@@ -19,6 +20,10 @@ def username(request):
def password(request):
return request.config.getoption("--password")
@pytest.fixture
def root_password(request):
return request.config.getoption("--root-password")
@pytest.fixture
def server(request):
return request.config.getoption("--server")
@@ -0,0 +1,105 @@
version: "3.1"
services:
db_server:
image: ${DB:-mariadb:11}
command:
- "--plugin_load_add=server_audit"
- "--server_audit=FORCE_PLUS_PERMANENT"
- "--server_audit_events=connect"
- "--server_audit_logging"
#- "--server_audit_file_path=/var/log/mariadb-audit/audit.log"
- "--ssl-ca=/etc/phpmyadmin/ssl/ca-cert.pem"
- "--ssl-cert=/etc/phpmyadmin/ssl/server-cert.pem"
- "--ssl-key=/etc/phpmyadmin/ssl/server-key.pem"
- "--require-secure-transport=ON"
- "--server-audit-logging=ON"
environment:
MARIADB_USER: secure-user
MARIADB_PASSWORD: "${TESTSUITE_PASSWORD:-my-secret-pw}"
MARIADB_ROOT_PASSWORD: "${TESTSUITE_ROOT_PASSWORD:-random-pass}"
# The database name used in the import test
MARIADB_DATABASE: World
healthcheck:
test: ["CMD", "mariadb-admin", "ping", "-uroot", "-prandom-pass"]
start_period: 10s
interval: 5s
timeout: 60s
retries: 10
networks:
testing:
aliases:
- mariadb.phpmyadmin.local
tmpfs:
- /var/lib/mysql:rw,noexec,nosuid,size=300m
volumes:
#- ../secure-user.sql:/docker-entrypoint-initdb.d/secure-user.sql:ro
- ../ca-cert.pem:/etc/phpmyadmin/ssl/ca-cert.pem:ro
- ../ca-key.pem:/etc/phpmyadmin/ssl/ca-key.pem:ro
- ../server-cert.pem:/etc/phpmyadmin/ssl/server-cert.pem:ro
- ../server-key.pem:/etc/phpmyadmin/ssl/server-key.pem:ro
#- ../mariadb-audit:/var/log/mariadb-audit
phpmyadmin:
build:
context: ../../apache
environment:
PMA_HOST: mariadb.phpmyadmin.local
PMA_SSL: 1
PMA_SSL_VERIFY: 1
PMA_SSL_CA: /etc/phpmyadmin/ssl/ca-cert.pem
PMA_SSL_CERT: /etc/phpmyadmin/ssl/client-cert.pem
PMA_SSL_KEY: /etc/phpmyadmin/ssl/client-key.pem
UPLOAD_LIMIT: 123M
MAX_EXECUTION_TIME: 125
HIDE_PHP_VERSION: 1
volumes:
- ../config.user.inc.php:/etc/phpmyadmin/config.user.inc.php:ro
- ../ca-cert.pem:/etc/phpmyadmin/ssl/ca-cert.pem:ro
- ../client-cert.pem:/etc/phpmyadmin/ssl/client-cert.pem:ro
- ../client-key.pem:/etc/phpmyadmin/ssl/client-key.pem:ro
healthcheck:
test: ["CMD", "curl", "-Ss", "http://localhost/robots.txt"]
start_period: 5s
interval: 3s
timeout: 60s
retries: 10
networks:
testing:
aliases:
- phpmyadmin_testing_apache
depends_on:
db_server:
condition: service_healthy
sut:
depends_on:
phpmyadmin:
condition: service_healthy
db_server:
condition: service_healthy
build:
context: ../
command: "/tests/testing/test-docker.sh"
networks:
testing:
environment:
TESTSUITE_HOSTNAME: phpmyadmin_testing_apache
TESTSUITE_PORT: 80
TESTSUITE_USER: secure-user
TESTSUITE_PASSWORD: "${TESTSUITE_PASSWORD:-my-secret-pw}"
TESTSUITE_ROOT_PASSWORD: "${TESTSUITE_ROOT_PASSWORD:-random-pass}"
PMA_HOST: mariadb.phpmyadmin.local
PMA_PORT: 3306
IS_USING_SSL: true
volumes:
- ../ca-cert.pem:/etc/phpmyadmin/ssl/ca-cert.pem:ro
- ../server-cert.pem:/etc/phpmyadmin/ssl/server-cert.pem:ro
- ../client-cert.pem:/etc/phpmyadmin/ssl/client-cert.pem:ro
- ../client-key.pem:/etc/phpmyadmin/ssl/client-key.pem:ro
- ../../:/tests:ro
working_dir: /tests
networks:
testing:
driver: bridge
+37
View File
@@ -0,0 +1,37 @@
#!/bin/sh
set -eu
# Source: https://github.com/chio-nzgft/docker-MariaDB-with-SSL
# See: https://dev.mysql.com/doc/refman/5.7/en/creating-ssl-files-using-openssl.html
ROOT_DIR="$(realpath $(dirname $0))"
echo "Using root dir: $ROOT_DIR"
cd "$ROOT_DIR"
rm -f *.pem
SUBJECT_CA="/C=US/O=phpMyAdmin testing/OU=Docker/CN=ssl-ca.phpmyadmin.local/emailAddress=ssl-ca@example.org"
SUBJECT_CLIENT="/C=US/O=phpMyAdmin testing/OU=Docker/CN=client.phpmyadmin.local/emailAddress=secure-user@example.org"
SUBJECT_SERVER="/C=US/O=phpMyAdmin testing/OU=Docker/CN=mariadb.phpmyadmin.local"
echo "CA key"
openssl genrsa 2048 > ca-key.pem
openssl req -new -x509 -nodes -days 3600 -subj "${SUBJECT_CA}" -key ca-key.pem -out ca-cert.pem
echo "server key"
openssl req -subj "${SUBJECT_SERVER}" -newkey rsa:2048 -days 3600 -nodes -keyout server-key.pem -out server-req.pem
openssl rsa -in server-key.pem -out server-key.pem
openssl x509 -req -in server-req.pem -days 3600 -CA ca-cert.pem -CAkey ca-key.pem -set_serial 01 -out server-cert.pem
echo "client key"
openssl req -subj "${SUBJECT_CLIENT}" -newkey rsa:2048 -days 3600 -nodes -keyout client-key.pem -out client-req.pem
openssl rsa -in client-key.pem -out client-key.pem
openssl x509 -req -in client-req.pem -days 3600 -CA ca-cert.pem -CAkey ca-key.pem -set_serial 01 -out client-cert.pem
echo "check key ok"
openssl verify -CAfile ca-cert.pem server-cert.pem client-cert.pem
chmod 666 *.pem
+36 -2
View File
@@ -58,7 +58,9 @@ def test_import(url, username, password, server, sqlfile):
br.select_form('import')
br.form.add_file(open(sqlfile), 'text/plain', sqlfile)
response = br.submit()
assert(b'5326 queries executed' in response.read())
response = response.read()
assert(b'5326 queries executed' in response)
def docker_secret(env_name):
@@ -89,14 +91,46 @@ def test_phpmyadmin_secrets():
docker_secret('PMA_CONTROLUSER')
docker_secret('PMA_CONTROLPASS')
def test_is_using_ssl(url, username, password, server):
is_using_ssl = os.environ.get('IS_USING_SSL');
br = create_browser()
response = do_login(br, url, username, password, server)
response = response.read()
assert(b'Server connection' in response)
if is_using_ssl:
assert(b'SSL is used' in response)
assert(b'SSL is not being used' not in response)
else:
assert(b'SSL is used' not in response)
assert(b'SSL is not being used' in response)
def test_is_using_ssl_client_cert(url, server):
is_using_ssl = os.environ.get('IS_USING_SSL');
if not is_using_ssl:
pytest.skip("Missing IS_USING_SSL ENV", allow_module_level=True)
br = create_browser()
password = ""
response = do_login(br, url, "ssl-specific-user", password, server)
response = response.read()
assert(b'Server connection' in response)
assert(b'ssl-specific-user@' in response)
assert(b'SSL is used' in response)
assert(b'SSL is not being used' not in response)
def test_php_ini(url, username, password, server):
skip_expose_php_test = os.environ.get('SKIP_EXPOSE_PHP_TEST');
br = create_browser()
response = do_login(br, url, username, password, server)
response = response.read()
assert(b'Show PHP information' in response.read())
assert(b'Show PHP information' in response)
# Open Show PHP information
response = br.follow_link(text_regex=re.compile('Show PHP information'))
View File
+59 -4
View File
@@ -1,5 +1,7 @@
#!/bin/sh
set -eu
# Set phpMyAdmin environment
PHPMYADMIN_HOSTNAME=${TESTSUITE_HOSTNAME:=localhost}
PHPMYADMIN_PORT=${TESTSUITE_PORT:=80}
@@ -8,9 +10,24 @@ PHPMYADMIN_URL=http://${PHPMYADMIN_HOSTNAME}:${PHPMYADMIN_PORT}/
# Set database environment
PHPMYADMIN_DB_HOSTNAME=${PMA_HOST:=localhost}
PHPMYADMIN_DB_PORT=${PMA_PORT:=3306}
TESTSUITE_USER=${TESTSUITE_USER:=root}
TESTSUITE_ROOT_PASSWORD=${TESTSUITE_ROOT_PASSWORD:-}
if [ ! -z "${TESTSUITE_HOSTNAME_ARBITRARY}" ]; then
SERVER="--server ${PHPMYADMIN_DB_HOSTNAME}"
SUBJECT_CA="/C=US/O=phpMyAdmin testing/OU=Docker/CN=ssl-ca.phpmyadmin.local/emailAddress=ssl-ca@example.org"
SUBJECT_CLIENT="/C=US/O=phpMyAdmin testing/OU=Docker/CN=client.phpmyadmin.local/emailAddress=secure-user@example.org"
if [ "${TESTSUITE_USER}" = "root" ] && [ -n "${TESTSUITE_ROOT_PASSWORD}" ]; then
echo "Do not use TESTSUITE_ROOT_PASSWORD with TESTSUITE_USER=root"
exit 1
fi
TEST_CLI_ARGS=""
if [ -n "${TESTSUITE_HOSTNAME_ARBITRARY:-}" ]; then
TEST_CLI_ARGS="$TEST_CLI_ARGS --server ${PHPMYADMIN_DB_HOSTNAME}"
fi
if [ -n "${TESTSUITE_ROOT_PASSWORD}" ]; then
TEST_CLI_ARGS="$TEST_CLI_ARGS --root-password ${TESTSUITE_ROOT_PASSWORD}"
fi
# Find test script
@@ -20,7 +37,45 @@ else
FILENAME=./testing/phpmyadmin_test.py
fi
mariadb -h "${PHPMYADMIN_DB_HOSTNAME}" -P"${PHPMYADMIN_DB_PORT}" -u"${TESTSUITE_USER:=root}" -p"${TESTSUITE_PASSWORD}" --skip-ssl -e "SELECT @@version;" > /dev/null
SSL_FLAG="--skip-ssl"
if [ -n "${IS_USING_SSL:-}" ]; then
SSL_FLAG="--ssl --ssl-verify-server-cert --ssl-ca=/etc/phpmyadmin/ssl/ca-cert.pem"
fi
mariadb $SSL_FLAG -h "${PHPMYADMIN_DB_HOSTNAME}" -P"${PHPMYADMIN_DB_PORT}" -u"$TESTSUITE_USER" -p"${TESTSUITE_PASSWORD}" -e "SELECT @@version;SHOW VARIABLES LIKE 'require_secure_transport';SHOW VARIABLES LIKE '%ssl%';"
if [ -n "${IS_USING_SSL:-}" ]; then
set +e
mariadb --skip-ssl -h "${PHPMYADMIN_DB_HOSTNAME}" -P"${PHPMYADMIN_DB_PORT}" -u"$TESTSUITE_USER" -p"${TESTSUITE_PASSWORD}" -e "SELECT @@version;SHOW VARIABLES LIKE 'require_secure_transport';" 1> /dev/null 2> /dev/null
if [ $? != 1 ]; then
echo "The server does not enforce SSL connections, stopping the test."
exit 1
fi
set -e
fi
if [ -n "${IS_USING_SSL:-}" ] && [ -n "${TESTSUITE_ROOT_PASSWORD}" ]; then
mariadb $SSL_FLAG -h "${PHPMYADMIN_DB_HOSTNAME}" -P"${PHPMYADMIN_DB_PORT}" -u"root" -p"${TESTSUITE_ROOT_PASSWORD}" \
-e "CREATE USER 'ssl-specific-user'@'%' REQUIRE SUBJECT '$SUBJECT_CLIENT' AND ISSUER '$SUBJECT_CA';"
set +e
mariadb $SSL_FLAG --ssl-cert=/etc/phpmyadmin/ssl/client-cert.pem --ssl-key=/etc/phpmyadmin/ssl/client-key.pem -h "${PHPMYADMIN_DB_HOSTNAME}" -P"${PHPMYADMIN_DB_PORT}" -u"ssl-specific-user" -e "SELECT @@version;SHOW VARIABLES LIKE 'require_secure_transport';" 1> /dev/null 2> /dev/null
if [ $? != 0 ]; then
echo "The server should accept the SSL client cert login, stopping the test."
exit 1
fi
set -e
set +e
mariadb $SSL_FLAG -h "${PHPMYADMIN_DB_HOSTNAME}" -P"${PHPMYADMIN_DB_PORT}" -u"ssl-specific-user" -e "SELECT @@version;SHOW VARIABLES LIKE 'require_secure_transport';" 1> /dev/null 2> /dev/null
if [ $? != 1 ]; then
echo "The server should refuse the login without a client cert, stopping the test."
exit 1
fi
set -e
fi
ret=$?
if [ $ret -ne 0 ] ; then
@@ -38,7 +93,7 @@ fi
# Perform tests
ret=0
pytest -p no:cacheprovider -q --url "$PHPMYADMIN_URL" --username ${TESTSUITE_USER:=root} --password "$TESTSUITE_PASSWORD" $SERVER $FILENAME
pytest -p no:cacheprovider -q --url "$PHPMYADMIN_URL" --username $TESTSUITE_USER --password "$TESTSUITE_PASSWORD" $TEST_CLI_ARGS $FILENAME
ret=$?
# Show debug output in case of failure