Redis is a powerful in-memory database that excels at very high performance use cases. However, by default, Redis has no built-in authentication or access controls. Any client that can connect to your Redis instance has full read/write access.

In many cases, this is perfectly acceptable if Redis is only accessible within a private network. But as soon as Redis is exposed to untrusted clients, access controls become critical for security.

Redis ACLs (Access Control Lists) allow you to restrict connections and commands on a per-user basis. For example, you can specify that only certain users are allowed to run dangerous commands like FLUSHDB or CONFIG.

In this comprehensive guide, you‘ll learn:

  • How Redis ACLs work
  • The components of a Redis ACL rule
  • How to create and manage ACL users
  • Common mistakes and misconfigurations
  • Tips for properly securing a Redis server with ACLs

Overview of Redis ACLs

Redis ACLs were introduced in Redis 6.0 after much anticipation. They provide the ability to restrict commands and key patterns on a per-connection basis.

Some key capabilities of Redis ACLs:

  • Usernames and passwords – Connections must authenticate with a valid username and password in order to connect. This ensures that every client maps to a specific user.
  • Command rules – Specify commands that users can and cannot execute. This restricts dangerous commands.
  • Key patterns – Restrict user access to keys matching a glob-style pattern. Helps segment data.
  • Complex rules – Combine multiple conditions and rules to tune permissions.

ACLs provide a crucial additional layer of security for Redis. Instead of blindly trusting all clients with all commands, you can carefully control permissions at a granular level.

According to reports from Redis Labs, the top motivator for adopting ACLs is enhancing security:

  • 63% cite security and compliance as the top driver
  • 55% wanted to restrict privileged users
  • 37% highlight operational best practices

With cyber attacks on the rise, ACLs represent a big leap forward for Redis security.

The ACL SETUSER Command

The workhorse behind Redis ACLs is the ACL SETUSER command. This command allows you to create and manage ACL user accounts.

The basic syntax is:

ACL SETUSER username [rule [rule ...]]

When you create a new user with ACL SETUSER, you can specify multiple rules to apply to that user account.

Here is an example that creates a user named "app1" with a password and permission to call GET and SET on any key:

ACL SETUSER app1 on >p@ssword ~* +GET +SET  

Let‘s break down the rules:

  • on – Enables the user account
  • >p@ssword – Sets "p@ssword" as the password
  • *~ * – Allow access to all keys (the glob matches anything)
  • +GET +SET – Allow the GET and SET commands

Many additional rules can be combined to construct complex permissions.

Anatomy of an ACL Rule

ACL rules follow a specific syntax:

[rule type] [rule details]  

The rule type indicates what kind of rule it is, like password management, command permissions, etc. The rule details flesh out the specifics.

Here are some common rule types:

  • on – Enable the user account
  • off – Disable the user account
  • ~pattern – Key glob pattern
  • +command|-command – Allow/deny commands
  • >password – Set user password
  • <<password – Remove user password
  • reset – Reset user password
  • ~commands – Allow all commands
  • @all – Allow access to all keys
  • nopass – Permit no password

In addition, here are some less common but useful rules:

  • >copies – Set max clients with this ACL
  • +@list|set|zset – Allow command categories
  • allkeys – Allow all keys
  • resetkeys – Clear key patterns

Multiple rules can be combined together to grant specific permissions.

Managing Passwords

To secure an account, the first rule to put in place is adding a password. This ensures a client must authenticate before getting access.

Setting a password

Use the >password syntax:

ACL SETUSER app1 on >p@ssword ~* +GET +SET

This will set "p@ssword" as the password for user "app1".

Removing a password

To remove the password and set no password:

ACL SETUSER app1 <<p@ssword nopass

Allowing no password with the nopass flag actually blocks access until a new password is set.

Forcing password reset

If your credentials are ever compromised, you can force password reset:

ACL SETUSER app1 resetpass  

The next time app1 connects, Redis will reject the previous password and require a new one via the ACL SETUSER command.

Authentication from clients

For clients to authenticate, the standard Redis AUTH command is used:

AUTH app1 p@ssword  

This will attempt to authenticate as the "app1" user with the password provided. All subsequent commands will adhere to app1‘s permissions.

Common mistakes

Some common mistakes when configuring ACL passwords:

  • Forgetting to add passwords at all
  • Setting weak passwords that are easy to crack
  • Enabling the nopass flag inadvertently
  • Neglecting to reset compromised passwords

Follow security best practices for strong credentials. Periodically resetting passwords helps diminish risk from leaks.

Restricting Commands

A simple way to enhance security is restricting the commands a user can execute. Dangerous commands like FLUSHDB, CONFIG, etc should only be allowed from trusted clients.

To allow specific commands, use the +command syntax:

ACL SETUSER reader +GET +SCAN +HGETALL  

This enables the GET, SCAN and HGETALL commands for user "reader".

To block a command, use the -command syntax:

ACL SETUSER untrusted -KEYS -FLUSHDB   

This specifically blocks KEYS and FLUSHDB for safety.

Some special command rule shortcuts:

  • Use +@string to allow command names containing string
  • Use +@all to allow all commands
  • Use -@all to remove all commands

So for example:

ACL SETUSER admin +@all

Grants the "admin" permission to call any and all commands.

Restricting command categories

The @list, @set and @zset rules provide shortcuts to allow/deny command categories:

ACL SETUSER cache +@list|@set 

This grants access to all list and set commands while denying everything else.

Monitoring blocked commands

When a client runs a command that is blocked, it results in an error:

NOPERM error running command FLUSHDB

These can be monitored on the server with:

ACL LOG RESET
ACL LOG

This provides visibility into unauthorized command attempts.

Common mistakes

Command permission mistakes include:

  • Granting dangerous CONFIG, KEYS, FLUSH privileges too broadly
  • Allowing deprecated DEBUG or SLAVEOF commands
  • Not restrictingSUBCOMMAND category access adequately

Follow principle of least privilege when assigning command rules.

Restricting Key Patterns

In order to call a command on a Redis key, a user must have permissions to access the key‘s name. ACLs allow restricting keys with glob-style patterns.

For example, to allow access to only keys prefixed with "cache:":

ACL SETUSER cacheUser +GET +SET cache:*   

The pattern cache:* will match keys like "cache:users", "cache:posts", etc. But not keys like "db:posts".

The special shortcut @all can be used to allow all keys:

ACL SETUSER cacheUser +GET +SET ~*  

Common wildcard rules:

  • Use ***** to match all keys
  • Use cache:* for prefix matching
  • Use data?? for pattern matching

Combine command rules and key rules for enhanced security.

For example, you may allow a reporting user to call KEYS but restrict the results to specific key patterns:

ACL SET reporting +KEYS "*:report*"

While KEYS is allowed, the results will filter to the matching keys only.

Reset key patterns

You can completely clear any key patterns with:

ACL SETUSER app resetkeys

Then rebuilding the desired patterns from scratch.

Common mistakes

Key pattern mistakes:

  • Forgetting to set any key restrictions
  • Being too permissive with patterns like ~*
  • Accidentally granting access to sensitive keys

Key permissions need to be in sync with command permissions for true security.

Unblocking New Commands

When new Redis commands are added in the future, existing users may be blocked from using them by default.

To allow users to utilize new commands as they are added, there is a special rule +@future.

For example:

ACL SETUSER app1 +@future ~* +GET +SET

This grants the app1 user all existing Redis commands in addition to any new ones added later on.

Default User and New Connections

Redis ACLs always include a default user that is active, called "default". This user has no password set but has permission to call all commands and access all keys.

When a new client connects to Redis without calling AUTH, they are automatically associated with the "default" user permissions.

It‘s recommended to modify the default user to be more locked down:

ACL SETUSER default off +INFO +PING   

This denies access to most functionality by default. Any client that connects without AUTH must first authenticate to gain additional access.

Rules for Subcommands

Some Redis commands like CLIENT or CONFIG have many nested subcommands. By default, allowing a command does not allow access to its subcommands.

For example:

ACL SETUSER user +CONFIG  

Even though CONFIG is allowed, its subcommands like CONFIG SET are blocked.

To allow subcommands, separate the parent and sub with a space:

ACL SETUSER user +CONFIG SET   

Now CONFIG SET specifically is enabled.

This allows finer-grained control over tricky commands.

Subcommands can be explicitly allowed or denied:

ACL SETUSER user +CLIENT SETNAME -DEBUG SEGFAULT

Combining Rules

The real power of ACLs comes from combining multiple rules to create complex permissions.

For example, an application could have separate users for read traffic and writes:

ACL SETUSER reader ~keys:* +@list|@set|@zset -DEL  

ACL SETUSER writer +SET|HSET|LPUSH|RPUSH ~app:*

The reader has read-only access to certain keys. The writer can modify keys with a different prefix.

Rules can also get quite complex:

ACL SETUSER worker +LPOP|RPOP ~queue:* 100 >9261db2b157c6e3cdb2a0f48167c9dc21ee82e5af6f6b64c9313e07d5d91fc7f allkeys

This allows the worker user to pop from prefixed queue keys, enforces a complex password, and limits max 100 clients.

The possibilities are endless for tailored whitelists and restrictions.

Best Practices

Properly securing Redis with ACL is critical for production environments. Here are some best practices:

Disable the default user – Only permit authenticated users by disabling default. Force ACLs everywhere.

Restrict commands strictly – Only allow the literal set of commands required. No command wildcards that would allow new commands in the future.

Limit key patterns – Tightly restrict readable and writable key globs whenever feasible. Segment permissions.

Grant subcommands explicitly – Avoid granting dangerous parent commands like KEYS or FLUSH. Be specific in subcommand grants.

Create RO users – Provide read-only users to clients without write needs.

Add IP restrictions – Further lock down ACLs to client source IP ranges when possible.

Monitor auth failures – Use ACL LOG to monitor failed command attempts and authentication issues.

Rotate credentials regularly – Force password resets every 90 days or so.

Following these tips will ensure your Redis access controls are locked down properly.

Conclusion

Redis ACLs provide very granular and flexible system for controlling user permissions. Role-based access control allows much more intelligent whitelisting than simplistic network firewalls.

Be sure to restrict access properly, disable default user, monitor auth failures, create read-only users where possible, and regularly rotate credentials. This will mitigate risk and prevent unauthorized access.

For even more control, Redis Enterprise adds client-side SSL encryption and integrated RBAC in a multi-tenant environment. But ACLs get you quite far in open-source Redis when properly utilized.

As threats continue evolving, it is crucial to lock down database access comprehensively, not just at the network level. Redis ACLs are a powerful tool to significantly improve security posture across the board.

Stay proactive and happy coding!

Similar Posts