diff options
author | Chayim I. Kirshen <c@kirshen.com> | 2021-12-09 18:25:10 +0200 |
---|---|---|
committer | Chayim I. Kirshen <c@kirshen.com> | 2021-12-09 18:25:10 +0200 |
commit | 7365b267e2ac1ad6fd323c9bdb121a560b101337 (patch) | |
tree | 7af3784405327d89cc0daab59bb144b255529650 | |
parent | 72addeca0933a23bffa49637a90ffadf26c4eb0e (diff) | |
download | redis-py-ck-ssl-cert-passwords.tar.gz |
first ssl test - validates an invalid certificateck-ssl-cert-passwords
-rw-r--r-- | .gitignore | 1 | ||||
-rw-r--r-- | dev_requirements.txt | 1 | ||||
-rw-r--r-- | docker/base/Dockerfile | 1 | ||||
-rw-r--r-- | docker/base/Dockerfile.cluster | 3 | ||||
-rw-r--r-- | docker/base/Dockerfile.sentinel | 1 | ||||
-rw-r--r-- | docker/base/Dockerfile.stunnel | 11 | ||||
-rw-r--r-- | docker/stunnel/conf/redis.conf | 6 | ||||
-rwxr-xr-x | docker/stunnel/create_certs.sh | 43 | ||||
-rw-r--r-- | tests/conftest.py | 16 | ||||
-rw-r--r-- | tests/test_ssl.py | 17 | ||||
-rw-r--r-- | tox.ini | 26 |
11 files changed, 116 insertions, 10 deletions
@@ -17,3 +17,4 @@ coverage.xml .venv *.xml .coverage* +docker/stunnel/keys diff --git a/dev_requirements.txt b/dev_requirements.txt index 2a4f377..1d33b98 100644 --- a/dev_requirements.txt +++ b/dev_requirements.txt @@ -6,6 +6,7 @@ pytest==6.2.5 pytest-timeout==2.0.1 tox==3.24.4 tox-docker==3.1.0 +tox-run-before==0.1 invoke==1.6.0 pytest-cov>=3.0.0 vulture>=2.3.0 diff --git a/docker/base/Dockerfile b/docker/base/Dockerfile index 60be374..c76d15d 100644 --- a/docker/base/Dockerfile +++ b/docker/base/Dockerfile @@ -1,3 +1,4 @@ +# produces redisfab/redis-py:6.2.6 FROM redis:6.2.6-buster CMD ["redis-server", "/redis.conf"] diff --git a/docker/base/Dockerfile.cluster b/docker/base/Dockerfile.cluster index 70e8013..70df5ba 100644 --- a/docker/base/Dockerfile.cluster +++ b/docker/base/Dockerfile.cluster @@ -1,3 +1,4 @@ +# produces redisfab/redis-py-cluster:6.2.6 FROM redis:6.2.6-buster COPY create_cluster.sh /create_cluster.sh @@ -5,4 +6,4 @@ RUN chmod +x /create_cluster.sh EXPOSE 16379 16380 16381 16382 16383 16384 -CMD [ "/create_cluster.sh"]
\ No newline at end of file +CMD [ "/create_cluster.sh"] diff --git a/docker/base/Dockerfile.sentinel b/docker/base/Dockerfile.sentinel index 93c16a7..ef659e3 100644 --- a/docker/base/Dockerfile.sentinel +++ b/docker/base/Dockerfile.sentinel @@ -1,3 +1,4 @@ +# produces redisfab/redis-py-sentinel:6.2.6 FROM redis:6.2.6-buster CMD ["redis-sentinel", "/sentinel.conf"] diff --git a/docker/base/Dockerfile.stunnel b/docker/base/Dockerfile.stunnel new file mode 100644 index 0000000..bf45109 --- /dev/null +++ b/docker/base/Dockerfile.stunnel @@ -0,0 +1,11 @@ +# produces redisfab/stunnel:latest +FROM ubuntu:18.04 + +RUN apt-get update -qq --fix-missing +RUN apt-get upgrade -qqy +RUN apt install -qqy stunnel +RUN mkdir -p /etc/stunnel/conf.d +RUN echo "foreground = yes\ninclude = /etc/stunnel/conf.d" > /etc/stunnel/stunnel.conf +RUN chown -R root:root /etc/stunnel/ + +CMD ["/usr/bin/stunnel"] diff --git a/docker/stunnel/conf/redis.conf b/docker/stunnel/conf/redis.conf new file mode 100644 index 0000000..84f6d40 --- /dev/null +++ b/docker/stunnel/conf/redis.conf @@ -0,0 +1,6 @@ +[redis] +accept = 6666 +connect = master:6379 +cert = /etc/stunnel/keys/server-cert.pem +key = /etc/stunnel/keys/server-key.pem +verify = 0 diff --git a/docker/stunnel/create_certs.sh b/docker/stunnel/create_certs.sh new file mode 100755 index 0000000..b94c560 --- /dev/null +++ b/docker/stunnel/create_certs.sh @@ -0,0 +1,43 @@ +#!/bin/bash + +DESTDIR=`dirname "$0"`/keys +if [ ! -d ${DESTDIR} ]; then + mkdir `dirname "$0"`/keys +fi +cd ${DESTDIR} + +SSL_SUBJECT="/C=CA/ST=Winnipeg/L=Manitoba/O=Some Corp/OU=IT Department/CN=example.com" +which openssl &>/dev/null +if [ $? -ne 0 ]; then + echo "No openssl binary present, exiting." + exit 1 +fi + +openssl genrsa -out ca-key.pem 2048 + +openssl req -new -x509 -nodes -days 365000 \ + -key ca-key.pem \ + -out ca-cert.pem \ + -subj "${SSL_SUBJECT}" + +openssl req -newkey rsa:2048 -nodes -days 365000 \ + -keyout server-key.pem \ + -out server-req.pem \ + -subj "${SSL_SUBJECT}" + +openssl x509 -req -days 365000 -set_serial 01 \ + -in server-req.pem \ + -out server-cert.pem \ + -CA ca-cert.pem \ + -CAkey ca-key.pem + +openssl req -newkey rsa:2048 -nodes -days 365000 \ + -keyout client-key.pem \ + -out client-req.pem \ + -subj "${SSL_SUBJECT}" + +openssl x509 -req -days 365000 -set_serial 01 \ + -in client-req.pem \ + -out client-cert.pem \ + -CA ca-cert.pem \ + -CAkey ca-key.pem diff --git a/tests/conftest.py b/tests/conftest.py index 4b5f6cb..65e5369 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -14,6 +14,7 @@ from redis.retry import Retry REDIS_INFO = {} default_redis_url = "redis://localhost:6379/9" +default_redis_ssl_url = "rediss://localhost:6666" default_redismod_url = "redis://localhost:36379" default_cluster_nodes = 6 @@ -35,6 +36,13 @@ def pytest_addoption(parser): " with loaded modules," " defaults to `%(default)s`", ) + + parser.addoption( + "--redis-ssl-url", + default=default_redis_ssl_url, + action="store", + help="Redis SSL connection string," " defaults to `%(default)s`", + ) parser.addoption( "--redis-cluster-nodes", @@ -227,6 +235,14 @@ def modclient(request, **kwargs): redis.Redis, request, from_url=rmurl, decode_responses=True, **kwargs ) as client: yield client + +# @pytest.fixture() +# def sslclient(request, **kwargs): +# ssl_url = request.config.getoption("--redis-ssl-url") +# with _get_client( +# redis.Redis, request, from_url=ssl_url, decode_responses=True, **kwargs +# ) as client: +# yield client @pytest.fixture() diff --git a/tests/test_ssl.py b/tests/test_ssl.py new file mode 100644 index 0000000..4064ae3 --- /dev/null +++ b/tests/test_ssl.py @@ -0,0 +1,17 @@ +import pytest +import redis +from redis.exceptions import ConnectionError + + +class TestSSL: + """Tests for SSL connections""" + + def test_ssl_with_invalid_cert(self, request): + ssl_url = request.config.option.redis_ssl_url + sslclient = redis.from_url(ssl_url) + with pytest.raises(ConnectionError) as e: + sslclient.ping() + assert 'SSL: CERTIFICATE_VERIFY_FAILED' in str(e) + + def test_ssl_connection_creation(self, sslclient): + assert sslclient.ping()
\ No newline at end of file @@ -31,6 +31,7 @@ healtcheck_cmd = python -c "import socket;print(True) if 0 == socket.socket(sock volumes = bind:rw:{toxinidir}/docker/replica/redis.conf:/redis.conf + [docker:sentinel_1] name = sentinel_1 image = redisfab/redis-py-sentinel:6.2.6-buster @@ -91,6 +92,18 @@ healtcheck_cmd = python -c "import socket;print(True) if all([0 == socket.socket volumes = bind:rw:{toxinidir}/docker/cluster/redis.conf:/redis.conf +[docker:stunnel] +name = stunnel +image = redisfab/stunnel:latest +healtcheck_cmd = python -c "import socket;print(True) if 0 == socket.socket(socket.AF_INET, socket.SOCK_STREAM).connect_ex(('127.0.0.1',6666)) else False" +links = + master:master +ports = + 6666:6666/tcp +volumes = + bind:ro:{toxinidir}/docker/stunnel/conf:/etc/stunnel/conf.d + bind:ro:{toxinidir}/docker/stunnel/keys:/etc/stunnel/keys + [isort] profile = black multi_line_output = 3 @@ -107,10 +120,13 @@ docker = sentinel_3 redis_cluster redismod + stunnel extras = hiredis: hiredis setenv = CLUSTER_URL = "redis://localhost:16379/0" +run_before = + {toxinidir}/docker/stunnel/create_certs.sh commands = standalone: pytest --cov=./ --cov-report=xml:coverage_redis.xml -W always -m 'not onlycluster' {posargs} cluster: pytest --cov=./ --cov-report=xml:coverage_cluster.xml -W always -m 'not onlynoncluster and not redismod' --redis-url={env:CLUSTER_URL:} {posargs} @@ -119,15 +135,7 @@ commands = skipsdist = true skip_install = true deps = -r {toxinidir}/dev_requirements.txt -docker = - master - replica - sentinel_1 - sentinel_2 - sentinel_3 - redis_cluster - redismod - lots-of-pythons +docker = {[testenv]docker} commands = /usr/bin/echo [testenv:linters] |