一、现象与影响面:配置上”通了”,访问上没响应
这里说的”端口通了但不响应”,指的是配置看起来全都该通:控制台安全组放行了、防火墙也关过了、服务明明起来了,可从外面访问就是没有应答。典型症状清单:服务器本机 curl 一切正常,换到外网就超时;昨天还通、今天不通;ping 得通但端口不通;telnet 端口”通”了但服务不应答。
先建立模型。一次从外网发起的访问要过四道门:云安全组(云平台在主机之外做的虚拟防火墙)→ 系统防火墙(firewalld/ufw/iptables,在主机之内)→ 服务监听地址(0.0.0.0、127.0.0.1 还是内网 IP)→ 协议与服务本身。四道门任何一道关闭,外面看到的现象都是”不通”,但细看信号并不一样——这就是排查的抓手。
反模式一:排查无果就关防火墙、安全组放行 0.0.0.0/0 全端口。这是拿安全换省事的下策,而且经常连问题都复现不出来——关防火墙的动作顺手重启了服务,问题暂时消失,下次复发时现场又没了。正确姿势是按层验证,每一层留下”通或不通”的记录。
二、第零层:服务器本机自测,先把服务问题摘出去
网络排查之前,先证明服务本身是好的——这一步能筛掉占比最高的”假网络问题”:
# 以下命令都在服务器上执行
systemctl status nginx --no-pager # 服务活着吗;容器部署就看 docker ps
ss -tlnp | grep -E ':80|:443'
1. LISTEN 0 511 0.0.0.0:80 ... users:(("nginx",...)) ← 盯住监听地址那一列
curl -I --max-time 3 http://127.0.0.1:80
| 监听地址 | 谁能访问 | 典型场景 | 常见误会 |
|---|---|---|---|
0.0.0.0:80 |
所有网络可达本机的来源 | 对外服务的正确姿势 | 以为监听了就一定能被访问——前面还有两道防火墙 |
127.0.0.1:80 |
仅本机进程 | 供本机反代回源 | 配置文件照抄示例忘了改,外部必然不通 |
192.168.1.10:80(具体内网 IP) |
该地址可达者 | 多网卡机器分离业务 | 绑死具体 IP,机器换 IP 或换网卡后服务”神秘失联” |
本机 curl 不通:服务问题,回应用日志,别在网络层耗着。本机通:服务无罪,往下走。
三、第一分诊:timeout、refused 还是应答挂起
从一台真正在外的机器(你的电脑、另一台云主机)发起测试:
# 以下命令在测试机上执行
curl -v --max-time 5 http://<服务器公网IP>:80
nc -zv <服务器公网IP> 80 # -z 只探端口不发内容,-v 报结果;没装 nc 就用 telnet
结果分诊表是全文的枢纽:
| 现象 | 网络层发生了什么 | 指向 |
|---|---|---|
| connection timed out | SYN 发出去石沉大海,中间某层把包丢了 | 云安全组或系统防火墙(防火墙 DROP 的表现同样是超时),进第四、五节 |
| connection refused | 服务器立刻回了 RST,包到了主机但没人监听 | 监听地址或服务没起——注意:refused 恰恰说明 TCP 能到达主机,安全组多半已放行,回第二节 |
| 连上但挂起、无响应 | 三次握手成功,应用层不回话 | 服务卡死、连接池打满,或测的协议不对,转应用层 |
| 立刻报域名解析失败 | 客户端侧解析问题 | 先查测试机自己的 DNS,与服务器无关 |
UDP 要特别提醒:UDP 没有握手,nc -zv -u 对 UDP 端口报”成功”不代表对端真的在听;测 UDP 要用协议本身的报文拿真实应答说话——DNS 用 dig @<IP>,日志服务用对应客户端发一条真实消息。
这层如果是 timeout,问题在两道防火墙里,继续往下;refused 回第二节改监听;挂起转应用层排查。
四、第二层:系统防火墙——firewalld 与 ufw
# CentOS/RHEL 系(firewalld)——服务器上执行
firewall-cmd --state
firewall-cmd --list-all # 当前 zone 放行了哪些 service 与 port
firewall-cmd --permanent --add-port=80/tcp # 永久放行
firewall-cmd --reload # 不 reload,--permanent 的规则不生效
1. Ubuntu/Debian 系(ufw)——服务器上执行
ufw status verbose
ufw allow 80/tcp
1. 底层兜底:两套前端都没配过时,直接看 netfilter 本体——服务器上执行
iptables -L INPUT -n --line-numbers
| 维度 | firewalld | ufw |
|---|---|---|
| 常见发行版 | CentOS/RHEL/Fedora 系 | Ubuntu/Debian 系 |
| 抽象方式 | zone(区域)+ service/port,可按来源 IP 分区 | 简单规则列表,默认进 deny、出 allow |
| 生效方式 | --permanent 要配 --reload |
命令即时生效并持久化 |
| 共同点 | 底层都是内核 netfilter,只是命令皮肤不同 | 同左 |
两个高频坑。其一,--permanent 加了规则忘了 --reload,规则”配了但没生效”。其二,机器上两套防火墙并存——部分云镜像预装 firewalld,而你按习惯配了 ufw(或反过来),两套规则挂在同一个 netfilter 上,只查自己配的那套会得出”防火墙没拦”的错误结论,--state 和 status 要各查一遍。看 iptables 输出还要分清 DROP 与 REJECT:DROP 静默丢包(客户端表现为 timeout),REJECT 明确回绝(表现为 refused)——这直接决定第三节的分诊走向。
这层防火墙放行了、外网仍是 timeout,剩下的嫌疑集中在云安全组。
五、第三层:云安全组(以阿里云为例,细节以各厂商文档为准)
安全组是云平台在实例之外做的虚拟防火墙——流量还没到你主机就被它过滤,主机上的任何工具都看不到它的存在。这正是”服务器上一切正常、外面就是不通”最常见的原因。
控制台逐项核对五要素:
| 要素 | 核对什么 | 常见翻车 |
|---|---|---|
| 方向 | 入方向规则 | 把规则加到了出方向 |
| 协议类型 | 自定义 TCP / UDP / ICMP | 服务是 UDP,规则只放了 TCP(或反之) |
| 端口范围 | 精确到服务端口 | 范围填法理解错,以为放了一段实际只放了一个端口 |
| 授权对象 | 0.0.0.0/0 还是具体网段 | 只授权了自己的 IP,而本机是动态 IP 早就变了 |
| 优先级 | 多条规则冲突时的命中顺序 | 拒绝条目优先级更高,放行条目形同虚设 |
三条稳定事实值得记住:安全组是有状态的,入方向放行的连接其回包自动放行,不必再配出方向规则;ping 与 TCP 端口是两回事,ICMP 通常需要单独的授权条目,默认模板经常不含它,所以”ping 不通”不代表端口不通;安全组规则改动即时生效,不需要重启实例。
验证上有个干净的对照实验:服务器本机 curl 通(第二节)+ 外网 timeout(第三节)+ 系统防火墙全放行(第四节),三层证据齐了,几乎可以断定是安全组。此时去控制台补规则,补完立即用第三节的 nc 复测,前后不过几分钟。
反模式二:安全组对 0.0.0.0/0 放行全部端口图省事。SSH 应只对办公网段放行(或走跳板机),数据库、缓存这类组件原则上不进公网。安全组是成本最低的一道防线,别把它拆了。
六、三对概念,一张表收拢
| 概念对 | 一句话分工 | 排查时的动作 |
|---|---|---|
| 云安全组 vs 系统防火墙 | 一个在主机外(云平台),一个在主机内(操作系统) | 外层查控制台五要素,内层查 firewall-cmd/ufw/iptables |
| firewalld vs ufw | 同一内核能力的两套前端,发行版默认不同 | 先确认机器上跑的是哪套,警惕两套并存 |
| 0.0.0.0 vs 127.0.0.1 vs 内网 IP | 监听地址决定”谁有资格敲门” | ss -tlnp 的 Local Address 列对照第二节表 |
七、根因清单:按出现频率排序
| 根因 | 典型症状 | 一行验证 |
|---|---|---|
| 服务监听 127.0.0.1 | 外部 connection refused | ss -tlnp 看绑定地址 |
| 安全组未放行端口 | 外部 timeout,本机一切正常 | 控制台核对五要素 |
| 系统防火墙默认拒绝 | 安全组已放行仍 timeout | firewall-cmd --list-all / ufw status |
| 协议放错(TCP/UDP) | TCP 测试通、UDP 服务不通(或反之) | 控制台协议类型列 |
| ICMP 未放行 | ping 不通但服务正常 | 控制台找 ICMP 条目 |
| 服务绑死内网 IP | 换过 IP/网卡后突然失联 | ss -tlnp 对照当前 IP |
| 两套防火墙只配了一套 | 配置了等于没配置 | --state 与 ufw status 都查 |
| 前面还有负载均衡/CDN/WAF | 域名通但直连 IP 不通(或反之) | 绕过域名直测源站 IP |
八、预防:上线四步验收
| 步骤 | 在哪做 | 通过标准 |
|---|---|---|
| 本机 curl 127.0.0.1 | 服务器 | 服务应答正常,监听地址正确 |
| 内网另一台机器 curl 内网 IP | 同 VPC 测试机 | 系统防火墙放行正确 |
| 外网机器 curl 公网 IP | 办公网或拨测平台 | 安全组放行正确 |
| 换协议再测一遍 | 测试机 | UDP 服务用真实协议报文拿到应答 |
再配两条长效机制:从外部做拨测监控(端口加协议双维度),第一时间发现”昨天通的今天不通”;安全组与防火墙的每次变更留痕,出问题时能对比”上次到底动了什么”。
这套走法收拢成一句:先在本机自证服务无罪,再用 timeout 与 refused 分诊丢包发生在哪一侧,最后按 系统防火墙 → 云安全组 的顺序收网——顺序反了,就会在服务器上翻半天 iptables,而规则根本丢在云平台那层。
延展阅读:这套分层思路放到多节点部署里怎么用,见《多节点集群架构规划》;本文用到的命令的日常版本,见《Linux 常用命令》;新机器开箱时的环境与网络配置,见《开发环境》。
版本核实(以官方文档为准):安全组的有状态回包、ICMP 需单独授权、规则即时生效等行为以阿里云等各云厂商文档为准;firewalld、ufw、iptables 命令与 DROP/REJECT 语义为长期稳定接口;文中未引用具体版本号。