diff --git a/README.md b/README.md
index 479135c7a..569745e90 100644
--- a/README.md
+++ b/README.md
@@ -168,8 +168,8 @@ option and which are reproduced below:
 	  -f, --foreground                 Don't fork to background
 	  -m, --port-min=INT               Lowest port to use for RTP
 	  -M, --port-max=INT               Highest port to use for RTP
-	  -r, --redis=IP:PORT/INT          Connect to Redis database
-	  -w, --redis-write=IP:PORT/INT    Connect to Redis write database
+	  -r, --redis=[PW@]IP:PORT/INT   Connect to Redis database
+	  -w, --redis-write=[PW@]IP:PORT/INT Connect to Redis write database
 	  -b, --b2b-url=STRING             XMLRPC URL of B2B UA
 	  -L, --log-level=INT              Mask log priorities above this level
 	  --log-facility=daemon|local0|... Syslog facility to use for logging
@@ -358,6 +358,13 @@ The options are described in more detail below.
 	storage. The format of this option is `ADDRESS:PORT/DBNUM`, for example `127.0.0.1:6379/12`
 	to connect to the Redis DB number 12 running on localhost on the default Redis port.
 
+	If the Redis database is protected with an authentication password, the password can be supplied
+	by prefixing the argument value with the password, separated by an `@` symbol, for example
+	`foobar@127.0.0.1:6379/12`. Note that this leaves the password visible in the process list,
+	posing a security risk if untrusted users access the same system. As an alternative, the password
+	can also be supplied in the shell environment through the environment variable
+	`RTPENGINE_REDIS_AUTH_PW`.
+
 	On startup, *rtpengine* will read the contents of this database and restore all calls
 	stored therein. During runtime operation, *rtpengine* will continually update the database's
 	contents to keep it current, so that in case of a service disruption, the last state can be restored
@@ -372,6 +379,9 @@ The options are described in more detail below.
 	first one, then the first database will be used for read operations (i.e. to restore calls from) while
 	the second one will be used for write operations (to update states in the database).
 
+	For password protected Redis servers, the environment variable for the password is
+	`RTPENGINE_REDIS_WRITE_AUTH_PW`.
+
 	When both options are given, *rtpengine* will start and use the Redis database regardless of the
 	database's role (master or slave).
 
diff --git a/daemon/main.c b/daemon/main.c
index 2d0206410..c7a655990 100644
--- a/daemon/main.c
+++ b/daemon/main.c
@@ -71,6 +71,8 @@ static int port_max = 40000;
 static int max_sessions = -1;
 static int redis_db = -1;
 static int redis_write_db = -1;
+static char *redis_auth;
+static char *redis_write_auth;
 static char *b2b_url;
 static enum xmlrpc_format xmlrpc_fmt = XF_SEMS;
 static int num_threads;
@@ -215,10 +217,19 @@ static struct intf_config *if_addr_parse(char *s) {
 
 
 
-static int redis_ep_parse(endpoint_t *ep, int *db, char *str) {
+static int redis_ep_parse(endpoint_t *ep, int *db, char **auth, const char *auth_env, char *str) {
 	char *sl;
 	long l;
 
+	sl = strchr(str, '@');
+	if (sl) {
+		*sl = 0;
+		*auth = str;
+		str = sl+1;
+	}
+	else if ((sl = getenv(auth_env)))
+		*auth = sl;
+
 	sl = strchr(str, '/');
 	if (!sl)
 		return -1;
@@ -276,8 +287,8 @@ static void options(int *argc, char ***argv) {
 		{ "foreground",	'f', 0, G_OPTION_ARG_NONE,	&foreground,	"Don't fork to background",	NULL		},
 		{ "port-min",	'm', 0, G_OPTION_ARG_INT,	&port_min,	"Lowest port to use for RTP",	"INT"		},
 		{ "port-max",	'M', 0, G_OPTION_ARG_INT,	&port_max,	"Highest port to use for RTP",	"INT"		},
-		{ "redis",	'r', 0, G_OPTION_ARG_STRING,	&redisps,	"Connect to Redis database",	"IP:PORT/INT"	},
-		{ "redis-write",'w', 0, G_OPTION_ARG_STRING,    &redisps_write, "Connect to Redis write database",      "IP:PORT/INT"       },
+		{ "redis",	'r', 0, G_OPTION_ARG_STRING,	&redisps,	"Connect to Redis database",	"[PW@]IP:PORT/INT"	},
+		{ "redis-write",'w', 0, G_OPTION_ARG_STRING,    &redisps_write, "Connect to Redis write database",      "[PW@]IP:PORT/INT"       },
 		{ "b2b-url",	'b', 0, G_OPTION_ARG_STRING,	&b2b_url,	"XMLRPC URL of B2B UA"	,	"STRING"	},
 		{ "log-level",	'L', 0, G_OPTION_ARG_INT,	(void *)&log_level,"Mask log priorities above this level","INT"	},
 		{ "log-facility",0,  0,	G_OPTION_ARG_STRING, &log_facility_s, "Syslog facility to use for logging", "daemon|local0|...|local7"},
@@ -349,11 +360,12 @@ static void options(int *argc, char ***argv) {
 		silent_timeout = 3600;
 
 	if (redisps)
-		if (redis_ep_parse(&redis_ep, &redis_db, redisps))
+		if (redis_ep_parse(&redis_ep, &redis_db, &redis_auth, "RTPENGINE_REDIS_AUTH_PW", redisps))
 			die("Invalid Redis endpoint [IP:PORT/INT] (--redis)");
 
 	if (redisps_write)
-		if (redis_ep_parse(&redis_write_ep, &redis_write_db, redisps_write))
+		if (redis_ep_parse(&redis_write_ep, &redis_write_db, &redis_write_auth,
+					"RTPENGINE_REDIS_WRITE_AUTH_PW", redisps_write))
 			die("Invalid Redis endpoint [IP:PORT/INT] (--redis-write)");
 
 	if (xmlrpc_fmt > 1)
@@ -559,13 +571,13 @@ no_kernel:
 	}
 
 	if (!is_addr_unspecified(&redis_write_ep.address)) {
-		mc.redis_write = redis_new(&redis_write_ep, redis_write_db, ANY_REDIS_ROLE);
+		mc.redis_write = redis_new(&redis_write_ep, redis_write_db, redis_write_auth, ANY_REDIS_ROLE);
 		if (!mc.redis_write)
 			die("Cannot start up without Redis write database");
 	}
 
 	if (!is_addr_unspecified(&redis_ep.address)) {
-		mc.redis = redis_new(&redis_ep, redis_db, mc.redis_write ? ANY_REDIS_ROLE : MASTER_REDIS_ROLE);
+		mc.redis = redis_new(&redis_ep, redis_db, redis_auth, mc.redis_write ? ANY_REDIS_ROLE : MASTER_REDIS_ROLE);
 		if (!mc.redis)
 			die("Cannot start up without Redis database");
 
diff --git a/daemon/redis.c b/daemon/redis.c
index d193598e8..d4c906224 100644
--- a/daemon/redis.c
+++ b/daemon/redis.c
@@ -142,8 +142,14 @@ static int redis_connect(struct redis *r, int wait) {
 	if (r->ctx->err)
 		goto err2;
 
-	if (redisCommandNR(r->ctx, "PING"))
-		goto err2;
+	if (r->auth) {
+		if (redisCommandNR(r->ctx, "AUTH %s", r->auth))
+			goto err2;
+	}
+	else {
+		if (redisCommandNR(r->ctx, "PING"))
+			goto err2;
+	}
 
 	if (redisCommandNR(r->ctx, "SELECT %i", r->db))
 		goto err2;
@@ -206,7 +212,7 @@ err:
 
 
 
-struct redis *redis_new(const endpoint_t *ep, int db, enum redis_role role) {
+struct redis *redis_new(const endpoint_t *ep, int db, const char *auth, enum redis_role role) {
 	struct redis *r;
 
 	r = g_slice_alloc0(sizeof(*r));
@@ -214,6 +220,7 @@ struct redis *redis_new(const endpoint_t *ep, int db, enum redis_role role) {
 	r->endpoint = *ep;
 	sockaddr_print(&ep->address, r->host, sizeof(r->host));
 	r->db = db;
+	r->auth = auth;
 	r->role = role;
 	mutex_init(&r->lock);
 
@@ -1074,7 +1081,7 @@ int redis_restore(struct callmaster *m, struct redis *r) {
 	mutex_init(&ctx.r_m);
 	g_queue_init(&ctx.r_q);
 	for (i = 0; i < RESTORE_NUM_THREADS; i++)
-		g_queue_push_tail(&ctx.r_q, redis_new(&r->endpoint, r->db, r->role));
+		g_queue_push_tail(&ctx.r_q, redis_new(&r->endpoint, r->db, r->auth, r->role));
 	gtp = g_thread_pool_new(restore_thread, &ctx, RESTORE_NUM_THREADS, TRUE, NULL);
 
 	for (i = 0; i < calls->elements; i++) {
diff --git a/daemon/redis.h b/daemon/redis.h
index 6961953db..6140e0244 100644
--- a/daemon/redis.h
+++ b/daemon/redis.h
@@ -32,6 +32,7 @@ struct redis {
 
 	redisContext	*ctx;
 	int		db;
+	const char	*auth;
 	mutex_t		lock;
 	unsigned int	pipeline;
 };
@@ -78,7 +79,7 @@ INLINE gboolean g_hash_table_insert_check(GHashTable *h, gpointer k, gpointer v)
 
 
 
-struct redis *redis_new(const endpoint_t *, int, enum redis_role);
+struct redis *redis_new(const endpoint_t *, int, const char *, enum redis_role);
 int redis_restore(struct callmaster *, struct redis *);
 void redis_update(struct call *, struct redis *);
 void redis_delete(struct call *, struct redis *);
diff --git a/debian/ngcp-rtpengine-daemon.default b/debian/ngcp-rtpengine-daemon.default
index b341e198f..f9b56f89c 100644
--- a/debian/ngcp-rtpengine-daemon.default
+++ b/debian/ngcp-rtpengine-daemon.default
@@ -17,8 +17,10 @@ TABLE=0
 # PORT_MAX=50000
 # REDIS=127.0.0.1:6379
 # REDIS_DB=1
+# REDIS_AUTH_PW=foobar
 # REDIS_WRITE=127.0.0.1:6379
 # REDIS_WRITE_DB=1
+# REDIS_WRITE_AUTH_PW=foobar
 # B2B_URL=http://127.0.0.1:8090/
 # LOG_LEVEL=6
 # LOG_FACILITY=daemon
diff --git a/debian/ngcp-rtpengine-daemon.init b/debian/ngcp-rtpengine-daemon.init
index 67b4347f7..f1bbfd885 100755
--- a/debian/ngcp-rtpengine-daemon.init
+++ b/debian/ngcp-rtpengine-daemon.init
@@ -63,7 +63,9 @@ fi
 [ -z "$PORT_MIN" ] || OPTIONS="$OPTIONS --port-min=$PORT_MIN"
 [ -z "$PORT_MAX" ] || OPTIONS="$OPTIONS --port-max=$PORT_MAX"
 [ -z "$REDIS" -o -z "$REDIS_DB" ] || OPTIONS="$OPTIONS --redis=$REDIS/$REDIS_DB"
+[ -z "$REDIS_AUTH_PW" ] || export RTPENGINE_REDIS_AUTH_PW="$REDIS_AUTH_PW"
 [ -z "$REDIS_WRITE" -o -z "$REDIS_WRITE_DB" ] || OPTIONS="$OPTIONS --redis-write=$REDIS_WRITE/$REDIS_WRITE_DB"
+[ -z "$REDIS_WRITE_AUTH_PW" ] || export RTPENGINE_REDIS_WRITE_AUTH_PW="$REDIS_WRITE_AUTH_PW"
 [ -z "$B2B_URL" ] || OPTIONS="$OPTIONS --b2b-url=$B2B_URL"
 [ -z "$NO_FALLBACK" -o \( "$NO_FALLBACK" != "1" -a "$NO_FALLBACK" != "yes" \) ] || OPTIONS="$OPTIONS --no-fallback"
 OPTIONS="$OPTIONS --table=$TABLE"