Skip to content

Redis Storage for Oauth2 Proxy

Why Redis?

Frequently, Oauth2 Proxy will issue a warning:

[session_store.go:179] WARNING: Multiple cookies are required for this session as it exceeds the 4kb cookie limit. Please use server side session storage (eg. Redis) instead.
This warning occurs because OAuth2-Proxy stores session data in cookies by default. When the session data (including access tokens, ID tokens, and user info) exceeds 4KB, it splits into multiple cookies, which can cause issues with browsers and proxies.

Redis solves this by: - Storing session data server-side - Only keeping a small session ID in the cookie - Supporting much larger session payloads - Enabling session sharing across multiple oauth2-proxy instances (for scaling) - Providing built-in expiration handling

Step-by-Step Setup

1. Generate Redis Password

# Generate a strong Redis password
openssl rand -base64 32

Save this password - you'll need it in multiple places.

2. Update Docker Compose

The updated docker-compose.yaml includes: - Redis container with password protection - Volume for Redis data persistence - Health checks for all services - Dependencies ensuring Redis starts before oauth2-proxy

3. Update OAuth2-Proxy Configurations

Update both oauth2-proxy-adm.cfg and oauth2-proxy-web.cfg with:

# Add these Redis settings
session_store_type = "redis"
redis_connection_url = "redis://:YOUR_REDIS_PASSWORD@redis:6379"
redis_session_key_prefix = "oauth2-adm:"  # or "oauth2-web:" for web config

Important Notes: - Use different redis_session_key_prefix for each proxy to avoid conflicts - The hostname redis works because it's the service name in docker-compose - The format is: redis://[:password]@host:port[/db]

4. Deploy the Updated Setup

# Stop existing containers
docker-compose down

# Pull latest images (if needed)
docker-compose pull

# Start all services (Redis will start first due to dependencies)
docker-compose up -d

# Check all containers are running
docker-compose ps

# Check Redis is working
docker exec -it redis-sessions redis-cli -a your_redis_password_here ping
# Should return: PONG

5. Verify Redis Sessions

# Connect to Redis
docker exec -it redis-sessions redis-cli -a your_redis_password_here

# List all keys (after someone logs in)
KEYS *

# Should see keys like:
# oauth2-adm:session:xxxxx
# oauth2-web:session:xxxxx

# Check a session (replace with actual key)
GET oauth2-adm:session:xxxxx

# Check TTL (time to live)
TTL oauth2-adm:session:xxxxx

# Exit Redis CLI
exit

Redis Configuration Options

Basic Configuration (Current Setup)

session_store_type = "redis"
redis_connection_url = "redis://:password@redis:6379"
redis_session_key_prefix = "oauth2-adm:"

Advanced Configuration

# Use separate Redis database (0-15)
redis_connection_url = "redis://:password@redis:6379/1"

# TLS/SSL connection (for production)
redis_connection_url = "rediss://:password@redis:6380"
redis_use_ssl = true
redis_ssl_skip_verify = false  # Set to true only for self-signed certs

# Connection pool settings
redis_max_idle_connections = 10
redis_max_active_connections = 100
redis_idle_timeout = "5m"

# Clustering (for high availability)
redis_use_cluster = true
redis_cluster_connection_urls = [
    "redis://:password@redis1:6379",
    "redis://:password@redis2:6379",
    "redis://:password@redis3:6379"
]

# Sentinel (for high availability)
redis_use_sentinel = true
redis_sentinel_master_name = "mymaster"
redis_sentinel_connection_urls = [
    "redis://sentinel1:26379",
    "redis://sentinel2:26379",
    "redis://sentinel3:26379"
]
redis_sentinel_password = "sentinel_password"

Production Recommendations

1. Redis Persistence Configuration

Add to docker-compose.yaml:

redis:
  command: >
    redis-server
    --requirepass your_redis_password_here
    --appendonly yes
    --appendfsync everysec
    --save 900 1
    --save 300 10
    --save 60 10000

Persistence Options: - RDB (Snapshots): --save <seconds> <changes> - saves database to disk periodically - AOF (Append Only File): --appendonly yes - logs every write operation - Hybrid: Use both for maximum durability

2. Redis Memory Management

redis:
  command: >
    redis-server
    --requirepass your_redis_password_here
    --maxmemory 256mb
    --maxmemory-policy allkeys-lru

Memory Policies: - allkeys-lru: Evict least recently used keys - volatile-lru: Evict LRU keys with expire set - allkeys-lfu: Evict least frequently used keys - volatile-ttl: Evict keys with shortest TTL

3. Redis Security Hardening

redis:
  command: >
    redis-server
    --requirepass your_redis_password_here
    --bind 0.0.0.0
    --protected-mode yes
    --rename-command FLUSHDB ""
    --rename-command FLUSHALL ""
    --rename-command CONFIG "CONFIG_SECRET_NAME"

4. Monitoring Redis

# Real-time monitoring
docker exec -it redis-sessions redis-cli -a your_redis_password_here --stat

# Monitor all commands
docker exec -it redis-sessions redis-cli -a your_redis_password_here MONITOR

# Get Redis info
docker exec -it redis-sessions redis-cli -a your_redis_password_here INFO

# Check memory usage
docker exec -it redis-sessions redis-cli -a your_redis_password_here INFO memory

# Check connected clients
docker exec -it redis-sessions redis-cli -a your_redis_password_here CLIENT LIST

5. Backup and Recovery

# Manual backup (creates dump.rdb)
docker exec redis-sessions redis-cli -a your_redis_password_here BGSAVE

# Copy backup from container
docker cp redis-sessions:/data/dump.rdb ./redis-backup-$(date +%Y%m%d).rdb

# Restore (stop Redis, copy dump.rdb, start Redis)
docker-compose stop redis
docker cp ./redis-backup-20241104.rdb redis-sessions:/data/dump.rdb
docker-compose start redis

Troubleshooting

Issue: "NOAUTH Authentication required"

Solution: Ensure password is set correctly in redis_connection_url

# Test connection
docker exec -it redis-sessions redis-cli -a your_redis_password_here ping

Issue: "Could not connect to Redis"

Solution: Check Redis is running and accessible

# Check Redis container is running
docker-compose ps redis

# Check logs
docker-compose logs redis

# Test connection from oauth2-proxy container
docker exec -it oauth2-proxy-adm sh
wget -O- redis:6379

Issue: Sessions not being stored in Redis

Solution: Verify configuration

# Check oauth2-proxy logs for Redis errors
docker-compose logs oauth2-proxy-adm | grep -i redis

# Verify session_store_type is set
docker exec oauth2-proxy-adm cat /etc/oauth2-proxy.cfg | grep session_store_type

# Check Redis for keys after login
docker exec redis-sessions redis-cli -a your_redis_password_here KEYS "*"

Issue: High memory usage

Solution: Implement eviction policy and monitoring

# Check memory usage
docker exec redis-sessions redis-cli -a your_redis_password_here INFO memory

# Check number of keys
docker exec redis-sessions redis-cli -a your_redis_password_here DBSIZE

# Set maxmemory (already in config, but can be done at runtime)
docker exec redis-sessions redis-cli -a your_redis_password_here CONFIG SET maxmemory 256mb

Issue: Redis container keeps restarting

Solution: Check logs and permissions

# Check detailed logs
docker logs redis-sessions

# Common issues:
# 1. Permission on volume
sudo chown -R 999:999 redis-data/

# 2. Invalid config
docker exec redis-sessions redis-server --test-memory 100

Performance Tuning

Redis Configuration

redis:
  command: >
    redis-server
    --requirepass your_redis_password_here
    --tcp-backlog 511
    --timeout 300
    --tcp-keepalive 60
    --maxclients 10000
    --hz 10

OAuth2-Proxy Settings

# Adjust based on your needs
cookie_expire = "8h"
cookie_refresh = "1h"

# For high-traffic sites, increase connection pool
redis_max_active_connections = 100
redis_max_idle_connections = 20
  1. Deploy Redis without changing oauth2-proxy config
  2. Update one proxy at a time to use Redis
  3. Users will need to re-login (existing cookie sessions won't work)
  4. Monitor for any issues before updating the second proxy

Note: There's no direct migration path. Users will automatically get new Redis-backed sessions on their next login.

Health Checks

Add to your monitoring:

#!/bin/bash
# redis-health-check.sh

REDIS_PASSWORD="your_redis_password_here"

# Check Redis is responding
if ! docker exec redis-sessions redis-cli -a "$REDIS_PASSWORD" ping | grep -q PONG; then
    echo "CRITICAL: Redis not responding"
    exit 2
fi

# Check session count
SESSION_COUNT=$(docker exec redis-sessions redis-cli -a "$REDIS_PASSWORD" KEYS "oauth2-*:session:*" | wc -l)
echo "Active sessions: $SESSION_COUNT"

# Check memory usage
MEMORY_USED=$(docker exec redis-sessions redis-cli -a "$REDIS_PASSWORD" INFO memory | grep used_memory_human | cut -d: -f2 | tr -d '\r')
echo "Memory used: $MEMORY_USED"

# Check connected clients
CLIENTS=$(docker exec redis-sessions redis-cli -a "$REDIS_PASSWORD" INFO clients | grep connected_clients | cut -d: -f2 | tr -d '\r')
echo "Connected clients: $CLIENTS"

Quick Reference

# Start all services
docker-compose up -d

# Check Redis is working
docker exec redis-sessions redis-cli -a PASSWORD ping

# View active sessions
docker exec redis-sessions redis-cli -a PASSWORD KEYS "oauth2-*"

# Clear all sessions (force all users to re-login)
docker exec redis-sessions redis-cli -a PASSWORD FLUSHDB

# Monitor Redis operations
docker exec redis-sessions redis-cli -a PASSWORD MONITOR

# Check oauth2-proxy logs
docker-compose logs -f oauth2-proxy-adm

# Restart oauth2-proxy after config changes
docker-compose restart oauth2-proxy-adm oauth2-proxy-web