Draw a probe path first: every hop from local host to peer
Troubleshooting fails most often when there is no layering. Facing "cannot reach the Internet", first decide whether it is a single node or the whole path: whether the interface has an IP (ip a), whether a default route exists (ip route), whether the gateway answers ping, then climb upward one layer at a time. Use the layer-appropriate tool and never let curl guess about link loss.
Here is the standard command sequence from link to application, each step with a clear pass criterion: interface UP with an address, a route exists, gateway reachable, DNS resolves, TCP three-way handshake succeeds. Whichever step fails scopes the problem to that layer.
ip a # 网卡地址/UP 状态
ip route # 默认路由
ping -c 3 192.168.1.1 # 网关
ping -c 3 223.5.5.5 # 公网 IP(阿里 DNS)
dig +short example.com # 域名解析
curl -vI https://example.com --connect-timeout 5Loss and latency: ping both ends, read the stats, and look past ICMP
ping only measures ICMP, and many operators throttle or drop ICMP, so a little loss in ping is normal. What really matters is the TCP business traffic. When reading ping, watch mdev (jitter), duplicate packets, and the TX side TXerrors/TXdropped—loss happening at your egress versus at the peer requires very different treatments.
To pin down a specific path, use mtr hop-by-hop to watch loss and avg, turning an abstract "network is slow" into a concrete bad router in the middle. Then at TCP layer use ss -i for retransmission rates.
ping -c 100 -i 0.5 1.1.1.1 | tail -n 3
mtr -rwbc 50 1.1.1.1
# TCP 重传/丢包视角
ss -it | grep -E "retrans|rto|rtt"
# 网卡出口统计
ethtool -S eth0 | grep -iE "tx_error|tx_dropped|collisions"Stuck at transport: SYN dropped vs handshake timeout, triage with nc/ss
When ping works but a service does not connect, the problem is usually at the port layer. First confirm with ss -ltn whether the port is listening and whether it binds to 0.0.0.0 or only loopback; a surprising share of "port not reachable" cases are just the service bound to 127.0.0.1. Then bypass the firewall with tcping or nc for a raw TCP probe.
Dropped SYN at the half-open state usually points to firewalls or syncookies; connections that establish but reset frequently point to a full backlog (listen queue overflow), mirrored by a piling Recv-Q in ss -ltn and the kernel setting tcp_max_syn_backlog. Below is a round of triage.
ss -ltn | grep -E ":80 |:443 |:3306 "
ss -lnt | awk "! /127.0.0.1/ {print}" # 排除只回环的服务
nc -vz -w 3 10.0.0.8 3306
# 看 listen 队列是否溢出
ss -lt 'sport = :80' | grep -c SYN-RECV
cat /proc/sys/net/ipv4/tcp_max_syn_backlogDNS: three ways to read slow, failing, or poisoned resolution
Domain problems usually show as "browser occasionally fails to open". Read resolution latency straight from dig: a big gap between two query time values means the upstream resolver is flaky. Distinguish failures by code—NXDOMAIN means the name truly does not exist, SERVFAIL means upstream trouble or insufficient authority.
A huge chunk of DNS pain is the search domain suffix: with option ndots in effect, `curl good.com` may append a search suffix and trigger extra lookups, so what looks like slowness is actually doubled query count. Use +trace to walk the whole recursion chain and +short to grab the A record fast.
dig +short example.com
dig +trace example.com A
dig example.com | grep -E "Query time|flags:"
nslookup example.com 223.5.5.5
cat /etc/resolv.conf
# 统计每类解析耗时
for d in 223.5.5.5 8.8.8.8 114.114.114.114; do echo "-- $d"; dig +time=2 +tries=1 @$d example.com | grep "Query time"; doneMistake vs fix: do not dig a hole with iptables -F
When a server suddenly stops answering, the gut reaction is "flush the firewall". But iptables -F only clears rules in the default filter chains; if you rely on firewalld/nat or custom chains, it leaves a half-flushed state—INPUT emptied while FORWARD rules linger, or conversely your own traffic starts bleeding sideways.
The safest route is to know where rules come from: check systemctl status firewalld to see if firewalld owns them, or if you use ufw walk it with ufw status numbered. Back the chain rules to a file before touching anything, keep a second terminal open to confirm your session is not cut, then test the business port.
# 错误示范:无差别清空惹祸
# iptables -F # 会清空 filter 现有规则
# 修复对照:先备份再精确操作
iptables-save > /tmp/fw.$(date +%F).bak
# 只对指定链/端口放开,不动其它
iptables -I INPUT -p tcp --dport 443 -j ACCEPT
# 改完立刻验证
ss -lnt | grep :443
curl -sI https://example.com -o /dev/null -w "%{http_code}\n"Verify a full path: tcpdump a capture and read the handshake
Finish with tcpdump for a definitive answer: capture twenty packets and seeing the three-way handshake (SYN/SYN-ACK/ACK) proves the path and port are fine and the trouble is higher up; SYN with no reply means firewall or a non-listening peer; SYN→ACK but no follow-up data suggests a middlebox or MTU mismatch.
While capturing, watch for DF-marked packets—large segments silently dropped after fragmentation often show up as "small requests fine, bigger responses time out". After verifying, stop tcpdump promptly so it does not keep logging to the background forever.
sudo tcpdump -i eth0 -n host 10.0.0.8 and tcp port 443 -c 20
sudo tcpdump -i any -n 'tcp[tcpflags] & (tcp-syn) != 0 and host 10.0.0.8' -c 10
# 看 DF 分片
sudo tcpdump -i eth0 -n -e 'and (ip[6] & 0x40)' 2>/dev/null | head