From f34c40503cd1312184c1d9dbe8fe9810a0291b0e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dan=20=C4=8Cerm=C3=A1k?= Date: Thu, 5 Dec 2024 14:17:55 +0100 Subject: [PATCH] Add smoke tests for stunnel --- bci_tester/data.py | 9 ++ pyproject.toml | 1 + tests/files/stunnel/server.crt | 22 ++++ tests/files/stunnel/server.csr | 17 ++++ tests/files/stunnel/server.key | 28 ++++++ tests/files/stunnel/server.pem | 50 +++++++++ tests/files/stunnel/v3.ext | 8 ++ tests/test_metadata.py | 2 + tests/test_stunnel.py | 179 +++++++++++++++++++++++++++++++++ tox.ini | 2 +- 10 files changed, 317 insertions(+), 1 deletion(-) create mode 100644 tests/files/stunnel/server.crt create mode 100644 tests/files/stunnel/server.csr create mode 100644 tests/files/stunnel/server.key create mode 100644 tests/files/stunnel/server.pem create mode 100644 tests/files/stunnel/v3.ext create mode 100644 tests/test_stunnel.py diff --git a/bci_tester/data.py b/bci_tester/data.py index c73e0a29..12b1a0bd 100755 --- a/bci_tester/data.py +++ b/bci_tester/data.py @@ -995,6 +995,14 @@ def create_BCI( ) +STUNNEL_CONTAINER = create_BCI( + build_tag=f"{SAC_CONTAINER_PREFIX}/stunnel:5", + bci_type=ImageType.APPLICATION, + custom_entry_point="/bin/sh", + available_versions=["15.6", "15.7", "tumbleweed"], +) + + CONTAINERS_WITH_ZYPPER = ( [ BASE_CONTAINER, @@ -1005,6 +1013,7 @@ def create_BCI( PHP_8_CLI, PHP_8_FPM, OPENWEBUI_CONTAINER, + STUNNEL_CONTAINER, ] + ALERTMANAGER_CONTAINERS + BASE_FIPS_CONTAINERS diff --git a/pyproject.toml b/pyproject.toml index 6770878f..413a0f9f 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -146,6 +146,7 @@ markers = [ 'bci-sle15-kernel-module-devel_15.7', 'bci-sle16-kernel-module-devel_16.0', 'spack_0.21', + 'stunnel_5', ] [tool.ruff] diff --git a/tests/files/stunnel/server.crt b/tests/files/stunnel/server.crt new file mode 100644 index 00000000..9f587981 --- /dev/null +++ b/tests/files/stunnel/server.crt @@ -0,0 +1,22 @@ +-----BEGIN CERTIFICATE----- +MIIDqzCCApOgAwIBAgIUEaNbfs+EypSJdQ87Wasb8QqHimcwDQYJKoZIhvcNAQEL +BQAwZDELMAkGA1UEBhMCQ1oxDjAMBgNVBAcMBVByYWhhMREwDwYDVQQKDAhTVVNF +IHNybzESMBAGA1UEAwwJMTI3LjAuMC4xMR4wHAYJKoZIhvcNAQkBFg9ub3JlcGx5 +QHN1c2UuY3owHhcNMjQxMjA1MTA1MzU5WhcNMzQxMjAzMTA1MzU5WjBkMQswCQYD +VQQGEwJDWjEOMAwGA1UEBwwFUHJhaGExETAPBgNVBAoMCFNVU0Ugc3JvMRIwEAYD +VQQDDAkxMjcuMC4wLjExHjAcBgkqhkiG9w0BCQEWD25vcmVwbHlAc3VzZS5jejCC +ASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAIy9VjZaTBGsfG5HBDPh4Yxi +PSZOlZt9S2kACXPQBp4FSYx0yo2pPbx+0H9tMyDlLG6jNxxUI7alnbdRoc3vwIvc +87F1t3PH54k7d0Sf0IG81+gV1Or38bHiLLRfFzRSmZHGkSemhvZyYJoBGcSch8wO +eRrTYH48xo7Pq4+79ZBSBFASO127Us72U0Fw5qx8phXG6pmTeAi+YyZJ4HEWlWCO +LvAK4w4kvMS0rKMfLqeym6BwmgKgguQTJYo4D6r4z19Zl5qEVCPjWQI4tisnNZwW +vXthkajuku5+HjDjowIKU7brSCwb6qLZmbtNddEUW1WdQ+8PoE6zenqRClarDfcC +AwEAAaNVMFMwCQYDVR0TBAIwADALBgNVHQ8EBAMCBPAwGgYDVR0RBBMwEYIJbG9j +YWxob3N0hwR/AAABMB0GA1UdDgQWBBQkhtw3ft2EWXbKeyv/GkuvDYZYBTANBgkq +hkiG9w0BAQsFAAOCAQEAYO6kBgtgxNBqgcGbPpMFaRqfl4ZqWWnW/kbylIYO+OFO +12c7+rTdXP9daLjPB4yr1voEsrykc4tmbfObju+dH5CJAbnCZNF1s7/ciBk5Illv +YUkjT6sfvF7T0NKvyinMjLn0qkis0SQZiPpWObZh5o9DssZLCVptbgcQAowZIYvr +O3AHkBqUSYsNFOZRcNo8VEco5mmqRtwZ6TpwPZOLwrRTbz5oO71+uhcI+Nzr9Uc1 +Fp1R+wpnyo7pZ9aJrrbDHz4zx1J6a1y8+LAUyxfbZZn5eG+iTeVytSy++gdp2eiB +D3zuPH9CAunYWH3ARKBQaa0ZFXGkjYO+lV/l3fC8aQ== +-----END CERTIFICATE----- diff --git a/tests/files/stunnel/server.csr b/tests/files/stunnel/server.csr new file mode 100644 index 00000000..051a975f --- /dev/null +++ b/tests/files/stunnel/server.csr @@ -0,0 +1,17 @@ +-----BEGIN CERTIFICATE REQUEST----- +MIICqTCCAZECAQAwZDELMAkGA1UEBhMCQ1oxDjAMBgNVBAcMBVByYWhhMREwDwYD +VQQKDAhTVVNFIHNybzESMBAGA1UEAwwJMTI3LjAuMC4xMR4wHAYJKoZIhvcNAQkB +Fg9ub3JlcGx5QHN1c2UuY3owggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIB +AQCMvVY2WkwRrHxuRwQz4eGMYj0mTpWbfUtpAAlz0AaeBUmMdMqNqT28ftB/bTMg +5SxuozccVCO2pZ23UaHN78CL3POxdbdzx+eJO3dEn9CBvNfoFdTq9/Gx4iy0Xxc0 +UpmRxpEnpob2cmCaARnEnIfMDnka02B+PMaOz6uPu/WQUgRQEjtdu1LO9lNBcOas +fKYVxuqZk3gIvmMmSeBxFpVgji7wCuMOJLzEtKyjHy6nspugcJoCoILkEyWKOA+q ++M9fWZeahFQj41kCOLYrJzWcFr17YZGo7pLufh4w46MCClO260gsG+qi2Zm7TXXR +FFtVnUPvD6BOs3p6kQpWqw33AgMBAAGgADANBgkqhkiG9w0BAQsFAAOCAQEAWGZj +MyTHWxrxvX3r+CO65TGrHFazC9duG9dTcIynJD0AqjhHv54rdMYVM4ct/WhtkTYf +psMxX6LK+fsG8jdZtRgGomGVXnd81dzwozX1BL0LD966i++TLOMmalnBHhIdAopC +BVramLAAOx++xWslG+2DY2320ivnEvinXQTkVCxsTOw7UiAAfPWI+5cExBdw1Zqd +eyXkhCqiy8spfmdAKbLfowFDMtyO4noXSrDgsdtoBdEbd3ZOpCkA6mWboIS1vAGs +jZueOVo8Xw760BbLr/iZiU+H39vlBR5lgoFTon80wW56n9cWmbXpKximaXAbKW4P +z5PAx+cyp/Tt+cTCbA== +-----END CERTIFICATE REQUEST----- diff --git a/tests/files/stunnel/server.key b/tests/files/stunnel/server.key new file mode 100644 index 00000000..1612dafe --- /dev/null +++ b/tests/files/stunnel/server.key @@ -0,0 +1,28 @@ +-----BEGIN PRIVATE KEY----- +MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQCMvVY2WkwRrHxu +RwQz4eGMYj0mTpWbfUtpAAlz0AaeBUmMdMqNqT28ftB/bTMg5SxuozccVCO2pZ23 +UaHN78CL3POxdbdzx+eJO3dEn9CBvNfoFdTq9/Gx4iy0Xxc0UpmRxpEnpob2cmCa +ARnEnIfMDnka02B+PMaOz6uPu/WQUgRQEjtdu1LO9lNBcOasfKYVxuqZk3gIvmMm +SeBxFpVgji7wCuMOJLzEtKyjHy6nspugcJoCoILkEyWKOA+q+M9fWZeahFQj41kC +OLYrJzWcFr17YZGo7pLufh4w46MCClO260gsG+qi2Zm7TXXRFFtVnUPvD6BOs3p6 +kQpWqw33AgMBAAECggEAAO+tgb4zEBcJK51DGVor7RybOAvuwU7RIKosvbG3zh9r +n9zNjH2zs0r+2F1dLOFGNKbIcvxH2Rx84MMPM42KNJGymcWzlh7C63Y+7HDUhoRO +JKTJc0Ws+uBxll/fkO4GmJc7tuG5qL8g9C9f6v6K5LjCq0ELS4rGTW3g3UsH+bXE +Aq00MMDIoyPTpetKrlHMBb3DVdNi0EjvLIoBrz3El3duzeSdwKzFSeQpSjsWVZSG +3egy/1Wg9kQYuxA0SucNPGPOiNZttYFqb9zhOyKV4mxvmkXMK997O+IubYeV5Fww +rGr1EPgkt6q9zzQfjlwD7sO8vGeHlZT1DUdo5lLZ0QKBgQDEA3LmXYtJr+m2ARH8 +ZBGfenbf4/TQN6NS6gZ5eFyHEeBFJnYVdM2Mxtvoa9+uK/WK4hXqnb5B+LHUNC3h +mSW/PtTre5aTSbjbwnXLnDC8PxYJ9ENrPk5PVL8/dPmMsdkXhc7xjfb/yQXxI2OU +4NKQesF/51UJ8JidCJH7QrgkGQKBgQC3z33BZ8RiJrZaoNcWs6T1D4kOMFsnyJjK +A6K3Fk6uPSZY4LiyIcQGP2YOdWdEXYmiFFkL+ZAXI7MbgWmzURs9e/6vd4hrCwf6 +rZC2+izAvnkx6YPCWcjVzI3Zc4OM3+OnxympBOF5KfgruJWZFZ6McIS30TcpwUqP +F6ICbwKEjwKBgQCu7wkHcSrTS6z/4vqjTsevlcMr06z0ewNHB1dZ50JkxV5rOIUg +ZwrffcZbKpMJRXAxT88RgVCAXiyO3zanZV+by76Intbmgl/5uRYZ7j5Mctz/a0EU +IBoRkOfSAVqJ51uBM8laKUHsTAMCj3vbLb6edP/mX5W0dkYtt61ZGdVvWQKBgQCs +rFFY5SBJjFB2Zu5oNy7ZwFRibe7UOs+9xxiOongbmvpxN/qJ7Mp3jAtVvdjbEnv/ +NNpKM5G3CyRwzGv9tk2+vsMNF1+iH2TJi0+NdQuhrc2wo8vRQgM3Rchj5O5J4vG8 +ZY6vZxRhfJnUiLyQaQzepb0n6XTG1vwx3GOnoZ1d5QKBgGfQYZ76iCUz0lxjfTqF +JTAbVgK2XcGqHGWRegtFuJD6Ela6SFl3lCsIeGHjH9HmSTgftbCjXtF6CA6/j4AM +ILLFM9kOeXmFwupQADld2xQeLFHKkWVU1hRucAGhwRwUQGryjBsPqdWbl2idn7dU +MQPvY9msA82TU56CrfZsfRMO +-----END PRIVATE KEY----- diff --git a/tests/files/stunnel/server.pem b/tests/files/stunnel/server.pem new file mode 100644 index 00000000..d3add786 --- /dev/null +++ b/tests/files/stunnel/server.pem @@ -0,0 +1,50 @@ +-----BEGIN CERTIFICATE----- +MIIDqzCCApOgAwIBAgIUEaNbfs+EypSJdQ87Wasb8QqHimcwDQYJKoZIhvcNAQEL +BQAwZDELMAkGA1UEBhMCQ1oxDjAMBgNVBAcMBVByYWhhMREwDwYDVQQKDAhTVVNF +IHNybzESMBAGA1UEAwwJMTI3LjAuMC4xMR4wHAYJKoZIhvcNAQkBFg9ub3JlcGx5 +QHN1c2UuY3owHhcNMjQxMjA1MTA1MzU5WhcNMzQxMjAzMTA1MzU5WjBkMQswCQYD +VQQGEwJDWjEOMAwGA1UEBwwFUHJhaGExETAPBgNVBAoMCFNVU0Ugc3JvMRIwEAYD +VQQDDAkxMjcuMC4wLjExHjAcBgkqhkiG9w0BCQEWD25vcmVwbHlAc3VzZS5jejCC +ASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAIy9VjZaTBGsfG5HBDPh4Yxi +PSZOlZt9S2kACXPQBp4FSYx0yo2pPbx+0H9tMyDlLG6jNxxUI7alnbdRoc3vwIvc +87F1t3PH54k7d0Sf0IG81+gV1Or38bHiLLRfFzRSmZHGkSemhvZyYJoBGcSch8wO +eRrTYH48xo7Pq4+79ZBSBFASO127Us72U0Fw5qx8phXG6pmTeAi+YyZJ4HEWlWCO +LvAK4w4kvMS0rKMfLqeym6BwmgKgguQTJYo4D6r4z19Zl5qEVCPjWQI4tisnNZwW +vXthkajuku5+HjDjowIKU7brSCwb6qLZmbtNddEUW1WdQ+8PoE6zenqRClarDfcC +AwEAAaNVMFMwCQYDVR0TBAIwADALBgNVHQ8EBAMCBPAwGgYDVR0RBBMwEYIJbG9j +YWxob3N0hwR/AAABMB0GA1UdDgQWBBQkhtw3ft2EWXbKeyv/GkuvDYZYBTANBgkq +hkiG9w0BAQsFAAOCAQEAYO6kBgtgxNBqgcGbPpMFaRqfl4ZqWWnW/kbylIYO+OFO +12c7+rTdXP9daLjPB4yr1voEsrykc4tmbfObju+dH5CJAbnCZNF1s7/ciBk5Illv +YUkjT6sfvF7T0NKvyinMjLn0qkis0SQZiPpWObZh5o9DssZLCVptbgcQAowZIYvr +O3AHkBqUSYsNFOZRcNo8VEco5mmqRtwZ6TpwPZOLwrRTbz5oO71+uhcI+Nzr9Uc1 +Fp1R+wpnyo7pZ9aJrrbDHz4zx1J6a1y8+LAUyxfbZZn5eG+iTeVytSy++gdp2eiB +D3zuPH9CAunYWH3ARKBQaa0ZFXGkjYO+lV/l3fC8aQ== +-----END CERTIFICATE----- +-----BEGIN PRIVATE KEY----- +MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQCMvVY2WkwRrHxu +RwQz4eGMYj0mTpWbfUtpAAlz0AaeBUmMdMqNqT28ftB/bTMg5SxuozccVCO2pZ23 +UaHN78CL3POxdbdzx+eJO3dEn9CBvNfoFdTq9/Gx4iy0Xxc0UpmRxpEnpob2cmCa +ARnEnIfMDnka02B+PMaOz6uPu/WQUgRQEjtdu1LO9lNBcOasfKYVxuqZk3gIvmMm +SeBxFpVgji7wCuMOJLzEtKyjHy6nspugcJoCoILkEyWKOA+q+M9fWZeahFQj41kC +OLYrJzWcFr17YZGo7pLufh4w46MCClO260gsG+qi2Zm7TXXRFFtVnUPvD6BOs3p6 +kQpWqw33AgMBAAECggEAAO+tgb4zEBcJK51DGVor7RybOAvuwU7RIKosvbG3zh9r +n9zNjH2zs0r+2F1dLOFGNKbIcvxH2Rx84MMPM42KNJGymcWzlh7C63Y+7HDUhoRO +JKTJc0Ws+uBxll/fkO4GmJc7tuG5qL8g9C9f6v6K5LjCq0ELS4rGTW3g3UsH+bXE +Aq00MMDIoyPTpetKrlHMBb3DVdNi0EjvLIoBrz3El3duzeSdwKzFSeQpSjsWVZSG +3egy/1Wg9kQYuxA0SucNPGPOiNZttYFqb9zhOyKV4mxvmkXMK997O+IubYeV5Fww +rGr1EPgkt6q9zzQfjlwD7sO8vGeHlZT1DUdo5lLZ0QKBgQDEA3LmXYtJr+m2ARH8 +ZBGfenbf4/TQN6NS6gZ5eFyHEeBFJnYVdM2Mxtvoa9+uK/WK4hXqnb5B+LHUNC3h +mSW/PtTre5aTSbjbwnXLnDC8PxYJ9ENrPk5PVL8/dPmMsdkXhc7xjfb/yQXxI2OU +4NKQesF/51UJ8JidCJH7QrgkGQKBgQC3z33BZ8RiJrZaoNcWs6T1D4kOMFsnyJjK +A6K3Fk6uPSZY4LiyIcQGP2YOdWdEXYmiFFkL+ZAXI7MbgWmzURs9e/6vd4hrCwf6 +rZC2+izAvnkx6YPCWcjVzI3Zc4OM3+OnxympBOF5KfgruJWZFZ6McIS30TcpwUqP +F6ICbwKEjwKBgQCu7wkHcSrTS6z/4vqjTsevlcMr06z0ewNHB1dZ50JkxV5rOIUg +ZwrffcZbKpMJRXAxT88RgVCAXiyO3zanZV+by76Intbmgl/5uRYZ7j5Mctz/a0EU +IBoRkOfSAVqJ51uBM8laKUHsTAMCj3vbLb6edP/mX5W0dkYtt61ZGdVvWQKBgQCs +rFFY5SBJjFB2Zu5oNy7ZwFRibe7UOs+9xxiOongbmvpxN/qJ7Mp3jAtVvdjbEnv/ +NNpKM5G3CyRwzGv9tk2+vsMNF1+iH2TJi0+NdQuhrc2wo8vRQgM3Rchj5O5J4vG8 +ZY6vZxRhfJnUiLyQaQzepb0n6XTG1vwx3GOnoZ1d5QKBgGfQYZ76iCUz0lxjfTqF +JTAbVgK2XcGqHGWRegtFuJD6Ela6SFl3lCsIeGHjH9HmSTgftbCjXtF6CA6/j4AM +ILLFM9kOeXmFwupQADld2xQeLFHKkWVU1hRucAGhwRwUQGryjBsPqdWbl2idn7dU +MQPvY9msA82TU56CrfZsfRMO +-----END PRIVATE KEY----- diff --git a/tests/files/stunnel/v3.ext b/tests/files/stunnel/v3.ext new file mode 100644 index 00000000..68e35be8 --- /dev/null +++ b/tests/files/stunnel/v3.ext @@ -0,0 +1,8 @@ +authorityKeyIdentifier=keyid,issuer +basicConstraints=CA:FALSE +keyUsage = digitalSignature, nonRepudiation, keyEncipherment, dataEncipherment +subjectAltName = @alt_names + +[alt_names] +DNS.1 = localhost +IP.1 = 127.0.0.1 diff --git a/tests/test_metadata.py b/tests/test_metadata.py index c78e2573..7baa6dec 100644 --- a/tests/test_metadata.py +++ b/tests/test_metadata.py @@ -85,6 +85,7 @@ from bci_tester.data import RUST_CONTAINERS from bci_tester.data import SAC_PYTHON_CONTAINERS from bci_tester.data import SPACK_CONTAINERS +from bci_tester.data import STUNNEL_CONTAINER from bci_tester.data import TOMCAT_CONTAINERS from bci_tester.data import ImageType from bci_tester.runtime_choice import PODMAN_SELECTED @@ -286,6 +287,7 @@ def _get_container_label_prefix( (OPENWEBUI_CONTAINER, "open-webui", ImageType.SAC_APPLICATION), (MILVUS_CONTAINER, "milvus", ImageType.SAC_APPLICATION), ] + + [(STUNNEL_CONTAINER, "stunnel", ImageType.APPLICATION)] ] diff --git a/tests/test_stunnel.py b/tests/test_stunnel.py new file mode 100644 index 00000000..d5dc4d5d --- /dev/null +++ b/tests/test_stunnel.py @@ -0,0 +1,179 @@ +"""Test module for the stunnel container image. + +Stunnel requires a certificate to create TLS connections. We create a self +signed certificate for that in the :file:`tests/files/stunnel/` directory as +follows: + +.. code-block:: shell-session + + $ openssl genrsa -out server.key 2048 + $ openssl req -new -key server.key -out server.csr + $ openssl x509 -req -days 3650 -in server.csr -signkey server.key -out server.crt -extfile v3.ext + $ cat server.crt server.key > server.pem + +The :command:`openssl req` call will ask for some input, you may provide it with +any content that you like. + +""" + +from pathlib import Path + +import pytest +import requests +import tenacity +from _pytest.mark import ParameterSet +from pytest_container import BindMount +from pytest_container import DerivedContainer +from pytest_container import PortForwarding +from pytest_container import container_and_marks_from_pytest_param +from pytest_container.container import ContainerData +from pytest_container.pod import Pod +from pytest_container.pod import PodData + +from bci_tester.data import STUNNEL_CONTAINER + +_stunnel_ctr, _marks = container_and_marks_from_pytest_param(STUNNEL_CONTAINER) +_stunnel_kwargs = _stunnel_ctr.__dict__ +for key in [ + "custom_entry_point", + "extra_environment_variables", + "containerfile", + "forwarded_ports", +]: + _stunnel_kwargs.pop(key) + +_cert_dir = Path(__file__).parent / "files" / "stunnel" +_SERVER_PEM = str(_cert_dir / "server.pem") + +_stunnel_kwargs["volume_mounts"].extend( + [ + BindMount( + container_path="/etc/stunnel/stunnel.pem", + host_path=_SERVER_PEM, + ), + BindMount( + container_path="/etc/stunnel/stunnel.key", + host_path=str(_cert_dir / "server.key"), + ), + ] +) + +_STUNNEL_PYTHON_HTTP_TUNNEL_CTR = DerivedContainer( + **_stunnel_kwargs, + extra_environment_variables={ + "STUNNEL_DEBUG": "info", + "STUNNEL_SERVICE_NAME": "python", + "STUNNEL_ACCEPT": "0.0.0.0:8443", + "STUNNEL_CONNECT": "0.0.0.0:8000", + }, +) + +_PYTHON_WEB_SERVER = DerivedContainer( + base="registry.suse.com/bci/python", + containerfile=""" +RUN echo "hello world" > index.html +ENTRYPOINT ["python3", "-m", "http.server"] +""", +) + + +_STUNNEL_POD = pytest.param( + Pod( + containers=[_PYTHON_WEB_SERVER, _STUNNEL_PYTHON_HTTP_TUNNEL_CTR], + forwarded_ports=[PortForwarding(container_port=8443)], + ), + marks=_marks, +) + + +@pytest.mark.parametrize("pod", [_STUNNEL_POD], indirect=True) +def test_stunnel_http_proxy(pod: PodData): + """Smoke test for stunnel to wrap a python http server in a TLS connection + using the generated certificate. The python web server is running in its own + container and stunnel in another one both in a single pod that only exposes + the TLS endpoint. + + """ + + @tenacity.retry( + stop=tenacity.stop_after_attempt(5), wait=tenacity.wait_exponential() + ) + def get_request_to_stunnel(route: str = "") -> requests.Response: + resp = requests.get( + f"https://127.0.0.1:{pod.forwarded_ports[0].host_port}/{route}", + verify=_SERVER_PEM, + timeout=5, + ) + resp.raise_for_status() + return resp + + assert "hello world" in get_request_to_stunnel().text + + +_CTR_PORT = 8000 + + +def _create_http_forward_ctr(log_level: str = "info") -> ParameterSet: + return pytest.param( + DerivedContainer( + **_stunnel_kwargs, + forwarded_ports=[PortForwarding(container_port=_CTR_PORT)], + extra_environment_variables={ + "STUNNEL_DEBUG": log_level, + "STUNNEL_SERVICE_NAME": "wikipedia_dot_org", + "STUNNEL_ACCEPT": f"0.0.0.0:{_CTR_PORT}", + "STUNNEL_CONNECT": "wikipedia.org:80", + }, + ), + marks=_marks, + id=STUNNEL_CONTAINER.id, + ) + + +@pytest.mark.parametrize( + "container", [_create_http_forward_ctr()], indirect=True +) +def test_http_tunnel_to_suse_dot_com(container: ContainerData) -> None: + """Simple smoke test of stunnel wrapping the HTTP connection to + wikipedia.org with TLS. + + """ + + @tenacity.retry( + stop=tenacity.stop_after_attempt(5), wait=tenacity.wait_exponential() + ) + def get_request_to_stunnel(route: str = "") -> requests.Response: + resp = requests.get( + f"https://127.0.0.1:{container.forwarded_ports[0].host_port}/{route}", + verify=_SERVER_PEM, + timeout=5, + # wikipedia.org tries to redirect to TLS version, but we don't want + # that for the purpose of this test + allow_redirects=False, + ) + resp.raise_for_status() + return resp + + resp = get_request_to_stunnel() + assert resp.status_code >= 300 and resp.status_code < 400 + + +@pytest.mark.parametrize( + "container, log_level", + [(_create_http_forward_ctr("6"), 6), (_create_http_forward_ctr("1"), 1)], + indirect=["container"], +) +def test_stunnel_logging(container: ContainerData, log_level: int) -> None: + """Check that stunnel logging can be configured via the environment variable + `STUNNEL_DEBUG`. + + """ + _startup_log_levels = (5, 6) + logs = container.read_container_logs() + + for search_log_level in range(7): + if search_log_level <= log_level: + if search_log_level in _startup_log_levels: + assert f"LOG{search_log_level}" in logs + else: + assert f"LOG{search_log_level}" not in logs diff --git a/tox.ini b/tox.ini index 4e4adf9c..24a4bebc 100644 --- a/tox.ini +++ b/tox.ini @@ -1,5 +1,5 @@ [tox] -envlist = {py36,py39,py310,py311,py312,py313}-unit, all, base, cosign, fips, init, dotnet, python, ruby, node, go, openjdk, openjdk_devel, rust, php, busybox, 389ds, metadata, minimal, multistage, repository, doc, lint, get_urls, pcp, distribution, postgres, git, helm, nginx, kernel_module, mariadb, tomcat, spack, gcc, prometheus, grafana, kiwi, postfix, ai +envlist = {py36,py39,py310,py311,py312,py313}-unit, all, base, cosign, fips, init, dotnet, python, ruby, node, go, openjdk, openjdk_devel, rust, php, busybox, 389ds, metadata, minimal, multistage, repository, doc, lint, get_urls, pcp, distribution, postgres, git, helm, nginx, kernel_module, mariadb, tomcat, spack, gcc, prometheus, grafana, kiwi, postfix, ai, stunnel skip_missing_interpreters = True [common]