Redis is fast because it trusts its clients. The Redis security documentation says it plainly: Redis is designed to be accessed by trusted clients inside trusted environments, and should not be exposed directly to the internet. An exposed instance can be wiped with a single FLUSHALL, and a client that can run CONFIG can make Redis write files to arbitrary paths, which may lead to running code as the Redis user. This guide covers the layers that keep a Redis server on a VPS safe.
Layer 1: keep it off the network
If Redis and the application run on the same server, Redis should listen on loopback only. The upstream sample redis.conf for Redis 7.0 and 8.0 already does this and keeps protected mode on:
# /etc/redis/redis.conf on Debian and Ubuntu
bind 127.0.0.1 -::1
protected-mode yes
port 6379Since Redis 3.2, protected mode makes an instance that binds all interfaces and has no password answer only on loopback and send an error to everyone else. It is a safety net, not a configuration: an administrator can still disable it or bind all interfaces. Check what is really listening:
sudo ss -tlnp | grep 6379You should see 127.0.0.1:6379 and [::1]:6379, never 0.0.0.0:6379. If the application runs on another server, bind Redis to a private address, allow port 6379 only from the application servers in both the host firewall and any cloud firewall, and add TLS (layer 4).
Layer 2: real users instead of the open default user
Out of the box, Redis has a single default user that the ACL documentation lists as user default on nopass ~* &* +@all: every connection is authenticated automatically and can run every command on every key. Since Redis 6, Access Control Lists are the recommended way to authenticate; the older requirepass setting only sets a password on that default user.
A practical setup turns the default user off and defines named users in an external ACL file:
# /etc/redis/redis.conf
aclfile /etc/redis/users.acl
# /etc/redis/users.acl
user default off
user app on >REPLACE-WITH-LONG-RANDOM-PASSWORD ~app:* &* +@all -@dangerous
user admin on >REPLACE-WITH-ANOTHER-PASSWORD ~* &* +@all# generate passwords, protect the file, restart
openssl rand -base64 32
sudo chown redis:redis /etc/redis/users.acl
sudo chmod 640 /etc/redis/users.acl
sudo systemctl restart redis-serverPoints from the documentation that matter here:
- Users defined in
redis.confand an external ACL file cannot be mixed; Redis refuses to start.requirepassis ignored whenaclfileis used. - After editing the file,
ACL LOADreloads it, but only if every user line is valid. Otherwise the old configuration stays active. - Instead of a clear-text
>password, a line can hold#followed by the password's SHA-256 hash, so the file does not contain the password itself. - Passwords should be long: Redis answers so fast that an attacker can test many passwords per second.
Test it:
redis-cli
127.0.0.1:6379> PING # expect a NOAUTH error
127.0.0.1:6379> AUTH app the-password
127.0.0.1:6379> ACL WHOAMILayer 3: keep dangerous commands away from the application
The ACL category dangerous includes FLUSHALL, CONFIG, DEBUG, KEYS, SORT, CLIENT, INFO, SAVE, REPLICAOF and others. Removing it from the application user (-@dangerous) means a bug or an injection in the app cannot reconfigure Redis. Some frameworks call INFO or KEYS; if yours does, add back only that command, for example +info, and test.
The old rename-command directive still works but is deprecated; the documentation recommends ACL rules instead. Redis 7.0 and later also ship three settings that block risky features by default: enable-protected-configs keeps file-related settings such as dir and dbfilename immutable at runtime, and enable-debug-command and enable-module-command block DEBUG and MODULE. Leave them at their default no unless you have a specific need, and then prefer local.
Layer 4: TLS when traffic leaves the server
AUTH is sent in clear text like every other command, so on a network between servers, credentials and data can be read by anyone who can observe the traffic. Redis has supported TLS since version 6 as a build-time option (Redis TLS documentation). With a TLS-enabled build, a TLS-only listener looks like this:
port 0
tls-port 6379
tls-cert-file /etc/redis/tls/redis.crt
tls-key-file /etc/redis/tls/redis.key
tls-ca-cert-file /etc/redis/tls/ca.crtBy default clients must also present a certificate; tls-auth-clients no turns that off. Clients connect with redis-cli --tls --cacert ... plus their own certificate if required. On a single server, loopback binding is simpler and sufficient.
Run it unprivileged and keep it patched
Redis does not need root, and the documentation recommends a dedicated unprivileged user; check with ps -o user= -C redis-server. Debian 12 (bookworm) ships Redis 7.0.15 and Debian 13 (trixie) ships Redis 8.0.2, according to the package tracker, and both receive security fixes through Debian advisories. Follow the Debian security tracker page for redis, install updates with sudo apt update && sudo apt upgrade, and restart redis-server afterwards, because the running process keeps the old code until then.
Common pitfalls
- Changing
bindto0.0.0.0to "fix" a connection error from another host, without a firewall or password. - Publishing Redis from a Docker container with
-p 6379:6379, which binds every interface and is not covered by ufw. - Setting a password but leaving the default user with
+@allfor the application. - Keeping RDB or AOF files, which contain all the data, readable by other users or copied to unprotected backups.
What you should do
- Run
ss -tlnp | grep 6379on every server and make sure Redis listens only where it must. - Turn off the
defaultuser and create named ACL users with long passwords and only the keys they need. - Remove
@dangerousfrom application users and keep the protected-config settings atno. - Use TLS and firewall rules for any Redis traffic between servers.
- Track Redis security updates for your release and restart the service after installing them.
Sources
- redis.io/docs/latest/operate/oss_and_stack/management/security
- redis.io/docs/latest/operate/oss_and_stack/management/security/acl
- redis.io/docs/latest/operate/oss_and_stack/management/security/encryption
- raw.githubusercontent.com/redis/redis/8.0/redis.conf
- raw.githubusercontent.com/redis/redis/7.0/redis.conf
- redis.io/docs/latest/develop/tools/cli
- packages.ubuntu.com/noble/amd64/redis-server/filelist
- git.launchpad.net/ubuntu/+source/redis/plain/redis.conf?h=applied/ubuntu/noble
- tracker.debian.org/pkg/redis
- security-tracker.debian.org/tracker/source-package/redis
Comments
0 total · 0 threads