ARTICLE DETAIL

资讯详情

深耕网站视觉设计与运营推广的一线实战洞察。

Redis密码设置全攻略:从requirepass到ACL的实战避坑指南

Redis密码设置全攻略:从requirepass到ACL的实战避坑指南 前阵子帮朋友排查一台服务器刚登上去就发现不对劲Redis端口在公网暴露着进程还活着但数据库里多了一堆莫名其妙的keycrontab里被塞了定时任务一看就是被自动化脚本盯上了。这台Redis压根没设密码属于“裸奔”状态。朋友知道后问我“Redis密码设置不就一行requirepass的事吗还能有什么坑”——这句话其实代表了大多数人的认知。确实单看“设置密码”这个动作一行配置就完事了。但把这行配置放进生产环境会发现后面还牵着一串问题密码怎么跟主从同步、哨兵、集群协作客户端连接参数怎么配分布式锁、Lua脚本在鉴权下怎么跑密码在日志、历史命令、配置文件里会不会被泄露出去这些才是“Redis密码设置”真正值得写一篇长文的地方。这篇文章会从最基础的requirepass讲起一路覆盖到高可用架构和Redis 6的ACL精细权限适合刚接触Redis的新手也适合已经在生产环境用Redis、想回头查缺补漏的开发者或运维。1. 先算一笔账Redis裸奔到底有多危险1.1 那个被当成肉鸡的Redis实例先说朋友那台服务器的事。根因很快查清Redis监听在0.0.0.0:6379没有任何访问控制所有命令裸奔。攻击者连上来之后直接用CONFIG SET设置了dir和dbfilename把一段恶意数据写成了crontab任务。从那之后这台机器每隔几分钟就去拉取一段挖矿脚本CPU占用长期飘在80%以上。这不是个别案例而是互联网上每天都发生的事。Redis默认不鉴权如果你装完redis-server就直接扔到公网或者干脆没做任何网络层隔离那等同于把一个装满档案的抽屉摆在路边谁路过都能翻。更麻烦的是Redis的命令非常灵活攻击者不只会读数据还能通过主从复制加载自定义模块、写入计划任务、覆写系统文件这些技术细节网上都有讨论但核心就一句未授权访问的Redis等于把服务器最高权限的半把钥匙交了出去。1.2 攻击者的三条典型入侵路径很多人觉得“我的Redis里只有不重要数据被删了也无所谓”。这种想法在真实攻击里站不住脚因为攻击者盯上的不是你那几个key而是整台服务器写定时任务利用CONFIG SET dir和CONFIG SET dbfilename结合SAVE/BGSAVE把构造好的数据写到 /var/spool/cron/ 或 /etc/cron.d/ 下从而拿到周期性执行命令的能力。这是“Redis未授权访问拿服务器权限”里最经典的打法。写公钥文件把攻击者的SSH公钥写入 /root/.ssh/authorized_keys之后直接通过SSH密钥登录获得完整shell。加载恶意模块Redis 4.0之后支持MODULE LOAD攻击者可以复制一个恶意的so文件到服务器再让Redis加载执行任意命令。这三条路径的共同前提都是能连上Redis且无需密码。一旦配置了requirepass第一道门槛就把绝大多数自动化扫描脚本拦在门外了。不能保证百分百安全但攻击成本会被拉高一个数量级。1.3 设密码前的现状评估动手设置密码之前建议先梳理一下Redis实例的当前访问方式而不是闷头改配置。我会按这个顺序做一遍整体评估用INFO或CLIENT LIST看看当前有哪些应用在连接IP和端口都记下来。确认Redis部署形态单机、主从、Sentinel还是Cluster不同的形态决定后面密码参数往哪儿配。确认访问Redis的客户端类型命令行、Spring Boot/Node/Python应用、可视化工具、还有定时任务里跑的脚本。确认是否已经存在主从关系如果有从节点只改requirepass不够还要改masterauth否则密码一上主从同步直接断。检查现有的防火墙/安全组规则6379端口是否只对可信IP开放。这一步千万别省。我在很多生产环境里看到过改完requirepass后主从同步断了半天没人发现原因就是没提前做现状评估。下面进入正题说说密码到底怎么设。2. 设置密码的三条路径配置文件、命令行与启动参数怎么选Redis设置密码的方法有三条分别对应不同的使用习惯和运维场景。很多教程只提配置文件那条但实际运维中尤其是容器化部署和临时调试时后两条更常用。2.1 通过redis.conf设置requirepass最基础、也最推荐的方式是在配置文件里加上一行requirepass YourStrongPassword2025然后重启Redis或者用其他方式重新加载配置。注意requirepass在配置文件里就是这样的写法大小写不要写错。新版Redis虽然语法没变但配置文件改名或者注释位置不同容易让人一脸懵。我通常把它放在SECURITY段落下面和后面的rename-command之类安全配置放在一起方便日后维护。这里有个容易踩的小坑如果配置文件里已经有了一个被注释掉的# requirepass foobared你直接写一个新行没问题但最好把原来的注释行删掉避免有人粗心看到两行混淆。设置完后用redis-cli -a 密码或者redis-cli之后执行AUTH来验证就对了。2.2 动态设置CONFIG SET与CONFIG REWRITE的搭配不重启Redis就启用密码用CONFIG SETredis-cli CONFIG SET requirepass YourStrongPassword2025这种方式立刻生效适合线上实例不想重启的场景。但要记住CONFIG SET修改的只是运行时配置不会自动写回配置文件。如果哪天Redis重启了密码会直接消失回到裸奔状态。所以动态设置之后要执行一次redis-cli -a YourStrongPassword2025 CONFIG REWRITECONFIG REWRITE会把当前运行配置写进原有的配置文件。前提是Redis能以对应权限启动时的用户去写这个文件如果配置目录权限不对它会静默失败。因此改完配置后建议马上查看一下配置文件内容确认或者重启一次Redis做稳定验证。2.3 启动参数--requirepass的正确打开方式第三种是启动时直接带参数redis-server --requirepass YourStrongPassword2025这种方式在临时实例、测试环境或者命令行启动Redis时非常方便不需要准备配置文件。但缺点也明显启动参数会出现在shell的history里和设备系统日志中。在服务器管理工具、systemd服务文件里也可能被记录安全性打了折扣。我个人只有在本地开发环境才会这样用生产环境一律走配置文件。另外如果你用手写systemd unit文件启动Redis务必看下ExecStart那行有没有把密码参数暴露出去历史记录清一下比较好。2.4 三种方式的优先级与适用场景总结设置方式是否持久化推荐场景注意事项redis.conf中的requirepass持久生产环境所有实例修改需重启或加载配置CONFIG SET requirepass不持久线上实例临时调整需配合CONFIG REWRITE--requirepass启动参数随启动方式而定开发测试、容器启动注意命令历史和日志泄露前面提到容器化部署现在很多人在Docker里跑Redis。使用官方redis镜像时通常用两种方式之一传密码一是-v挂载配置文件进去并在配置里写requirepass二是用启动命令拼接docker run -d --name redis \ -p 6379:6379 \ redis:7 redis-server --requirepass YourStrongPassword2025在Docker Compose里也可以写成command: redis-server --requirepass YourStrongPassword2025。但同样是那个问题如果密码写在compose文件里务必确保这个文件在仓库里做了脱敏或者访问权限受限。3. 密码设置后的连接方式命令行、代码客户端与可视化工具全适配密码设好只是第一步。接下来各种客户端连接不上才是一连串问题的开始。这块的内容你在Redis官网文档里能看到基本API但真实参数细节和坑文档里可不会全部提到。3.1 redis-cli-a参数与交互式AUTH最直接的验证方式redis-cli -a YourStrongPassword2025 PING这时会返回PONG同时cli会打印一行警告大意是“使用命令行参数传递密码不安全其他用户可能通过ps看到”。如果你在一个多人共享的服务器上执行这条命令确实会被别人通过ps aux看到明文密码。有两种办法缓解一是用交互方式连接然后再AUTHredis-cli AUTH YourStrongPassword2025二是设置环境变量export REDISCLI_AUTHYourStrongPassword2025 redis-cli PING设置了REDISCLI_AUTH之后redis-cli会自动完成认证而且密码不会出现在命令行参数里比-a稳妥得多。我在脚本里也倾向用环境变量或者在脚本头部用read读取密码文件而不是死写在脚本里。3.2 代码客户端含Python/Java如何传密码在Python的redis-py里连接参数的写法非常直观import redis r redis.Redis( host127.0.0.1, port6379, passwordYourStrongPassword2025, db0 ) print(r.ping())如果是连接池pool redis.ConnectionPool( host127.0.0.1, port6379, passwordYourStrongPassword2025, max_connections20 ) r redis.Redis(connection_poolpool)Java这边用Jedis时很多人踩过坑。Jedis的构造方法里new Jedis(host, port)是无密码的必须显式调用auth或者通过JedisPoolConfig配合创建连接池时塞入密码JedisPool pool new JedisPool( new JedisPoolConfig(), 127.0.0.1, 6379, 2000, YourStrongPassword2025 );Spring Boot的spring-boot-starter-data-redis也一样在application.yml中配置spring: data: redis: host: 127.0.0.1 port: 6379 password: YourStrongPassword2025注意Spring Boot 2.x和3.x的属性前缀略有不同2.x用spring.redis.password3.x用spring.data.redis.password。如果你升级了Spring Boot突然一连就报NOAUTH Authentication required先检查这里。3.3 可视化客户端Redis Desktop Manager等工具配置热词里也看到了Redis Desktop Manager、Another Redis Desktop Manager这些工具。这类可视化客户端连接配置很相似地址填Redis服务器IP端口默认6379。认证填密码不同工具叫法略有差异有的是Password有的是Auth。如果Redis还配置了ACL用户需要填用户名默认是default。远程连接带密码的Redis我建议一定要另外勾选SSL/TLS选项。如果没有启用TLS密码走明文传输内网还能接受跨公网就非常危险。另一件事是生产环境尽量避免使用可视化工具至少不要把生产数据库配置信息长留在工具里否则工具一旦被植入恶意代码或者电脑被盗等于把钥匙串整个交出去。3.4 连接出现NOAUTH时的排查思路给Redis设置密码后最常见的报错是NOAUTH Authentication required。排查链路大概是先确认密码确实设置上了本地跑CONFIG GET requirepass看返回值是否非空。确认客户端确实传了密码逐一检查连接池参数、配置文件、环境变量。如果用的连接池确认池是否创建于设置密码之前。有些长连接是旧连接可能没经过认证需要让连接池重建连接。如果是多台应用服务器确认所有应用都改了配置漏掉一台就会单独报错。看Redis日志Redis会打印客户端的IP能帮你定位是哪台机器没配置对。4. 高可用架构下的密码坑主从复制、Sentinel与Cluster的密码传递单机设密码简单一旦进入主从、哨兵、集群密码配置立刻翻几倍复杂度。这几块我踩坑踩得最多也见到生产事故最多。4.1 主从复制中的masterauth为什么比requirepass更关键主从架构中requirepass只控制客户端访问Redis时需要AUTH。从节点主动连接主节点做同步时走的不是普通客户端鉴权路径而是单独的密码参数masterauth。如果只配了主节点的requirepass没配从节点的masterauth从节点会连接主节点时报MASTER auth failed然后每隔一段时间重试一次数据自然就一直保持不了同步。配置方法是在从节点的redis.conf里也加requirepass 你的密码 masterauth 你的密码注意从节点自己也要设置requirepass否则从节点会成为架构里的防守漏洞。很多和我做过排查的人都说主从复制断开了吗同步日志拉出来一看十有八九是masterauth忘了配。4.2 Sentinel的sentinel auth-pass配置位置Redis Sentinel的高可用架构里Sentinel本身要连接主从节点去检查状态所以Sentinel的配置文件也需要密码信息。常见的错误是只给Redis配了密码Sentinel进程一直用无密码方式探测于是日志里全是-NOAUTH或者无法ping通主节点。需要在每个Sentinel节点的配置文件sentinel.conf中写上sentinel monitor mymaster 127.0.0.1 6379 2 sentinel auth-pass mymaster YourStrongPassword2025第二行的mymaster必须和第一行的master name完全一致。更重要的是如果主从节点都配置了requirepassSentinel也只能连上后才能做后续操作。当发生故障转移时升级为新的主节点的节点它的requirepass和masterauth都会保留Sentinel继续用auth-pass里的密码去连这样才能保障切换后整个单元依然可用。4.3 Cluster模式下的多节点密码同步Redis Cluster环境下每个节点都要配置requirepass和masterauth。一般做法是让所有节点使用相同密码并且在配置文件里都加上这两行。cluster管理命令在加密码后节点之间通信和握手时会用masterauth进行认证。如果集群节点间密码不一致会出现ERR invalid password或者cluster状态一直是fail的奇葩问题。我用一个土办法来验证集群密码是否统一redis-cli -c -h node1 -p 6379 -a 密码 CLUSTER INFO看返回结果中的cluster_state是不是ok以及各个节点日志中是否出现auth失败记录。密码统一是集群的基本卫生条例别想着给节点搞差异化密码那是自找麻烦。4.4 主从切换后写入失败的真实案例复盘之前帮一家公司排查过这么个案例某次Sentinel故障转移完成新主节点已经提升从节点开始重连。业务那边大量出现READONLY You cant write against a read only replica。日志里看新主节点明明处于master状态却还在拒绝写入。最后定位到的原因非常典型新主节点是原来的从节点它的配置文件里masterauth指向的是老主的密码但它在提升为master后并不需要masterauth而业务连接的密码字符串比配置的多了一个换行符——挂在配置中心里的时候密码末尾被粘贴进了多余的空白字符。客户端每次AUTH时密码里带着\n老实例居然能接受因为老实例密码长度校验相对宽松不是真正原因其实是新主节点的auth校验逻辑发现密码不匹配。这个案例后来处理方式是整理配置中心里的密码统一去掉了异常空白。还有个小细节必须说高可用架构里改密码一定要梳理好“先改从、再改主、再改Sentinel配置”的顺序。如果先改主从节点会断同步如果先从从节点改主节点暂时不受影响。我自己习惯先用CONFIG SET对从节点和主节点都更新一遍再更新配置文件和Sentinel最后用CONFIG REWRITE固化尽可能降低窗口期。5. 密码与业务场景联动分布式锁和Lua脚本的鉴权细节生产环境里Redis密码设置之后受影响的除了普通读写还包括分布式锁、Lua脚本这类进阶用法。这里面的细节很少有人在“设置密码”教程里讲清楚但恰恰是业务代码里最容易翻车的地方。5.1 分布式锁客户端Jedis/Redisson的密码参数传递先看Redisson——Spring Cloud生态下分布式锁很常用。Redisson创建客户端时如果不给密码程序不会立刻报错而是到获取锁那一步才开始报NOAUTH或权限异常。配置方式在YAML里redisson: singleServerConfig: address: redis://127.0.0.1:6379 password: YourStrongPassword2025Jedis做分布式锁通常需要自己封装一套SET NX EX逻辑。很多人直接用new Jedis(host, port)创建连接忘了密码锁操作就失败。加密码的写法刚才已经提到用带Password参数的构造器。还有一点如果Redis配置了ACLRedisson还支持username字段这是被很多人忽略的redisson: singleServerConfig: username: default password: YourStrongPassword20255.2 Lua脚本执行是否需要单独鉴权Redis的Lua脚本是通过EVAL或EVALSHA执行的本身不涉及额外的一套鉴权机制但有两个需要注意的点连接必须已经完成AUTH认证否则任何EVAL都会返回NOAUTH。Lua脚本内部的redis.call(GET, key)等操作用的是已认证连接的权限不需要在脚本里重新传密码。实际操作中我用Spring Data Redis执行Lua脚本最常见的错误是脚本内容没问题但连接没带密码报错和处理普通命令一样。还有一点如果你在Redis事务或者管道里执行Lua同样是在同一个连接上鉴权状态延续不需要重复AUTH。很多人会问设置密码能不能限制Lua脚本执行危险命令答案是不行只要认证成功脚本里就可以调用所有允许的命令。要想按业务隔离权限就得用Redis 6的ACL这个我放到下一节讲。5.3 设置了密码后连接池和缓存的兼容性注意密码设置后缓存和连接池的兼容性也会引发怪现象。比如Spring Boot的缓存模块通过Lettuce连接Redis如果在配置了密码后仍使用LettuceConnectionFactory默认无密码构造会出现能启动但不一定能操作缓存的诡异状态。因为Lettuce是懒连接真正执行缓存操作才去建连接那时候报NOAUTH。排查这类问题我一般两步走看启动日志里是否出现Redis连接相关的exception。用spring-boot-starter-actuator的health端点检查Redis health状态报RedissonConnectionFailureException或RedisConnectionFailureException基本可以定位到鉴权配置。连接池方面JEDIS和Lettuce都存在“池内连接”和“密码参数”耦合的问题。修改密码后连接池里残留的未认证连接往往不会自动重建。有些连接池会通过testOnBorrow参数去校验连接是否可用如果没开就会出现偶发性的NOAUTH。处理办法是在连接池配置里开启合理的校验机制或直接重启应用。这属于在生产环境切换Redis密码时的隐藏雷区值得提前打预防针。6. 从requirepass到ACLRedis 6的精细权限控制聊到这儿你会发现requirepass只能实现对Redis整体访问的口令控制功能上比较“一刀切”。不管你是谁只要密码对了想执行什么命令都可以。这在多业务共用一个Redis实例的环境中特别危险。Redis 6引入ACLAccess Control List之后权限控制的粒度才真正细化到“用户命令Key级别”。6.1 ACL是什么和requirepass有什么区别简单理解requirepass相当于一把总钥匙ACL相当于一堆分控制卡。传统requirepass模式下所有客户端共享同一个密码A应用能执行的命令B应用只要拿到同样密码也能执行。ACL模式下你可以创建不同用户每个用户拥有独立的密码、独立的命令白名单、独立的可访问key范围。比如业务A只能读某个前缀的key业务B只能执行SET/GET运维账号才能执行CONFIG、SHUTDOWN这类敏感命令。这让密码设置的边界更小更贴近最小权限原则。6.2 快速上手ACL SETUSER创建专用账号Redis 6之后创建用户的基本语法ACL SETUSER biz_readonly ON BizOnlyPass2025 ~cache:* read解释一下这段ON表示激活该用户。BizOnlyPass2025设置密码。~cache:*限制只允许访问以cache:开头的key。read允许所有读类命令。客户端用这个账号连接时需要在AUTH时指定用户名AUTH biz_readonly BizOnlyPass2025在Spring Boot里用户名和密码可以分别配置spring: data: redis: username: biz_readonly password: BizOnlyPass2025这里要说个细节即使你只配置了requirepassRedis内部也等于存在一个default用户密码就是这个requirepass。ACL设置时如果对default用户做修改会影响所有使用传统密码方式的客户端。所以平滑过渡时最好先为每个业务建好ACL用户切换客户端最后再收紧default用户权限。6.3 平滑迁移建议从单一密码到多用户权限如果你现在还在用requirepass想要迁移到ACL我建议按以下步骤先用ACL LIST查看当前用户情况备份好default用户设置。逐业务创建ACL用户密码尽量用独立随机串不要大家共用一个。客户端配置逐步切换用户灰度发布观察业务日志。确认所有客户端都切走后再把default用户取消密码或删除敏感命令权限防止它成为后门。迁移代价并不小但收益也很明显一旦某个业务的密码泄露攻击者拿到的只是一个受限账号而不是整个Redis实例。补充一个ACL的恢复技巧如果不小心把自己锁在Redis外面了——比如把default用户的超级权限删了——只要底层用户还有系统权限可以直接改配置文件里的user default行或者在文件里临时重置ACL规则。如果Redis没有开启保护模式且是内网环境也可以直接改配置文件然后重启。总之做ACL实验时千万别在唯一的运维连接上缩紧到连认证都过不了最好先保留一个高权限的备用用户。最后再分享几个我长期在用的密码管理习惯密码设置不是配一次就一劳永逸的事。我自己的习惯大致是密码尽量由随机生成器产生不包含字典词长度至少16位以上。运行在公网环境的重要实例甚至会用密码管理工具生成独立的随机串。为每套环境独立设密码。测试环境、预发环境、生产环境建议不要用同一个密码不然一处泄露处处危机。配置文件权限收紧。redis.conf和部署目录尽量用单独的用户避免任意用户可读。如果密码不得不放在Spring的配置文件或K8s Secret里记得配合平台的密钥管理能力去处理别用明文提交到代码仓库。定期轮换密码每次轮换前写好变更清单包括客户端、主从、哨兵、集群节点、可视化工具等所有访问入口。轮换后用一个简单的redis-benchmark -a或者健康检查接口验证一遍。关注Redis日志的warn级别输出连接密码错误都会留下记录方便发现是否有暴力破解尝试。写到这里回头看“Redis密码设置”这件事已经远不止“一行requirepass”那么简单。从单机裸奔的防御到客户端连接适配再到高可用架构的密码传递最后到ACL权限模型的落地每一步都有现实的踩坑教训在里面。希望这篇内容能帮你把Redis的访问控制补得扎实一点至少下次再遇到那台“裸奔”的Redis你能第一时间想起哦密码这个环节不仅仅是加一行配置那么简单。如果你还在用老版本Redis连ACL都还不支持建议认真考虑升级毕竟现在所有必要的新安全能力基本都集中在6.0往后的版本上了。
返回列表