By Mark Drake and Manikandan Kurup
Redis is an in-memory key-value store known for its flexibility, performance, and wide language support. It is frequently used as a database, cache, and message broker. While a default installation is functional, it is not secure and leaves your data and server exposed to attack. An unsecured Redis instance can lead to data breaches, unauthorized access, and even server compromise.
This tutorial will guide you through installing the latest version of Redis on an Ubuntu server and implementing a production-ready security configuration. You will learn to configure user access with Access Control Lists (ACLs), encrypt traffic with TLS, restrict network access with a firewall, and apply additional system hardening measures covering memory management, persistence, and secure network configurations.
Key Takeaways
requirepass
directive. Disable the default
user and create specific users with the minimum required permissions for enhanced security.ufw
) to only accept traffic on the Redis port from specific, trusted IP addresses.maxmemory
directive in your configuration. Also, define a maxmemory-policy
to control how Redis evicts keys when the limit is reached.-@dangerous
).journalctl
and enable the Redis slow log. Watch for patterns like repeated failed authentications, connections from unknown sources, or abusive commands that could indicate a security issue or performance problem.dump.rdb
, appendonly.aof
) have strict file permissions and are included in your regular, encrypted, off-site backup strategy.To complete this guide, you will need access to an Ubuntu server that has a non-root user with sudo
privileges and a firewall configured with ufw
. You can set this up by following our Initial Server Setup guide for Ubuntu.
We’ll use the APT package manager to install redis from the official Ubuntu repositories. As of this writing, the version available in the default repositories is 7.0.15.
Begin by updating your local apt
package cache:
- sudo apt update
Then install Redis by typing:
- sudo apt install redis-server
This will download and install Redis and its dependencies. Once the installation is complete, it is good practice to verify the installed version:
- redis-server --version
Following this, there is one important configuration change to make in the Redis configuration file, which was generated automatically during the installation.
Open this file with your preferred text editor:
- sudo nano /etc/redis/redis.conf
Inside the file, find the supervised
directive. This directive allows you to declare an init system to manage Redis as a service, providing you with more control over its operation. The supervised
directive is set to no
by default. Since you are running Ubuntu, which uses the systemd init system, change this to systemd
:
. . .
# If you run Redis from upstart or systemd, Redis can interact with your
# supervision tree. Options:
# supervised no - no supervision interaction
# supervised upstart - signal upstart by putting Redis into SIGSTOP mode
# supervised systemd - signal systemd by writing READY=1 to $NOTIFY_SOCKET
# supervised auto - detect upstart or systemd method based on
# UPSTART_JOB or NOTIFY_SOCKET environment variables
# Note: these supervision methods only signal "process is ready."
# They do not enable continuous liveness pings back to your supervisor.
supervised systemd
. . .
That’s the only change you need to make to the Redis configuration file at this point, so save and close it when you are finished. If you used nano
to edit the file, do so by pressing CTRL + X
, Y
, then ENTER
.
Then, restart the Redis service to reflect the changes you made to the configuration file:
- sudo systemctl restart redis.service
With that, you’ve installed and configured Redis and it’s running on your machine. Before you begin using it, though, it’s prudent to first check whether Redis is functioning correctly.
As with any newly-installed software, it’s a good idea to ensure that Redis is functioning as expected before making any further changes to its configuration. We will go over a handful of ways to check that Redis is working correctly in this step.
Start by checking that the Redis service is running:
- sudo systemctl status redis
If it is running without any errors, this command will produce output similar to the following:
Output● redis-server.service - Advanced key-value store
Loaded: loaded (/lib/systemd/system/redis-server.service; enabled; vendor preset: enabled)
Active: active (running) since Thu 2020-04-30 23:26:54 UTC; 4s ago
Docs: http://redis.io/documentation,
man:redis-server(1)
Process: 36552 ExecStart=/usr/bin/redis-server /etc/redis/redis.conf (code=exited, status=0/SUCCESS)
Main PID: 36561 (redis-server)
Tasks: 4 (limit: 2345)
Memory: 1.8M
CGroup: /system.slice/redis-server.service
└─36561 /usr/bin/redis-server 127.0.0.1:6379
. . .
Here, you can see that Redis is running and is already enabled, meaning that it is set to start up every time the server boots.
Note: This setting is desirable for many common use cases of Redis. If, however, you prefer to start up Redis manually every time your server boots, you can configure this with the following command:
- sudo systemctl disable redis
To test that Redis is functioning correctly, connect to the server using redis-cli
, Redis’s command-line client:
- redis-cli
In the prompt that follows, test connectivity with the ping
command:
- ping
OutputPONG
This output confirms that the server connection is still alive. Next, check that you’re able to set keys by running:
- set test "It's working!"
OutputOK
Retrieve the value by typing:
- get test
Assuming everything is working, you will be able to retrieve the value you stored:
Output"It's working!"
After confirming that you can fetch the value, exit the Redis prompt to get back to the shell:
- exit
As a final test, we will check whether Redis is able to persist data even after it’s been stopped or restarted. To do this, first restart the Redis instance:
- sudo systemctl restart redis
Then connect with the command-line client again:
- redis-cli
And confirm that your test value is still available
- get test
The value of your key should still be accessible:
Output"It's working!"
Exit out into the shell again when you are finished:
- exit
With that, your Redis installation is fully operational and ready for you to use. However, some of its default configuration settings are insecure and provide malicious actors with opportunities to attack and gain access to your server and its data. The remaining steps in this tutorial cover methods for mitigating these vulnerabilities, as prescribed by the official Redis website. Although these steps are optional and Redis will still function if you choose not to follow them, it is strongly recommended that you complete them in order to harden your system’s security.
By default, Redis is only accessible from localhost. However, if you installed and configured Redis by following a different tutorial than this one, you might have updated the configuration file to allow connections from anywhere. This is not as secure as binding to localhost.
To correct this, open the Redis configuration file for editing:
- sudo nano /etc/redis/redis.conf
Locate this line and make sure it is uncommented (remove the #
if it exists):
bind 127.0.0.1 ::1
Save and close the file when finished (press CTRL + X
, Y
, then ENTER
).
Then, restart the service to ensure that systemd reads your changes:
- sudo systemctl restart redis
To check that this change has gone into effect, run the following netstat
command:
- sudo netstat -lnp | grep redis
Outputtcp 0 0 127.0.0.1:6379 0.0.0.0:* LISTEN 14222/redis-server
tcp6 0 0 ::1:6379 :::* LISTEN 14222/redis-server
Note: The netstat
command may not be available on your system by default. If this is the case, you can install it (along with a number of other handy networking tools) with the following command:
- sudo apt install net-tools
This output shows that the redis-server
program is bound to localhost (127.0.0.1
), reflecting the change you just made to the configuration file. If you see another IP address in that column (0.0.0.0
, for example), then you should double check that you uncommented the correct line and restart the Redis service again.
Now that your Redis installation is only listening in on localhost, it will be more difficult for malicious actors to make requests or gain access to your server. However, Redis isn’t currently set to require users to authenticate themselves before making changes to its configuration or the data it holds. To remedy this, Redis allows you to require users to authenticate with a password before making changes via the Redis client (redis-cli
).
Starting with Redis 6, Access Control Lists (ACLs) are the preferred method for managing user access and permissions. ACLs replace the older requirepass
directive with a more flexible system that lets you define multiple users with distinct passwords and command permissions.
First, generate a strong password for your user. You can use the openssl
command to create a long, random string.
- openssl rand 60 | openssl base64 -A
Copy the output, as you will use it as the password for your new Redis user.
Now, open the Redis configuration file again.
- sudo nano /etc/redis/redis.conf
Scroll to the ACL
section. To create a new user, you will add a user
directive. It is also a security best practice to disable the default
user, which by default has no password and full permissions.
Add the following lines to your configuration:
# Disable the default user.
user default off
# Create a new user with a strong password and full permissions.
user myuser on >your_generated_password ~* &* +@all
Here is a breakdown of the new user rule:
myuser
: The username.on
: Enables the user.>your_generated_password
: Sets the user’s password.~* &* +@all
: A rule that allows the user to run all commands (+@all
) on all keyspaces (~*
) and all Pub/Sub channels (&*
).Save and close the file, then restart Redis.
- sudo systemctl restart redis.service
To verify that the changes worked, try to connect with redis-cli
and run a command without authenticating.
- redis-cli ping
Because the default
user is now disabled, Redis will return an authentication error.
OutputNOAUTH Authentication required.
This confirms that unauthenticated access is blocked. Now, test the new user. Using the --askpass
flag is more secure than typing the password directly, as it prevents the password from being stored in your shell history.
- redis-cli --user myuser --askpass
Enter the password you generated when prompted. Once connected, try to run a command.
- ping
Redis should return PONG
. Your ACL configuration is working correctly.
ACLs protect your Redis instance from unauthorized access, but they do not protect the data being transmitted over a network. TLS (Transport Layer Security) encrypts this traffic, preventing eavesdropping between the client and the server.
First, create a directory to store your certificates.
- sudo mkdir /etc/redis/tls
Next, use openssl
to generate a self-signed certificate authority (CA), a server key, and a server certificate. You will be prompted to enter information (Country Name, Organization Name, etc.).
- # Generate CA Key and Certificate
- sudo openssl genrsa -out /etc/redis/tls/ca.key 4096
- sudo openssl req -x509 -new -nodes -key /etc/redis/tls/ca.key -sha256 -days 365 -out /etc/redis/tls/ca.crt
-
- # Generate Server Key and Certificate Signing Request (CSR)
- sudo openssl genrsa -out /etc/redis/tls/redis.key 2048
- sudo openssl req -new -key /etc/redis/tls/redis.key -out /etc/redis/tls/redis.csr
-
- # Sign the server certificate with the CA
- sudo openssl x509 -req -in /etc/redis/tls/redis.csr -CA /etc/redis/tls/ca.crt -CAkey /etc/redis/tls/ca.key -CAcreateserial -out /etc/redis/tls/redis.crt -days 365 -sha256
Set the correct permissions to ensure only the redis
user can access these sensitive files.
- sudo chmod 640 /etc/redis/tls/*
- sudo chown redis:redis /etc/redis/tls/*
Warning: Self-signed certificates are suitable for development, testing, or internal services where you can securely distribute the CA certificate to all clients. For production environments connecting over the public internet, use certificates issued by a trusted Certificate Authority (CA) like Let’s Encrypt.
Open the Redis configuration file.
- sudo nano /etc/redis/redis.conf
Add or modify the following lines to enable TLS. The best practice is to disable the unencrypted port by setting port 0
and only use the TLS-enabled port.
# Disable the non-encrypted TCP port.
port 0
# Enable the TLS port on the standard Redis port.
tls-port 6379
# Point to your certificate files.
tls-cert-file /etc/redis/tls/redis.crt
tls-key-file /etc/redis/tls/redis.key
tls-ca-cert-file /etc/redis/tls/ca.crt
Save the file and restart Redis.
- sudo systemctl restart redis.service
To connect with redis-cli
, you now need to specify the TLS parameters.
- redis-cli --user myuser --askpass --tls --cacert /etc/redis/tls/ca.crt
After authenticating, your connection to Redis is fully encrypted.
For an even higher level of security, you can configure mutual TLS (mTLS), where the client must also present a valid certificate to the server.
First, generate a client key and certificate, signed by your CA.
- # Generate client key and CSR
- openssl genrsa -out client.key 2048
- openssl req -new -key client.key -out client.csr
-
- # Sign the client certificate with your CA
- sudo openssl x509 -req -in client.csr -CA /etc/redis/tls/ca.crt -CAkey /etc/redis/tls/ca.key -CAcreateserial -out client.crt -days 365 -sha256
Next, enable client authentication in /etc/redis/redis.conf
.
tls-auth-clients yes
Restart Redis. Now, clients must present their certificate and key to connect.
- redis-cli --user myuser --askpass --tls \
- --cacert /etc/redis/tls/ca.crt \
- --cert client.crt \
- --key client.key
A firewall is a critical layer of security that restricts network traffic to your server. By default, Redis only listens on the local loopback interface (127.0.0.1
), so it is not exposed to the public internet. If you need to connect from an external server, you must configure Redis to listen on its public IP and set strict firewall rules.
Warning: Exposing a Redis instance directly to the public internet is a significant security risk. It is strongly recommended to use safer alternatives for remote access.
If you must allow direct connections, use ufw
to allow traffic on the Redis TLS port (6379) only from one specific, trusted IP address.
- sudo ufw allow from your_trusted_ip/32 to any port 6379 proto tcp
Replace your_trusted_ip
with the static IP address of your application server.
Always ensure your SSH port is allowed.
- sudo ufw allow OpenSSH
Finally, enable the firewall if it’s not already active.
- sudo ufw enable
Instead of opening the Redis port to the world, consider these more secure methods:
Example of creating an SSH tunnel:
- ssh -L 8000:127.0.0.1:6379 user@your_redis_server_ip
You can then connect your local Redis client to localhost:8000
, and the traffic will be securely forwarded to the Redis server.
You can further secure your Redis instance with these additional measures.
Instead of renaming dangerous commands (an older practice), use ACL rules to restrict them on a per-user basis. This provides more granular control and does not break Redis clients or monitoring tools.
For example, to prevent myuser
from using commands that could cause significant damage (like FLUSHALL
, DEBUG
, SHUTDOWN
), you can modify their ACL rule by removing the @all
category and adding more specific ones, while also explicitly blocking dangerous commands.
# Example of a more restrictive user
user myuser on >your_generated_password ~* &* +@read +@write +@connection -@dangerous -FLUSHALL
This rule allows the user to perform read, write, and connection commands but explicitly blocks the @dangerous
command category and the FLUSHALL
command.
The practice of renaming commands is largely obsolete and should be avoided in favor of ACLs. Renaming commands can break client libraries, complicate maintenance, and cause issues with persistence (AOF) and replication.
If you encounter a system using this method, commands are renamed in /etc/redis/redis.conf
like this:
# rename-command FLUSHALL ""
# rename-command CONFIG MY_SECURE_CONFIG_COMMAND
An attacker could attempt a Denial-of-Service (DoS) attack by filling up your server’s memory. Configure Redis to set a memory limit to prevent this.
In /etc/redis/redis.conf
, uncomment and set the maxmemory
and maxmemory-policy
directives:
maxmemory 2gb
maxmemory-policy allkeys-lru
maxmemory
: Sets a hard limit on how much memory Redis can use.maxmemory-policy
: Tells Redis what to do when the limit is reached. allkeys-lru
evicts the least recently used keys, which is a common choice for caches.Unix Sockets: For applications running on the same machine as Redis, using a Unix socket is more secure than a TCP port because it bypasses the network stack. Enable it in redis.conf
:
unixsocket /var/run/redis/redis.sock
unixsocketperm 770
Then connect with redis-cli -s /var/run/redis/redis.sock
.
Idle Timeouts: Close idle connections automatically to free up resources and reduce the attack surface.
timeout 300
This will close connections that are idle for 300 seconds.
Ubuntu includes AppArmor, a security module that confines programs to a limited set of resources. The redis-server
package comes with a default AppArmor profile that is automatically enabled.
You can verify its status with:
- sudo aa-status | grep redis
This profile provides an important layer of defense by restricting what the Redis process can do on the system. On other Linux distributions like CentOS, SELinux serves a similar purpose.
Regularly monitoring logs is important for detecting errors, performance issues, and suspicious activity.
You can view the real-time logs managed by systemd
with journalctl
.
- sudo journalctl -u redis-server.service -f
Watch for patterns like:
NOAUTH
).For production systems, forward these logs to a centralized logging platform (like an ELK stack) to set up automated alerts for suspicious patterns.
The Redis slow log records queries that exceed a specified execution time. It is useful for finding performance bottlenecks and can also help identify abusive or inefficient commands from clients.
Enable it in /etc/redis/redis.conf
:
slowlog-log-slower-than 10000
slowlog-max-len 128
slowlog-log-slower-than
: Logs commands taking longer than this value in microseconds (10000 = 10ms).slowlog-max-len
: The maximum number of entries in the slow log.View the slow log with redis-cli
:
- redis-cli SLOWLOG GET
By default, Redis keeps all data in memory. Persistence mechanisms save this data to disk, protecting it from being lost if the server restarts.
Redis offers two main persistence modes:
You can enable one or both in /etc/redis/redis.conf
. The default configuration enables RDB. To enable AOF:
appendonly yes
The Redis data files (dump.rdb
, appendonly.aof
) are stored in /var/lib/redis/
by default. Ensure this directory and its files are owned by the redis
user and are not world-readable.
- sudo ls -l /var/lib/redis
For disaster recovery, you must back up these files.
gpg
before transferring them off the server.requirepass
method?Redis Access Control Lists (ACLs), introduced in Redis 6, are the modern standard for managing user permissions. Unlike the single password provided by requirepass
, ACLs allow you to create multiple users with unique passwords and granular permissions. You can control which commands a user can run, which keys they can access, and which Pub/Sub channels they can use. This “principle of least privilege” is a core security practice, as it limits the potential damage an attacker can cause if a single user’s credentials are compromised.
No, it is highly discouraged. Exposing Redis directly, even with a password and TLS, makes it a target for brute-force attacks and potential zero-day vulnerabilities. The most secure methods for remote access involve a private network. You should use a VPN (like WireGuard or OpenVPN) or an SSH tunnel to create a secure, encrypted channel between your application server and your Redis instance without ever exposing the Redis port to the open internet.
Both RDB and AOF are methods for saving your in-memory Redis data to disk.
For most production use cases, it is recommended to enable both persistence methods to get the benefits of durability (AOF) and convenient backups (RDB).
An attacker could launch a Denial-of-Service (DoS) attack by continuously writing data until your server’s memory is exhausted. To prevent this, you should set a memory limit in your redis.conf
file using the maxmemory
directive (e.g., maxmemory 2gb
). You should also define a maxmemory-policy
(like allkeys-lru
) to tell Redis how to evict keys once that limit is reached.
Renaming commands is a legacy security practice that is no longer recommended. The modern and more effective approach is to use Redis ACLs to restrict access to dangerous commands on a per-user basis. Renaming commands is difficult to maintain, can break client libraries and monitoring tools, and causes complications with replication and AOF persistence.
ACLs and passwords protect your Redis server from unauthorized access (authentication), but they do not protect the data as it travels over a network. Without TLS (Transport Layer Security), all your data—including commands and responses—is sent in plaintext. An attacker on the network could intercept this traffic to steal sensitive information. TLS encrypts the entire connection, ensuring that all communication between your client and the Redis server is private and secure.
You should monitor both the system logs and the Redis slow log.
journalctl -u redis-server.service
): Check these for a high volume of failed authentication attempts, unexpected connections from unknown IP addresses, or errors related to blocked commands.For production systems, these logs should be sent to a centralized logging platform where you can set up automated alerts for these patterns.
AppArmor is a Linux security module included with Ubuntu that confines programs to a limited set of system resources. The redis-server
package comes with a pre-configured AppArmor profile that is enabled by default. This profile restricts the files and network capabilities the Redis process can access, providing a critical layer of defense if an attacker finds a vulnerability in Redis itself. For a standard installation, no additional configuration is required.
When your application and Redis are running on the same machine, the most secure connection method is a Unix socket, not a TCP port. A Unix socket is a file on the filesystem used for inter-process communication, and it bypasses the network stack entirely. This is faster and more secure because it is subject to filesystem permissions and cannot be accessed from outside the server.
Self-signed certificates are acceptable for development, testing, or internal services where you can securely distribute your self-generated Certificate Authority (CA) to every client. However, for applications connecting over the public internet or in larger, more complex production environments, it is strongly recommended to use TLS certificates issued by a trusted, public Certificate Authority like Let’s Encrypt. This simplifies certificate management and avoids trust issues with clients.
In this tutorial, you installed and configured Redis, validated that your Redis installation is functioning correctly, and used its built-in security features to make it less vulnerable to attacks from malicious actors.
Keep in mind that once someone is logged in to your server, it’s very easy to circumvent the Redis-specific security features we’ve put in place. Therefore, the most important security feature on your Redis server is your firewall (which you configured if you followed the prerequisite Initial Server Setup tutorial), as this makes it extremely difficult for malicious actors to jump that fence.
Although this guide will get you started with installing and securing Redis, we strongly recommend refering to the official documentation for better security:
Thanks for learning with the DigitalOcean Community. Check out our offerings for compute, storage, networking, and managed databases.
Former Technical Writer at DigitalOcean. Focused on SysAdmin topics including Debian 11, Ubuntu 22.04, Ubuntu 20.04, Databases, SQL and PostgreSQL.
With over 6 years of experience in tech publishing, Mani has edited and published more than 75 books covering a wide range of data science topics. Known for his strong attention to detail and technical knowledge, Mani specializes in creating clear, concise, and easy-to-understand content tailored for developers.
This textbox defaults to using Markdown to format your answer.
You can type !ref in this text area to quickly search our full set of tutorials, documentation & marketplace offerings and insert the link!
One of the best guides on the internet. Thank you Mark, It was very informative and useful.
The tutorial is very detailed and easy to follow. But I think Redis password authentication is redundant for trusted networks such as localhost or private network between servers of the same application. However, it will be useful for public access though.
Hey, can you explain why the SPOP, SREM, RENAME commands are dangerous? I specifically intent to use 2 of those commands for a message buffering system (I filter subsequent duplicate message on the same id which eventually triggers a read to a different database and sends that data to another part of the application)
Good Post on Redis. The renaming of commands should be put in a different article for more advanced Redis implementations. Perhaps a post on Redis Dedicated servers or HA clusters. Again, Thanks ^^.
Failed to restart redis.service: Unit redis.service not found.
Execute the following
$ sudo systemctl enable redis-server
I tried this recommendation, however, this will not work with secure WSS (websocket) It seems like Redis - Daphne needs to connect to your droplet IP to create a secure working WSS websocket for users.
I am using Nginx - Gunicorn for HTTP requests and Redis - Daphne for WSS. Clients are authenticated for using this service, however, in terms of backend attacks towards the Redis server itself, I am not sure (Other than a PWD protection) how to limit incoming access when it needs to be allowed and set to the droplet IP. 127.0.0.1 will not work.
Configuring this type is also vague, as it is still fairly new. Bear in mind, that having this up and running locally is easier than getting it to a point where it will run securely - successfully - pain-free for you and your users on a live setup.
Get paid to write technical tutorials and select a tech-focused charity to receive a matching donation.
Full documentation for every DigitalOcean product.
The Wave has everything you need to know about building a business, from raising funding to marketing your product.
Stay up to date by signing up for DigitalOcean’s Infrastructure as a Newsletter.
New accounts only. By submitting your email you agree to our Privacy Policy
Scale up as you grow — whether you're running one virtual machine or ten thousand.
Sign up and get $200 in credit for your first 60 days with DigitalOcean.*
*This promotional offer applies to new accounts only.