Skip to content

Instantly share code, notes, and snippets.

@diegofcornejo
Last active May 4, 2024 21:13
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save diegofcornejo/0c3bf32655c8d499809ebca64731306f to your computer and use it in GitHub Desktop.
Save diegofcornejo/0c3bf32655c8d499809ebca64731306f to your computer and use it in GitHub Desktop.
Redis: Create docker containers dinamically with secure connection using stunnel

Redis Container with stunnel Secure Access

This script automates the setup of a Redis container with secure access via stunnel. It generates a unique ID for the Redis instance, a secure password, and finds free ports for Redis and stunnel.

Features

  • Starts a Redis container with a unique volume and password.
  • Sets up a stunnel container to provide secure access to the Redis instance.
  • Assumes the availability of a wildcard certificate, key, and CA file for your domain.

Usage

Run the script start-redis-stunnel.sh to start the Redis container with stunnel.

# Start script with default values
# TLS is disabled
# Redis memory is set to 256m
# Stunnel memory is set to 64m
./start-redis-stunnel.sh

# Start Redis with TLS enabled
./start-redis-stunnel.sh --tls

# Start Redis with custom memory limit
./start-redis-stunnel.sh --redis-memory 512m --stunnel-memory 128m

Prerequisites

  • Docker installed
  • Wildcard certificate, key, and CA file for your domain

Note

This script is intended for demonstration purposes and may require customization for production use.

#!/bin/bash
# Script to start a Redis container optionally with a stunnel container for TLS support based on the --tls flag.
# It now generates URLs in the format compatible with Redis 6 ACL authentication.
# Generates a unique ID, a secure password, finds free ports, and outputs ready-to-use Redis URLs.
# Prerequisites:
# - Docker installed and running
# - Wildcard SSL certificate and key for your domain (if using TLS)
log() {
echo "[$(date '+%Y-%m-%d %H:%M:%S')] $1"
}
# Initialize default values
tls_enabled=0
redis_memory="256m" # Default memory value for Redis
stunnel_memory="64m" # Default memory value for stunnel
DOMAIN="redis.diegocornejo.com" # Adjust to your domain
# Command-line options
while [[ "$#" -gt 0 ]]; do
case $1 in
--tls) tls_enabled=1 ;;
--redis-memory) redis_memory="$2"; shift ;;
--stunnel-memory) stunnel_memory="$2"; shift ;;
*) echo "Unknown parameter passed: $1"; exit 1 ;;
esac
shift
done
find_free_port() {
local port=10000
while : ; do
if ! sudo lsof -Pi :$port -sTCP:LISTEN -t >/dev/null 2>&1; then
echo $port
break
fi
((port++))
done
}
ID=$(uuidgen | tr -d '-' | tr '[:upper:]' '[:lower:]')
PASSWORD=$(openssl rand -base64 16)
REDIS_PORT=$(find_free_port)
VOLUME="redis-data-$ID"
docker volume create "$VOLUME"
docker run -d --name redis-$ID --memory="$redis_memory" -v "$VOLUME":/data -p "$REDIS_PORT":6379 \
redis redis-server --appendonly yes --requirepass "$PASSWORD"
log "Redis container started. Password: $PASSWORD"
USERNAME="default" # Default username for Redis 6 ACL
HOSTNAME="$ID.$DOMAIN"
# Redis URL without TLS/SSL
log "Redis URL: redis://$USERNAME:$PASSWORD@$HOSTNAME:$REDIS_PORT"
if [ "$tls_enabled" -eq 1 ]; then
CERT_PATH="/etc/letsencrypt/live/$DOMAIN/fullchain.pem"
KEY_PATH="/etc/letsencrypt/live/$DOMAIN/privkey.pem"
STUNNEL_PORT=$(find_free_port)
while [[ "$STUNNEL_PORT" -eq "$REDIS_PORT" ]]; do
log "Port $STUNNEL_PORT is in use. Finding another..."
STUNNEL_PORT=$(find_free_port)
done
log "Using port $STUNNEL_PORT for stunnel."
docker run -d --name stunnel-redis-$ID --memory="$stunnel_memory" \
-e STUNNEL_SERVICE=stunnel-redis-$ID \
-e STUNNEL_ACCEPT="$STUNNEL_PORT" \
-e STUNNEL_CONNECT="redis-$ID:$REDIS_PORT" \
-p "$STUNNEL_PORT":"$STUNNEL_PORT" \
-v "$CERT_PATH":/etc/stunnel/stunnel.pem:ro \
-v "$KEY_PATH":/etc/stunnel/stunnel.key:ro \
dweomer/stunnel
log "stunnel container started on port $STUNNEL_PORT."
# Redis URL with TLS/SSL
log "Secure Redis URL: rediss://$USERNAME:$PASSWORD@$HOSTNAME:$STUNNEL_PORT"
fi
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment