☰
Redis密码设置全指南:从requirepass到ACL权限体系
2026/10/3 7:46:08 网站建设 项目流程

上周帮朋友排查一个线上故障,起因特别小——他只是在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密码设置或者其他认证相关变更时,都会走一套固定的五步流程,每次都很稳:

  1. 盘点连接方:先把谁在连这台Redis列出来。业务应用(哪个环境、哪个端口、用的什么客户端库)、定时任务、监控脚本、数据备份任务、从库、哨兵节点,全部登记。
  2. 更新客户端侧配置:把连接串里加上密码,改应用配置、改脚本、更新可视化工具的连接信息。这一步要在服务端改之前做完。
  3. 修改服务端配置:改requirepass或ACL,确认无误后重启服务或者CONFIG SET生效。
  4. 端到端验证:从应用侧发起一次真实的读写操作,确认认证通过、数据读写正常,同时观察主从状态。
  5. 清理遗留信息:检查有没有哪个脚本还在用旧的连接参数,有没有配置文件里残留了旧的密码。

这套流程看起来简单,但真正执行的时候很多人会跳过第一步直接改配置,结果就是朋友的现场翻车。尤其是现在微服务架构下,连同一个Redis的服务可能分布在好几套环境里,稍不留神就会漏掉一个。

1.3 验证环节怎么做得更细

验证不能只敲一个ping就完事。我通常会做这样一组检查:

# 带密码连接并执行命令 redis-cli -a '你的密码' ping # 查看认证配置是否生效 redis-cli -a '你的密码' config get requirepass # 检查主从状态是否正常 redis-cli -a '你的密码' info replication

info 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 123,Redis只会把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-py:

import redis r = redis.Redis(host='192.168.10.10', port=6379, password='你的密码', decode_responses=True)

Node.js的ioredis:

const 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,还有一个更强大的认证和权限管理方案——ACL(Access 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,这里显示的是密码的哈希),~*表示可以访问所有key,+@all表示拥有所有命令权限。

创建新用户:

# 创建一个只读用户,只能访问以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。~*表示所有key
  • +@read:允许读取类命令。+@write允许写类命令。-@dangerous表示从允许集中排除危险命令

查看某个用户的详细信息:

redis-cli -a '管理员密码' ACL GETUSER app1_reader

删除用户:

redis-cli -a '管理员密码' ACL DELUSER app1_reader

4.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,不用停服务,可以按这个顺序操作:

  1. 先确认Redis版本是6.0及以上,并且配置文件里aclfile的路径是设置好的(比如/etc/redis/users.acl)。
  2. 设置default用户保留现有密码。正常情况下,配置了requirepass时,default用户就对应这个密码。你不需要做额外操作,原有客户端继续用旧密码连接。
  3. 创建业务用户并分配权限,让新客户端逐步切换到新用户密码。
  4. 全部切换完成后,再把default用户改成off状态,禁用默认用户的连接权限:
ACL SETUSER default off

这样即使有人拿到了旧的默认密码也无法连接。整个过程可以做到无缝切换,客户端不需要同时停机。

执行ACL SETUSER之后,注意执行ACL SAVE把配置持久化到aclfile,配置才会在重启后保留。

5. 密码之外还要盯的事:强度、轮换与命令审计

最后聊一个很多人不重视但很重要的层面:密码本身的安全管理。很多人的Redis密码是123456、root、redis123,或者干脆跟公司名、项目名挂钩。在真实的安全事件里,这类密码几乎等于没有。

5.1 密码强度怎么定才够用

推荐使用随机生成的强密码,长度至少16位以上,包含大小写字母、数字、特殊符号。生成密码可以直接用系统工具:

openssl rand -base64 24 # 输出类似:xK3#mP9@aQ7$wL2&dR5^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这台"保险柜"真正锁得起来,只有拿到正确钥匙的人和企业才能打开。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询