
先问一句有没有人把 Redis 部署到公网或者测试机之后被提醒“你的 Redis 被别人连上了”然后你用redis-cli一敲发现里面真的多了不少奇奇怪怪的 key我见过不止一次起因基本都是同一件事——Redis 默认不设密码只要端口暴露出去谁都能直接执行FLUSHALL或者把你的数据当临时存储用。所以今天的主题很简单怎么给 Redis 设置密码。我按大家最常见的三种使用方式来拆解——第一是直接用redis.conf 配置文件做永久设置第二是Docker 容器部署时的几种改密方式第三是命令行下既改临时参数也做动态修改。这三条路覆盖了自建安装、容器化部署、临时调试三种真实工作场景看完你应该能直接上手顺带把几个常见的坑一起避开。1. 先理解 Redis 的密码机制再动手改1.1 Redis 默认的安全状态Redis 在默认配置下是不要求认证的也就是说只要客户端能连上 6379 端口发送PING、GET、SET、FLUSHALL这些命令都会被直接执行。本地开发环境这样用很顺手因为你会下意识把它绑定在127.0.0.1上外部网络根本连不进来。问题出在两类场景一是你用0.0.0.0去监听所有网卡二是你把它放进了 Docker 容器并映射了宿主机端口。这两种情况下Redis 的服务端口就是暴露给整个网络的等于你家大门敞开门锁是不存在的。Redis 官方其实提供了一个叫protected-mode的保护机制。默认情况下它确实是yes但这个保护模式只有在“没有显式设置密码、没有绑定bind地址、没有配置 ACL 用户”时才生效。更麻烦的是它的保护逻辑是如果 Redis 只监听在回环地址外部请求会被拒绝可一旦你手动设置了bind 0.0.0.0或者让容器端口映射到宿主机protected-mode的判断就不那么靠谱了。所以指望默认配置是不现实的最可靠的做法是设置一个强密码并且让所有客户端统一走认证。1.2 requirepass、AUTH、protected-mode 三者的关系requirepass是 Redis 配置文件里最核心的认证参数它设置“全局密码”。一旦设置Redis 会要求所有连接在真正执行命令前先发送AUTH password。命令行参数--requirepass和运行时命令CONFIG SET requirepass最终改的也是同一个全局配置项。protected-mode前面说了是“保险栓”。当密码没设置时Redis 会拒绝来自非回环地址的连接。但只靠它会有误伤也会带来“以为安全了其实没安全”的错觉所以应该把requirepass当成主要手段protected-mode保持不变作为第二道防线。还有一个新东西叫ACL 用户体系从 Redis 6 开始提供。ACL 可以给不同用户设置不同权限requirepass本质上只是创建了一个默认用户的认证方式。对大多数中小项目来说先用requirepass把门锁上后续需要精细化权限再迁移到 AC L也不迟。1.3 动手前先做三件准备工作第一件确定密码策略。不要用123456这种级别的密码我建议至少 16 位包含大小写字母、数字、特殊字符而且不要和其他系统的口令重复。你想想 Redis 里可能缓存了什么多半是 session、计数、热点数据有些甚至是业务表的一级缓存泄露出去不只是面子问题。第二件确认你手上有管理权限。如果是远程服务器上的 Redis你需要能改配置文件并且能重启服务如果是 Docker 容器你需要能执行docker exec或者能重新docker run一个新的容器。否则你只能让运维协助操作。第三件备份。改配置文件之前先把redis.conf复制一份例如cp redis.conf redis.conf.bak。如果你用的是云厂商的托管 Redis那还要先搞清楚服务面板里有没有“重置密码”入口有的话优先用客户端提供的安全能力而不是直接改机器上的配置因为托管实例很多配置是被云平台锁定的。2. 场景一配置文件方式设置 Redis 密码2.1 找到 node_modules 都在哪个路径不同安装方式的 Redis配置文件位置差别很大。我列几个常见位置帮你快速定位安装方式常见路径Ubuntu / Debian apt 安装/etc/redis/redis.confCentOS / RHEL yum 安装/etc/redis.conf或/etc/redis/redis.conf源码编译安装你执行./configure --prefixxxx时指定的目录下通常是源码目录里的redis.conf安装后可能在/usr/local/redis/etc/redis.confWindows 安装包安装目录下的redis.windows.confMac 上用 Homebrew 安装/usr/local/etc/redis.conf或/opt/homebrew/etc/redis.conf如果实在找不到可以用redis-server --version看版本信息然后用ps -ef | grep redis查看启动命令启动命令里往往带redis-server /path/to/redis.conf这类路径。再不行就find / -name redis.conf 2/dev/null虽然慢一点但能找到。2.2 修改 redis.conf 中的 requirepass以最常见的/etc/redis/redis.conf为例。先用编辑器打开比如vim /etc/redis/redis.conf然后找到这一行# requirepass foobared注意#注释。默认配置里requirepass是被注释掉的表示“不设密码”。你需要把注释去掉改成自己的密码requirepass YourStrongPassw0rd!2024改完之后保存退出。这里有两个小细节要留意。第一requirepass后面是明文的这意味着凡是能读到配置文件的人都会看到密码。所以在团队环境里要注意这个文件本身的权限比如chmod 640 /etc/redis/redis.conf。第二配置文件里如果同时存在多个requirepassRedis 只认最后一个所以别指望用“多个密码并存”的方式来做轮换旧版本那是行不通的要做密码轮换就用 ACL 多用户。2.3 重启 Redis 并验证密码是否生效改完配置文件必须重启 Redis 才能生效因为配置文件只在启动时加载。不同系统的重启命令不一样systemctl restart redis适用于大多数 Linux 发行版服务化安装。service redis-server restart适用于 SysV init 管理的老环境。如果你是直接前台起的那就CtrlC停掉再用同样命令启动。重启之后验证是非常关键的一步不然你根本不知道密码是否真的生效。最简单的验证动作是执行redis-cli ping如果密码生效你会看到(error) NOAUTH Authentication required.出现这个报错就说明密码已经挡在最前面了。紧接着用密码认证redis-cli -a YourStrongPassw0rd!2024 ping看到PONG就说明认证成功。这里有个提示-a参数会把密码留在 shell 历史记录里所以正式环境推荐用redis-cli进入交互模式后输入AUTH或者临时设置REDISCLI_AUTH环境变量来完成验证。2.4 配置文件方式的三个注意点注意点一是不要把密码写在命令行参数里然后写进 systemd service 文件因为 systemd 里用ExecStart启动 Redis 时命令行参数会暴露给所有能执行ps的用户。正确的做法是让 systemd 通过-c /etc/redis/redis.conf指向配置文件密码只存在于redis.conf中。注意点二是改完配置后先做一次redis-cli -a 密码 config get requirepass验证CONFIG GET返回的是一个数组一般样子是1) requirepass 2) YourStrongPassw0rd!2024如果返回值是空那就是你改错文件了Redis 实际读取的是另一份配置。注意点三是最容易被忽略的配置文件方式适合永久生效但不适合频繁换密码。你一改配置文件就要重启而重启意味着短暂断连缓存雪崩风险也会升高。所以线上环境如果突然需要紧急换密码我一般先用后面要讲的命令行方式动态切换等到业务低峰期再改配置文件做持久化。3. 场景二Docker 容器中设置 Redis 密码3.1 Docker 环境下的三种改密思路Docker 里跑 Redis 和本机跑 Redis 有个本质区别容器的文件系统是临时层你在容器里改的东西容器一删就全没了。所以“在容器里用vim改 redis.conf” 这种操作虽然能生效但是非常不可靠。靠谱的思路有三种启动容器时直接通过命令行参数--requirepass设置挂载一份自定义配置文件到容器内或者在docker-compose.yml里编排好配置。下面逐个说。3.2 方式 A使用 docker run 启动参数直接指定密码大多数官方 Redis 镜像默认会执行redis-server所以你可以直接给它传参数。先看一条真实可用的启动命令docker run -d \ --name redis-pass \ -p 6379:6379 \ redis:7 \ redis-server --requirepass YourStrongPassw0rd!2024 --appendonly yes这条命令的意思是用redis:7镜像启动一个叫redis-pass的容器把宿主机 6379 映射到容器 6379然后在启动 Redis 服务时追加两个配置参数一个是密码一个是开启 AOF 持久化。验证方式同样很简单docker exec -it redis-pass redis-cli -a YourStrongPassw0rd!2024 ping看到PONG就正常。如果你这时候进入容器内部用redis-cli ping会得到NOAUTH报错因为docker exec进去默认就在 Redis 容器里执行redis-cli不会自动带密码。这个方式的优点是干净、直接、不用准备配置文件。缺点是密码会出现在docker run的命令行里如果你用 shell history 保存了这条命令别人history一下就能看到。所以本地测试可以用但正式环境建议用下面的挂载配置文件方式或者把密码放到 Docker Secret 这种专门机制里。3.3 方式 B把自定义 redis.conf 挂载进容器这是我自己在生成环境最常采用的方式因为配置的可维护性更强。步骤分三步。第一步在宿主机上准备一份redis.conf。你可以从官方镜像里拷贝一份模板也可以自己写一个最小配置。例如我在宿主机/opt/redis/config/redis.conf里写了bind 0.0.0.0 protected-mode yes port 6379 requirepass YourStrongPassw0rd!2024 appendonly yes appendfilename appendonly.aof第二步用挂载参数启动容器docker run -d \ --name redis-pass-file \ -p 6379:6379 \ -v /opt/redis/config/redis.conf:/usr/local/etc/redis/redis.conf \ redis:7 \ redis-server /usr/local/etc/redis/redis.conf这里的重点是把宿主机上的/opt/redis/config/redis.conf挂载到容器里的/usr/local/etc/redis/redis.conf然后启动命令要显式指定让 Redis 使用这个配置文件。如果不指定官方镜像默认启动时可能用的是源码编译目录里的默认配置挂载进去也不会被读取。第三步验证docker exec redis-pass-file redis-cli -a YourStrongPassw0rd!2024 ping这个方式的好处非常明显所有配置项都在宿主机的一个文件里后续要调整maxmemory、持久化策略、密码等只需要改宿主机的redis.conf再重启容器就行。而且这个配置文件还能直接用 Git 管理整个 Redis 的运行时配置都有了版本记录。3.4 方式 Cdocker-compose 编排配置文件如果你用 Docker Compose 来管理一堆服务那 Redis 的密码配置应该写进docker-compose.yml里。我给出一个可以直接套用的示例services: redis: image: redis:7 container_name: redis-compose-pass restart: always ports: - 6379:6379 volumes: - /opt/redis/config/redis.conf:/usr/local/etc/redis/redis.conf - /opt/redis/data:/data command: [redis-server, /usr/local/etc/redis/redis.conf]启动命令docker compose up -d然后验证docker compose exec redis redis-cli -a YourStrongPassw0rd!2024 pingCompose 方式最大优势是配置声明式、可复制新环境只要把这份 YAML 和 redis.conf 拿过去docker compose up -d就能得到一模一样的容器。3.5 容器场景的避坑细节这里我必须多说几句都是踩过的坑。第一个是挂载文件的权限问题。宿主机上挂载进容器的redis.conf文件如果权限设置成777部分 Redis 镜像可能会拒绝执行。规范做法是chmod 644保证 Redis 进程用户有读取权限而不是直接给最高权限。第二个是CONFIG REWRITE和容器配置文件的矛盾。假设你在容器里用redis-cli config set requirepass xxx改了密码再执行config rewrite这时 Redis 会尝试把当前配置写回它启动时读取的配置文件。如果这个文件是被挂载进容器的重写会成功但它如果属于容器内部文件系统容器一删就全丢。更尴尬的是如果挂载文件是只读的config rewrite还会直接报错。所以容器场景下的正确姿势是在宿主机上改redis.conf再重启容器。第三个是日志排查技巧。如果容器启动异常不要只盯着docker logs的简短输出很多 Redis 配置错误会出现在最后几行。比如我遇到过容器直接退出docker logs输出里明确写了# Warning: couldnt set memory limit # Cant open the log file: Permission denied这多半是挂载文件或数据目录的权限问题。调整目录归属chown -R redis:redis /opt/redis/data后就能解决。第四个是关于端口冲突。如果宿主机 6379 已经被本机 Redis 占用了Docker 启动时会报bind: address already in use。这种时候要么关掉本机 Redis要么把宿主机端口改成16379再映射比如-p 16379:6379。4. 场景三命令行方式设置 Redis 密码4.1 启动时通过命令行参数指定密码启动 Redis 时可以直接通过--requirepass传参这个方式在临时测试和调试时最常用。看示例redis-server --port 6380 --requirepass TmpPassw0rd!888 --protected-mode yes这条命令会在 6380 端口启动一个 Redis 实例并且设置密码为TmpPassw0rd!888。启动时加--protected-mode yes是为了避免“设置了密码但保护模式关闭”的不稳定状态。验证这一步redis-cli -p 6380 -a TmpPassw0rd!888 ping这种方式适合本地多实例测试比如你想在 6380、6381、6382 上分别起三个不同配置的 Redis用命令行参数最省事不用准备三份配置文件。但它也有致命缺陷密码一旦以参数形式出现在进程启动信息里你就能通过ps -ef看到明文所以只适合临时调试用来做生产环境是不可取的。如果你用redis-server /usr/local/etc/redis/redis.conf --requirepass optimizePassword这种混合方式要注意命令行参数的优先级高于配置文件。也就是说如果配置文件和命令行参数都写了密码以命令行参数为准。这个特性在临时覆盖配置时很有用但也会迷惑人我曾经遇到过有人改了配置文件却没生效就是因为 service 启动脚本里残留了旧的命令参数。4.2 运行中动态修改密码CONFIG SET这是不需要重启服务就能改密码的方法也是线上应急改密的首选。先连接到 Redisredis-cli然后执行CONFIG SET requirepass NewPassword-2024执行成功后Redis 会立刻启用新密码。这里有个非常关键的点当你把requirepass设置为一个新密码时当前连接不会断开其他连接则会丢到认证区需要重新AUTH。你自己这个连接是“以前密码连接进来的”但它不会因为你改了密码就被踢掉因为 Redis 只认证“连接建立后第一条命令”而且CONFIG SET本身就是特殊命令已验证过的连接保持可用。如果你把密码设成空字符串CONFIG SET requirepass 就相当于去掉密码立刻恢复无认证状态。这个操作非常危险但偶尔会用在调试和自动化环境里生产环境千万别这么干。4.3 持久化密码CONFIG REWRITE 的作用CONFIG SET只改内存中的配置重启后就没了。要想把修改写入配置文件必须执行CONFIG REWRITECONFIG REWRITE会把当前 Redis 配置和它启动时读取的配置文件进行合并把内存中的变更写回文件。如果 Redis 启动时没有指定配置文件也就是纯命令行参数的临时实例执行CONFIG REWRITE会报错(error) ERR The server is running without a config file所以在生产环境我一般这么做先用CONFIG SET requirepass临时降低风险比如在漏报告警时快速加密码。业务低峰期执行CONFIG REWRITE让配置持久化。再准备一个快速重启窗口确认配置文件里的requirepass已经出现。CFG REWRITE 还有一个坑它不会完整保留配置文件里的所有注释和排版因为它会按 Redis 自身的内存配置重新生成文件内容。所以一个写满精美中文注释的配置文件执行一次 rewrite 之后注释可能就少了一半。我的建议是配置文件还是要通过 Git 管理生成好的redis.conf是基础设施的一部分不要依赖运行时 rewrite 来维护。4.4 命令行验证密码的正确姿势最后说说怎么用命令行验证密码。最常规的命令redis-cli -a YourPassword ping输出为PONG第二招是进入交互模式后用AUTHredis-cli 127.0.0.1:6379 AUTH YourPassword OK 127.0.0.1:6379 PING PONG第三招是不用-a参数用环境变量export REDISCLI_AUTHYourPassword redis-cli ping这样也能自动认证并且密码不会出现在ps -ef的进程参数列表中。这个方法我在批量执行脚本时经常用。需要提醒的是-a参数如果密码有特殊字符比如!、$、shell 可能会做变量展开建议用单引号把密码括住或者用--raw再手动控制输出。5. 三种方式对比与高频排障5.1 三种设置方式对比设置方式生效方式持久性适合场景风险点配置文件修改重启 Redis永久生产环境正式部署需要重启有短暂中断Docker 挂载配置文件重启容器永久容器化生产环境挂载权限、路径易错docker run 带参重启容器容器生命周期内临时测试、快速验证密码会出现在命令行命令行 CONFIG SET立即生效不持久需 REWRITE线上临时改密忘写 rewrite 则重启失效redis-server 启动参数启动时进程运行期间本地多实例调试密码在进程参数中可见我给你的实用建议是开发环境用命令行参数测试环境用 docker 挂载生产环境要么用真机配置文件、要么用 Docker 挂载配置文件。核心原则只有一个——不要让密码出现在能被人轻松看到的地方。5.2 常见报错与排查手册先列一个快速排查表报错 / 现象可能原因解决办法(error) NOAUTH Authentication required.认证未通过或还没发 AUTH用redis-cli -a 密码或在连接后先执行 AUTH(error) ERR Client sent AUTH, but no password is set.正打算发 AUTH但 Redis 没配置密码检查CONFIG GET requirepass为空说明没设密码(error) WRONGPASS invalid username-password pair密码输错了重新确认密码注意特殊字符转义docker: Error response from daemon: Conflict.容器名冲突换个容器名或docker rm旧容器Cannot connect to the Docker daemondocker 服务未启动或无权限systemctl start docker或检查用户组容器启动后立即退出配置文件路径错误或数据目录权限不对看docker logs 容器名最后的错误信息(error) ERR Unsupported CONFIG parameter: requirepass你连的可能不是 Redis或者版本极老确认端口和客户端类型MISCONF Redis is configured to save RDB snapshotsCONFIG SET后持久化写入异常检查磁盘权限和dir配置这里重点说一下NOAUTH的排查思路。你看到NOAUTH不要立刻怀疑密码错了先确认 Redis 是否真的设置了密码redis-cli -a 原密码 CONFIG GET requirepass或者当你知道密码但想试探时redis-cli CONFIG GET requirepass如果返回的是空数组说明 Redis 当前是没有密码的如果返回的是1) requirepass 2) 密码那说明有密码你需要在连接时带上。排查容器端口的报错也要注意顺序。先用docker ps看容器状态是否Up再用docker logs看启动日志最后再决定是检查配置文件还是数据目录权限。顺序乱了容易白忙活。5.3 设置密码后对主从复制、客户端和工具链的影响设置密码这件事最容易被忽视的是“连锁影响”。我举三个真实场景。场景一主从复制。如果你有一个 Redis 主实例和若干个从实例给主实例设置密码后从实例必须配置masterauth否则从节点连不上主节点。从节点的配置里可以加masterauth YourMasterPasswordmasterauth要填写的是主实例的requirepass密码。如果你用的是 Redis 6 的 ACL那么还需要对应主实例 master 用户权限。这个坑非常常见我见过有人给主库加了强密码结果从库同步中断了半天才发现。场景二客户端连接。你的业务代码里所有连接 Redis 的地方都要带上密码。以 Java 的 Lettuce 为例需要在RedisClient配置里设置 password以 Go 的 go-redis 为例需要在Options里写Password字段。如果服务端已经设密码而客户端没跟上你会看到大量ERR Client sent AUTH, but no password is set或者NOAUTH错误业务日志瞬间被刷屏。场景三可视化工具。像 Redis Desktop Manager、Another Redis Desktop Manager、Redis Insight 这类 GUI 工具连接时需要填写密码字段。更多人忽略的是连接地址里的认证方式比如某些老版本工具默认是NoAuth你填了密码也未必能在连接前认证反而需要手动设置“使用密码认证”。5.4 进阶用 ACL 用户替代全局 requirepass如果你只有一个密码控制全局读写一旦密码泄露攻击者能执行FLUSHALL把数据清空。Redis 6 之后的 ACL 可以把风险拆细。我简单举个例子。在redis-cli里创建两个用户ACL SETUSER app_user on AppUserPassword!123 ~* all -dangerous ACL SETUSER admin_user on AdminPassword!456 ~* all第一行创建了app_user只能操作普通键空间但禁止执行危险命令组比如FLUSHALL、SHUTDOWN、KEYS等。第二行创建了admin_user拥有全部权限。实际使用时业务连接用app_user运维排查用admin_user密码各自独立即使业务侧密码泄露也不能清空数据。ACL 的设置同样可以写进redis.confuser default on nopass ~* all user app_user on AppUserPassword!123 ~* all -dangerous user admin_user on AdminPassword!456 ~* all从长期维护角度看ACL 比单一requirepass更优雅也更安全。但前提是你得规划好用户权限矩阵否则前期迁移成本不小。对个人项目和小团队先用好requirepass守住底线等真有多个客户端、多角色需求时再升级到 ACL。6. 最后再聊几个我踩过的细节坑给 Redis 设置密码这件事说起来就是改一行配置的事但真正放到生产上是有一堆细节的。最后分享几条能帮你少走弯路的心得。第一设置完密码一定要在第二台机器上测一下外网连接。我见过有人只在服务器本机用redis-cli验证通过结果从办公网连过去还是报NOAUTH原因是他本机 redis-cli 用了默认端口 6379但服务器实际监听的是另一个端口。验证命令里一定要带上-h 服务器IP -p 端口。第二动态改密时优先改代码再改 Redis。线上环境如果必须换密码不要先动 Redis 再改业务配置那会造成一段时间内所有业务请求全部报错。正确顺序是先把客户端连接信息改成新密码然后灰度发布最后再执行CONFIG SET requirepass切换服务端。如果客户端配置已经全部更新但 Redis 还没换旧密码仍然有效业务不会中断。第三不要把密码和 Redis 放在同一个配置文件里提交到公开仓库。即使你的redis.conf写得再规范一旦推送到公开 GitHub密码就已经泄露。现在很多项目会用到.gitignore过滤配置文件模板或者用环境变量${REDIS_PASSWORD}占位再由部署系统注入真实值这才是更稳的做法。第四如果你用的是云厂商提供的 Redis 实例千万不要尝试在控制台外去手动改配置文件。托管实例的配置入口通常在控制台的“参数组”或“安全设置”里。手动连接到服务器内部去改大概率改变不了实际生效配置还容易把实例搞到不可用。这个结论我反复验证过云上资源就按云上的玩法来。最后再补充一个小技巧无论用了哪种方式设置密码都应该在客户端的工具脚本里加一个快速自检。比如我习惯在部署脚本里加一行redis-cli -h $REDIS_HOST -p $REDIS_PORT -a $REDIS_PASSWORD ping /dev/null 21 echo Redis auth OK别小看这一行它能让你在代码上线前第一时间发现问题而不是等业务跑起来之后被超时和报错淹没。毕竟 Redis 的密码设置不是“设完就结束”的事后面跟着的是客户端、主从、监控、工具链的一整套联动。把每个环节都打通这个密码才算真正设置成功了。