2026/10/3 7:46:17

Redis密码设置全指南:从requirepass到ACL权限体系

Redis密码设置全指南:从requirepass到ACL权限体系 上周帮朋友排查一个线上故障起因特别小——他只是在Redis配置文件里加了一行密码。结果加完密码的一瞬间二十多个服务同时报连接失败日志刷得跟瀑布似的主从同步直接断开监控群炸了锅。朋友一脸无辜地问我我不就是给Redis设了个密码吗怎么感觉像拆了个炸弹这种场景我见过太多次了。很多刚接触Redis的人以为设置密码就是把配置文件里的注释解开或者敲一条CONFIG SET完事。但在真实的生产环境里这一步牵一发而动全身客户端要带密码、主从要配同步密码、哨兵要改认证信息、监控脚本和定时任务也得跟着调。今天这篇文章就把Redis如何设置密码这件事彻底讲透从最基本的命令行操作到生产环境的全套适配再到Redis 6.0之后的ACL用户权限体系一次性梳理清楚。不管你是刚入门的小白还是正在维护线上集群的运维这篇都应该能帮到你。1. 一次加个密码引发的连环故障先把朋友那个事故拆开看你就能明白为什么设置密码不是一个孤立的动作。1.1 故障链路还原一行配置背后的连锁反应朋友的架构其实不算复杂一台Redis 6.x服务器三台业务应用服务器每台机器上跑着四五个服务另外还有一套基于脚本的健康检查定时任务。他做的操作是把redis.conf里的requirepass那行取消注释填上密码然后systemctl restart redis。重启之后他先自己用redis-cli -a 密码 ping测试返回PONG觉得一切正常。结果业务方马上找他线上接口全挂了超时、重试、报错轮番上演。问题出在哪我帮他一条条捋第一业务应用服务器的连接配置没改。应用里写的是redis://127.0.0.1:6379这种不带密码的连接串Redis服务端开启密码验证后客户端发起的命令会被直接拒绝返回NOAUTH Authentication required。很多框架的重试策略会让这个错误被反复打到服务端看上去就像是Redis卡死了。第二主从同步断了。他其实还有一个从库但从库的配置文件里没有设置masterauth。主库加了密码后从库同步时携带的认证信息是错误的或空的主库直接拒绝从库不停重试同步日志里全是MASTER - REPLICA sync started的报错。第三监控脚本全废。他原来的健康检查脚本是用redis-cli ping来判断Redis存活状态的。没有密码参数之后这个命令返回的是错误信息而不是PONG监控系统直接判定Redis挂了告警通知哗哗往外发。这个过程完整地说明了一件事**给Redis设置密码本质上是一次认证体系的变更牵涉到所有与Redis建立连接的客户端、工具和下游节点。**只看服务端那一行配置等于只看到了冰山一角。1.2 安全变更的正确姿势先盘点再动手经历过这次事故之后我做Redis密码设置或者其他认证相关变更时都会走一套固定的五步流程每次都很稳盘点连接方先把谁在连这台Redis列出来。业务应用哪个环境、哪个端口、用的什么客户端库、定时任务、监控脚本、数据备份任务、从库、哨兵节点全部登记。更新客户端侧配置把连接串里加上密码改应用配置、改脚本、更新可视化工具的连接信息。这一步要在服务端改之前做完。修改服务端配置改requirepass或ACL确认无误后重启服务或者CONFIG SET生效。端到端验证从应用侧发起一次真实的读写操作确认认证通过、数据读写正常同时观察主从状态。清理遗留信息检查有没有哪个脚本还在用旧的连接参数有没有配置文件里残留了旧的密码。这套流程看起来简单但真正执行的时候很多人会跳过第一步直接改配置结果就是朋友的现场翻车。尤其是现在微服务架构下连同一个Redis的服务可能分布在好几套环境里稍不留神就会漏掉一个。1.3 验证环节怎么做得更细验证不能只敲一个ping就完事。我通常会做这样一组检查# 带密码连接并执行命令 redis-cli -a 你的密码 ping # 查看认证配置是否生效 redis-cli -a 你的密码 config get requirepass # 检查主从状态是否正常 redis-cli -a 你的密码 info replicationinfo replication的输出里要专门看master_link_status是不是up。如果是down说明从库的同步认证没配上。这是很多人容易漏掉的点验证的时候只测了本机连接完全没看下游节点。2. 基础认知Redis的默认防护机制与两种设密方式先把最基础的概念说清楚不然越往后越容易混乱。2.1 为什么Redis默认不设密码也相对安全很多新手第一次装完Redis会有个疑问怎么默认没有密码是不是不安全其实Redis的默认安全策略不是不设防而是不对外。默认配置下Redis只监听本机回环地址127.0.0.1外部网络根本连不进来。再加上protected-mode这个保护模式即使被外部访问到在没有配置密码的情况下也会拒绝非本机的连接请求。所以在你没有主动改bind配置、没有把端口暴露到外网的情况下Redis的默认姿态是相对封闭的。但问题恰恰出在相对两个字上。很多人图省事把bind 0.0.0.0写上或者部署在Docker里直接映射端口出去这时候Redis就开始裸奔了。网上那些Redis被挖矿病毒入侵Redis被勒索的事件几乎都是这个原因服务暴露到公网又没有密码等于把门敞开让人进来搬东西。**所以设置密码的真正触发点通常是你准备让Redis跨越主机被访问的时候。**即便只是内网访问只要其他机器能连到这个端口密码就应该配上这是底线。2.2 临时方案CONFIG SET改运行时配置最快速的设密方式是直接在命令行执行redis-cli 127.0.0.1:6379 CONFIG SET requirepass 你的密码 OK # 注意执行完上面的命令后当前连接也处于未认证状态 127.0.0.1:6379 AUTH 你的密码 OK这里有三个细节要注意第一CONFIG SET只修改内存中的配置重启之后恢复原样。如果你只是临时想加个密码做测试这个方式很方便但如果想正式生效必须配合配置文件修改。第二执行完CONFIG SET requirepass之后当前这个redis-cli连接也会变成未认证状态任何命令都会被拒绝得先执行AUTH才能继续操作。这个很多人不知道第一次执行完以为自己把Redis弄坏了。第三想取消密码时把值设为空字符串redis-cli -a 旧密码 CONFIG SET requirepass 这样就可以关闭认证。注意和直接不写是有区别的空字符串代表关闭不写会被当成语法错误。2.3 永久方案修改redis.conf配置文件正式环境肯定要用永久配置。找到Redis的配置文件通常位置在Linux包管理器安装/etc/redis/redis.conf源码编译安装/usr/local/redis/redis.conf或你自己指定的路径Docker容器/usr/local/etc/redis/redis.conf取决于镜像和数据卷挂载找到requirepass这一行把注释去掉并填上密码# 在redis.conf中 requirepass 你的强密码然后重启Redis服务systemctl restart redis # 或者 redis-server /etc/redis/redis.conf注意如果是从源码启动的Redis启动命令里没带配置文件路径那配置文件改了也不会生效。很多人踩过这个坑明明改了redis.conf重启后密码没生效结果发现启动命令压根没用这个配置文件。2.4 密码里的特殊字符与语法坑密码本身是字符串但放在不同的环境里有不同的解读方式这里必须展开说因为我见过太多人栽在这里。第一密码包含空格。Redis的requirepass是允许空格的但在命令行或者配置文件里直接写requirepass abc 123Redis只会把abc当作密码后面的123会被当成额外参数要么报错要么静默忽略。这种情况下密码必须用引号包起来requirepass 密码 中含 空格第二密码包含#号。在redis.conf里#是注释符号如果密码里带#且没有加引号后面的内容会被当成注释吃掉导致密码变成一段残缺值。同样用双引号包裹即可解决。第三通过命令行参数传密码时的转义问题。比如在Shell里执行redis-cli -a 密码里$有特殊符号!Shell的变量符号、通配符、引号都可能导致密码被改写。最稳妥的做法是使用单引号或者在交互式提示中输入密码。第四关于空密码的语义。requirepass 表示认证关闭这跟直接删掉这一行是等价的。所以如果你看到配置里有一行requirepass 别以为密码是空字符串这其实是关闭认证的意思。3. 密码生效后的配套调整从客户端到主从哨兵一个都不能漏前面说的那些是基础操作这一章才是生产环境的关键。密码是给所有要进门的人看的那所有进门的人就必须都有对应的钥匙。3.1 客户端连接方式的变化最常用的redis-cli有几种传密码的方式# 方式一-a参数直接传 redis-cli -a 你的密码 ping # 方式二使用REDISCLI_AUTH环境变量避免密码出现在命令行 export REDISCLI_AUTH你的密码 redis-cli ping # 方式三交互式登录后再认证 redis-cli -a 你的密码 127.0.0.1:6379 AUTH 你的密码这里有个安全细节-a参数会把密码暴露在shell历史记录和进程列表里ps aux能看到完整命令。生产环境为了避免密码泄露我更推荐用环境变量REDISCLI_AUTH的方式或者干脆让redis-cli交互式提示输入密码。代码层面的适配更直接。Java的Spring Boot配置里只需加密码字段spring: redis: host: 192.168.10.10 port: 6379 password: 你的密码Python的redis-pyimport redis r redis.Redis(host192.168.10.10, port6379, password你的密码, decode_responsesTrue)Node.js的ioredisconst Redis require(ioredis); const redis new Redis({ host: 192.168.10.10, port: 6379, password: 你的密码 });只要数据库连接池配置了正确的密码字段应用本身不需要改代码逻辑。但要注意如果应用的配置中心或环境变量是集中管理的改密码时要记得同步所有环境——开发、测试、预发、生产每个环境可能都有一份独立的配置。3.2 主从复制别忘了masterauth这是设置密码时最容易被忽略的环节。主从架构下从库必须配置一个masterauth用这个密码去主库完成认证。在从库的redis.conf中# 从库配置 replicaof 192.168.10.10 6379 masterauth 与主库相同的密码有个容易混淆的点从库自己的requirepass和masterauth是两个不同配置。requirepass是别人连接这个从库时需要的密码masterauth是它连接主库时自己提供的密码。很多人会把这两个搞混导致主从一直连不上。配置完成后在从库上执行redis-cli -a 从库密码 info replication看master_link_status是否为up。如果是down去从库日志里搜索Authentication相关报错基本就是masterauth没配或者配错。3.3 哨兵模式下的认证同步哨兵模式比普通主从多了一层哨兵节点自己需要连到主库去检测状态所以每个哨兵进程都需要配置访问主库的密码。在sentinel.conf中# 哨兵连接主库的认证信息 sentinel auth-pass mymaster 你的密码注意这里的mymaster是哨兵配置里主库的名字要和sentinel monitor里面设置的名字保持一致。而且每个哨兵节点都要配不是只配一个。哨兵节点向下切换、选择新主库时依然会带着这个密码去连接新主库所以主从节点的密码要统一不然后面做故障转移时会莫名其妙失败。3.4 可视化工具和运维脚本的适配现在很多人用Another Redis Desktop Manager这类可视化客户端连接Redis时需要在连接设置里填密码这个不复杂填上就行。容易忽略的是那些看不见的脚本。比如定时备份脚本里的redis-cli命令健康检查脚本里的ping探活数据迁移工具里的同步任务应用启动时的连接测试逻辑我的习惯是给Redis做认证变更之前先全局搜一遍所有脚本和配置文件里包含Redis IP或端口的地方把所有连接方都拎出来逐个确认要不要改。宁可每次都麻烦一点也比事后线上故障强。3.5 常见连接失败问题排查表遇到密码设置后连不上不要慌对照下面的表现看看现象可能原因处理方式报错NOAUTH Authentication required客户端没带密码或密码为空在连接配置中加上正确密码报错WRONGPASS invalid username-password pair密码错误或者用户名错误检查密码是否有多余空格、转义字符主从同步断开master_link_status:down从库的masterauth没设置或设置错误在从库配置masterauth并检查与主库密码是否一致哨兵无法切换主库sentinel.conf的auth-pass未配置或名字不一致检查sentinel auth-pass与monitor名字是否对应密码带空格但连接不上配置文件里没加引号密码被截断在配置文件中给密码加双引号改了配置但重启后密码失效启动命令没加载配置文件确认redis-server启动时带了正确的配置文件路径4. 进阶玩法从单一密码到ACL用户权限体系如果你的Redis版本是6.0及以上恭喜你除了最简单的requirepass还有一个更强大的认证和权限管理方案——ACLAccess Control List。这一章讲清楚什么时候该用它以及具体怎么用。4.1 requirepass的先天局限requirepass只有一个密码所有人共用同一把钥匙。这在简单的个人项目里够用但在多团队、多应用的场景下就很别扭你没法控制谁能执行什么命令。监控脚本需要只读权限但也拿着管理员密码误操作删除数据的风险始终存在。密码一旦泄露只能全局改密码所有客户端都要跟着重新配置非常痛苦。无法针对不同的key前缀做隔离A应用的代码可以访问B应用的数据。ACL正好解决这些问题。你可以创建多个用户每个用户拥有独立的密码和独立的权限范围。4.2 ACL的核心概念与基本操作ACL里最重要的概念是用户。Redis默认有一个default用户我们平时用requirepass设置密码本质上就是设置default用户的密码。查看当前ACL配置和用户列表redis-cli -a 密码 ACL LIST # 输出类似user default on nopass ~* all这行的含义default用户状态是on启用nopass表示不需要密码如果你设置了requirepass这里显示的是密码的哈希~*表示可以访问所有keyall表示拥有所有命令权限。创建新用户# 创建一个只读用户只能访问以app1:开头的key redis-cli -a 管理员密码 ACL SETUSER app1_reader on app1_read_2024 ~app1:* read # 创建一个可写但不危险命令的用户 redis-cli -a 管理员密码 ACL SETUSER app1_writer on app1_write_2024 ~app1:* write -dangerous拆解一下这个命令ACL SETUSER app1_reader创建/修改名为app1_reader的用户on启用该用户如果写off该用户密码失效连接会被拒绝密码设置用户密码。注意是符号开头不是。密码或!密码还有特殊含义建议只用来设置新密码~app1:*限定只能访问app1:前缀的key。~*表示所有keyread允许读取类命令。write允许写类命令。-dangerous表示从允许集中排除危险命令查看某个用户的详细信息redis-cli -a 管理员密码 ACL GETUSER app1_reader删除用户redis-cli -a 管理员密码 ACL DELUSER app1_reader4.3 一个实战例子按团队和应用划分权限假设你的Redis被三个应用共用订单系统需要读写order:*的key库存系统需要读写stock:*的key还要能订阅频道数据平台只需要只读权限可以这样设计# 订单系统用户只允许操作order:前缀 ACL SETUSER order_service on order_pwd_2024 ~order:* all -dangerous # 库存系统用户只允许操作stock:前缀允许订阅发布消息 ACL SETUSER stock_service on stock_pwd_2024 ~stock:* all -dangerous subscribe publish # 数据平台用户只读所有key但不能执行写操作 ACL SETUSER data_reader on data_reader_pwd ~* read这样的好处是就算某个应用的密码泄露了攻击者能影响的范围也仅限于对应的key前缀而且执行不了FLUSHALL、SHUTDOWN、DEBUG这些危险命令。这比所有人都用同一个管理员密码安全得多。4.4 从requirepass平滑迁移到ACL老项目从requirepass切换到ACL不用停服务可以按这个顺序操作先确认Redis版本是6.0及以上并且配置文件里aclfile的路径是设置好的比如/etc/redis/users.acl。设置default用户保留现有密码。正常情况下配置了requirepass时default用户就对应这个密码。你不需要做额外操作原有客户端继续用旧密码连接。创建业务用户并分配权限让新客户端逐步切换到新用户密码。全部切换完成后再把default用户改成off状态禁用默认用户的连接权限ACL SETUSER default off这样即使有人拿到了旧的默认密码也无法连接。整个过程可以做到无缝切换客户端不需要同时停机。执行ACL SETUSER之后注意执行ACL SAVE把配置持久化到aclfile配置才会在重启后保留。5. 密码之外还要盯的事强度、轮换与命令审计最后聊一个很多人不重视但很重要的层面密码本身的安全管理。很多人的Redis密码是123456、root、redis123或者干脆跟公司名、项目名挂钩。在真实的安全事件里这类密码几乎等于没有。5.1 密码强度怎么定才够用推荐使用随机生成的强密码长度至少16位以上包含大小写字母、数字、特殊符号。生成密码可以直接用系统工具openssl rand -base64 24 # 输出类似xK3#mP9aQ7$wL2dR5^nB8这样生成的密码足够随机也不会有规律性的脆弱点。还有一个原则每个环境的密码尽量不同。开发环境用一套测试环境用一套生产环境用一套不要图省事全用同一个。否则开发环境密码泄露等于生产环境也跟着裸奔。5.2 密码轮换如何平滑切换不让服务中断定期换密码是安全审计的常规要求。但直接改密码客户端全得跟着换稍有不慎就引发连接中断。这里教一个平滑轮换的小技巧Redis 6.0.5及以上版本ACL支持给用户设置多个密码切换时可以新旧密码并存一段时间# 给default用户同时设置旧密码和新密码 ACL SETUSER default 新密码 旧密码 # 等所有客户端切换到新密码后移除旧密码 ACL SETUSER default 旧密码具体格式上多个密码可以用多个参数同时添加删除旧密码用前缀加旧密码。这个技巧可以让密码轮换在不停服、业务无感知的情况下完成。如果你的环境用的是老版本Redis不支持多密码那就只能先跟所有相关方约定好切换时间窗口统一改完再操作。5.3 防止密码泄露的四个细节密码设得再强泄露了也白搭。以下几个细节必须注意第一不要直接在命令行参数里写密码。像redis-cli -a 密码这种密码会出现在shell的history和进程列表里。任何能执行ps aux的用户都可能看到。使用环境变量、配置文件或者交互式输入更安全。第二不要把密码硬编码在代码里。应该放到环境变量、配置中心或者密钥管理系统里。否则代码仓库一旦泄露密码跟着一起完蛋。第三日志里不要打印连接串。很多框架在初始化时会把完整的连接信息打进日志开发者图方便还加过print(redis_url)。这个习惯要改掉统一改为打印Redis连接已初始化这类不带敏感信息的内容。第四监控脚本里的密码要注意权限。脚本通常存放在服务器上如果文件的读取权限是777任何人都能看到密码。脚本文件建议设置为600权限并限制只能由特定用户执行。5.4 密码不是万能配合bind、防火墙和危险命令禁用我见过太多人把所有安全希望都寄托在密码上。事实上密码只是第一道门组合拳才是生产环境的正确姿势限定监听地址bind只写成内网IP或网段不写0.0.0.0。防火墙层控制用安全组或iptables只允许特定来源IP访问6379端口。禁用危险命令通过rename-command把FLUSHALL、FLUSHDB、DEBUG、SHUTDOWN等命令改名或者禁用减少误操作和恶意破坏的风险。一个合理的Redis安全基线应该是绑定内网地址 防火墙白名单 强密码认证 最小权限ACL 危险命令禁用。所有层面互相兜底而不是有密码就万事大吉。最后再分享一个小技巧如果哪天你发现Redis密码忘记或丢失了最稳妥的办法是停掉服务以加载临时配置文件的方式启动临时去掉requirepass或者直接在配置文件中修改密码后重启。但这里有个前提——密码要妥善保管最好放在内部密钥管理系统里别指望靠记忆去管生产环境的密码。设置密码的意义不是给自己添堵而是让Redis这台保险柜真正锁得起来只有拿到正确钥匙的人和企业才能打开。