Redis诞生于2009年,因其丰富的数据结构和高性能,是目前使用最广泛的缓存技术。据DB-Engines对Key-Value类型数据库流行度排名,Redis已连续多年位列第一,Redis已成为互联网应用和云原生应用的标配。本文基于Redis 5.X,系统地对Redis安全应用方面进行增强,从开发、运维的各方面对安全使用Redis提出建议。
应用平台部 李文波 文
一、Redis认证与账户安全
Redis认证安全
◐ Redis服务的默认配置中,客户端不需要密码即可登录Redis服务,攻击者探测到Redis服务后可直接登录Redis服务。建议配置Redis服务密码,客户端连接服务时需通过-a命令输入密码才能连接。
【解决方案】:启用Redis配置文件中requirepass配置项以配置Redis服务密码。
◐ Redis服务默认配置中,主、从节点之间通信是不进行密码校验的,攻击者可启动一个从节点,主动备份暴露在外的主节点数据。建议配置masterauth,当从节点连接主节点时会校验通信密码是否一致,不一致则拒绝该从节点的数据备份请求。
【解决方案】:启用Redis配置文件中masterauth配置项以配置主从通信密码。

Redis账户安全
◐ Redis原生只支持密码明文配置,是不安全的。
【解决方案】:1.修改源码,使支持密文密码。2.新增Redis服务代理层【注1】,使Redis服务完全不暴露在外。【推荐】
◐ Redis无密码失败次数限制及用户锁定、解锁能力,攻击者可通过暴力破解Redis密码。
【解决方案】:1.修改源码,使支持用户锁定、解锁能力等。2.对Redis服务添加访问代理层【注1】,在代理层实现密码管理功能。【推荐】
◐ Redis原生只有一个超级用户,攻击者一旦获取该密码,可对Redis服务造成巨大影响。
【解决方案】:1. 修改源码新增用户组管理,对Redis客户端分配不同的命令权限。2. 新增Redis服务代理层(见注1),在代理层实现客户端用户权限管理。【推荐】

注1:对于Redis服务代理层的实现,业内常用的代理软件对比如下,其中性能方面无论是单线程还是多线程调用Redis代理,Predixy的性能都是最好的,甚至与直连Redis服务相差无几:

二、Redis通信加固
使用spiped代理通信
◐ Redis客户端与服务端交互的数据在网络上传输时是明文传输,存在被窃听的风险,需要对通信进行加密、认证,而Spiped(发音“ess-pipe-dee”)是一款在sokect地址之间创建对称加密和身份认证管道的工具,与Stunnel等提供SSL代理的工具相比,具有轻量化、易使用的特点,是Redis官方推荐的通信代理工具。故推荐使用spiped代理Redis客户端与服务端直接的通信
【解决方案】:建议使用spiped对Redis通信进行加密认证。
避免暴露默认网络端口
◐ Redis服务的默认配置会监听来自所有网段的客户端连接,如果该服务器有多个网卡,同时对接内网和外网,则外网的攻击者可对Redis服务发起攻击。
【解决方案】:启用Redis配置文件中bind配置项以绑定网卡。例如:一台服务器内网地址是:10.10.11.187,外网地址是220.181.22.123,回环地址是127.0.0.1,如果配置bind 10.10.11.187,则通过外网地址和回环地址都无法连接到Redis。
◐ Redis默认通信接口是6379,应修改避免猜测攻击。
【解决方案】:启用Redis配置文件中port配置项以配置Redis服务端口。
◐ Redis cluster是使用gossip通信,默认接口为服务端端口偏移10000。例如Redis服务的通信接口是6379,则Redis cluster的节点通信端口是16379。
【解决方案】:1.修改Redis配置文件中port配置项以间接修改Redis cluster通信端口。2.新增Redis服务代理层,使Redis服务完全不暴露在外。
三、Redis运行环境安全
Redis最小操作权限
◐ 修改Redis服务的运行账号,以较低权限账号运行Redis服务,限制Redis服务运维人员修改操作系统的其他敏感文件。
◐ 为保护Redis服务相关文件,避免任意登录服务器人员操作Redis服务资源文件,建议设置Redis主目录运行权限为700(文件所有者可读可写可运行),配置文件单独为600(文件所有者可读可写不能执行)。
隐藏操作记录中的敏感信息
◐ 操作系统可通过ps命令或history命令显示用户输入过的操作命令,如果运维人员通过Redis-cli指定-a参数,Redis服务密码会被操作系统记录,攻击者登录后可获取Redis服务的登录密码。

【解决方案】:尽量通过API访问的方式请求Redis服务。
配置Redis运行环境防火墙策略
◐ 设置Redis服务所在环境的防火墙策略,只允许特定的IP地址访问Redis服务。如果Redis服务有代理层,则也应对代理层所在环境设置防火墙策略。
例如:对于Redhat7操作系统,可以使用命令将ip加入白名单:firewall-cmd --permanent--add-rich-rule="rule family="ipv4" source address="白名单IP" accept" 再使用firewall-cmd –reload重新加载防火墙。
四、Redis客户端安全
禁用危险命令
◐ Redis服务无命令权限分组,任意用户登录Redis服务后可执行任意命令,如flush清空数据库数据、config修改redis配置等。
【解决方案】:修改redis.conf对重要命令进行隐藏,使其不能被随意执行。包括不限于flushdb, flushall, pexpire, del, config, shutdown, bgsave, save, stop, srm, rename, debug, eval, grewriteaof等。

慎用影响Redis服务性能的命令
◐ keys命令能获取当前Redis服务中的所有key值信息,连续的keys命令可能令Redis阻塞,导致Redis服务宕机,形成服务拒绝攻击,使用keys命令应谨慎!
【解决方案】:使用scan命令,SCAN cursor {match pattern} {Count}
五、Redis开发安全
设置数据失效时间
◐ 向Redis存入缓存、验证码等数据时,如果忘记配置key的过期时间,则随着数据增长,可能会出现内存溢出的现象。
【解决方案】:对有必要的key设置失效时间和失效策略。
慎用不设置范围的批量操作
◐ Redis是单线程运行的,当取数操作不设置取数范围时,会导致数据量过大而引起引起Redis阻塞,出现服务拒绝攻击。例如使用hgetall命令,会取出相关hash的所有数据,在此期间会阻塞Redis服务,导致大量的客户端请求超时,引起服务拒绝攻击。
【解决方案】:对于批量操作,考虑是否一定得一次性取出所有数据,可否分批次处理。
敏感数据存储前加密
◐ 由于Redis没有数据隔离,所有连接到Redis服务的客户端均可互相读取数据,故建议对存储到Redis的数据进行加密,限制Redis服务运维人员或攻击者登录Redis服务获取到敏感数据。
【解决方案】:在存储数据前,对数据进行加密,再将数据存储到Redis中。
六、审计和日志
Redis审计记录
◐ Redis服务端应对客户端连接进行审计。
【解决方案】1. Redis服务提供了client list命令审计客户端连接,可以显示客户端地址、连接时长、正在使用的数据库id等信息;但只能审计当前保持连接的客户端。2. 新增Redis服务代理层,在代理层上对来自客户端的连接进行审计。
◐ Redis API客户端应记录发起的Redis命令。
例如:扩展Jedis客户端中redis.clients.jedis.Connection类的sendCommand方法,在执行命令前记录发起命令29118:S 26 Nov 11:19:29.100 * redisUser01 config set requirepass;10.145.93.119:52817;
Redis日志记录
◐Redis本身支持记录日志,如/ciblog/Redis9001/Redis9001.log。需要通过在Redis.conf进行如下配置:
logfile:日志输出的路径
syslog-enabled:是否把日志输出到系统日志中:yes
syslog-ident:设置系统日志标识:Redis
syslog-facility:指定syslog设备,值可以是USER或LOCAL0-LOCAL7

今日话题
大家还有什么增强Redis安全应用的措施或方法呢,一起来讨论吧~




