Redis安全防范:三种实战场景设置密码与认证配置

发布时间:2026/10/14 7:33:48
Redis安全防范:三种实战场景设置密码与认证配置 说句糙理不糙的话Redis 刚装好的默认状态和“银行卡没设密码”没什么区别。你 bind 0.0.0.0 跑在服务器上6379 端口一开任何能扫到你 IP 的人都能拿 redis-cli 直接连进去缓存数据、登录态、队列里的业务信息等于全裸。我见过不止一次有团队图省事不设密码线上 Redis 被扫描器扫到数据被 flushall 清空还留下勒索提示的邮件。这篇文章不聊虚的就把 Redis 设置密码这件事按三种最常见的场景讲透配置文件、docker 容器、命令行外加一堆只有踩过坑才写得出来的排查经验。无论你是刚入门的运维新手还是被 Redis 安全问题折磨过的老开发这篇都值得从头到尾看一遍。1. 为什么 Redis 一定要设置密码1.1 没有密码的 Redis 到底有多危险很多人觉得 Redis 只是个缓存丢了数据大不了重启重建。这个想法很危险。现在的业务里 Redis 早就不是单纯缓存了分布式锁、消息队列、限流计数、热点数据、甚至部分业务的核心状态都存在里面。一旦被入侵者拿到访问权他不仅能读数据还能执行 FLUSHALL 清空全部 key还能通过 EVAL 执行 Lua 脚本甚至利用 Redis 的主从复制机制把恶意数据扩散到其他节点。更麻烦的是Redis 默认配置里protected-mode yes只在没有设置密码、没有绑定 IP 的情况下才启动“保护模式”。说得直白一点如果你给 Redis 配了密码但 bind 的是 0.0.0.0同时把保护模式关了那就等于把所有防护都压在了密码这一个点上。密码弱或者空密码攻破只是时间问题。我在实际项目里见过最典型的攻击路径是扫描器批量扫 6379 端口 → 发现未授权访问 → 写入一个定时任务反向 shell → 服务器直接失守。这不是危言耸听安全圈把这叫“Redis 未授权访问漏洞”经典老漏洞了到现在依然有大量机器中招。1.2 requirepass 和 AUTH 的认证机制Redis 的密码认证机制非常简单粗暴服务端配置一个密码客户端每次连接后要执行AUTH password命令完成认证认证通过后才能操作数据。配置文件里对应的是requirepass这个指令。requirepass MyStr0ngPass!设置好之后你再用 redis-cli 连接不先 AUTH 就直接 GET/SET会收到这样的错误(error) NOAUTH Authentication required.这个机制理解起来不复杂和进小区门卫要看门禁卡一个道理。但有几个细节容易被忽略第一requirepass是全局的一旦设置连本机自己的 redis-cli 执行命令都需要认证第二在 Redis 6.0 之前只有这一种密码体系Redis 6.0 之后引入了 ACL访问控制列表可以给不同用户分配不同权限requirepass实际是给默认用户default设置密码第三requirepass设置的密码存储在内存里如果通过命令行动态修改了没有同步写回配置文件的话重启后就失效了。后面讲到的三种场景本质上都是在解决同一件事把密码写进 Redis 的运行态并确保它按你预期的方式持久化。2. 配置文件场景最常规的持久化方案2.1 找到并修改 redis.conf 的完整步骤配置文件方式是最正统、也最符合“一次配置长期有效”理念的方案。第一步是先找到你 Redis 实例实际加载的是哪个配置文件。很多人在这里就踩坑了以为自己改了 redis.conf结果 Redis 启动时压根没加载这个文件。怎么确认Linux 下执行ps -ef | grep redis看启动命令里有没有-f或--config参数以及后面跟的路径是什么。比如我看到的是redis-server /etc/redis/redis.conf那就说明配置文件是/etc/redis/redis.conf。如果启动命令是裸的redis-server没有路径说明用的是默认配置这时你单独改任何 redis.conf 文件都不一定生效。这种情况建议直接用CONFIG SET方式或者干脆找到官方默认配置修改后重新指定路径启动。确认文件后开始修改。找到这段# requirepass foobared把注释符号#去掉把foobared换成你自己的密码requirepass MyStr0ngPass!关于密码强度我强烈建议不要用123456、redis、admin这种。你可以用系统命令生成随机密码比如openssl rand -base64 24得到一串类似xQ7m2vNpL9kR4tZ8wUjB3eA1sD5fG6h的字符串既难猜又足够长放到 requirepass 后面即可。如果配置文件里密码值包含特殊字符比如!、#、空格一定记得用引号包起来因为 Redis 自己解析配置时会把空格和#当成分隔符或注释。这是配置解析的细节很多人改完密码带个空格结果 Redis 启动报错或认证失败一脸懵。2.2 重启服务与验证配置是否生效修改完 redis.conf 后需要重启 Redis 进程让配置生效。根据你的安装方式可能是# systemd 管理的 systemctl restart redis # 通过 init.d 脚本装的 /etc/init.d/redis-server restart # 直接命令行起的 kill -9 redis进程PID redis-server /etc/redis/redis.conf # 重新启动重启后做两件事验证。第一件看进程启动参数是否还是指向同一个配置文件ps -ef | grep redis第二件用 redis-cli 测试认证是否生效redis-cli 127.0.0.1:6379 AUTH MyStr0ngPass! OK 127.0.0.1:6379 SET testkey 1 OK 127.0.0.1:6379 GET testkey 1如果 AUTH 返回 OK就说明密码已经生效。如果命令直接执行时报NOAUTH说明密码生效只是你还没认证。配置文件方式最大的优势是稳定密码写在磁盘文件里无论进程重启多少次都还在。缺点就是修改后必须重启 Redis 才能生效如果你的 Redis 承载着线上流量重启就意味着连接中断。所以在线业务我更推荐后面讲的命令行动态修改方式可以做到不重启轮换密码。3. Docker 容器场景容器里设密码的正确姿势3.1 使用 docker run 启动并传参设置密码Docker 跑 Redis 现在已经是很多团队的标配了。容器方式和物理机有个本质区别容器本身是临时环境你在容器运行后进去改配置一旦容器重建就全部丢失。所以在启动阶段就把密码传进去是正路。最直接的方式是用docker run的命令行参数覆盖 Redis 启动命令docker run -d \ --name redis-demo \ -p 6379:6379 \ redis:7 \ redis-server --requirepass MyStr0ngPass!这里redis:7之后的redis-server --requirepass MyStr0ngPass!会覆盖镜像默认的CMD以带密码的方式启动 Redis。启动后验证docker exec -it redis-demo redis-cli -a MyStr0ngPass! ping正常返回PONG说明密码已经生效。我建议小写-a这种直接带密码的验证方式只用于临时测试因为它会把密码留在 shell 历史里而且 redis-cli 自己也会打一段警告提示。后面我会讲更安全的连接方式。这种方式的另一个坑是-a后面如果密码里有!、$这类 shell 特殊字符会先被 shell 解释掉导致实际传进去的密码和你预想的不一样。稳妥做法是加引号docker run -d --name redis-demo -p 6379:6379 redis:7 redis-server --requirepass MyStr0ng!Pass3.2 docker-compose 方式配置与传参结合团队协作项目里docker-compose 比裸 docker run 更常用。同样可以在command里指定启动参数services: redis: image: redis:7 container_name: redis-demo ports: - 6379:6379 command: redis-server --requirepass MyStr0ngPass! restart: always这里restart: always是个容易忽略的细节。如果不加服务器重启后容器可能不会自动拉起Redis 直接离线。如果你希望密码和其他 Redis 配置一起管理也可以把整个自定义配置文件挂载进容器services: redis: image: redis:7 container_name: redis-demo ports: - 6379:6379 volumes: - ./redis.conf:/etc/redis/redis.conf command: redis-server /etc/redis/redis.conf然后./redis.conf里像物理机一样写requirepass MyStr0ngPass!。这种方式适合配置项很多的情况比如同时要设置持久化参数appendonly yes、最大内存限制maxmemory、内存淘汰策略maxmemory-policy allkeys-lru等等。把所有配置集中在文件里不管是 review 还是版本管理都比塞一堆命令行参数清楚。3.3 容器场景的三个高频踩坑点第一个坑容器重启后密码消失。如果你不是用docker run传参或挂载配置而是启动容器后docker exec -it redis-demo redis-cli CONFIG SET requirepass xxx那么只要容器一删一重建密码立刻回到初始状态。因为 CONFIG SET 只改内存而容器文件系统本身是可写的重启容器一般还在但如果你用的编排工具重建容器这些运行时改动全没了。所以原则是密码必须作为“基础设施代码”的一部分在创建容器时就注入。第二个坑宿主机 firewall 和容器端口映射组合出的安全盲区。-p 6379:6379等于把容器的 6379 映射到了宿主机所有网卡上如果安全组又放开了 6379Redis 等于直接暴露公网。建议只在确有需要时映射端口并且限制来源 IP。很多容器 Redis 被黑问题不在 Redis 本身而在端口映射太随意。第三个坑容器日志会泄露密码。启动命令里写了--requirepass xxx那么docker inspect和容器日志里都可能明文出现这个密码。如果你的容器日志会收集到日志平台等于把密码直接存了一份在日志系统里。运维同事都能看到泄密风险很大。基于这个考虑生产环境我更推荐挂载配置文件的方式密码写在权限严格控制的环境变量或配置中心里日志不落地。4. 命令行场景临时生效与动态轮换4.1 CONFIG SET 动态修改密码命令行场景适合两种人一种是线上 Redis 不能重启需要临时加密码另一种是定期做密码轮换。核心命令就一个redis-cli 127.0.0.1:6379 CONFIG SET requirepass MyNewPass!2024 OK这里有个细节CONFIG SET执行成功后当前连接仍然保持认证状态你可以继续操作但其他已经建立的连接不会受影响它们依然能继续用——直到它们重新认证。而新连接进来后必须使用新密码MyNewPass!2024进行 AUTH。这个特性在密码轮换时非常实用你可以在低峰期先执行CONFIG SET定新密码再逐步切换客户端配置全程 Redis 不重启老连接不受影响新连接用新密码实现平滑过渡。如果某次操作失误写错密码Redis 也不会立刻崩只是新连接全部无法认证此时改回来就行。还要注意一点如果你当前 Redis 本来没有密码执行CONFIG SET requirepass xxx后这条命令本身不需要 AUTH 就能执行成功。但如果 Redis 已经有密码你就必须先AUTH旧密码才能执行CONFIG SET修改这是很常见的权限控制逻辑。很多人没意识到直接连上去执行 CONFIG SET 结果收到NOAUTH还以为是密码设置坏了。4.2 让修改永久生效CONFIG REWRITECONFIG SET的局限是只改内存不改磁盘配置文件。重启 Redis 之后密码会回到旧值甚至回到无密码状态。所以动态修改完密码后记得执行127.0.0.1:6379 CONFIG REWRITE OK这条命令会把当前运行配置写回启动时加载的配置文件。这里有个前提Redis 必须以“指定了配置文件”的方式启动CONFIG REWRITE才有地方可写。如果你当初是redis-server不带任何配置启动的执行CONFIG REWRITE会得到这样的错误(error) ERR The server is running without a config file这种情况就死心吧别想靠 REWRITE 持久化了。要么接受“重启后密码丢失”的现实要么按规定文件方式重新整理一遍。另外注意CONFIG REWRITE的权限问题。如果 redis 进程对配置文件只有读权限执行 rewrite 也会失败。容器场景里如果挂载的是只读卷同样会有这个问题。我在实际运维中遇到过一次配置文件属主是 root而 Redis 进程以 redis 用户运行CONFIG REWRITE一直报权限错误。解决办法是把配置文件属主改成 redis或者改用别的持久化方式。4.3 平滑切换密码的完整操作流程这里分享一套我实际用过的密码轮换流程多条命令组合保证线上不断服务# 1. 连接 Redis用旧密码认证 redis-cli -h 127.0.0.1 -p 6379 # 2. 进入命令行后先认证旧密码 127.0.0.1:6379 AUTH OldPass123 OK # 3. 设置新密码 127.0.0.1:6379 CONFIG SET requirepass NewPass456 OK # 4. 写回配置文件 127.0.0.1:6379 CONFIG REWRITE OK执行完后先不要急着关连接用另一个终端再开一个 redis-cli 验证新密码redis-cli -h 127.0.0.1 -p 6379 -a NewPass456 ping PONG确认新密码可用后再逐个更新业务代码里的 Redis 连接配置。这个流程最大的好处是没有重启窗口不会出现“Redis 重启导致缓存雪崩”的问题。缓存雪崩这个词专门指大量缓存同时失效或服务不可用时流量直接打到底层数据库线上高并发业务对重启非常敏感能不动就不动。5. 设置完密码客户端和工具怎么连5.1 redis-cli 连接方式与安全警告设置密码后的第一件事就是解决怎么连的问题。最常见的几种 redis-cli 连法# 方式一连接后手动输入 AUTH redis-cli -h 127.0.0.1 -p 6379 127.0.0.1:6379 AUTH MyStr0ngPass! # 方式二连接时直接带密码 redis-cli -h 127.0.0.1 -p 6379 -a MyStr0ngPass! # 方式三通过环境变量传密码推荐 REDISCLI_AUTHMyStr0ngPass! redis-cli -h 127.0.0.1 -p 6379这里重点说下安全警告的问题。方式二直接在命令里写-a 密码redis-cli 启动时会打印一行警告Warning: Using a password with -a or -u option on the command line interface may not be safe.这警告不是吓唬你。因为-a参数会在进程列表ps里明文显示出来别人执行ps aux | grep redis-cli就能看到你的密码。如果你非要这么用建议加上--no-auth-warning参数去掉输出但这只是掩盖表象进程列表里密码照样可见。所以安全级别高一点的环境我推荐方式三通过环境变量传密码进程列表里看不到用完退出 shell 即可。5.2 代码客户端的连接参数然后是各语言客户端的连接写法。以最常见的 Python 和 Java 为例Python 的 redis-pyimport redis r redis.Redis( host127.0.0.1, port6379, passwordMyStr0ngPass!, db0, decode_responsesTrue ) print(r.ping())Java 的 JedisJedis jedis new Jedis(127.0.0.1, 6379); jedis.auth(MyStr0ngPass!); String value jedis.get(testkey); jedis.close();Spring Boot 则是在配置文件里spring: data: redis: host: 127.0.0.1 port: 6379 password: MyStr0ngPass! timeout: 3s如果密码包含特殊字符在 URL 形式的连接串里还需要 URL 编码。比如你用的客户端支持redis://协议redis://:MyStr0ng%21Pass127.0.0.1:6379/0这里的!被编码成%21否则解析可能出错。这个细节藏得比较深很多人第一次用 URI 方式连 Redis 带特殊字符密码折腾半天连不上最后发现是编码问题。5.3 连接池和工具类软件的密码配置连接池场景下也要注意。很多框架在初始化连接池时只需要密码一次之后所有连接共享认证信息。比如 Spring Boot 默认使用 Lettuce 连接池密码配好就完事。但如果你在代码里手动创建多个 Jedis 实例每个都要单独auth()。我见过有人写了工具类只在第一个连接上 auth后面的连接复用连接对象结果流量一大新连接全是NOAUTH错误——因为 Jedis 从池里拿出的部分连接根本没有认证过。另外像是可视化工具比如常见的 Redis Desktop Manager、Another Redis Desktop Manager 这类工具连接配置里都有独立的密码字段填上即可。这里倒是难得踩坑的地方基本就是填对就行。6. 常见问题与排查技巧实录6.1 密码设置后不生效的排查思路密码设置后不生效排在首位的原因就是改错了配置文件。确认方式照我之前讲的ps -ef | grep redis看启动参数。如果你的 redis 实际加载的是/etc/redis/redis.conf你改的却是/usr/local/redis/redis.conf那改一百遍都不生效。第二个常见原因是没重启。配置文件方式改完必须重启进程光改文件不重启内存里跑的还是旧配置。第三个是 Docker 里密码“不生效”的错觉。前面说过容器重建后运行时配置丢失你进容器里CONFIG SET完当时是有效的但一旦容器被删、被重新编排创建密码就没了。这不是“不生效”而是“没持久化”。第四个是权限或语法问题。比如配置里写了requirepass 123456 # 这是密码Redis 会把#后面的内容当作注释吃掉实际密码变成123456。再比如密码里有空格没加引号Redis 解析的时候只取了第一个空格前的部分。这些都属于配置解析的连环坑排查时可以先cat看一眼配置文件再快速重启看日志tail -f /var/log/redis/redis-server.log启动日志里通常能看到Server initialized和配置加载情况如果 requirepass 那行解析出错日志里会直接爆出来。6.2 NOAUTH 和 WRONGPASS 报错的区分这两个报错是 Redis 密码最常见的“双子星”但含义完全不同。NOAUTH Authentication required的意思是服务器设置了密码但你的当前连接还没有认证或者认证状态已失效。出现这个报错时说明密码本身是对的你只需要先执行AUTH 正确密码。WRONGPASS invalid username-password pair or user is disabled的意思就直白了你输入的密码不对或者你 AUTH 时指定的用户名不存在。Redis 6.0 之后支持 ACLAUTH 命令可以带用户名127.0.0.1:6379 AUTH default MyStr0ngPass! OK如果只写密码默认对default用户认证。如果你之前用 ACL 改过 default 用户的密码或状态就可能出现WRONGPASS。排查这种问题的步骤是确认业务代码配置里的密码字段有没有被框架解析掉特殊字符确认有没有多个 Redis 实例连接串混用确认环境变量没有覆盖配置文件里的密码。6.3 忘记密码的应急处理这是个谁都不想碰到但迟早会遇到的问题。如果你把 Redis 密码忘了而且没有留存应急思路不是暴力破解而是利用 Redis 的重启机制绕开密码。思路一修改配置文件把requirepass那行注释掉或改成空然后重启 Redis。这样就回到无密码状态再用新密码重新设置。注意这个操作有短暂的无认证窗口内网环境风险可控公网环境建议先断开网络或改防火墙规则再操作。思路二不注释配置如果你能登录服务器直接改配置文件里的密码为新值重启后新密码生效。思路三Docker 场景下更简单因为容器配置是声明式的直接改 compose 文件里的command参数或挂载的配置文件重新创建容器即可docker compose up -d --force-recreate redis这里要提醒一句千万不要在忘记密码后靠CONFIG SET requirepass来找回因为这条命令本身需要先认证旧密码你既然忘了旧密码就执行不了。这不是绕圈子的笑话真的有人这么试过以为 CONFIG SET 不需要认证。6.4 容易被忽略的安全配置细节最后聊几个和密码配套的安全配置单独设了密码但不做这些安全等级还是不够。第一bind设置。如果 Redis 只给本机应用用就把bind 127.0.0.1写上不要用默认的bind 0.0.0.0。密码再强也不如直接把端口藏起来。第二protected-mode yes要开着。这个指令和密码是互补关系protected-mode 开启时如果 Redis 没有密码且绑定的是所有网卡它会拒绝外部连接。设置密码后这个保护机制反而会被弱化——很多资料说“设了密码 protected-mode 就不生效了”这说法不够精确。准确地说protected-mode 的主要作用是“在没有密码时对你进行兜底”。你设了密码它就把判断交给密码机制。所以两者不是一个替代关系而是配合关系。第三建议用 ACL 做更细的权限控制。Redis 6.0 加入了 ACL可以单独创建一个用户只给它部分权限。比如某个业务只需要读写某个库就可以ACL SETUSER bizuser on BizPass2024 ~cache:* read write然后连接时用AUTH bizuser BizPass2024这样就算这个用户密码泄露攻击者能操作的空间也被限制在cache:*这些 key 上不至于把整个 Redis 翻个底朝天。生产环境我会建议默认用户default只做管理业务连接都走专用 ACL 用户。这套方案比单纯依赖requirepass高级得多值得花时间研究。第四禁用危险命令。不管用不用 ACL至少把FLUSHALL、FLUSHDB、KEYS、CONFIG这几个高危命令改名或禁用。配置文件里加一行rename-command FLUSHALL rename-command CONFIG xconfigFLUSHALL改名为空字符串就等于完全禁用。这样就算密码泄露攻击者也不能一键清空数据。修改后记得重启验证因为改名命令写错位置同样会造成 Redis 无法启动。写在最后我个人在实际运维中体会最深的一点是Redis 密码不是“配一次就完事”的静态配置它应该像 SSH 密钥一样纳入日常安全维护。密码强度要够轮换要有节奏连接方式要避免明文暴露而且一定要把密码设置和配置管理结合起来。拿我自己的项目来说早期把密码直接写在 docker run 命令里图一时方便后来排查一个连接问题时才发现密码已经通过日志平台被多人看到。后来改成挂载配置文件 ACL 专用用户的方式问题才彻底解决。这篇文章里提到的三种场景覆盖了从单机到容器到动态运维的绝大多数情况。你不需要全部用上但至少要搞清楚你当前环境属于哪一种把对应的方案落下去。Redis 本身体积小、部署快正因为轻量才容易被轻视。密码这道门槛不设后面的安全建设都等于空谈。

关于本文作者

来自尧图内容编辑团队

尧图内容编辑团队 内容团队

尧图内容编辑团队

本文由尧图网络内容编辑团队执笔。团队由资深项目经理、前端工程师与设计师组成,所有内容均来自亲手交付的真实项目,先讲清问题、再给出可落地的解法。尧图深耕北京网站建设十年,服务过京华建材集团、智造科技等各行业客户,把一线经验沉淀为可复用的行业观察。

  • 十年建站经验,覆盖建材、制造、服务、文创等
  • 项目经理把关选题与事实准确性
  • 工程师与设计师联合撰写专业细节
  • 统一编辑规范,保证文风与排版一致
  • 每月复盘转化数据,迭代选题方向

延伸阅读

相关资讯与近期热门内容

深度阅读推荐

建站决策前值得细读的三篇

网站改版的5个关键决策
2024-08-12

网站改版的5个关键决策

什么时候该改版、改到什么程度、如何避免流量掉光,京华建材集团改版复盘给出答案。

获取专属建站方案

看完文章,把您的行业与预算告诉我们,免费获取一份量身定制的官网建设方案与报价。

立即免费咨询