From 919832ba2af0497c379d50e941c2e9a83171626c Mon Sep 17 00:00:00 2001 From: Jose Diaz-Gonzalez Date: Sat, 27 Aug 2016 23:39:31 -0400 Subject: [PATCH] Implement AUTH. Closes #58 This change makes password authentication required for redis usage, and removes anonymous access. Users will need to change their underlying clients to enable writing the auth token for authenticating, otherwise requests will fail. This is a non-optional change, and improves security for users who wish to expose their redis installations outside of their network. --- README.md | 12 ++++++------ functions | 10 ++++++++-- tests/service_export.bats | 2 ++ tests/service_import.bats | 1 + tests/service_info.bats | 9 ++++++--- tests/service_link.bats | 6 ++++-- tests/service_promote.bats | 13 ++++++++----- 7 files changed, 35 insertions(+), 18 deletions(-) diff --git a/README.md b/README.md index 63be812..e3ae9ca 100644 --- a/README.md +++ b/README.md @@ -99,7 +99,7 @@ dokku redis:link lolipop playground # # and the following will be set on the linked application by default # -# REDIS_URL=redis://dokku-redis-lolipop:6379 +# REDIS_URL=redis://lolipop:SOME_PASSWORD@dokku-redis-lolipop:6379 # # NOTE: the host exposed here only works internally in docker containers. If # you want your container to be reachable from outside, you should use `expose`. @@ -110,7 +110,7 @@ dokku redis:link other_service playground # since REDIS_URL is already in use, another environment variable will be # generated automatically # -# DOKKU_REDIS_BLUE_URL=redis://dokku-redis-other-service:6379 +# DOKKU_REDIS_BLUE_URL=redis://other_service:ANOTHER_PASSWORD@dokku-redis-other-service:6379 # you can then promote the new service to be the primary one # NOTE: this will restart your app @@ -120,9 +120,9 @@ dokku redis:promote other_service playground # another environment variable to hold the previous value if necessary. # you could end up with the following for example: # -# REDIS_URL=redis://dokku-redis-other-service:63790 -# DOKKU_REDIS_BLUE_URL=redis://dokku-redis-other-service:6379 -# DOKKU_REDIS_SILVER_URL=redis://dokku-redis-lolipop:6379/lolipop +# REDIS_URL=redis://other_service:ANOTHER_PASSWORD@dokku-redis-other-service:63790 +# DOKKU_REDIS_BLUE_URL=redis://other_service:ANOTHER_PASSWORD@dokku-redis-other-service:6379 +# DOKKU_REDIS_SILVER_URL=redis://lolipop:SOME_PASSWORD@dokku-redis-lolipop:6379/lolipop # you can also unlink a redis service # NOTE: this will restart your app and unset related environment variables @@ -156,7 +156,7 @@ dokku redis:link lolipop playground ``` Will cause REDIS_URL to be set as -redis2://dokku-redis-lolipop:6379/lolipop +redis2://lolipop:SOME_PASSWORD@dokku-redis-lolipop:6379/lolipop CAUTION: Changing REDIS_DATABASE_SCHEME after linking will cause dokku to believe the redis is not linked when attempting to use `dokku redis:unlink` diff --git a/functions b/functions index fca7066..344ad53 100755 --- a/functions +++ b/functions @@ -22,8 +22,12 @@ service_create() { mkdir -p "$SERVICE_ROOT" || dokku_log_fail "Unable to create service directory" mkdir -p "$SERVICE_ROOT/data" || dokku_log_fail "Unable to create service data directory" mkdir -p "$SERVICE_ROOT/config" || dokku_log_fail "Unable to create service config directory" - touch "$LINKS_FILE" curl -sSL "https://raw.githubusercontent.com/antirez/redis/${REDIS_IMAGE_VERSION:0:3}/redis.conf" > "$SERVICE_ROOT/config/redis.conf" || dokku_log_fail "Unable to download the default redis.conf to the config directory" + PASSWORD=$(openssl rand -hex 32) + echo "$PASSWORD" > "$SERVICE_ROOT/PASSWORD" + chmod 640 "$SERVICE_ROOT/PASSWORD" + sed -i.bak "s/# requirepass.*/requirepass ${PASSWORD}/" "$SERVICE_ROOT/config/redis.conf" && rm "$SERVICE_ROOT/config/redis.conf.bak" + touch "$LINKS_FILE" if [[ -n $REDIS_CUSTOM_ENV ]]; then echo "$REDIS_CUSTOM_ENV" | tr ';' "\n" > "$SERVICE_ROOT/ENV" @@ -102,8 +106,10 @@ service_start() { service_url() { local SERVICE="$1" + local SERVICE_ROOT="$PLUGIN_DATA_ROOT/$SERVICE" + local PASSWORD="$(cat "$SERVICE_ROOT/PASSWORD")" local SERVICE_ALIAS="$(service_alias "$SERVICE")" - echo "$PLUGIN_SCHEME://$SERVICE_ALIAS:${PLUGIN_DATASTORE_PORTS[0]}" + echo "$PLUGIN_SCHEME://$SERVICE:$PASSWORD@$SERVICE_ALIAS:${PLUGIN_DATASTORE_PORTS[0]}" } update_plugin_scheme_for_app() { diff --git a/tests/service_export.bats b/tests/service_export.bats index 6667eb4..b09e492 100755 --- a/tests/service_export.bats +++ b/tests/service_export.bats @@ -25,6 +25,7 @@ teardown() { export ECHO_DOCKER_COMMAND="true" export SSH_TTY=`tty` run dokku "$PLUGIN_COMMAND_PREFIX:export" l + password="$(cat "$PLUGIN_DATA_ROOT/l/PASSWORD")" assert_exit_status 0 assert_output "docker exec dokku.redis.l cat /data/dump.rdb" } @@ -33,6 +34,7 @@ teardown() { export ECHO_DOCKER_COMMAND="true" unset SSH_TTY run dokku "$PLUGIN_COMMAND_PREFIX:export" l + password="$(cat "$PLUGIN_DATA_ROOT/l/PASSWORD")" assert_exit_status 0 assert_output "docker exec dokku.redis.l cat /data/dump.rdb" } diff --git a/tests/service_import.bats b/tests/service_import.bats index cd6c8a3..afabaa9 100755 --- a/tests/service_import.bats +++ b/tests/service_import.bats @@ -31,6 +31,7 @@ teardown() { @test "($PLUGIN_COMMAND_PREFIX:import) success" { export ECHO_DOCKER_COMMAND="true" run dokku "$PLUGIN_COMMAND_PREFIX:import" l < "$PLUGIN_DATA_ROOT/fake.rdb" + password="$(cat "$PLUGIN_DATA_ROOT/l/PASSWORD")" assert_output "docker run --rm -i -v $PLUGIN_DATA_ROOT/l/data:/data redis:3.2.3 bash -c cat > /data/dump.rdb && chown redis: /data/dump.rdb" } diff --git a/tests/service_info.bats b/tests/service_info.bats index 6da4307..fd1aa5e 100755 --- a/tests/service_info.bats +++ b/tests/service_info.bats @@ -21,19 +21,22 @@ teardown() { @test "($PLUGIN_COMMAND_PREFIX:info) success" { run dokku "$PLUGIN_COMMAND_PREFIX:info" l - assert_contains "${lines[*]}" "redis://dokku-redis-l:6379" + password="$(cat "$PLUGIN_DATA_ROOT/l/PASSWORD")" + assert_contains "${lines[*]}" "redis://l:$password@dokku-redis-l:6379" } @test "($PLUGIN_COMMAND_PREFIX:info) replaces underscores by dash in hostname" { dokku "$PLUGIN_COMMAND_PREFIX:create" test_with_underscores run dokku "$PLUGIN_COMMAND_PREFIX:info" test_with_underscores - assert_contains "${lines[*]}" "redis://dokku-redis-test-with-underscores:6379" + password="$(cat "$PLUGIN_DATA_ROOT/test_with_underscores/PASSWORD")" + assert_contains "${lines[*]}" "redis://test_with_underscores:$password@dokku-redis-test-with-underscores:6379" dokku --force "$PLUGIN_COMMAND_PREFIX:destroy" test_with_underscores } @test "($PLUGIN_COMMAND_PREFIX:info) success with flag" { run dokku "$PLUGIN_COMMAND_PREFIX:info" l --dsn - assert_output "redis://dokku-redis-l:6379" + password="$(cat "$PLUGIN_DATA_ROOT/l/PASSWORD")" + assert_output "redis://l:$password@dokku-redis-l:6379" run dokku "$PLUGIN_COMMAND_PREFIX:info" l --config-dir assert_success diff --git a/tests/service_link.bats b/tests/service_link.bats index ef383ce..73c7b10 100755 --- a/tests/service_link.bats +++ b/tests/service_link.bats @@ -40,7 +40,8 @@ teardown() { @test "($PLUGIN_COMMAND_PREFIX:link) exports REDIS_URL to app" { dokku "$PLUGIN_COMMAND_PREFIX:link" l my_app url=$(dokku config:get my_app REDIS_URL) - assert_contains "$url" "redis://dokku-redis-l:6379" + password="$(cat "$PLUGIN_DATA_ROOT/l/PASSWORD")" + assert_contains "$url" "redis://l:$password@dokku-redis-l:6379" dokku "$PLUGIN_COMMAND_PREFIX:unlink" l my_app } @@ -63,6 +64,7 @@ teardown() { dokku config:set my_app REDIS_DATABASE_SCHEME=redis2 dokku "$PLUGIN_COMMAND_PREFIX:link" l my_app url=$(dokku config:get my_app REDIS_URL) - assert_contains "$url" "redis2://dokku-redis-l:6379" + password="$(cat "$PLUGIN_DATA_ROOT/l/PASSWORD")" + assert_contains "$url" "redis2://l:$password@dokku-redis-l:6379" dokku "$PLUGIN_COMMAND_PREFIX:unlink" l my_app } diff --git a/tests/service_promote.bats b/tests/service_promote.bats index 8e9831c..3bd9d2f 100755 --- a/tests/service_promote.bats +++ b/tests/service_promote.bats @@ -39,22 +39,25 @@ teardown() { } @test "($PLUGIN_COMMAND_PREFIX:promote) changes REDIS_URL" { - dokku config:set my_app "REDIS_URL=redis://host:6379/db" "DOKKU_REDIS_BLUE_URL=redis://dokku-redis-l:6379" + password="$(cat "$PLUGIN_DATA_ROOT/l/PASSWORD")" + dokku config:set my_app "REDIS_URL=redis://u:p@host:6379/db" "DOKKU_REDIS_BLUE_URL=redis://l:$password@dokku-redis-l:6379" dokku "$PLUGIN_COMMAND_PREFIX:promote" l my_app url=$(dokku config:get my_app REDIS_URL) - assert_equal "$url" "redis://dokku-redis-l:6379" + assert_equal "$url" "redis://l:$password@dokku-redis-l:6379" } @test "($PLUGIN_COMMAND_PREFIX:promote) creates new config url when needed" { - dokku config:set my_app "REDIS_URL=redis://host:6379/db" "DOKKU_REDIS_BLUE_URL=redis://dokku-redis-l:6379" + password="$(cat "$PLUGIN_DATA_ROOT/l/PASSWORD")" + dokku config:set my_app "REDIS_URL=redis://u:p@host:6379/db" "DOKKU_REDIS_BLUE_URL=redis://l:$password@dokku-redis-l:6379" dokku "$PLUGIN_COMMAND_PREFIX:promote" l my_app run dokku config my_app assert_contains "${lines[*]}" "DOKKU_REDIS_" } @test "($PLUGIN_COMMAND_PREFIX:promote) uses REDIS_DATABASE_SCHEME variable" { - dokku config:set my_app "REDIS_DATABASE_SCHEME=redis2" "REDIS_URL=redis://u:p@host:6379" "DOKKU_REDIS_BLUE_URL=redis2://dokku-redis-l:6379" + password="$(cat "$PLUGIN_DATA_ROOT/l/PASSWORD")" + dokku config:set my_app "REDIS_DATABASE_SCHEME=redis2" "REDIS_URL=redis://u:p@host:6379" "DOKKU_REDIS_BLUE_URL=redis2://l:$password@dokku-redis-l:6379" dokku "$PLUGIN_COMMAND_PREFIX:promote" l my_app url=$(dokku config:get my_app REDIS_URL) - assert_equal "$url" "redis2://dokku-redis-l:6379" + assert_equal "$url" "redis2://l:$password@dokku-redis-l:6379" }