ARTICLE DETAIL

资讯详情

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

Redis设置密码全攻略:配置文件、Docker容器、命令行三场景

Redis设置密码全攻略:配置文件、Docker容器、命令行三场景 Redis 设置密码配置文件、docker容器、命令行3种场景半夜两点被告警叫醒Redis 实例 CPU 打满登录服务器一看几千个 key 被清空还多了几个奇怪的 cron 任务。再一查redis-cli -h 公网IP连上去连密码都不用输——裸奔的 Redis 被人扫到直接当成免费矿机。这是我见过最多的 Redis 安全事故没有之一。那次之后我就把“Redis 设置密码”列进了所有项目的安全基线清单。本文不绕弯子直接讲清楚在三种最常见的场景下如何给 Redis 设置密码改配置文件、docker 容器里面设置、以及命令行动态调整。这三条路覆盖了从裸机部署到容器化编排、再到线上紧急改密的全部需求是每个用 Redis 的人都该掌握的保命技能。1. 为什么 Redis 默认没密码官方设计逻辑与真实风险1.1 默认配置其实不是一个“漏洞”而是信任边界设计很多第一次接触 Redis 的人都会问同一个问题为什么一个数据库默认不设密码安装完就能直接连这不是疏忽。Redis 的设计哲学是“高性能、低延迟”而认证本身是有成本的——每次连接都要做握手校验在高并发场景下哪怕是微秒级别的开销也会被放大。所以官方默认把它关掉前提是 Redis 默认只监听127.0.0.1并且开启了protected-mode yes相当于只信任本机访问。在内网环境、由专门的应用服务器连接时这个默认配置通常够用。问题出在部署方式上。很多人部署 Redis 时会为了图省事改成bind 0.0.0.0或者用 docker 做端口映射时把6379直接暴露到公网同时又没开密码。此时 Redis 的“信任边界”被彻底打破攻击者只需要一个端口扫描工具就能拿到访问权。1.2 没有密码时的真实攻击面零访问控制下的 Redis 能干什么说几个我实际遇到过的场景数据被恶意刷空攻击者执行FLUSHALL缓存数据全部消失应用层顿时的雪崩效应能把后端打挂。被写入定时任务结合 Redis 写文件的特性向服务器写入 crontab变成持续挖矿的肉鸡。这类事件在网络上公开通报过不少手法都是一样的套路。主从复制被利用未授权访问时攻击者可以用SLAVEOF把自己控制的服务器变成 Redis 的从节点通过复制把数据拖走形成数据泄露。这些风险在部署 Redis 6.0 之前特别常见。即便现在已经有了更细粒度的 ACL 权限体系requirepass仍是第一道也是最基础的防线。先把这道门锁上再谈后续的账号体系隔离。1.3 安全基线这件事越早做越省心给 Redis 加密码不复杂几句话就能搞定。但我见过太多项目开发环境图省事不设密码等要上生产时才发现到处都引用了裸连接改密码要牵扯一堆客户端配置于是不断往后拖。设置密码不只是敲一行命令的事它会影响客户端连接串、主从复制、可视化工具等所有下游环节。所以这件事的正确姿势是从第一台 Redis 部署开始就纳入标准流程用下面的三种方式覆盖所有环境。2. 配置文件方案永久生效的 redis.conf 修改全流程2.1 定位 redis.conf常见安装路径与易错点配置文件方式的核心是requirepass指令。在配置文件里找到这一行把注释去掉改成你的密码# 在 redis.conf 中默认这一行是被注释掉的 # requirepass foobared # 改成如下格式 requirepass YourStrongPassword123但很多人在这一步就踩坑了修改完配置重启 Redis 后密码没有生效。原因十有八九是启动时没有指定配置文件。用redis-server直接启动的进程会使用内置默认配置你改的 redis.conf 根本没被加载。正确启动方式必须显式指定配置文件# 正确指定配置文件启动 redis-server /etc/redis/redis.conf # 错误不带路径启动使用默认配置你的修改全部无效 redis-server检查当前启动是否加载了正确的配置文件可以通过命令确认# 查看配置文件路径如果是空字符串说明用的是默认配置 redis-cli CONFIG GET dir redis-cli INFO server | grep config_file如果是 systemd 管理的 Linux 发行版Ubuntu、CentOS 等一般用systemctl start redis或systemctl restart redis此时服务单元里已经指定了配置文件路径但你要先确认/etc/redis/redis.conf确实是当前生效的那个。2.2 修改 requirepass 并正确重启 Redis推荐完整的操作链路是备份原始配置cp /etc/redis/redis.conf /etc/redis/redis.conf.bak改配置前永远先备份。用编辑器修改requirepass注意密码尽量用高熵字符串不要用123456这种。校验语法redis-server /etc/redis/redis.conf --test-memory不会测配置语法更稳妥的是直接重启后看日志RediSearch 这类模块也没法预检。简单做法是先确认redis-cli ping能通再重启。重启服务后验证# 重启后必须认证才能操作 redis-cli AUTH YourStrongPassword123 OK CONFIG GET requirepass 1) requirepass 2) YourStrongPassword123验证时留意在未认证状态下执行任何数据操作命令Redis 会返回NOAUTH Authentication required这是密码生效的典型标志。2.3 配置文件方案的三个高频坑第一个坑是密码里有特殊字符。比如密码写成了requirepass mima123在 redis-cli 里执行AUTH mima123毫无问题但如果在 shell 脚本里调用就得注意符号可能被解析成特殊含义。建议密码只使用字母、数字和部分安全符号连接串里使用 URL 编码的%40代替。第二个坑是主从架构。如果你在从节点的配置里只设置了requirepass却忘了配masterauth主从复制会报错。原因是主节点要求客户端认证从节点作为客户端去同步数据时如果没有密码凭据会被主节点拒绝。正确配置如下# 主节点 requirepass MasterPassword # 从节点连接主节点时使用的账号密码 masterauth MasterPassword第三个坑是改了配置后重启但系统里有多个 redis 实例。使用 systemd 时如果服务器的配置里又跑了 docker 容器里的 Redis很容易犯“配置文件改了但连的是容器”这种混乱。我的建议是动手前先想清楚当前要改的是哪个实例用INFO server看进程 id、端口、配置文件路径确认身份再操作。3. Docker 容器场景镜像参数、配置挂载与 Compose 编排3.1 为什么容器里改配置重启后就没了这是容器场景下最容易踩的坑也是新手问得最多的问题。假设你执行了docker exec -it redis-container bash进到容器里编辑了 Redis 配置文件然后重启容器——改的内容全部丢失。原因很简单容器运行时的可写层是临时的容器重建后所有改动都会被丢弃。要让配置永久生效必须在启动容器之前就用镜像参数或配置挂载的方式把设置注入进去。另外要明确一点官方 redis 镜像并没有提供REDIS_PASSWORD形式的环境变量。很多习惯了 MySQL 镜像的人会习惯性去设置MYSQL_ROOT_PASSWORD那样的环境变量但 Redis 镜像不吃这一套。这是新手最容易困惑的地方。必须在运行参数、挂载配置或 Compose 文件里动手脚。3.2 方式一启动命令直接带 --requirepass最简单粗暴的方式是在docker run时把--requirepass参数传给容器内的 redis-serverdocker run -d \ --name redis \ -p 6379:6379 \ redis:7 redis-server --requirepass YourStrongPassword123命令的末尾redis-server --requirepass YourStrongPassword123会覆盖镜像默认的启动命令等价于在命令行设密码。这样设置后外部连接必须认证。但这种方式的缺点也很明显密码写在进程命令行里容易被进程列表、编排工具、脚本日志泄露此外动态调整需要重建容器。它适合临时验证连接配置不适合生产长期使用。3.3 方式二挂载自定义 redis.conf更贴近生产实践的做法是把宿主机上的 redis.conf 挂载进容器让容器加载你指定的配置文件docker run -d \ --name redis \ -p 6379:6379 \ -v /opt/redis/redis.conf:/etc/redis/redis.conf \ redis:7 redis-server /etc/redis/redis.conf宿主机/opt/redis/redis.conf的内容可以复用到物理机、虚拟机部署比如requirepass YourStrongPassword123 appendonly yes maxmemory 256mb挂载后验证配置是否生效可以进入容器查看docker exec -it redis redis-cli -a YourStrongPassword123 CONFIG GET requirepass注意命令中的-a就是带密码执行稍后我会详细说密码在命令行中泄露的问题这里先记住这个用法。3.4 方式三Docker Compose 配置实例现代部署基本离不开 Compose。Compose 的写法同样是把配置挂载和启动参数组合起来services: redis: image: redis:7 container_name: redis restart: always ports: - 6379:6379 volumes: - /opt/redis/redis.conf:/etc/redis/redis.conf - redis-data:/data command: redis-server /etc/redis/redis.conf volumes: redis-data:这里的command字段指定加载挂载进容器的配置文件数据卷redis-data用于持久化 RDB/AOF 文件避免容器重建后数据丢失。启动后用docker-compose ps看状态确认容器正常运行。3.5 容器端口映射与安全加固容器场景还有一个和裸机迥异的安全问题如果你的服务要暴露到公网-p 6379:6379等于把 Redis 直接放到大街上此时光有密码还不够。最佳实践是绑定内网 IP-p 192.168.1.100:6379:6379而不是0.0.0.0:6379。只让需要访问的应用容器通过 Docker 内部网络连接也就是同一 Compose 网络内用服务名访问不映射宿主机端口。配合防火墙只放行指定来源 IP再叠加 Redis ACL 做账号隔离。密码是内网信任边界的补强不是公网暴露的豁免牌——这两件事要分开看。4. 命令行场景临时生效、动态调整与持久化4.1 CONFIG SET 让密码“秒生效”线上 Redis 正在跑不能停、不能重启怎么办用命令行动态调整。Redis 提供了CONFIG SET指令可以在运行时直接修改配置项# 免密连接本机 Redis redis-cli # 设置密码立即生效 CONFIG SET requirepass YourStrongPassword123 OK # 设置后当前连接仍然可用但后续新连接必须认证 AUTH YourStrongPassword123 OK这种方式最大的价值是不停机。在生产环境遇到未授权访问风险或者需要紧急加密码时这就是最快的止血手段。我以前处理过一个应急事件发现 Redis 端口被扫描当场敲下CONFIG SET requirepass几秒钟就封死了匿名访问的通道。4.2 在线改密对已建立的连接有何影响这是一个很多人搞错的知识点。CONFIG SET requirepass之后已经通过认证的连接不会立刻被踢掉它还能继续使用但新建立的连接必须带着正确的密码完成认证否则任何命令都会返回NOAUTH。所以在平滑迁移场景中你可以先CONFIG SET requirepass设置新密码再让客户端逐步切换连接串最后把旧客户端全部更新。整个过程不需要重启服务业务中断窗口为零。4.3 避免密码写进 Shell 历史的小技巧命令行设密码有个大坑密码会留在 shell 历史里。redis-cli -a YourStrongPassword123执行完你的密码就躺在~/.bash_history或.zsh_history里别人一翻就能看到。两个规避技巧很实用用环境变量读取密码而不是直接写在命令行里# 从环境变量读取密码不暴露在历史记录中 redis-cli -a $REDIS_PASSWORD # 更安全的方式让 redis-cli 提示输入不会留任何历史 redis-cli AUTH在命令前加一个空格如果 shell 开启了HISTCONTROLignorespace以空格开头的命令不会写入历史记录redis-cli -a YourStrongPassword123但这依赖 shell 配置最保险的还是第一种。为了保证连接串里带的密码不被日志采集系统捞走你还要注意-a传入的密码会出现在进程列表里因此也可以考虑用--no-auth-warning参数去掉“Using a password with -a option may be unsafe”的警告但这个参数只是销声匿迹密码本身还是可能被进程监控工具抓到。真正安全的做法是配合 ACL 用户授予最小权限降低单一密码泄露的爆炸半径。4.4 CONFIG REWRITE 的适用边界命令行设置密码是“内存态”重启后就会失效。如果需要改完立刻固化到配置文件执行CONFIG REWRITE这条命令会把当前运行时的有效配置写回 redis.conf。但有几个前提你要注意启动 Redis 时必须指定了配置文件否则CONFIG REWRITE会报错The server is running without a config file。写入的是“和默认配置不一样的部分”不会把整个运行时配置全部铺开。如果 redis.conf 的目录权限不够重写也会失败要留意进程运行用户的写权限。所以我通常的建议是线上应急先用CONFIG SET立刻止血等业务低峰期再更新配置文件并重启或者直接CONFIG REWRITE固化。两步走既快又稳。5. 三种场景怎么选环境对照与混合使用思路5.1 选型对照表三种方式各有适用边界列个表看得踏实场景推荐方式生效时机重启后是否保留适用环境裸机/虚拟机部署修改 redis.conf 的 requirepass重启服务后保留生产长期运行Docker 容器挂载配置文件或启动参数--requirepass容器启动时保留容器化部署、CI/CD线上应急/不停机CONFIG SETCONFIG REWRITE命令执行后立即重写后保留故障处理、灰度迁移物理机和容器里的“永久生效”本质不同物理机改配置文件重启一次就完事容器则要确保配置在镜像参数、挂载卷或 Compose 文件里重建容器后依旧生效。5.2 主从、哨兵、集群架构里容易漏掉的 auth 配置如果你只有一个 Redis 实例设置好requirepass就结束了。但一旦涉及主从、哨兵、集群关联配置不止一处漏一个就会造成复制断开或故障转移异常。主从架构主节点requirepass从节点要配masterauth。具体原因前面讲过了这里再强调一遍从节点复制数据时本质上也是一个普通客户端不携带认证凭据就会被拒绝。哨兵架构哨兵节点要同时配置两个东西一是sentinel auth-pass master-name password来连接受保护的主节点二是确保哨兵自己与其他哨兵通信时也完成认证。如果哨兵连不上主节点它就无法判断主节点是否真正存活故障转移时会出现误判。Cluster 模式所有节点都要统一设置requirepass并且每个节点都要配置masterauth。集群节点之间的握手、槽位迁移都走内部通信只要有一个节点认证配置不一致集群就会不停报错表现为ERR Cluster authentication failed。这些点虽然和设置密码本身不直接相关但只要你在生产环境用过一次集群就知道“给 Redis 加密码”从来不是改一行配置就结束的事。我自己的踩坑记录里主从复制因密码配置不一致导致备份数据无法同步的情况至少出现过三次。5.3 我推荐的“先临时后固化”流程现在的项目部署结构基本都是“裸机 docker 云上托管”混合形态。我的习惯流程如下新环境部署 Redis第一件事就是把密码写进初始化脚本和配置模板而不是等出问题再补。线上存量裸奔实例先用CONFIG SET临时上锁同步修改客户端连接串业务低峰期再更新配置文件并CONFIG REWRITE固化。容器环境直接改 Compose 文件统一在command或者挂载的 redis.conf 里维护密码不搞一次性docker run手工命令。每半年轮换一次密码轮换时按“改配置 → 更新客户端 → 验证 → 清理旧连接”的顺序执行。这样一套组合拳下来既解决了应急需求也兼顾了长期可维护性。6. 设密之后的客户端改造与常见报错排查6.1 redis-cli 与连接串的正确写法密码设置完成后最直接的验证就是 redis-cli。常见写法有几种# 方式一-a 参数直接带密码有历史泄露风险 redis-cli -h 127.0.0.1 -p 6379 -a YourStrongPassword123 --no-auth-warning # 方式二AUTH 命令手动认证 redis-cli AUTH YourStrongPassword123 OK # 方式三连接 URL 里带密码 redis-cli -u redis://:YourStrongPassword123127.0.0.1:6379/0URL 形式中的密码如果有特殊字符需要 URL 编码。比如密码是pss在 URL 里要写成p%40ss否则解析会出错。6.2 主流编程语言客户端的密码配置服务端设好密码后客户端改造是绕不开的一步。给出几个常见语言的示例JavaSpring Boot Lettuce在application.yml中配置spring: data: redis: host: 127.0.0.1 port: 6379 password: YourStrongPassword123JavaJedis / Redisson// Jedis Jedis jedis new Jedis(127.0.0.1, 6379); jedis.auth(YourStrongPassword123); // Redisson config.useSingleServer().setAddress(redis://127.0.0.1:6379).setPassword(YourStrongPassword123);Pythonredis-pyimport redis r redis.Redis(host127.0.0.1, port6379, passwordYourStrongPassword123, decode_responsesTrue)Spring Data Redis 老版本的写法略有区别只有spring.redis.password这样的扁平属性名新版本迁移到spring.data.redis.*之后路径变了升级 Spring Boot 时容易忽略要留意。可视化客户端这里也提一句Redis Desktop Manager、Another Redis Desktop Manager、RedisInsight 这些工具都是在连接设置里填Password字段。连不上时先检查端口、密码、认证用户名基本能排查掉九成的问题。6.3 常见报错对照与根因分析设置密码后客户端会集中出现三类报错报错信息含义排查方向NOAUTH Authentication required未提供密码或密码为空客户端连接串是否遗漏 password密码是否被改了WRONGPASS invalid username-password pair密码错误或用户名不存在Redis 6 默认用户名default确认密码是否被环境变量或配置模板覆盖ERR Client sent AUTH, but no password is set设置了密码但服务端没有开启认证客户端配了密码服务端 requirepass 未生效重启后配置丢失容器挂载没生效排查时还有一个小技巧看看CONFIG GET requirepass输出是否为空。如果为空说明你确认的实例根本不是你以为的那个——常见于多实例、多容器场景。这跟前面提到的“先确认再操作”是同一原则。6.4 从 requirepass 到 ACL多用户隔离的进阶方向如果你只是给自己用的 Redis 设置密码requirepass足够了。但如果是团队共享的 Redis多个人、多个应用共用同一个密码出问题时根本定位不了是谁在刷数据。Redis 6.0 开始引入了 ACL可以给不同应用创建不同账号并限制权限。比如给缓存应用只开读写权限给运维账号开全部权限给只读报表账号开GET权限redis-cli -a YourStrongPassword123 # 创建只读用户 ACL SETUSER readonly_user on ReadOnlyPass123 ~* read # 创建带过期时间的临时账号 ACL SETUSER temp_user on TempPass456 ~* get set EX 3600ACL 出来后requirepass更像是一个“超级入口”而 ACL 则解决了“谁在用、能用什么命令、碰哪些 key”的治理问题。如果项目对安全有更高要求建议在设置密码的基础上再往前走一步把每个应用、每个环境都拆成独立账号。这样将来排查慢查询、异常删除、key 过期策略时能省下大量扯皮时间。最后再分享一点经验关于 Redis 设密码我给新人的建议是别嫌麻烦先把requirepass配上再按项目情况决定要不要上 ACL。在实际踩过几次坑之后我形成了两个习惯一是在所有部署脚本和 Compose 模板里把密码作为环境变量注入而不是写死在文件里二是每次改完密码先拿一台测试机跑一遍客户端连接验证再批量更新配置。密码本身解决的是“你能不能连”的问题职责边界很清晰。真要守住 Redis 的安全底线密码、网络隔离、最小权限这三件事缺一不可。先把密码设置这条链路彻底跑通后面再逐步补网络和权限的功课生产事故就会少很多。
返回列表