# Redis Setup with PHP, Nginx, and Security Configuration on Ubuntu 22.04

This guide will walk you through the installation and configuration of Redis, PHP-Redis, Nginx, and important security configurations to ensure a robust and secure Redis setup for your distributed system.

## Prerequisites

1. Ubuntu 22.04 server with PHP 8.2 installed.
2. Nginx installed and configured.
3. Basic knowledge of Linux commands and file system.

## Step 1: Install Redis

First, let's install Redis on your Ubuntu 22.04 system.

```bash
sudo apt update
sudo apt install redis-server
```

### Verify Redis Installation
Check if Redis is running.

```bash
sudo systemctl status redis-server
```

If Redis is not running, you can start it using:

```bash
sudo systemctl start redis-server
```

To ensure Redis starts on boot:

```bash
sudo systemctl enable redis-server
```

## Step 2: Install PHP-Redis

Next, we need to install PHP Redis extension to enable PHP to interact with Redis.

```bash
sudo apt install php-redis
```

After installation, verify the extension is enabled by running:

```bash
php -m | grep redis
```

If "redis" appears, the extension is successfully installed.

## Step 3: Configure Redis

Redis has a configuration file located at `/etc/redis/redis.conf`. Let's make sure it's configured for optimal use.

### Change Redis Binding Address

By default, Redis only binds to localhost. If you're using Redis in a production environment and need to access it remotely, update the `bind` setting:

```bash
sudo nano /etc/redis/redis.conf
```

Find the line:

```bash
bind 127.0.0.1 ::1
bind 127.0.0.1 192.168.1.100 192.168.1.101 //ip whitelist
```

And change it to:

```bash
bind 0.0.0.0
```

This will allow connections from any IP address. Be careful with this setting in a production environment, as it can expose Redis to unwanted access.

### Set Redis to Require a Password

For security, let's require a password to access Redis. In `redis.conf`, locate the following line:

```bash
# requirepass foobared
```

Uncomment it and set a strong password:

```bash
requirepass StrongPasswordHere
```

### Secure Redis Further

For added security, we will disable commands that could potentially harm your system.

In `redis.conf`, disable the following commands:

```bash
rename-command FLUSHDB ""
rename-command FLUSHALL ""
rename-command SHUTDOWN ""
rename-command CONFIG ""
rename-command DEBUG ""
rename-command SCRIPT ""
```

This will prevent certain dangerous commands from being executed.

### Enable Redis Persistence (Optional)

If you're setting up Redis as a central cache or store, you may want to enable persistence.

Locate and adjust the following lines in `redis.conf` to enable AOF (Append Only File):

```bash
appendonly yes
appendfsync everysec
```

## Step 4: Set up User and ACL (Access Control List)

In Redis, you can create multiple users with specific permissions using ACL. Redis ACLs help you restrict the access to commands and data in Redis.

### Enable ACL in Redis

To enable ACLs, ensure the following line is in your `redis.conf`:

```bash
user default on nopass ~* +@all
```

You can create custom users with specific commands and keys access restrictions.

### Creating a User with Permissions

1. To create a new user with specific commands and keys access, run the following command from Redis CLI:

```bash
ACL SETUSER new_user on >password ~keyprefix:* +get +set -del
```

This command does the following:
- Creates a new user `new_user`.
- Assigns a password `password` (be sure to change it).
- Restricts access to keys starting with `keyprefix:*`.
- Allows only `get` and `set` commands but denies `del` command.

2. You can also set default ACLs for users. For example:

```bash
ACL SETUSER default +@all -@dangerous
```

This allows all commands but disables dangerous ones.

### Check User Permissions

To check a user's ACL:

```bash
ACL LIST
```

To see which commands the user can run:

```bash
ACL GETUSER new_user
```

## Step 5: Set Up Redis as a Service

Make sure Redis is set up to run as a service that starts on boot:

```bash
sudo systemctl enable redis-server
```

## Step 6: Secure Redis Server

Security is crucial when running Redis, especially for a production environment. Here are some tips:

1. **Limit Redis Access**: Ensure Redis only listens on the necessary interfaces. Modify the `bind` and `protected-mode` settings in `redis.conf` as needed.
2. **Firewall**: Restrict access to Redis by IP using UFW (Uncomplicated Firewall):

```bash
sudo ufw allow from <trusted_ip> to any port 6379
sudo ufw deny 6379
```

3. **Disable Dangerous Commands**: As mentioned earlier, disable commands that could compromise the Redis server, such as `FLUSHDB`, `FLUSHALL`, and `SHUTDOWN`.

## Step 7: Nginx Configuration

Now, configure Nginx to interact with your PHP server. Ensure that Nginx and PHP are working together.

1. **Install Nginx** (if not installed):

```bash
sudo apt install nginx
```

2. **Configure Nginx for PHP**

Edit the Nginx site configuration file:

```bash
sudo nano /etc/nginx/sites-available/default
```

Make sure the server block is configured as follows:

```nginx
server {
    listen 80;
    server_name example.com;

    root /var/www/html;
    index index.php index.html index.htm;

    location / {
        try_files $uri $uri/ =404;
    }

    location ~ \.php$ {
        include snippets/fastcgi-php.conf;
        fastcgi_pass unix:/var/run/php/php8.2-fpm.sock;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        include fastcgi_params;
    }
}
```

Restart Nginx to apply changes:

```bash
sudo systemctl restart nginx
```

## Step 8: Testing Redis and PHP

To ensure that everything is working, you can test Redis and PHP integration with a simple PHP script.

1. Create a test file in `/var/www/html`:

```bash
sudo nano /var/www/html/test.php
```

2. Add the following content:

```php
<?php
$redis = new Redis();
$redis->connect('127.0.0.1');
$redis->set('test_key', 'Hello, Redis!');
echo $redis->get('test_key');
?>
```

3. Access this PHP file from your browser (e.g., `http://your_server_ip/test.php`) and verify if it returns the correct output (`Hello, Redis!`).

## Step 9: Performance Optimization (Optional)

To optimize Redis for better performance, you can adjust the following settings in `redis.conf`:

1. **Max memory**: Set a memory limit for Redis to avoid overloading your system:

```bash
maxmemory 2gb
maxmemory-policy allkeys-lru
```

2. **TCP Backlog**: Increase the backlog for TCP connections:

```bash
tcp-backlog 511
```

3. **Disable Swap**: Prevent Redis from swapping to disk by setting:

```bash
vm.overcommit_memory = 1
```

Edit the sysctl configuration file:

```bash
sudo nano /etc/sysctl.conf
```

Add:

```bash
vm.overcommit_memory = 1
```

Reload the settings:

```bash
sudo sysctl -p
```

## Conclusion

With these steps, you have successfully installed and configured Redis with PHP-Redis and Nginx on your Ubuntu 22.04 server. You’ve also set up Redis user permissions, security configurations, and optimizations to ensure it performs securely and efficiently in a distributed system environment.