Run Redis as an unprivileged user
/etc/systemd/system/redis-server.service.d/user.conf[Service]User=redisGroup=redisNoNewPrivileges=trueProtectSystem=strictProtectHome=truePrivateTmp=trueReadWritePaths=/var/lib/redis /var/log/redis /run/redissudo systemctl daemon-reloadsudo systemctl restart redis-serverDistribution packages already run as redis (or valkey). This page mostly
matters for hand-rolled installs and containers.
Why it matters
Section titled “Why it matters”Redis’s own documentation states plainly that it “does not require root
privileges to run” and recommends an unprivileged redis user.
The reason is specific rather than general hygiene. Redis can be made to write
files to arbitrary paths — CONFIG SET dir plus CONFIG SET dbfilename plus
SAVE writes the dataset wherever you point it. That is
the standard exploitation path for an exposed
instance.
The user Redis runs as decides what that write can reach:
- As
redis: the attacker writes files owned byredis, in placesrediscan write. Bad, and often enough to pivot — but bounded. - As
root: the same write lands in/root/.ssh/authorized_keys, or/etc/cron.d/, or a systemd unit. That is not a pivot, it is the machine.
Same bug, same command, entirely different blast radius. This control doesn’t stop the write; it decides what the write costs you.
The systemd hardening directives are the free part
Section titled “The systemd hardening directives are the free part”User=redis is the essential line. The rest above are cheap additions that
narrow the same write further:
| Directive | Effect |
|---|---|
NoNewPrivileges |
The process cannot gain privileges via setuid |
ProtectSystem=strict |
The entire filesystem is read-only except ReadWritePaths |
ProtectHome |
/home, /root and /run/user are inaccessible |
PrivateTmp |
Private /tmp, so no tmp-based interference |
ProtectSystem=strict with an explicit ReadWritePaths is the one that pays.
It means even a successful CONFIG SET dir /etc/cron.d cannot write, because the
path is read-only to the process regardless of file permissions.
Containers
Section titled “Containers”USER redis in the Dockerfile, or user: redis in compose. Running Redis as
root inside a container is common and is a smaller problem than on a host — but
combined with a bind mount it reaches the host filesystem as root, which puts you
straight back to the worst case.
Related
Section titled “Related”- Secure the config and data files — the permissions on what this user owns.
- Restrict dangerous commands with ACLs — removing
CONFIGremoves the write.