9

I'm following this tutorial.

In my case I am operating in a Docker environment, and I have a secured site (i.e. https://localhost). which requires secured ssl communication.

I adjusted the web, and celery containers for secure connection.
But I don't know how to configure the Redis container for secure connection with ssl
Note that when I run without ssl connection in the web and celery containers, the connection is fine.

How do I configure and run redis with ssl?

Thanks


EDIT:

I followed this tutorial to set redis with ssl and this tutorial to set redis with ssl via stunnel in Docker container.

I successfully tested the connection from my localhost to the redis docker container, by invoking redis-cli from localhost (via stunnel) to the redis docker container, using the following call from the localhost:

redis-cli -h 127.0.0.1 -p 6381
127.0.0.1:6381> auth foobared
OK
127.0.0.1:6381> 

Related files on the redis server Docker side:

docker-compose file (my webapp includes multiple services, but to for simplification I removed all services except for the redis container):

version: '3'

services:
  redis:
    build:
      context: ./redis
      dockerfile: Dockerfile
    restart: always
    command: sh -c "stunnel /stunnel_take2.conf && /usr/local/bin/redis-server /etc/redis/redis.conf"
    expose:
      - '6379'
    ports:
     - "6379:6379"
    volumes:
      - /home/avner/avner/certs:/etc/certs
      - /home/avner/avner/redis/conf:/etc/redis

redis container Dockerfile

FROM redis:5-alpine

RUN apk add --no-cache \
    stunnel~=5.56 \
    python3~=3.8

COPY stunnel-redis-server.conf /

WORKDIR /

ENV PYTHONUNBUFFERED=1

redis server redis conf file - redis/conf/redis.conf

...
requirepass foobared
...

redis server stunnel conf file - redis/stunnel-redis-server.conf

cert = /etc/certs/private.pem
pid = /var/run/stunnel.pid

[redis]
accept = 172.19.0.2:6380
connect = 127.0.0.1:6379

Related files on the client side (localhost):

redis client stunnel conf file - /etc/stunnel/redis-client.conf

cert = /etc/cert/private.pem
client = yes
pid = /var/run/stunnel.pid
[redis]
accept = 127.0.0.1:6381
connect = 172.19.0.2:6380
Avner Moshkovitz
  • 1,138
  • 1
  • 18
  • 35
  • if you dont want docker-compose but just a container capable of running redis on SSL check this answer https://stackoverflow.com/a/75308711/5371505 – PirateApp Feb 01 '23 at 10:22

2 Answers2

11

I've created an example repo, for how one might setup a docker container to use the new redis v6+ ssl:

docker-compose.yml

version: "3"

volumes:
  redis:

services:
  redis:
    image: "example/redis:v6.0.13"
    command: ["/app/docker-redis-entrypoint.sh"]
    container_name: redis
    ports:
      - 6379:6379
    volumes:
      - redis:/data
      - ./:/app

Dockerfile:

FROM redis:6.0.13 as base
COPY ./redis/tls /tls

entrypoint.sh


#!/bin/sh
set -e

redis-server --tls-port 6379 --port 0 \
    --tls-cert-file /tls/redis.crt \
    --tls-key-file /tls/redis.key \
    --tls-ca-cert-file /tls/ca.crt

gen-redi-certs.sh


#!/bin/bash

# COPIED/MODIFIED from the redis server gen-certs util

# Generate some test certificates which are used by the regression test suite:
#
#   tls/ca.{crt,key}          Self signed CA certificate.
#   tls/redis.{crt,key}       A certificate with no key usage/policy restrictions.
#   tls/client.{crt,key}      A certificate restricted for SSL client usage.
#   tls/server.{crt,key}      A certificate restricted for SSL server usage.
#   tls/redis.dh              DH Params file.

generate_cert() {
    local name=$1
    local cn="$2"
    local opts="$3"

    local keyfile=tls/${name}.key
    local certfile=tls/${name}.crt

    [ -f $keyfile ] || openssl genrsa -out $keyfile 2048
    openssl req \
        -new -sha256 \
        -subj "/O=Redis Test/CN=$cn" \
        -key $keyfile | \
        openssl x509 \
            -req -sha256 \
            -CA tls/ca.crt \
            -CAkey tls/ca.key \
            -CAserial tls/ca.txt \
            -CAcreateserial \
            -days 365 \
            $opts \
            -out $certfile
}

mkdir -p tls
[ -f tls/ca.key ] || openssl genrsa -out tls/ca.key 4096
openssl req \
    -x509 -new -nodes -sha256 \
    -key tls/ca.key \
    -days 3650 \
    -subj '/O=Redis Test/CN=Certificate Authority' \
    -out tls/ca.crt

cat > tls/openssl.cnf <<_END_
[ server_cert ]
keyUsage = digitalSignature, keyEncipherment
nsCertType = server
[ client_cert ]
keyUsage = digitalSignature, keyEncipherment
nsCertType = client
_END_

generate_cert server "Server-only" "-extfile tls/openssl.cnf -extensions server_cert"
generate_cert client "Client-only" "-extfile tls/openssl.cnf -extensions client_cert"
generate_cert redis "Generic-cert"

[ -f tls/redis.dh ] || openssl dhparam -out tls/redis.dh 2048
jmunsch
  • 22,771
  • 11
  • 93
  • 114
  • how can I do this inside a plain Dockerfile without compose – PirateApp Feb 01 '23 at 04:52
  • 1
    @PirateApp you can mount the `tls` directory, and do something like this: https://stackoverflow.com/questions/45141402/build-and-run-dockerfile-with-one-command I think its the `-v` flag with docker to mount a volume https://docs.docker.com/storage/volumes/ – jmunsch Feb 01 '23 at 21:50
3

Redis doesn't provide SSL by itself, you have to do it yourself. There's an in-depth post about it which you can read and follow. Or, if you want to use a Dockerized solution, you can use ready images like this one or this one. When it comes to setting up Celery to work with Redis over SSL, just follow the documentation.

Tomáš Linhart
  • 9,832
  • 1
  • 27
  • 39
  • 2
    thanks @Tomas I followed the links that you suggested and was able to create a redis with ssl Docker container. I edited my steps above. – Avner Moshkovitz Feb 18 '20 at 01:30
  • 6
    [Redis 6.0 comes with SSL](https://redis.io/topics/encryption). No idea yet though on how to use it in docker. Probably mount your certificate data into the container. – and0x000 Aug 26 '20 at 11:05