拓十年匠心定制 · 商业建站与技术教学双线并行 咨询热线:400-886-1026 service@lmnt.cn
ARTICLE DETAIL

资讯详情

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

Redis远程连接配置详解:从默认限制到安全加固

Redis远程连接配置详解:从默认限制到安全加固

做后端开发的,基本都绕不开Redis。平时在本地开发环境用得顺手,一部署到服务器或者需要跨机器访问的时候,往往会卡在一个很基础的问题上——明明Redis进程跑得好好的,在服务器上连接、读写一切正常,可换到另一台机器上,客户端怎么都连不上,报错不是Connection refused就是连接超时。这篇文章就是把“Redis开启远程连接”这件事彻底拆开讲清楚,从默认配置为什么不让连,到具体场景下怎么改,再到连接之后怎么排查问题、怎么加固安全,一次讲透。

适合两类人看:一类是刚接触Redis、被远程连接折磨过的新手,另一类是已经能跑通但总担心配置有安全隐患的运维或全栈开发者。看完之后你不仅能自己配通远程连接,还能讲明白每个配置项为什么要这样改。

1. 先搞明白Redis默认为什么不让远程连接

1.1 bind、protected-mode、requirepass三个配置项的默认行为

Redis安装完成之后,默认配置其实做了两件很克制的事:只允许本机访问,并且不设置任何密码。核心控制项就是配置文件里的三个:bind、protected-mode、requirepass。

bind默认是bind 127.0.0.1 -::1,意思是只监听回环地址。这台机器上的网卡收不到任何来自外部IP的TCP握手请求,相当于门根本没对外开。protected-mode默认是yes,这个参数叫保护模式,它的逻辑是:如果Redis没有设置密码,同时没有显式绑定到非回环地址,那么来自外部IP的连接一律拒绝。这算是第二道保险,防止有人把bind改了但忘了设密码,结果Redis裸奔在公网上。requirepass默认是被注释掉的,也就是没有密码,客户端连接成功之后可以直接执行所有命令。

很多人只记住“要把protected-mode改成no”,这其实是一个流传很广的误解。保护模式触发的前提是“没密码且没绑定非回环地址”,换句话说,只要你设置了密码,或者显式绑定了具体IP,即使protected-mode保持默认的yes,外部连接也是允许的。真正需要把它改成no的场景非常少。

1.2 默认安全策略的设计逻辑与适用场景

Redis官方把默认配置设计得这么保守,不是给开发者添堵,而是有明确的前车之鉴。Redis作为高性能缓存,早期版本装完就能全网上访问,一旦部署在公网服务器上,极容易被扫描工具发现并爆破。我在实际项目中见过不止一次因为Redis未设置密码导致服务器被入侵的案例,轻则缓存数据被清空,重则被利用写入计划任务。

所以从3.2版本开始,protected-mode被引入并默认开启,官方态度很明确:你想要对外提供服务,就必须主动做一个安全决策。理解了这个背景,你再看那些配置项就不觉得繁琐了。开启远程连接本质上是在回答三个问题:允许谁来连、通过什么方式认证、暴露哪些能力。这三个问题没有标准答案,完全取决于你的部署场景。内网开发环境可以宽松一些,生产环境就必须严格收敛。

2. 开启远程连接前的配置准备与方案选型

2.1 找到redis.conf并理解关键配置行

不管你用什么方式安装的Redis,配置文件里需要关心的内容基本一致。Linux下通过apt或者yum安装,配置文件一般在/etc/redis/redis.conf,如果用源码编译安装,则在你指定的安装目录下面。Windows版本解压后,配置文件名是redis.windows.conf或redis.windows-service.conf。

打开配置文件后,远程连接真正要看的参数不多,核心是以下六项:

  • bind:决定Redis监听哪些网卡IP。127.0.0.1只允许本机,0.0.0.0表示监听所有IPv4网卡,也可以写具体内网IP来缩小暴露面。
  • port:服务端口,默认6379,除非有特殊需求,一般不用改。
  • protected-mode:保护模式开关,默认yes,具体触发规则上面已经说过。
  • requirepass:全局访问密码,注释状态为不启用。
  • timeout:空闲连接关闭时间,默认0表示不关闭,远程连接如果经常被莫名其妙断开,可以检查这个值。
  • maxclients:最大客户端连接数,默认10000,连接数打满时会报错。

配置文件的每一行都要认真看,不要整段复制别人的配置。因为不同Redis版本的默认配置注释格式有差异,手工合并的时候容易漏掉关键行。

2.2 三种常见部署场景的配置方案对比

根据实际部署位置不同,远程连接的配置策略也有明显差异。我把最常见的三种情况整理成了一张对比表,方便你对照自己的场景:

场景bind建议protected-mode密码策略
本地开发机开启远程0.0.0.0yes建议设置,避免局域网误连
内网服务器(非公网)具体内网IPyes建议设置
公网云服务器具体内网IP或安全组收敛yes必须设置复杂密码,推荐ACL

先说内网开发场景。开发机一般跟同事处于同一局域网,这时候把bind改成0.0.0.0最省事,配合一个密码就能满足基本需求。要注意的是,即使在内网,也不建议完全不设密码,因为局域网里可能有扫描器,更有可能是同事看错了IP直接连到你的实例上,然后把数据搞乱。

再说生产环境。生产服务器的Redis一般不会直接暴露公网,而是只监听内网IP,由应用服务器通过网络访问。这种情况下bind写具体内网IP比写0.0.0.0稳妥得多。如果你的Redis必须被公网访问,那重点就不是配置Redis本身了,而是云平台安全组和防火墙的精确放行,后面会细说。

2.3 密码认证选型:requirepass还是ACL

Redis提供两种密码认证方式。第一种是传统的requirepass,设置一个全局密码,所有客户端共用同一个密码连接。优点是简单直接,适合个人项目或者团队内部共用的小集群。第二种是从Redis 6.0开始引入的ACL(Access Control List),可以创建多个用户,分别赋予不同的命令权限和数据访问范围。

举个例子,你可以创建一个应用专用账号,只允许执行读写命令,不允许执行CONFIG、FLUSHALL这类高风险命令。这样即使应用被攻破,攻击者也无法通过Redis把服务器搞崩溃。如果只是自己调试,requirepass完全够用;如果是团队共用一台Redis,或者生产环境对外暴露,强烈建议直接用ACL做权限隔离。

密码强度这块,老生常谈但必须重点说。Redis被爆破的案例里,绝大多数是因为密码太简单,比如redis、123456、password这种。密码至少要有16位以上,混合大小写字母、数字和特殊符号,且不要跟服务器登录密码重复。

3. 实战操作:不同环境下开启Redis远程连接

3.1 Linux本机部署的完整配置过程

Linux是最常见的Redis部署环境,我用Ubuntu下的配置过程举例,CentOS的路径略有差异但逻辑一样。整个过程分五步,每步都值得仔细看。

第一步,备份原配置文件。动手之前养成备份习惯,出问题可以快速回滚:

cp /etc/redis/redis.conf /etc/redis/redis.conf.bak

第二步,修改bind参数。用vim等编辑器打开配置文件,找到bind 127.0.0.1 -::1这一行。如果你希望所有网卡都能被访问,可以注释掉这行,或者改成:

bind 0.0.0.0

如果只想允许某个具体IP访问,就写那个IP,例如bind 192.168.1.100。这里有个细节要提醒:修改bind之后,Redis启动时会尝试解析这些地址,如果写了不存在的网卡IP,服务可能直接启动失败。

第三步,设置密码。找到requirepass这一行,默认是注释状态,取消注释并填入强密码:

requirepass YourStrongPassword2024

第四步,确认protected-mode保持默认的yes。只要密码已经设置,这个参数不需要改。很多教程会让你改成no,遇到远程连不上时不要去动它,先检查其他配置。

第五步,重启Redis服务并验证。

systemctl restart redis-server redis-cli -h 你的服务器IP -p 6379 -a 你的密码 ping

如果返回PONG,说明远程连接已经通了。测试时不要直接在服务器上测试,那样走的是本地回环地址,测不出真实效果。从另一台机器执行同样的命令才是有效验证。

3.2 Docker部署Redis的端口映射与配置挂载

Docker里部署Redis,远程连接的难点不在Redis配置本身,而在容器端口和宿主机之间的映射关系。很多人Docker启动命令写对了,但Redis容器内的bind还是默认的127.0.0.1,导致宿主机能转发端口却转不进去。

推荐的做法是用官方镜像加配置挂载启动。先在宿主机准备好一份修改好的redis.conf,然后执行:

docker run -d --name redis7 \ -p 6379:6379 \ -v /etc/redis/redis.conf:/etc/redis/redis.conf \ redis:7 \ redis-server /etc/redis/redis.conf

这里有个关键点:Redis容器内的配置如果只写了bind 127.0.0.1,外部通过宿主机访问时,Docker的端口转发会把流量送到容器的回环接口上,Redis会直接拒绝,表现就是宿主机上连接成功,换成外部机器就失败。所以在Docker环境下,bind至少要写成0.0.0.0,或者写成宿主机在Docker网络中的网关地址,但最省心的写法就是0.0.0.0加上强密码。

用docker-compose部署也是一样的逻辑,核心配置项不变:

services: redis: image: redis:7 container_name: redis7 ports: - "6379:6379" volumes: - /etc/redis/redis.conf:/etc/redis/redis.conf command: redis-server /etc/redis/redis.conf

容器方式还要注意一点:不要在容器运行之后用docker exec进入容器修改配置,容器重建之后所有修改都会丢。配置文件的唯一正确管理方式是挂载,每次修改宿主机上的redis.conf,然后docker restart redis7让容器重新加载。

3.3 Windows环境下的Redis远程连接配置

Windows下安装Redis一般有两种方式:一种是直接用开源项目提供的Windows发行版,解压后运行;另一种是通过WSL或者Docker跑Linux版本。如果只是本地调试,直接使用Windows发行版就够了。

Windows版的配置文件名通常是redis.windows.conf,用文本编辑器打开,同样的三个配置项照着改:bind 0.0.0.0、设置requirepass,保存后重新启动redis-server.exe并指定配置文件:

redis-server.exe redis.windows.conf

Windows上有个容易踩的坑:如果你把Redis注册成了Windows服务,修改配置后必须重启服务才能生效,光杀掉redis-server重新启动是没有用的。注意区分当前系统里有没有Redis服务在后台运行,确认修改已经加载到当前进程。

3.4 防火墙与云安全组的放行操作

Redis配置改完之后仍然连不上,十有八九问题出在网络放行上。Linux服务器上有两层网络过滤要检查:操作系统防火墙和云平台安全组。

以CentOS的firewalld为例,放行6379端口:

firewall-cmd --permanent --add-port=6379/tcp firewall-cmd --reload

如果是Ubuntu,可能用的是ufw:

sudo ufw allow 6379/tcp

如果是云服务器,还必须去云平台控制台的安全组里添加入方向规则,放行TCP端口6379。这里有个很容易被忽视的细节:安全组的规则分为入方向和出方向,出方向默认一般是放行所有流量,所以只需要关注入方向。但是入方向规则的来源IP要尽可能精确,不要直接写0.0.0.0/0,尤其对于生产环境,只放行你的办公网IP或者应用服务器的内网IP更合理。

4. 用可视化客户端验证远程连接是否真正生效

4.1 主流Redis可视化客户端的选型参考

配置命令行连通的下一步,就是找个可视化客户端看看数据,管理起来方便很多。现在常用的工具主要有三款:Redis Desktop Manager、Another Redis Desktop Manager和RedisInsight。

Redis Desktop Manager简称RDM,是老牌客户端,界面清爽,基本功能齐全,但商业版需要付费,社区版后来停止更新了。Another Redis Desktop Manager是开源的替代品,功能上继承了RDM的常用能力,Windows、macOS、Linux都能用,也是我目前最常用的。

RedisInsight是Redis官方出的客户端,功能很全,支持GUI命令行、内存分析、慢查询分析等,对生产环境的Redis实例做体检非常合适。缺点是相对重一些,如果你是纯开发者只看key和value,用Another Redis Desktop Manager就足够。

4.2 客户端连接参数的配置细节与常见误区

用客户端连接Redis,需要填的无非是地址、端口、密码这几项。看似简单,但我见过大量连接失败都是填错了这几项。

第一,Address字段要填部署Redis的服务器IP,不要填127.0.0.1。客户端跑在本地,填127.0.0.1访问的是自己电脑,自然连不上远程服务器。第二,Port如果Redis没改过就是6379,填错端口会直接连接失败。第三,Password必须填,如果Redis开启了requirepass而客户端没填,会出现认证失败;反之如果密码填错,也会提示认证失败。第四,有些客户端有连接超时设置,默认值有时只有5秒,跨公网连接时建议调到10秒以上,避免网络延迟稍微一大就提示超时。

验证连接是否真正生效,可以做一个最简单的操作:在客户端里执行ping,返回PONG就说明链路完全通了。然后执行keys *看看能不能看到已有键,注意生产环境不要没事用keys *,因为大key数量多时这个命令会阻塞Redis。用scan 0代替更稳妥。

5. 远程连接高频问题排查实录

5.1 常见报错速查表

我把实际运维中高频出现的远程连接报错整理成了速查表,遇到问题时按表格顺序排查,大多数情况五分钟内能定位。

错误信息可能原因排查与解决
Connection refusedRedis未启动、端口未监听、bind配置不对确认服务状态,检查监听地址netstat -tlnp,核对bind
Connection timed out网络不通、防火墙丢包、安全组未放行检查网络连通性,用telnet IP 6379测试端口
NOAUTH Authentication required未填密码或密码错误确认requirepass是否设置,检查客户端密码
ERR max number of clients reached客户端连接数超过maxclients调大maxclients,排查连接泄漏
Redis is running in protected mode未设置密码且bind非回环地址设置密码,或显式绑定目标IP

补充一点:telnet IP 6379是排查端口连通性的利器。如果telnet能通但redis-cli连不上,基本可以排除网络层问题,往Redis配置和密码方向查;如果telnet都不通,问题多半在安全组或防火墙,先不用折腾配置文件。

5.2 几个我踩过的隐形坑

排查连接问题最怕遇到“配置看着全对,但就是连不上”的情况。这类问题往往藏在下面几个容易被忽略的细节里。

第一个坑:改完配置没有重启服务。Redis的大部分配置项,尤其是bind、requirepass、protected-mode,都是在服务启动时加载的,运行中修改配置并不会热更新。你改了配置文件但没重启,Redis实际上还在用旧配置运行。

第二个坑:配置文件里有多个bind项。有些发行版默认会在配置里写几行注释,有些自定义配置会在文件末尾追加新的bind,如果存在多个非注释的bind,最后一个生效或者行为会变得难以预料。排查时用grep -n "^bind" redis.conf一次性看清所有生效的bind行。

第三个坑:云安全组的规则其实没生效。有些云平台改完安全组规则后需要一两分钟才完全下发,如果刚改完规则立刻测试失败,等两分钟再测,别急着改Redis配置。另外安全组规则有优先级概念,某些情况下低优先级规则会干扰放行。

第四个坑:服务器的多个Redis实例在监听同一个端口。开发环境容易存在多个Redis进程,你改的配置对应的是进程A,但访问连接被监听同一端口的进程B接收了,自然行为不一致。用lsof -i:6379看看是哪个进程在监听该端口。

第五个坑:Redis 7.0及以上版本对ACL的处理方式与旧版不同。如果你升级过版本,但配置文件中还有旧的AOF和用户配置残留,连接时的认证行为会跟预期不符。排查时先确认版本,再确认该版本的认证逻辑。

第六个坑:DNS解析问题。客户端填写的服务器地址在局域网内可能被解析成错误IP,尤其在使用hostname而不是IP连接时更容易出现。排查时在客户端机器上ping 服务器名,确认解析结果。

6. 远程连接开启后的安全加固与运维建议

6.1 用ACL做最小权限控制

远程连接一旦打开,原来的安全边界就从“本机进程”变成了“网络可达”。这时候Redis提供的ACL功能就显得尤为重要。ACL可以在Redis 6.0及以上版本使用,通过命令创建独立的用户和权限位。

常用做法是给应用单独建账号,只赋予业务需要的命令权限。例如:

ACL SETUSER appuser on >AppPassw0rd2024 ~cache:* +@read +@write -CONFIG -FLUSHALL -FLUSHDB

这条命令创建了一个叫appuser的用户,密码为AppPassw0rd2024,只能访问键名以cache:开头的数据组,只能执行读和写两类命令,并且禁用了CONFIG、FLUSHALL、FLUSHDB这些危险操作。这样即使应用账号被入侵,攻击者能造成的破坏也极其有限。

ACL也可以用配置文件管理,在redis.conf里添加:

user appuser on >AppPassw0rd2024 ~cache:* +@read +@write -CONFIG -FLUSHALL -FLUSHDB

配置文件的写法连接后立即生效。日常运维时始终用默认的default用户管理操作,把应用连接账号发给业务方,两者互不干扰,这是生产环境的推荐状态。

6.2 网络层与命令层加固

远程连接开了之后,Redis的暴露面明显扩大,网络层和命令层都需要同步加固。

网络层首先要做的是限制来源IP范围。在bind中写具体内网IP,而不是0.0.0.0,配合防火墙规则只允许业务网段访问6379。其次,可以考虑把默认端口改掉,虽然靠隐藏端口提升安全性效果有限,但可以大幅降低被扫描工具命中的概率,属于典型的低成本防御手段。

命令层加固更关键。生产环境的Redis应该禁用高危险命令,下面是一组常见的配置行:

rename-command CONFIG "" rename-command FLUSHALL "" rename-command FLUSHDB "" rename-command KEYS ""

rename-command把命令重命名为空字符串,相当于禁用了这些命令。CONFIG对运维调试有用,但远程环境下一旦被利用,攻击者可以直接修改Redis配置;FLUSHALL、FLUSHDB清库命令一旦被误操作或者恶意执行,恢复成本极高;KEYS在远程环境下同样危险,键数量大时会导致Redis阻塞。

还有一点容易被忽略:Redis的持久化文件所在目录是否有权限保护。如果Redis进程以redis用户运行,redis.conf、RDB、AOF这些文件的权限应该尽量收紧到只有该用户可读写,避免其他系统用户拿到后直接分析数据或篡改配置。

6.3 日常运维中的几个检查习惯

远程连接配置不是一次性工作,而是一个持续的状态维护。养成下面几个检查习惯,能减少很多不必要的麻烦。

定期用redis-cli info检查连接数和命令统计。Connected clients如果异常增长,很可能是应用连接池配置错了或者哪台服务器在重复建连。total_connections_received的增速快但活跃连接数不高,通常说明连接没有复用,排查应用端的连接池参数。

修改任何配置之前先备份。我在前面已经提过,这里再说一次:备份不丢人,丢数据才丢人。即使是测试环境,备份一下配置文件也只需要一条命令。

生产环境的Redis不要放在Docker默认网桥后面直接映射公网端口。如果需要Docker部署,尽量配合云平台的安全组精确放行,并且限制只能从特定内网访问,而不是把端口暴露到0.0.0.0。

最后,日志要定期看。打开Redis的日志级别配置,错误日志里有大量远程连接失败的记录,这些记录能帮你快速发现异常扫描或者暴力破解尝试。一旦发现异常IP频繁尝试认证,直接在防火墙层拒绝该IP。


就我个人而言,远程连接Redis这件事,配置本身十分钟就能做完,真正花时间的从来都是安全思考和问题定位。踩过几次坑之后,我反而养成了一个习惯:每次要对外开放一个服务,先问自己三个问题——谁需要连、不需要谁连、被连上了他能做什么。把这三个问题答清楚,Redis的远程连接配置几乎不会出错。如果你现在正卡在某个连接报错上,建议从防火墙排查开始,一步步来,别急着改protected-mode,很多问题其实不在Redis本身。

返回列表