diff --git a/Dockerfile b/Dockerfile index 40fc793..336dd95 100644 --- a/Dockerfile +++ b/Dockerfile @@ -10,7 +10,7 @@ ENV DEBIAN_FRONTEND noninteractive # Install system dependencies RUN apt-get update -qq && \ apt-get install --no-install-recommends -yqq \ - net-tools supervisor ruby rubygems locales gettext-base wget gcc make g++ build-essential libc6-dev tcl && \ + net-tools supervisor ruby rubygems locales gettext-base wget gcc make g++ build-essential libc6-dev tcl-tls libssl-dev && \ apt-get clean -yqq # # Ensure UTF-8 lang and locale @@ -30,13 +30,18 @@ RUN wget -qO redis.tar.gz https://github.com/redis/redis/tarball/${redis_version && tar xfz redis.tar.gz -C / \ && mv /redis-* /redis -RUN (cd /redis && make) +RUN (cd /redis && make BUILD_TLS=yes) RUN mkdir /redis-conf && mkdir /redis-data -COPY redis-cluster.tmpl /redis-conf/redis-cluster.tmpl -COPY redis.tmpl /redis-conf/redis.tmpl -COPY sentinel.tmpl /redis-conf/sentinel.tmpl +COPY redis-cluster.tmpl /redis-conf/redis-cluster.tmpl +# File removed: Support for standalone instances dropped +# COPY redis.tmpl /redis-conf/redis.tmpl +COPY sentinel.tmpl /redis-conf/sentinel.tmpl +COPY redis-cluster-tls.tmpl /redis-conf/redis-cluster-tls.tmpl +COPY tls-certs/ca.crt /redis-conf/ca.crt +COPY tls-certs/redis.key /redis-conf/redis.key +COPY tls-certs/redis.crt /redis-conf/redis.crt # Add startup script COPY docker-entrypoint.sh /docker-entrypoint.sh diff --git a/README.md b/README.md index 7465ccc..87f8211 100644 --- a/README.md +++ b/README.md @@ -57,6 +57,7 @@ The cluster is 6 redis instances running with 3 master & 3 slaves, one slave for If the flag `-e "SENTINEL=true"` is passed there are 3 Sentinel nodes running on ports 5000 to 5002 matching cluster's master instances. +If the flag `-e "TLS=true"` is passed then TLS is set up with certs taken from directory `tls-certs`. This image requires at least `Docker` version 1.10 but the latest version is recommended. @@ -156,6 +157,45 @@ When running with docker-compose set the environment variable on your system `RE environment: SENTINEL: 'true' +## TLS + +TLS is not enabled by default, but available. It is supported by Redis starting with version 6 and when enabled all non-TLS traffic is disabled. + +If running with plain docker send in `-e TLS=true` to enable TLS. + +When running with docker-compose set the environment variable on your system `REDIS_USE_TLS=true` and start your container or modify the `docker-compose.yml` file + + version: '2' + services: + redis-cluster: + ... + environment: + TLS: 'true' + +### TLS certificates + +Sample certificates are bundled, see folder `tls-certs`. +If you want to create your own certificates you can do this by downloading Redis distribution and using +the script `gen-test-certs.sh` in utils directory. More details can be found in the [Redis TLS documentation](https://redis.io/topics/encryption). + +### Feed your own certificates using docker run + +Place generated certificates into the `tls-certs` directory and mount the files: + +``` +docker run ... -v ./tls-certs/ca.crt:/redis-conf/ca.crt:ro -v ./tls-certs/ca.key:/redis-conf/ca.key:ro -v ./tls-certs/redis.crt:/redis-conf/redis.crt:ro -v ./tls-certs/redis.key:/redis-conf/redis.key:ro +``` + +### Feed your own certificates using docker-compose + +Place generated certificates into the `tls-certs` directory and add the following to `docker-compose.yml`: + + volumes: + - ./tls-certs/ca.crt:/redis-conf/ca.crt:ro + - ./tls-certs/ca.key:/redis-conf/ca.key:ro + - ./tls-certs/redis.crt:/redis-conf/redis.crt:ro + - ./tls-certs/redis.key:/redis-conf/redis.key:ro + ## Change number of nodes diff --git a/docker-compose.yml b/docker-compose.yml index 94d0c90..614218d 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -5,6 +5,7 @@ services: IP: ${REDIS_CLUSTER_IP} SENTINEL: ${REDIS_USE_SENTINEL} STANDALONE: ${REDIS_USE_STANDALONE} + TLS: ${REDIS_USE_TLS} build: context: . args: diff --git a/docker-entrypoint.sh b/docker-entrypoint.sh index 0b2e67f..140a0cf 100644 --- a/docker-entrypoint.sh +++ b/docker-entrypoint.sh @@ -56,7 +56,11 @@ if [ "$1" = 'redis-cluster' ]; then fi if [ "$port" -lt "$first_standalone" ]; then - PORT=${port} BIND_ADDRESS=${BIND_ADDRESS} envsubst < /redis-conf/redis-cluster.tmpl > /redis-conf/${port}/redis.conf + if [ "$TLS" = "true" ]; then + PORT=${port} BIND_ADDRESS=${BIND_ADDRESS} envsubst < /redis-conf/redis-cluster-tls.tmpl > /redis-conf/${port}/redis.conf + else + PORT=${port} BIND_ADDRESS=${BIND_ADDRESS} envsubst < /redis-conf/redis-cluster.tmpl > /redis-conf/${port}/redis.conf + fi nodes="$nodes $IP:$port" else PORT=${port} BIND_ADDRESS=${BIND_ADDRESS} envsubst < /redis-conf/redis.tmpl > /redis-conf/${port}/redis.conf @@ -87,8 +91,13 @@ if [ "$1" = 'redis-cluster' ]; then echo "Using old redis-trib.rb to create the cluster" echo "yes" | eval ruby /redis/src/redis-trib.rb create --replicas "$SLAVES_PER_MASTER" "$nodes" else - echo "Using redis-cli to create the cluster" - echo "yes" | eval /redis/src/redis-cli --cluster create --cluster-replicas "$SLAVES_PER_MASTER" "$nodes" + if [ "$TLS" = "true" ]; then + echo "Using redis-cli to create the TLS Redis cluster" + echo "yes" | eval /redis/src/redis-cli --tls --cacert /redis-conf/ca.crt --cert /redis-conf/redis.crt --key /redis-conf/redis.key --cluster create --cluster-replicas "$SLAVES_PER_MASTER" "$nodes" + else + echo "Using redis-cli to create the cluster" + echo "yes" | eval /redis/src/redis-cli --cluster create --cluster-replicas "$SLAVES_PER_MASTER" "$nodes" + fi fi if [ "$SENTINEL" = "true" ]; then diff --git a/redis-cluster-tls.tmpl b/redis-cluster-tls.tmpl new file mode 100644 index 0000000..4dcc88c --- /dev/null +++ b/redis-cluster-tls.tmpl @@ -0,0 +1,16 @@ +bind ${BIND_ADDRESS} +port 0 +cluster-enabled yes +cluster-config-file nodes.conf +cluster-node-timeout 5000 +appendonly yes +dir /redis-data/${PORT} + +tls-cluster yes +tls-replication yes +tls-port ${PORT} +tls-ca-cert-file /redis-conf/ca.crt +tls-key-file /redis-conf/redis.key +tls-cert-file /redis-conf/redis.crt +tls-auth-clients yes +tls-session-caching yes