Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .test/config.sh
Original file line number Diff line number Diff line change
Expand Up @@ -6,5 +6,6 @@ imageTests+=(
valkey-basics-tls
valkey-basics-config
valkey-basics-persistent
valkey-ssl-cert
'
)
158 changes: 158 additions & 0 deletions .test/tests/valkey-ssl-cert/run.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,158 @@
#!/usr/bin/env bash
set -eo pipefail

dir="$(dirname "$(readlink -f "$BASH_SOURCE")")"
testDir="$(readlink -f "$(dirname "$BASH_SOURCE")")"
testName="$(basename "$testDir")"

image="$1"

# Determine if this is Alpine or Debian variant
imageVariant="$(docker run --rm --entrypoint sh "$image" -c 'if [ -f /etc/alpine-release ]; then echo alpine; else echo debian; fi')"

network="valkey-network-$RANDOM-$RANDOM"
docker network create "$network" >/dev/null

cname="valkey-container-$RANDOM-$RANDOM"
cid="$(docker run -d --name "$cname" --network "$network" "$image")"

trap "docker rm -vf '$cid' >/dev/null; docker network rm '$network' >/dev/null" EXIT

# Test OpenSSL is available
echo "Testing OpenSSL availability..."
docker exec "$cid" openssl version >/dev/null
echo "✓ OpenSSL is accessible"

# Test make-ssl-cert functionality
if [ "$imageVariant" = "alpine" ]; then
echo "Testing Alpine make-ssl-cert..."

# Test basic certificate generation
docker exec "$cid" make-ssl-cert /tmp/test.pem /tmp/test.key

# Verify files exist
docker exec "$cid" test -f /tmp/test.pem
docker exec "$cid" test -f /tmp/test.key

# Test nested directory creation
docker exec "$cid" make-ssl-cert /deep/nested/cert.pem /another/path/key.pem
docker exec "$cid" test -f /deep/nested/cert.pem
docker exec "$cid" test -f /another/path/key.pem

# Test error handling
if docker exec "$cid" make-ssl-cert 2>/dev/null; then
echo "ERROR: Should have failed with no arguments"
exit 1
fi

if docker exec "$cid" make-ssl-cert /tmp/only-one 2>/dev/null; then
echo "ERROR: Should have failed with one argument"
exit 1
fi

else
echo "Testing Debian make-ssl-cert..."

# Test standard generation
docker exec "$cid" env DEBIAN_FRONTEND=noninteractive make-ssl-cert generate-default-snakeoil

# Verify files exist
docker exec "$cid" test -f /etc/ssl/certs/ssl-cert-snakeoil.pem
docker exec "$cid" test -f /etc/ssl/private/ssl-cert-snakeoil.key
fi

# Common tests for both variants
echo "Testing certificate validity..."

if [ "$imageVariant" = "alpine" ]; then
certFile="/tmp/test.pem"
keyFile="/tmp/test.key"
else
certFile="/etc/ssl/certs/ssl-cert-snakeoil.pem"
keyFile="/etc/ssl/private/ssl-cert-snakeoil.key"
fi

# Verify certificate is valid X.509
docker exec "$cid" openssl x509 -in "$certFile" -noout -text >/dev/null

# Verify private key is valid
docker exec "$cid" openssl rsa -in "$keyFile" -check -noout >/dev/null 2>&1

# Verify certificate subject
subject="$(docker exec "$cid" openssl x509 -in "$certFile" -noout -subject)"
if [ "$imageVariant" = "alpine" ]; then
if [[ "$subject" != *"CN=localhost"* ]] && [[ "$subject" != *"CN = localhost"* ]]; then
echo "ERROR: Certificate subject should contain CN=localhost, got: $subject"
exit 1
fi
else
# For Debian, just verify it has some CN field
if [[ "$subject" != *"CN="* ]] && [[ "$subject" != *"CN ="* ]]; then
echo "ERROR: Certificate subject should contain CN field, got: $subject"
exit 1
fi
fi

# Verify certificate and key match
certMod="$(docker exec "$cid" openssl x509 -noout -modulus -in "$certFile" | openssl md5)"
keyMod="$(docker exec "$cid" sh -c "openssl rsa -noout -modulus -in '$keyFile' 2>/dev/null | openssl md5")"

if [ "$certMod" != "$keyMod" ]; then
echo "ERROR: Certificate and key modulus don't match"
exit 1
fi

# Edge case tests
echo "Testing edge cases..."

if [ "$imageVariant" = "alpine" ]; then
# Test with special characters in filenames
docker exec "$cid" make-ssl-cert "/tmp/cert with spaces.pem" "/tmp/key-with-dashes.pem"
docker exec "$cid" test -f "/tmp/cert with spaces.pem"
docker exec "$cid" test -f "/tmp/key-with-dashes.pem"

# Test overwriting existing files
firstSerial="$(docker exec "$cid" openssl x509 -in "$certFile" -noout -serial)"
docker exec "$cid" make-ssl-cert "$certFile" "$keyFile"
secondSerial="$(docker exec "$cid" openssl x509 -in "$certFile" -noout -serial)"

if [ "$firstSerial" = "$secondSerial" ]; then
echo "ERROR: Certificate should have been overwritten"
exit 1
fi
else
# Test self-signed certificate validates
if ! docker exec "$cid" openssl verify -CAfile "$certFile" "$certFile" 2>/dev/null | grep -q "OK"; then
echo "ERROR: Self-signed certificate should validate"
exit 1
fi

# Test key size is reasonable (should be 2048 bits)
keySize="$(docker exec "$cid" openssl rsa -in "$keyFile" -text -noout 2>/dev/null | grep "Private-Key" | grep -o "[0-9]*" | head -1)"
if [ "$keySize" -lt 2048 ]; then
echo "ERROR: Key size should be at least 2048 bits, got $keySize"
exit 1
fi
fi

# Test certificate validity period (should be ~10 years)
notAfter="$(docker exec "$cid" openssl x509 -in "$certFile" -noout -enddate | cut -d= -f2)"
currentYear="$(date +%Y)"
certYear="$(date -d "$notAfter" +%Y 2>/dev/null || echo "2035")"
yearDiff=$((certYear - currentYear))

if [ "$yearDiff" -lt 9 ] || [ "$yearDiff" -gt 11 ]; then
echo "ERROR: Certificate should be valid for ~10 years, got $yearDiff years"
exit 1
fi

# Test file permissions are secure (Alpine only)
if [ "$imageVariant" = "alpine" ]; then
keyPerm="$(docker exec "$cid" stat -c %a "$keyFile")"
if [ "$keyPerm" != "600" ]; then
echo "ERROR: Private key should have 600 permissions, got $keyPerm"
exit 1
fi
fi

echo "✓ All SSL certificate tests (including edge cases) passed for $imageVariant variant"
4 changes: 4 additions & 0 deletions 7.2/alpine/Dockerfile

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

10 changes: 10 additions & 0 deletions 7.2/alpine/make-ssl-cert-alpine.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
#!/bin/sh
set -e

if [ $# -ne 2 ]; then
echo "Usage: make-ssl-cert <cert_file> <key_file>" >&2
exit 1
fi

mkdir -p "$(dirname "$1")" "$(dirname "$2")"
openssl req -new -x509 -days 3650 -nodes -out "$1" -keyout "$2" -subj "/CN=localhost"
2 changes: 2 additions & 0 deletions 7.2/debian/Dockerfile

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 4 additions & 0 deletions 8.0/alpine/Dockerfile

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

10 changes: 10 additions & 0 deletions 8.0/alpine/make-ssl-cert-alpine.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
#!/bin/sh
set -e

if [ $# -ne 2 ]; then
echo "Usage: make-ssl-cert <cert_file> <key_file>" >&2
exit 1
fi

mkdir -p "$(dirname "$1")" "$(dirname "$2")"
openssl req -new -x509 -days 3650 -nodes -out "$1" -keyout "$2" -subj "/CN=localhost"
2 changes: 2 additions & 0 deletions 8.0/debian/Dockerfile

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 4 additions & 0 deletions 8.1/alpine/Dockerfile

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

10 changes: 10 additions & 0 deletions 8.1/alpine/make-ssl-cert-alpine.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
#!/bin/sh
set -e

if [ $# -ne 2 ]; then
echo "Usage: make-ssl-cert <cert_file> <key_file>" >&2
exit 1
fi

mkdir -p "$(dirname "$1")" "$(dirname "$2")"
openssl req -new -x509 -days 3650 -nodes -out "$1" -keyout "$2" -subj "/CN=localhost"
2 changes: 2 additions & 0 deletions 8.1/debian/Dockerfile

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 6 additions & 0 deletions Dockerfile.template
Original file line number Diff line number Diff line change
Expand Up @@ -159,13 +159,19 @@ RUN set -eux; \
openssl \
libgcc \
;

# Add make-ssl-cert script for snakeoil certificates (Alpine)
COPY make-ssl-cert-alpine.sh /usr/local/bin/make-ssl-cert
RUN chmod +x /usr/local/bin/make-ssl-cert
{{ ) else ( -}}
RUN set -eux; \
apt-get update; \
apt-get install -y --no-install-recommends \
# add tzdata explicitly for https://github.com/docker-library/valkey/issues/138 (see also https://bugs.debian.org/837060 and related)
tzdata \
libssl3 \
# add ssl-cert for snakeoil certificates (Debian)
ssl-cert \
; \
rm -rf /var/lib/apt/lists/*
{{ ) end -}}
Expand Down
3 changes: 3 additions & 0 deletions apply-templates.sh
Original file line number Diff line number Diff line change
Expand Up @@ -53,5 +53,8 @@ for version; do
} > "$dir/Dockerfile"

cp -a docker-entrypoint.sh "$dir/"
if [ "$variant" = "alpine" ]; then
cp -a make-ssl-cert-alpine.sh "$dir/"
fi
done
done
10 changes: 10 additions & 0 deletions make-ssl-cert-alpine.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
#!/bin/sh
set -e

if [ $# -ne 2 ]; then
echo "Usage: make-ssl-cert <cert_file> <key_file>" >&2
exit 1
fi

mkdir -p "$(dirname "$1")" "$(dirname "$2")"
openssl req -new -x509 -days 3650 -nodes -out "$1" -keyout "$2" -subj "/CN=localhost"
4 changes: 4 additions & 0 deletions unstable/alpine/Dockerfile

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

10 changes: 10 additions & 0 deletions unstable/alpine/make-ssl-cert-alpine.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
#!/bin/sh
set -e

if [ $# -ne 2 ]; then
echo "Usage: make-ssl-cert <cert_file> <key_file>" >&2
exit 1
fi

mkdir -p "$(dirname "$1")" "$(dirname "$2")"
openssl req -new -x509 -days 3650 -nodes -out "$1" -keyout "$2" -subj "/CN=localhost"
2 changes: 2 additions & 0 deletions unstable/debian/Dockerfile

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.