ARTICLE DETAIL

资讯详情

深耕编程入门与网站建设的一线实战洞察。

Redis默认端口6379背后的故事与安全配置实战

Redis默认端口6379背后的故事与安全配置实战 你可能每天都在用 Redis但对 6379 这五个数字未必有过好奇。我问过不少用了好几年 Redis 的同事Redis 默认端口是多少他们脱口而出6379。再追问一句为什么是 6379而不是 3306、8080 这种更常见的数字能答上来的人寥寥无几。这个数字背后的来历挺有意思而且顺着端口这个话题往下挖能牵扯出一堆和 Redis 使用、部署、安全相关的实战细节。这篇文章不光是为了讲一个冷知识我打算把 6379 的来历、Redis 端口相关的核心配置、修改端口的完整操作、以及围绕端口衍生出的安全实践和面试高频问题全部串一遍。不管你刚接触 Redis还是已经在生产环境维护了好几年都能在里面找到点能用得上的东西。1. 6379 端口的来历一组数字背后的程序员故事1.1 手机键盘上的意大利女孩Redis 的作者 Salvatore Sanfilippo网名 antirez是个典型的意大利程序员。他在自己的博客里交代过 6379 的来历答案和一段私人感情有关。早年他喜欢一个意大利女孩名字叫 Alessia Merz。那个年代手机还是九宫格实体键盘输入英文字母靠 T9 输入法数字和字母的对应关系是固定的2 对应 ABC3 对应 DEF4 对应 GHI5 对应 JKL6 对应 MNO7 对应 PQRS8 对应 TUV9 对应 WXYZ。把 Merz 这个姓氏拆开看M 在 6 键上E 在 3 键上R 在 7 键上Z 在 9 键上连起来正好是 6379。所以 Redis 的默认端口其实是作者把喜欢的人的名字用手机键盘转码成了一串数字顺手写进了这个日后火遍全球的开源项目里。这种表达方式很程序员不写情书不搞惊喜而是把一段小心思编码进技术产品里让全世界几百万开发者在每天的日常操作中反复接触到它。顺便说一下如果你见过老式手机就会理解那个年代的人对九宫格键盘有多熟悉。后来很多人问 antirez为什么不直接用全名 Alessia那样数字会更长他没正面回答过但大概率是因为姓氏短、好记而且 6379 念起来节奏感也不错。技术选型有时候就这么感性但恰恰是这种感性的决定让一个端口号有了人情味。1.2 这个端口为什么十几年没变过从 2009 年 Redis 第一个版本发布到现在的 Redis 7.x6379 这个默认端口一路沿用了十几年。中间社区不是没人讨论过要不要把默认端口换成更有意义的数字但 antirez 一直没改。原因其实很务实底层生态太依赖这个默认值了。想想看全球有大量自动化脚本、客户端 SDK、云服务模板、监控系统、容器编排配置都是直接写死连接 6379。一旦默认端口变了意味着所有依赖默认配置的部署方式都要跟着升级这会给整个 Redis 生态带来巨大的兼容性冲击。对一个开源项目来说向后兼容是对用户最基本的尊重所以哪怕 6379 背后没有特别深刻的工程含义它也因为历史惯性变成了 Redis 的招牌之一。这里其实能看出一个规律很多开源项目的默认端口一旦定下来就很少再变。技术选型时默认值代表的是约定而约定一旦形成改变的成本会远超你的想象。所以现在你新装一个 Redis看到的还是 6379这就是那个故事最好的结局——一个数字被无数人记住不是因为多特殊而是因为它承载了一个社区十几年的信任和习惯。2. 端口不是单独存在的Redis 监听端口的三个关键配置想知道 Redis 为什么会监听在某个端口上以及为什么有时候你改完端口还是连不上必须搞清楚 redis.conf 里三个关联配置项的作用。很多人只盯着 port 改结果改完照样踩坑就是没理解另外两个配置的逻辑。2.1 port、bind、protected-mode 各自管什么第一是 port最直白就是 Redis 监听的 TCP 端口默认 6379。如果你把它改成 0Redis 会关闭 TCP 监听只接受 Unix socket 连接这种模式一般只在同机部署、且对安全性要求极高的场景下才会用到。第二是 bind控制 Redis 监听在哪个网络地址上。默认配置是127.0.0.1 -::1也就是只允许本机通过回环地址访问外部机器连不上。想让局域网其他机器访问可以把 bind 改成内网 IP 或者0.0.0.0。但这里特别提醒一句改成0.0.0.0意味着监听本机所有网卡相当于把 Redis 暴露给所有能到达这台机器的网络风险非常大生产环境慎用。第三是 protected-mode保护模式默认 yes。它和 bind、密码机制是联动的。官方文档里写得很清楚当 Redis 同时满足没有配置密码和bind 没有显式指定其他地址这两个条件时只要有来自非本机回环地址的连接请求Redis 会直接拒绝并在日志里给出明确的报错提示。2.2 三个配置的联动关系和常见误区我见过太多人踩同一个坑为了局域网访问把 bind 从 127.0.0.1 改成 0.0.0.0然后发现其他机器还是连不上。一翻日志Redis 明明在监听但请求被 protected-mode 给拦了报错信息告诉你DENIED Redis is running in protected mode。这就是典型的没搞懂联动关系。其实 protected-mode 的拦截逻辑不复杂它只在没有密码 bind 是默认状态 请求来自非本机地址三个条件同时满足时才生效。换句话说只要你设置了 requirepass保护模式基本就不会再拦你了因为密码本身就是一层认证屏障。反过来讲如果你既想开放远程访问又不想设置密码那 Redis 就会认为你处于不安全状态主动启动自我保护。所以配置端口的正确姿势不是单独改一个项而是把 port、bind、protected-mode、requirepass 这四项放在一起想清楚。我个人的建议是生产环境务必设置强密码bind 尽量写具体的内网 IP别图省事用 0.0.0.0protected-mode 保持默认的 yes 就好。2.3 怎么确认 Redis 到底监听在哪个端口上配置改完之后第一件事是验证监听状态而不是直接跑业务。在 Linux 上我惯用的命令是ss -lntp | grep 6379输出里能看到 Redis 进程确实在监听 6379以及它绑定的 IP 地址。如果你的机器没有 ss 命令用netstat -lntp | grep 6379效果一样。在 Windows 上对应命令是netstat -ano | findstr 6379这里会出现一个 PID再配合任务管理器或者tasklist就能看到占用进程的名字。顺带提一句很多人在 Windows 上装完 Redis发现双击窗口能跑但程序一关服务就没了这类问题往往和端口无关而是没把 Redis 注册成 Windows 服务这里先不展开。还有一个小技巧用redis-cli直接验证redis-cli -p 6379 ping返回 PONG 说明端口和进程都正常。这比单纯看端口监听更靠谱因为 TCP 端口通不代表 Redis 真正可用。3. 实战修改 Redis 端口的完整操作流改 Redis 端口是个再常见不过的需求了。可能是端口冲突可能是安全要求也可能是同一台机器要跑多个 Redis 实例做集群。不管哪种场景操作逻辑是相通的我分别讲一下本地部署和 Docker 部署两种方式。3.1 本地安装场景下修改端口的三种方式第一种临时启动参数适合测试环境快速验证。直接启动时指定端口不写进配置文件进程重启后失效redis-server --port 6380第二种修改 redis.conf 配置文件这是生产环境最推荐的方式。找到 redis.conf 里的port配置项# 找到这一行 port 6379 # 改成目标端口 port 6380保存后用 redis-server 指定配置文件启动redis-server /etc/redis/redis.conf如果用 systemd 托管比如 Debian/Ubuntu 上通过 apt 安装的 Redis改完配置文件后需要重启服务sudo systemctl restart redis-server第三种多实例场景。如果你想在一台机器上跑多个 Redis最简单的方式是每份实例一个配置文件端口各自不同。比如 redis-6379.conf 用 6379redis-6380.conf 用 6380启动时分别指定配置文件。Redis Cluster 的节点本质上就是多个不同端口上的 Redis 实例。改完端口必做验证三连redis-cli -p 6380 ping 返回 PONGss 确认监听端口变了再检查一下 redis.conf 里 port 的真实值防止改错文件。3.2 客户端连接与连接串同步更新这里必须提醒一句改完服务端端口之后最容易翻车的环节是客户端忘了改。Redis 客户端的报错普遍不够直观经常是 connect timeout 或者 connect refused你不会第一时间想到是端口对不上。常见的客户端配置对应关系Java Spring Boot 项目里改application.ymlspring: redis: host: 192.168.1.100 port: 6380 password: yourpasswordPython 代码里改 redis-py 的构建参数import redis r redis.Redis(host192.168.1.100, port6380, passwordyourpassword, db0)命令行工具直接加 -p 参数redis-cli -h 192.168.1.100 -p 6380还有一个容易被忽略的地方就是连接串形式的 URL。很多框架里会写成redis://:password192.168.1.100:6379/0如果端口从 6379 改成 6380这个 URL 里的端口也要同步改不然一样连不上。我自己的习惯是把 Redis 地址端口这些都收敛到配置中心或者环境变量里避免在多个代码仓库里硬编码改起来想死的心都有。3.3 Docker 部署 Redis 时的端口映射细节Docker 场景下端口分两层容器内端口和宿主机端口。默认情况下容器内 Redis 还是监听 6379宿主机通过映射关系把某个端口转发到容器的 6379。最常用的启动方式docker run -d --name redis-6380 \ -p 6380:6379 \ -v /data/redis:/data \ redis:7这条命令的意思是宿主机 6380 端口转发到容器内 6379 端口。客户端连接时填宿主机 IP 加 6380千万不要去连容器的 6379除非你正好在容器网络里。也有需求是容器内也改端口比如多实例可以通过启动参数覆盖docker run -d --name redis-6381 \ -p 6381:6381 \ redis:7 redis-server --port 6381用 Docker Compose 更直观写 ports 时左侧是宿主机右侧是容器services: redis: image: redis:7 container_name: redis-6380 command: redis-server --port 6380 ports: - 6380:6380 volumes: - /data/redis:/data这里最常踩的坑有这几个第一端口映射写反了比如6379:6380这种意思是宿主机 6379 转发到容器 6380如果容器内 Redis 监听的是默认 6379那这个映射就是错的。第二容器内改了端口但命令参数没生效排查时优先看 docker logs。第三云服务器上忘了在安全组放行宿主机映射出来的端口在服务器本机 curl 没问题一旦从外网连就超时。3.4 远程机器和云环境放行端口的完整顺序Redis 部署在云服务器上时从客户端到你 Redis 进程之间通常要经过三层检查。一层不过关连接就失败。第一层Redis 进程本身是否在监听。这一层用 ss、netstat、redis-cli ping 来确认。第二层服务器本地防火墙。CentOS 上默认可能是 firewalld操作命令如下firewall-cmd --permanent --add-port6380/tcp firewall-cmd --reloadUbuntu 上可能是 ufwufw allow 6380/tcp如果公司内部还有 iptables 策略也要一并检查。第三层云厂商的安全组。在控制台里找到你的 ECS 实例添加入方向规则端口填 6380源 IP 可以限定为你自己的出口 IP 或者办公网段不要直接填 0.0.0.0/0。排查顺序有个标准套路先从 Redis 所在机器本机 telnet 一下确认服务没问题然后在同一内网的另一台机器 telnet检查防火墙最后再从外网 telnet验证安全组。telnet 127.0.0.1 6380能通但telnet 公网IP 6380不通问题基本就锁定在安全组或者防火墙上了。Windows 上的 telnet 默认没装可以改用Test-NetConnection或者干脆用 redis-cli 试连接效果差不多。4. 从端口安全到 Redis 整体安全实践改端口这件事很多人关心的是改了是不是就安全了。我的回答是改端口有价值但千万别把它当成安全措施的主体。4.1 改端口到底能不能防攻击先说实话对有针对性攻击者而言改端口几乎没用全端口扫描工具一跑什么端口都藏不住而且扫描全端口对攻击者来说成本并不高。改端口真正防住的是那些无差别扫描的自动化恶意程序和蠕虫。安全扫描器默认会优先探测认知度高的端口6379 就是 Redis 最知名的端口堆在公网扫描的最前列。所以你会发现Redis 默认端口的知名度越高越容易被自动化攻击盯上。把默认端口改成一个不常见的数字确实能减少很大一部分来自自动化扫描的暴露面。但你必须清醒一点改端口不是安全方案只是增加了一点攻击成本密码认证才是 Redis 安全的底线。我见过有些团队觉得改了端口就万事大吉密码都不设这简直是自欺欺人。4.2 Redis 未授权访问事故复盘早些年互联网上爆发过一轮影响面非常大的 Redis 未授权访问攻击事件。攻击者的思路很简单扫描公网上大量 6379 端口找到没设密码、bind 又暴露在公网的 Redis 实例然后利用 Redis 写文件的机制把恶意数据写入服务器系统目录伪造定时任务脚本下载并运行挖矿程序。很多团队直到服务器 CPU 飙到 100% 才发现不对劲。复盘这批事件问题根本不在于 Redis 本身而在于三个叠满的安全失误第一Redis 直接暴露在公网没有做网络隔离第二没有设置密码或者密码太弱第三Redis 进程权限过高让攻击者可以通过 Redis 写入到系统敏感目录。这三个环节单独拆开看都是很低级的错误但组合在一起就酿成了大规模事故。这个案例给我们的启示很清晰Redis 的安全不是单点问题而是网络层、系统层、Redis 层三层联动的结果。现在如果你还能在公网上扫到开放 6379 且未授权访问的 Redis那就相当于把服务器钥匙挂在门口非常危险。4.3 推荐的端口与安全配置组合结合我自己的生产实践一套比较稳妥的 Redis 安全配置长这样# 修改默认端口降低被自动化扫描命中的概率 port 6380 # 只监听内网地址不要用 0.0.0.0 bind 192.168.1.100 # 开启保护模式 protected-mode yes # 强密码长度 32 位以上包含大小写字母数字和特殊字符 requirepass YourStrongPassword123!再加上网络层的配合云安全组只放行特定来源 IP 访问 6380Redis 所在服务器不直接暴露公网端口至少前置一层防火墙或者安全组策略。系统层面Redis 进程尽量用独立用户运行降低写文件攻击带来的影响。这套组合拳打下来比单纯改个端口要靠谱得多。我一直跟团队说端口混淆只是顺手的事真正的底线是不暴露公网、有强密码、有限制权限、有访问控制。5. 围绕 6379 衍生出的高频面试题与工程延伸端口这个点看起来小但在面试和技术交流里经常是连环问题的起点。5.1 Redis 面试中的端口与基础考点很多面试官喜欢拿为什么 Redis 默认端口是 6379当开场这题如果你知道 T9 键盘的故事几乎能立刻破冰因为它能证明你不仅会用 Redis还对它的历史有了解这在面试中是很大的加分项。答完来历之后面试官大概率会顺着追问几个基础题Redis 为什么快这个问题的标准答案包括基于内存存储、单线程避免了锁竞争和上下文切换、底层用了 IO 多路复用、以及高效的数据结构设计。其中单线程这个点经常有人误解Redis 6.0 之后引入了多线程 IO但核心命令执行依然是单线程的面试时候注意表述准确。端口相关还可能追问6379 端口被占用了怎么办这就是考你 Linux 排查能力了按前面说的 ss 查 PID、kill 或者改端口即可。同一台机器怎么跑多个 Redis改端口、多配置文件、多实例这些答案都能体现你对 Redis 部署架构的理解。5.2 不同中间件的默认端口对比端口知识还有一个很实用的场景就是排查网络问题时快速定位服务。你把常用中间件端口记熟了看到一个端口大概就能判断是什么服务在跑这个能力在运维和排查问题的时候非常值钱。我整理了常见中间件默认端口表中间件默认端口备注MySQL3306关系型数据库PostgreSQL5432关系型数据库Redis6379键值缓存数据库MongoDB27017文档型数据库Elasticsearch9200 / 9300HTTP 和节点通信RabbitMQ5672 / 15672AMQP 和 Web 管理端Kafka9092消息队列Nginx80 / 443Web 服务器比如你在服务器上跑ss -lntp看到 3306 和 6379 同时监听基本能猜出这是一套 MySQL 加 Redis 的组合。再配合进程信息整个服务的拓扑就能快速还原出来。这些默认端口不一定不能改但绝大多数情况下没人改所以当成约定俗成记下来最有效率。5.3 端口之外的 Redis 高频问题速览从搜索热词来看大家除了关心端口就是 Redis 数据类型、分布式锁、可视化管理工具这类高频实践问题。虽然这些和端口不是直接相关但它们往往是同一次技术交流里会被一起聊到的内容。Redis 五种基础数据类型String 适合做缓存、计数器、Session 共享Hash 适合存对象List 可以做简单的消息队列Set 用于去重、共同好友ZSet 适合排行榜。很多人一开始会纠结选型我的建议很简单存储单个值用 String存储对象字段用 Hash涉及排序用 ZSet其他场景再根据实际需求选。分布式锁是面试和实战都绕不开的话题核心方案是 SETNX 加过期时间但要注意锁的误删、续期、以及 Redisson 框架的实现方式。可视化工具方面Redis Desktop Manager 是比较经典的选择现在 Another Redis Desktop Manager 的更新更活跃连接时填 Host、Port、Password 三项就行如果你把 Redis 跑在 Docker 里填的一定是宿主机映射端口不是容器内部端口。6. 常见问题排查实录最后这部分我把实战中遇到频率最高的端口相关故障整理成几个典型问题每个问题都附上排查思路和解决方案方便你直接照方抓药。6.1 端口被占用Redis 启动时报错Could not create server TCP listening socket *:6379: bind: Address already in use不用猜就是 6379 被其他进程占用了。处理思路分两步先查是谁占的再决定是清理进程还是给 Redis 换端口。Linux 下执行ss -lntp | grep 6379这条命令会显示进程 PID杀掉它kill -9 PID如果是同机已有 Redis 在跑你只是重复启动了那就不该杀而是把新实例的端口改成 6380多实例共存没问题。Windows 下用netstat -ano | findstr 6379 tasklist | findstr PID查出是哪个进程占用的 6379再决定下一步操作。提醒一句排查端口占用前先想清楚这台机器是不是原本就跑着别的 Redis别杀错进程。6.2 本机能连、远程连不上这个问题是所有端口排查里最常见的而且原因五花八门。我习惯先区分两种现象Connection refused 还是 Connection timed out。这两个现象的排查方向完全不同。Connection refused说明连接请求被主动拒绝了问题出在 Redis 进程本身Redis 没启动或者启动后又崩了先看日志。bind 配置不对没监听在目标网卡上。protected-mode 拦截了非本机回环请求日志里会有明确报错。密码认证失败客户端用了错误密码一般会显示 NOAUTH 或者 WRONGPASS。Connection timed out说明请求发出去了但没收到任何回应大概率是中间链路有人丢包云安全组没放行对应端口。服务器防火墙规则把端口 DROP 了。跨网段路由不通或者企业网络的访问控制列表拦截。排查命令参考# 在 Redis 所在机器自查 redis-cli -p 6379 ping # 在本机检查端口监听 ss -lntp | grep 6379 # 从其他机器检查连通性 telnet 192.168.1.100 6379如果 Redis 所在机器上 ping 通telnet 本机通telnet 内网 IP 不通防火墙和 bind 就是重点怀疑对象。6.3 改端口后日志、监控和部署脚本全部跟着废了改完端口Redis 本身倒是起来了但配套系统会出各种怪问题这是最容易被忽略的连锁反应。部署脚本里的 redis-cli 如果还写着 -p 6379连接肯定会失败。监控系统采集 Redis 指标用默认端口去采集采集不上就会告警。日志采集组件如果按固定端口去匹配连接日志也会跟着失效。我自己的处理习惯是改端口前先全局搜索一遍代码、部署脚本、监控配置里写死在 6379 的地方用全局替换把端口统一成新值再执行变更。改完端口后至少要在测试环境跑一轮完整的部署和监控验证确认没有遗漏的硬编码。这个步骤不能省省了就是生产事故。还有一个小细节Redis 的日志文件里也会记录监听地址和端口信息排查问题时养成先看日志的习惯。日志里通常会明确告诉你 Redis 到底 bind 在哪个地址、监听哪个端口很多配置上的问题一眼就能定位。另外再补一条建议如果项目里用了 Docker 或者 Kubernetes端口配置一定要和容器编排里的映射关系放在一起管理端口改起来要同时更新容器配置、服务发现配置、监控配置。这些配置之间的一致性比 Redis 本身改端口这个动作要难维护得多。我自己这些年用 Redis 的一个小习惯是每次新装完 Redis第一件事不是急着写业务代码而是把端口、bind、密码、防火墙这几个基础项从头到尾过一遍用 redis-cli ping 一下确认链路通顺才开始干活。这个习惯帮我避了很多没必要的坑。以后如果再有人问你为什么 Redis 端口是 6379你可以从 T9 键盘的故事讲起讲到保护模式讲到安全组讲到分布式锁。一个简单的数字背后是一整套工程方法论这些东西串起来比单纯背配置参数有用得多。
返回列表