Redis from source
Simple setup
yum --enablerepo=remi install redis
systemctl enable redis
systemctl start redis
cd /tmp
wget https://pecl.php.net/get/redis-4.3.0.tgz
tar xzvf redis-4.3.0.tgz
phpize
cd redis-4.3.0/
phpize
./configure
make
make test
make install
php -m | grep redis
nano /etc/php.d/redis.iniextension=redis.so
php -m | grep redis
systemctl restart httpd php-fpm
nano /etc/redis/redis.conf
daemonize yes
supervised systemd
# save 3600 1
# save 300 100
# save 60 10000dir /var/lib/redis
maxmemory 1024mb (or 512mb)
maxmemory-policy allkeys-lfu
appendonly yes
redis-cli PING
tail /var/log/redis/redis.log
nano /var/www/html/resource.php
<?php
$redis = new Redis();
$redis->connect('127.0.0.1', 6379);
$redis->auth('REDIS_PASSWORD');
$max_calls_limit = 7;
$time_period = 10;
$total_user_calls = 0;
if (!empty($_SERVER['HTTP_CLIENT_IP'])) {
$user_ip_address = $_SERVER['HTTP_CLIENT_IP'];
} elseif (!empty($_SERVER['HTTP_X_FORWARDED_FOR'])) {
$user_ip_address = $_SERVER['HTTP_X_FORWARDED_FOR'];
} else {
$user_ip_address = $_SERVER['REMOTE_ADDR'];
}
if (!$redis->exists($user_ip_address)) {
$redis->set($user_ip_address, 1);
$redis->expire($user_ip_address, $time_period);
$total_user_calls = 1;
} else {
$redis->INCR($user_ip_address);
$total_user_calls = $redis->get($user_ip_address);
if ($total_user_calls > $max_calls_limit) {
echo "Hey, " . $user_ip_address . ", You've already reached your requests limit. Total requests "
. $total_user_calls . " Allowed requests " . $max_calls_limit;
exit();}
}
?>
curl http://localhost/resource.php?[1-20]
Unmounting
systemctl stop redis.service
systemctl mask redis.service
systemctl disable redis.service
yum remove redis
Installation
cd /usr/local/src
wget http://download.redis.io/releases/redis-5.0.0.tar.gz
tar xf redis-5.0.0.tar.gz
cd redis-5.0.0
make
make test
make install
groupadd redis
adduser --system -g redis --no-create-home redis
Next create the /var/lib/redis
directory which will store the redis databases:
mkdir -p /var/lib/redis
Give the redis user and group ownership over the directory:
chown redis: /var/lib/redis
Set the correct permissions with:
chmod 770 /var/lib/redis
Step 4. Creating Redis Configuration
Now that Redis is installed and intial setup has been completed on your CentOS 7 VPS, you’ll need to create the configuration file.
First, create the /etc/redis
directory with:
mkdir /etc/redis
Next copy the default configuration file by running:
cp /usr/local/src/redis-5.0.0/redis.conf /etc/redis/
Open the file with your preferred text editor (we’ll be using nano
):
nano /etc/redis/redis.conf
Search for the supervised directive and change it 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
Search for the dir directive and set it to /var/lib/redis
:
# The working directory. # # The DB will be written inside this directory, with the filename specified # above using the 'dbfilename' configuration directive. # # The Append Only File will also be created inside this directory. # # Note that you must specify a directory here, not a file name. dir /var/lib/redis
Once done, save and close the file.
Step 5. Creating a Redis Systemd Unit File
Now that Redis is installed and configured, the last step is to create a systemd unit file so that you can manage the Redis servis as a regular systemd service.
Open your text editor and create the follwing file:
nano /etc/systemd/system/redis.service
Then add the following content to it:
[Unit] Description=Redis Data Store After=network.target [Service] User=redis Group=redis ExecStart=/usr/local/bin/redis-server /etc/redis/redis.conf ExecStop=/usr/local/bin/redis-cli shutdown Restart=always [Install] WantedBy=multi-user.target
Save and close the file. Enable and start the Redis service with:
systemctl enable redis systemctl start redis
To check that the Redis service has no errors, run:
systemctl status redis
ln -s /usr/local/bin/redis-cli /usr/bin/redis-cli
redis-cli PING
systemctl restart redis.service
tail /var/log/redis/redis.log
reboot
USEFUL COMMANDS
Performing an LRU simulation
Redis is often used as a cache with LRU eviction. Depending on the number of keys and the amount of memory allocated for the cache (specified via the maxmemory
directive), the amount of cache hits and misses will change. Sometimes, simulating the rate of hits is very useful to correctly provision your cache.
The CLI has a special mode where it performs a simulation of GET and SET operations, using an 80-20% power law distribution in the requests pattern. This means that 20% of keys will be requested 80% of times, which is a common distribution in caching scenarios.
Theoretically, given the distribution of the requests and the Redis memory overhead, it should be possible to compute the hit rate analytically with with a mathematical formula. However, Redis can be configured with different LRU settings (number of samples) and LRU's implementation, which is approximated in Redis, changes a lot between different versions. Similarly the amount of memory per key may change between versions. That is why this tool was built: its main motivation was for testing the quality of Redis' LRU implementation, but now is also useful in for testing how a given version behaves with the settings you had in mind for your deployment.
In order to use this mode, you need to specify the amount of keys in the test. You also need to configure a maxmemory
setting that makes sense as a first try.
IMPORTANT NOTE: Configuring the maxmemory
setting in the Redis configuration is crucial: if there is no cap to the maximum memory usage, the hit will eventually be 100% since all the keys can be stored in memory. Or if you specify too many keys and no maximum memory, eventually all the computer RAM will be used. It is also needed to configure an appropriate maxmemory policy, most of the times what you want is allkeys-lru
.
In the following example I configured a memory limit of 100MB, and an LRU simulation using 10 million keys.
WARNING: the test uses pipelining and will stress the server, don't use it with production instances.
$ ./redis-cli --lru-test 10000000
156000 Gets/sec | Hits: 4552 (2.92%) | Misses: 151448 (97.08%)
153750 Gets/sec | Hits: 12906 (8.39%) | Misses: 140844 (91.61%)
159250 Gets/sec | Hits: 21811 (13.70%) | Misses: 137439 (86.30%)
151000 Gets/sec | Hits: 27615 (18.29%) | Misses: 123385 (81.71%)
145000 Gets/sec | Hits: 32791 (22.61%) | Misses: 112209 (77.39%)
157750 Gets/sec | Hits: 42178 (26.74%) | Misses: 115572 (73.26%)
154500 Gets/sec | Hits: 47418 (30.69%) | Misses: 107082 (69.31%)
151250 Gets/sec | Hits: 51636 (34.14%) | Misses: 99614 (65.86%)
The program shows stats every second. As you see, in the first seconds the cache starts to be populated. The misses rate later stabilizes into the actual figure we can expect in the long time:
120750 Gets/sec | Hits: 48774 (40.39%) | Misses: 71976 (59.61%)
122500 Gets/sec | Hits: 49052 (40.04%) | Misses: 73448 (59.96%)
127000 Gets/sec | Hits: 50870 (40.06%) | Misses: 76130 (59.94%)
124250 Gets/sec | Hits: 50147 (40.36%) | Misses: 74103 (59.64%)
A miss rage of 59% may not be acceptable for our use case. So we know that 100MB of memory is not enough. Let's try with half gigabyte. After a few minutes we'll see the output stabilize to the following figures:
140000 Gets/sec | Hits: 135376 (96.70%) | Misses: 4624 (3.30%)
141250 Gets/sec | Hits: 136523 (96.65%) | Misses: 4727 (3.35%)
140250 Gets/sec | Hits: 135457 (96.58%) | Misses: 4793 (3.42%)
140500 Gets/sec | Hits: 135947 (96.76%) | Misses: 4553 (3.24%)
So we know that with 500MB we are going well enough for our number of keys (10 millions) and distribution (80-20 style).
redis-server --version
gives you the version.
redis-cli
INFO
redis-cli --stat
redis-cli
127.0.0.1:6379> config get repl*
curl http://localhost/resource.php?[1-20]
resource.php
<?php
try {
$redis = new Redis();
$redis->connect('127.0.0.1', 6379);
$username = $_SERVER['PHP_AUTH_USER'];
$password = $_SERVER['PHP_AUTH_PW'];
$key = $username;
$allowed_requests_per_period = 5;
$time_frame_in_seconds = 10;
$total_requests = 0;
if ($redis->exists($key)) {
$redis->INCR($key);
$total_requests = $redis->get($key);
if ($total_requests > $allowed_requests_per_period) {
echo "Hey, " . $username . ", You've already reached your requests limit. Total requests "
. $total_requests . " Allowed requests " . $allowed_requests_per_period;
exit();
}
} else {
$redis->set($key, 1);
$redis->expire($key, $time_frame_in_seconds);
$total_requests = 1;
}
echo "ok, total requests " . $total_requests;
} catch (Exception $e) {
echo $e->getMessage();
}
?>
either shorten version
try {
$redis = new Redis();
$redis->connect('127.0.0.1', 6379);
$username = $_SERVER['PHP_AUTH_USER'];
$password = $_SERVER['PHP_AUTH_PW'];
$key = $username;
$allowed_requests_per_period = 12;
$time_frame_in_seconds = 10;
$total_requests = 0;
if ($redis->exists($key)) {
$redis->INCR($key);
$total_requests = $redis->get($key);
if ($total_requests > $allowed_requests_per_period) {
exit();
}
} else {
$redis->set($key, 1);
$redis->expire($key, $time_frame_in_seconds);
$total_requests = 1;
}
}
catch (Exception $e)
{
}
MORE STABLE version
$redis = new Redis();
$redis->connect('127.0.0.1', 6379);
$redis->auth('REDIS_PASSWORD');
$max_calls_limit = 7;
$time_period = 10;
$total_user_calls = 0;
if (!empty($_SERVER['HTTP_CLIENT_IP'])) {
$user_ip_address = $_SERVER['HTTP_CLIENT_IP'];
} elseif (!empty($_SERVER['HTTP_X_FORWARDED_FOR'])) {
$user_ip_address = $_SERVER['HTTP_X_FORWARDED_FOR'];
} else {
$user_ip_address = $_SERVER['REMOTE_ADDR'];
}
if (!$redis->exists($user_ip_address)) {
$redis->set($user_ip_address, 1);
$redis->expire($user_ip_address, $time_period);
$total_user_calls = 1;
} else {
$redis->INCR($user_ip_address);
$total_user_calls = $redis->get($user_ip_address);
if ($total_user_calls > $max_calls_limit) {
exit();
}
}
COMPLETE TUTORIAL
Redis Rate-Limiter
Install the Redis package by typing:
sudo yum install redis
Once the installation is completed, start the Redis service and enable it to start automatically on boot with:
sudo systemctl start redis
sudo systemctl enable redis
Created symlink from /etc/systemd/system/multi-user.target.wants/redis.service to /usr/lib/systemd/system/redis.service.
To check the status of the service enter the following command:
sudo systemctl status redis
You should see something like the following:
● redis.service - Redis persistent key-value database Loaded: loaded (/usr/lib/systemd/system/redis.service; enabled; vendor preset: disabled) Drop-In: /etc/systemd/system/redis.service.d └─limit.conf Active: active (running) since Sat 2018-11-24 15:21:55 PST; 40s ago Main PID: 2157 (redis-server) CGroup: /system.slice/redis.service └─2157 /usr/bin/redis-server 127.0.0.1:6379
Configure Redis
Open the Redis configuration file in your favorite editor:
$ sudo nano /etc/redis.conf
Set the desired memory capacity for your application.
maxmemory 512mb
By default, when maxmemory is reached, Redis will stop writing new data. If you want Redis to write new data by removing old data automatically, you have to tell Redis how to remove it. The allkeys-lru eviction policy is a good choice for most users. Add the following line:
maxmemory-policy allkeys-lru
Learn more about eviction methods here.
Set the save-to-disk policy.
By default, Redis will save its in-memory data on disk after a specified period or a specified number of write operations against the DB. The default settings are:
save 900 1 save 300 10 save 60 10000
That means saving will occur:
- after 900 sec (15 min) if at least 1 key changed
- after 300 sec (5 min) if at least 10 keys changed
after 60 sec if at least 10000 keys changed
With the default settings above, Redis will load the saved data into memory every time it restarts. So your previous in-memory data will be restored. If you don't need this feature, you can disable it entirely by commenting out those lines:
# save 900 1 # save 300 10 # save 60 10000
If you decide to keep this feature, you should upgrade the server to a bigger plan or add an appropriate Linux swap file to ensure that Redis's memory is double the maxmemory declared above. Otherwise, in the worst-case scenario, when the maxmemory is reached, the saving process can cause your server to run out of memory.
Save and close the configuration file, then restart Redis to apply the changes.
$ sudo systemctl restart redis.service
3. Fine-Tune the System
Check the Redis log file:
tail /var/log/redis/redis.log
| `-._`-._ _.-'_.-' |
`-._ `-._`-.__.-'_.-' _.-'
`-._ `-.__.-' _.-'
`-._ _.-'
`-.__.-'
4681:M 28 Feb 19:16:48.584 # Server started, Redis version 3.2.12
4681:M 28 Feb 19:16:48.584 # WARNING you have Transparent Huge Pages (THP) support enabled in your kernel. This will create latency and memory usage issues with Redis. To fix this issue run the command 'echo never > /sys/kernel/mm/transparent_hugepage/enabled' as root, and add it to your /etc/rc.local in order to retain the setting after a reboot. Redis must be restarted after THP is disabled.
4681:M 28 Feb 19:16:48.584 * DB loaded from disk: 0.000 seconds
4681:M 28 Feb 19:16:48.584 * The server is now ready to accept connections on port 6379
To fix that warning, you need to disable transparent hugepages at boot time before starting the Redis service.
Create a new script file:
nano /usr/bin/disable-transparent-hugepage
Paste the following text into the file:
#!/bin/bash
echo never > /sys/kernel/mm/transparent_hugepage/enabled
exit 0
Save and close the file, then make it runnable and owned by the root account:
chown root:root /usr/bin/disable-transparent-hugepage
chmod 770 /usr/bin/disable-transparent-hugepage
Next, create the configuration file for the systemd service that will call the script at boot time:
nano /etc/systemd/system/disable-transparent-hugepage.service
Paste the following text into the file:
[Unit]
Description=Disable Transparent Huge Pages (THP) for Redis.
Before=redis.service
[Service]
Type=exec
ExecStart=/usr/bin/disable-transparent-hugepage
[Install]
WantedBy=multi-user.target
Save and close the file, then enable the service:
systemctl enable disable-transparent-hugepage.service
4. Verify the Setup
Restart the Redis server:
reboot
After the server restarts, check the Redis log file to ensure there are not any warnings:
tail /var/log/redis/redis.log
Use the redis-cli program to connect to Redis through the default loopback IP 127.0.0.1 and port 6379.
$ redis-cli -h 127.0.0.1 -p 6379
If the connection succeeds, you will see the Redis command prompt:
127.0.0.1:6379>
Enter some Redis commands to ensure it works:
set testkey testvalue get testkey exit
If you see the following result, then Redis is working correctly.
127.0.0.1:6379> set testkey testvalue OK 127.0.0.1:6379> get testkey "testvalue" 127.0.0.1:6379> exit
5. (Optional) Configure Redis for Private Network Access
If you set up a production environment with multiple servers for your application, the application servers need access to the Redis server. It's recommended to use a private network for safety.
Configure the private network
- Follow this guide to enable and configure a private network for this Redis server and the application servers that need to communicate with Redis.
Update the firewalld service to allow incoming connections from the private network:
$ sudo firewall-cmd --permanent --zone=trusted --change-interface=ens7
iptables -A INPUT -s 10.22.96.3 -p tcp --dport 6379 -j ACCEPT
Create a systemd service to delay the Redis start-up until the private interface is up and IP address is assigned.
$ sudo nano /etc/systemd/system/redis.service.d/wait-for-ips.conf
Paste the following text into the file, then save and close it:
[Unit] After=network-online.target Wants=network-online.target
Edit the Redis configuration file.
$ sudo nano /etc/redis.conf
Add the private IP address that Redis should bind to. For example, if Redis should bind to both the internal loopback (127.0.0.1) and a private IP address (192.168.0.100):
bind 127.0.0.1 private_ip
Save and close the configuration file.
Restart Redis to apply the changes.
$ sudo systemctl restart redis.service
Test the private network
- Connect to one of your application servers on your private network via SSH.
Assuming the application server is also CentOS 8, temporarily install Redis to get the redis-cli software.
$ sudo dnf install redis
Use the redis-cli program to connect to the Redis server.
$ redis-cli -h 192.168.0.100 -p 6379
If the connection succeeds, you will see the Redis command prompt:
192.168.0.100:6379>
Enter some Redis commands to ensure it works:
set testkey testvalue get testkey exit
If you see the following result, then Redis is working correctly.
127.0.0.1:6379> set testkey testvalue OK 127.0.0.1:6379> get testkey "testvalue" 127.0.0.1:6379> exit
Uninstall the redis package on the application server.
Use the redis-cli program to connect to the Redis server.
$ redis-cli -h ip.add.re.ss -p 6379
iptables -A INPUT -s 10.22.96.3 -p tcp --dport 6379 -j ACCEPT
(probably, the decision to fix staled keys be refreshed) https://www.digitalocean.com/community/tutorials/how-to-set-up-a-redis-s...
Persistence Options
Redis provides two options for disk persistence:
- Point-in-time snapshots of the dataset, made at specified intervals (RDB).
- Append-only logs of all the write operations performed by the server (AOF).
Each option has its own pros and cons which are detailed in the Redis documentation. For the greatest level of data safety, consider running both persistence methods.
Because the Point-in-time snapshot persistence is enabled by default, you only need to set up AOF persistence:
- Make sure that the following values are set for the
appendonly
andappendfsync
settings inredis.conf
:
File: /etc/redis.conf
1 2 |
|
- Restart Redis:
sudo systemctl restart redis
Search for the supervised directive and change it 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
Search for the dir directive and set it to /var/lib/redis:
# The working directory.
#
# The DB will be written inside this directory, with the filename specified
# above using the 'dbfilename' configuration directive.
#
# The Append Only File will also be created inside this directory.
#
# Note that you must specify a directory here, not a file name.
dir /var/lib/redis
Once done, save and close the file.
Renaming Dangerous Commands
The other security feature built into Redis allows you to rename or completely disable certain commands that are considered dangerous. When run by unauthorized users, such commands can be used to reconfigure, destroy, or otherwise wipe your data. Some of the commands that are known to be dangerous include:
- FLUSHDB
- FLUSHALL
- KEYS
- PEXPIRE
- DEL
- CONFIG
- SHUTDOWN
- BGREWRITEAOF
- BGSAVE
- SAVE
- SPOP
- SREM RENAME DEBUG
nano /etc/redis.conf
# It is also possible to completely kill a command by renaming it into
# an empty string:
#
rename-command FLUSHDB ""
rename-command FLUSHALL ""
rename-command DEBUG ""
rename-command SHUTDOWN SHUTDOWN_MENOT
rename-command CONFIG ASC12_CONFIG
systemctl restart redis.service
redis-cli
config get requirepass
Output
(error) ERR unknown command 'config'
Use Redis as a Rate Limiter
Introduction
Rate limiting is a method of limiting resource usage in your server. For instance, if you're running an API (Application Programming Interface), you may put a cap limiting the number of requests a user can make on your server within a specific timeframe. Controlling the rate of requests made in your web application reduces the risk of DoS (Denial of Service) attack. This allows you to enforce a fair usage policy for your application. In a large-scale web application, limiting operations from exceeding certain constraints also allows you to save huge costs on bandwidth and resource usage.
Prerequisites
To follow along with this guide, ensure you have the following:
- An Centos 7 server.
- A sudo user.
- A Lamp Stack.
- A Redis Server
1. Install Redis Extension
Log in to your Vultr Ubuntu cloud server and install the php-redis
extension. This module allows you to use the Redis Library in PHP code.
$ sudo apt install -y php-redis
Restart the Apache server to load the new configuration.
$ sudo systemctl restart httpd
2. Create a PHP Resource
Create a PHP resource in the root directory of your server.
$ sudo nano /var/www/html/resource.php
Then, add the information below to the file.
<?php
try {
$redis = new Redis();
$redis->connect('127.0.0.1', 6379);
$username = $_SERVER['PHP_AUTH_USER'];
$password = $_SERVER['PHP_AUTH_PW'];
$key = $username;
$allowed_requests_per_period = 3;
$time_frame_in_seconds = 10;
$total_requests = 0;
if ($redis->exists($key)) {
$redis->INCR($key);
$total_requests = $redis->get($key);
if ($total_requests > $allowed_requests_per_period) {
echo "Hey, " . $username . ", You've already reached your requests limit. Total requests "
. $total_requests . " Allowed requests " . $allowed_requests_per_period;
exit();
}
} else {
$redis->set($key, 1);
$redis->expire($key, $time_frame_in_seconds);
$total_requests = 1;
}
echo "ok, total requests " . $total_requests;
} catch (Exception $e) {
echo $e->getMessage();
}
?>
When you finish editing the file, save and close it by pressing CTRL + X, Y then ENTER.
The /var/www/html/resource.php
code explained:
$redis = new Redis();
$redis->connect('127.0.0.1', 6379);
You've used the above code to connect to a Redis server on your localhost via port 6379.
$username = $_SERVER['PHP_AUTH_USER'];
$password = $_SERVER['PHP_AUTH_PW'];
When you've configured PHP to run as an Apache module, the $_SERVER['PHP_AUTH_USER']
and $_SERVER['PHP_AUTH_PW']
variables assign the HTTP Basic Authentication credentials to the $username
and $password
variables respectively.
$key = $username;
Because you might have many users accessing your web resource, creating a Redis key with the $username
variable retrieved from the $_SERVER['PHP_AUTH_USER']
variable allows you to track the traffic of each user independently.
$allowed_requests_per_period = 3;
$time_frame_in_seconds = 10;
The two variables above allow you to limit your web resource requests depending on the set usage policy in your application. This example limits users to 3 requests in 10 seconds. Adjust these values depending on your needs.
$total_requests = 0;
You've initialized the total requests made by a user using the $total_requests
variable.
if ($redis->exists($key)) {
$redis->INCR($key);
$total_requests = $redis->get($key);
if ($total_requests > $allowed_requests_per_period) {
echo "You've already reached your requests limit. Total requests "
. $total_requests . " Allowed requests " . $allowed_requests_per_period;
exit();
}
} else {
$redis->set($key, 1);
$redis->expire($key, $time_frame_in_seconds);
$total_requests = 1;
}
The code above checks for the existence of the $key
variable on the Redis server. If the key exists, you are incrementing it by 1
using the $redis->INCR($key)
command. If the key does not exist, you are setting a new key with a default value of 1
using the $redis->set($key, 1)
command as well as the expiration period defined by the $time_frame_in_seconds
variable. Next, you are accessing the current count of the $key
key using the $redis->get($key)
. Once the value is retrieved, you're assigning it to the $total_requests
variable.
Then, you're using the PHP logic if...else
syntax to evaluate if the client has exceeded the total requests allowed during the period defined. If the limit is exceeded, you're raising an error to the user.
echo "ok, total requests " . $total_requests;
Towards the bottom of the file, you're echoing the number of requests made by the user if they've not exceeded their limit.
3. Test the Redis Rate Limiter
Open a command prompt on your server and use the curl
command to query the /var/www/html/resource.php
web resource that you have created above. The dummy query string ?[1-20]
at the end of the http://localhost/resource.php
URL allows you to access the resource 20 times to see if the script will be rate-limited by the Redis server.
$ curl http://localhost/resource.php?[1-20]
After running the above code, you should get the below output.
[1/20]: http://localhost/resource.php?1 --> <stdout>
--_curl_--http://localhost/resource.php?1
ok, total requests 1
[2/20]: http://localhost/resource.php?2 --> <stdout>
--_curl_--http://localhost/resource.php?2
ok, total requests 2
[3/20]: http://localhost/resource.php?3 --> <stdout>
--_curl_--http://localhost/resource.php?3
ok, total requests 3
[4/20]: http://localhost/resource.php?4 --> <stdout>
--_curl_--http://localhost/resource.php?4
Hey, , You've already reached your requests limit. Total requests 4 Allowed requests 3
[5/20]: http://localhost/resource.php?5 --> <stdout>
--_curl_--http://localhost/resource.php?5
Hey, , You've already reached your requests limit. Total requests 5 Allowed requests 3
...
Notice that the first three requests are accepted. However, the PHP script started throwing a rate-limit error beginning at the fourth request.
Private Network
ifconfig
eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 137.220.55.24 netmask 255.255.254.0 broadcast 137.220.55.255
inet6 2001:19f0:b001:652:5400:3ff:fe36:121c prefixlen 64 scopeid 0x0<global>
inet6 fe80::5400:3ff:fe36:121c prefixlen 64 scopeid 0x20<link>
ether 56:00:03:36:12:1c txqueuelen 1000 (Ethernet)
RX packets 569 bytes 54267 (52.9 KiB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 446 bytes 86970 (84.9 KiB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
eth1: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1450
inet 10.22.96.3 netmask 255.255.240.0 broadcast 10.22.111.255
inet6 fe80::5800:3ff:fe36:121c prefixlen 64 scopeid 0x20<link>
ether 5a:00:03:36:12:1c txqueuelen 1000 (Ethernet)
RX packets 3 bytes 390 (390.0 B)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 81 bytes 12702 (12.4 KiB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
nano /etc/sysconfig/network-scripts/ifcfg-eth1
# Private network: net603b78f8af125
DEVICE=eth1
ONBOOT=yes
BOOTPROTO=static
IPADDR=10.22.96.3
NETMASK=255.255.240.0
MTU=1450
ifup eth1
service network restart
Configure Redis
In this step, we're going to configure our Redis Server installation on the CentOS 7 server.
Edit the Redis configuration file '/etc/redis.conf' using vim editor.
vim /etc/redis.conf
Now change 'bind' address with your internal IP address. If you're running as a cluster, you can change with the private IP address. It's recommended to run the Redis Server on private internal IP address.
bind 127.0.0.1
The Network security for redis server is related with the 'bind' configuration on the redis configuration 'redis.conf'. It's recommended to use the internal private network for your Redis installation and don't use the public.
On the 'bind' section, change the IP address with your own internal network IP address.
bind INTERNAL-IP-ADDRESS
Save and close.
And now the redis service will run under the 'INTERNAL-IP-ADDRESS'.
Now change the 'daemonize' value to 'yes', because we will run the Redis service as a daemon.
daemonize yes
Since we're using the CentOS 7 server and systemd, so we need to change the 'supervised' line configuration to 'systemd'.
supervised systemd
Save and close.
Now restart the redis service.
systemctl restart redis
The basic configuration of the Redis Server has been completed. Now connect to the Redis Server using the redis-cli command as below.
redis-cli
Run the ping command below.
ping
ping "Hello Redis"
If your installation is correct, you will get the 'PONG' reply and the message that you write after the command.
redis-cli
127.0.0.1:6379> ping
PONG
127.0.0.1:6379> ping "Hello Redis"
"Hello Redis"
127.0.0.1:6379>
Password Authentication
The password authentication for Redis will give you access control to your Redis server. This is a little layer of security that will enhance your Redis server security, and it is not yet enabled by default installation.
To enable the Password Authentication for Rediser server, you will need to uncomment the 'requirepass' section on the 'redis.conf' file and type your strong password after it.
requirepass hakase-labs321@#$
Change the 'hakase-labs321@#$' with your strong password. And now the password authentication for Redis has been enabled.
3. Disabling Dangerous Redis Command
Redis provides a feature for disabling some specific Redis command. This feature can be used to rename or disable some of the dangerous commands such as 'FLUSHALL' for erasing all data, 'CONFIG' command to setup configuration parameter through the Redis CLI, etc.
To change or disable the Redis command, you can use the 'rename-command' option. Edit the redis configuration file 'redis.conf' and add some configurations below.
# rename-command COMMAND "CUSTOM"
rename-command CONFIG "REDISCONFIG"
rename-command FLUSHALL "DELITALL"
Save and close.
Once all is complete, restart the redis service using the systemctl command below.
systemctl restart redis
And the basic Redis security for securing Redis installation has been applied to our host.
Delete default or currently selected database (usually `0) with
redis-cli flushdb
Clear SPECIFIC
Delete specific redis database with (e.g. 8
as my target database):
redis-cli -n 8 flushdb
Clear ALL
Delete all redis databases with
redis-cli flushall