Linux服务器端口访问不通的排查方法(Connection refused、Connection timed out与No route to host的区分定位)

机器上服务明明跑着,另一台连过来却报错。报错串不一样,方向就完全不一样:Connection refused是秒回的,说明对端主机是活的,只是那个端口没人接或者被主动拒了;Connection timed out要等满超时才返回,多半是包被静默丢掉;No route to host又是另一回事,本机路由表或者链路上给了不可达。先认清这三种长相,能省掉一大半瞎试的时间。


先在服务端确认到底有没有在听

连不上第一件事不是改防火墙,是看端口上有没有进程。netstat已经很少用了,ss快得多:

ss -tlnp | grep 8080

输出里Local Address那一列要看仔细。写127.0.0.1:8080的服务只能本机连,远程访问一律refused;0.0.0.0:8080才是对外全开;写成:::8080是只监听IPv6,纯IPv4的客户端连过来同样是refused。这三种情况报错长相一模一样,不查监听地址就一路往防火墙上找,白跑一趟。

顺手确认进程真的活着,systemctl status看一眼,或者本机curl一次。本机curl 127.0.0.1通、远程不通,问题就锁在监听地址或者中间链路上。

三种报错怎么分

nc -zv -w 3 10.0.0.5 8080,秒回refused,说明对端回了RST;同样一条命令卡满三秒才超时,说明SYN发出去没有任何回应。这个时间差是最省事的分诊依据:立刻报错的一般是端口没监听或者防火墙REJECT,等满超时的是DROP、路由问题或者安全组没放行。

curl也有同样的特征,连不上退出码是7,加-v能看出卡在哪一步:

curl -v -m 5 http://10.0.0.5:8080/ ; echo $?

No route to host跟前两个不在一层。它通常是本机路由表里没有到目标的路径,或者链路上回了ICMP不可达。让内核自己算一遍走哪条路最快:

ip route get 10.0.0.5
ip neigh show | grep 10.0.0.5

同网段的目标,ip neigh里状态是FAILED或者干脆没有条目,那是二层没通,ARP没解析到MAC,去看交换机端口、VLAN、网线。跨网段的先看默认网关在不在、网关自己能不能通。

防火墙:REJECT与DROP表现不一样

Ubuntu 22.04、24.04,默认的防火墙工具链已经是nftables,iptables命令还在,但底层走的是nft后端,改规则只认一种别混着写。nftables 1.0.2、1.0.9,ufw 0.36.1、0.36.2,这四组版本分别对应22.04与24.04,内核5.15.0、6.8.0,也是一样的关系。CentOS、Rocky那边的默认还是firewalld。

sudo nft list ruleset | grep -n 8080
sudo iptables -t filter -nvL INPUT | head -30
sudo firewall-cmd --list-all

REJECT会回一个RST或者ICMP host administratively prohibited,客户端看到的是立刻refused;DROP什么都不回,客户端只能干等到超时。同样是端口没放行,报错串差得很远。iptables -nvL里的pkts计数器也是证据,连接试过之后那一列没涨,说明包压根没走到这条链。

云主机还得多想一层安全组。实测过好几次,机器内部规则全清了还是不通,最后是安全组没放行,而安全组是默认拒绝的,没加规则之前一切都是黑的。这一层在机器内部抓包看不出来,SYN根本进不来。

抓包确认SYN到底到没到

tcpdump 4.99.4(libpcap 1.10.4),命令本身不长:

sudo tcpdump -ni any host 10.0.0.5 and port 8080

服务端能看到客户端发来的SYN,说明链路是通的,问题在服务端自己的规则或者监听;一个包都看不到,说明包在中途就没了,往上游查安全组、ACL、路由。两端同时抓最有说服力,客户端看到SYN发出去、服务端那边收不到,分界点就锁定了。

握手卡住的情况,看连接状态更省事:

ss -tn state syn-sent

一堆连接停在SYN-SENT不动,配上tcpdump里只有SYN没有SYN-ACK,那是回程有问题,或者反向路径过滤在作怪。rp_filter会检查回程是不是走同一块网卡,多网卡、策略路由的环境里经常踩到:

cat /proc/sys/net/ipv4/conf/all/rp_filter

值是1的时候,非对称路由的包会被直接丢掉,且不留日志。

小包通、大包不通

ping得通、SSH能登录,传文件却卡住、HTTP大响应下载到一半断掉,这种基本是MTU的事。隧道、VXLAN、IPSec、WireGuard这些封装都会吃掉一部分MTU,路径MTU比1500小,而ICMP的frag needed消息又被中间设备拦掉,PMTUD失效,大包就无声无息地消失了。

带DF位探测能测出路径上真正能过多大的包:

ping -M do -s 1472 10.0.0.5
ping -M do -s 1400 10.0.0.5

1472加上28字节的IP与ICMP头正好是1500。1472不通、1400通,路径MTU就落在1400到1500之间。救急可以把TCP的MSS钳到路径MTU:

sudo iptables -t mangle -A FORWARD -p tcp --tcp-flags SYN,RST SYN -j TCPMSS --clamp-mss-to-pmtu

这招是权宜之计,能做的正事是改隧道接口的MTU。只改一侧不改另一侧,会造出更难查的单向故障。

通了,但是慢

连通性没问题、速度上不去,iperf3最直观。Ubuntu 22.04、24.04,自带的iperf3 3.9(cJSON 1.7.13),服务端iperf3 -s默认听5201端口,客户端iperf3 -c 10.0.0.5 -t 30 -P 4。输出里Retr那一列是重传次数,重传多说明链路上有丢包,接着查网卡错误计数:

ip -s link show dev eth0
ethtool -S eth0 | grep -i -E 'err|drop'

之前遇到过一次是光模块收光衰减,iperf3跑出来只有标称带宽的十分之一,ethtool -m看光功率才发现毛病在物理层。软件层面查不出异常的时候,回头看一眼物理层往往有惊喜。

丢包要定位到具体哪一跳,mtr比traceroute好用,它持续采样并给出每一跳的丢包率:

mtr --tcp --port 443 -r -c 100 10.0.0.5

中间某一跳丢包率明显高、后面又正常,那一跳多半只是限速回ICMP,不代表真丢;最后一跳就开始丢,问题才在对端。

数据截至2026年10月,命令与默认值以Ubuntu 22.04、24.04,这两个版本为准。