Linux网络排查完整教程
核心概念
1. IP地址与子网
概念: - IP地址:网络中设备的唯一标识(如 10.10.10.47) - 子网掩码:划分网络范围(如 /24 = 255.255.255.0) - 10.10.10.0/24 表示:10.10.10.0 到 10.10.10.255 的256个地址 设计思路: - 同一子网内的设备可以直接通信(二层通信) - 跨子网通信需要通过网关(三层路由)
2. 路由(Routing)
概念: 路由决定数据包如何从源地址到达目标地址 类型: 1. 直连路由:同一网段内,直接通过二层(MAC)通信 2. 默认路由:不知道怎么走的流量,发给默认网关 3. 静态路由:手动配置的路由规则 4. 动态路由:通过路由协议自动学习(OSPF, BGP等) 设计思路: - 路由表按照"最长前缀匹配"原则查找 - 更具体的路由优先级更高 例如:10.10.10.0/24 > 10.10.0.0/16 > 0.0.0.0/0
3. 策略路由(Policy Routing)
概念: 传统路由只看目标IP,策略路由可以基于: - 源IP地址 - 目标IP地址 - 端口号 - 协议类型 - 数据包标记 设计思路: Linux使用多路由表(Routing Table)实现策略路由: - table 0 (local):本地地址 - table 253 (default):默认表 - table 254 (main):主路由表 - table 255 (local):本地回环 - 自定义表:50, 80, 100 等 查找顺序:ip rule 规定的优先级(priority)
4. ARP协议(Address Resolution Protocol)
概念: 将IP地址解析为MAC地址的协议 工作流程: 1. 主机A要访问10.10.10.47 2. 检查本地ARP缓存 3. 如果没有,广播ARP请求:"谁是10.10.10.47?" 4. 10.10.10.47回复:"我是,我的MAC是xx:xx:xx:xx:xx:xx" 5. 主机A缓存这个映射关系 设计思路: - ARP只在同一二层网络(VLAN/子网)内工作 - 跨网段通信时,ARP解析的是网关的MAC地址
5. DNS(Domain Name System)
概念: 将域名(example.com)解析为IP地址(93.184.216.34) 工作流程: 1. 应用查询 example.com 2. 检查本地缓存 3. 查询 /etc/hosts 4. 查询 /etc/resolv.conf 中配置的DNS服务器 5. DNS服务器返回IP地址 Linux DNS实现: - 传统方式:/etc/resolv.conf + glibc resolver - systemd-resolved:现代Linux发行版的DNS管理器 - 提供本地DNS缓存 - 支持DNSSEC、DNS over TLS - 监听127.0.0.53:53
6. 防火墙与Netfilter
概念: Linux内核的数据包过滤框架 iptables/nftables: 用户空间工具,配置Netfilter规则 表(Tables): - filter:过滤数据包(INPUT, OUTPUT, FORWARD) - nat:网络地址转换(PREROUTING, POSTROUTING) - mangle:修改数据包(标记、TTL等) - raw:连接跟踪前处理 链(Chains): - INPUT:进入本机的数据包 - OUTPUT:本机发出的数据包 - FORWARD:经过本机转发的数据包 设计思路: 数据包按顺序匹配规则,第一个匹配的规则决定动作(ACCEPT/DROP/REJECT)
网络层次模型
OSI七层模型与TCP/IP四层模型对照
OSI模型 TCP/IP模型 相关工具/协议 ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 7. 应用层 ┐ 6. 表示层 ├─→ 应用层 HTTP, DNS, SSH 5. 会话层 ┘ ping, nslookup 4. 传输层 ──→ 传输层 TCP, UDP netstat, ss 3. 网络层 ──→ 网络层 IP, ICMP ip route, traceroute 2. 数据链路层 ┐ Ethernet, ARP 1. 物理层 ├─→ 链路层 ip link, ethtool ┘ arp, arping
排查时的层次对应关系
问题现象 可能的层次 排查工具 ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 网线没插/灯不亮 物理层(L1) ethtool, ip link MAC地址学不到 数据链路层(L2) arp, arping, tcpdump Ping不通(同网段) 数据链路/网络层 ping, arp, ip route Ping不通(跨网段) 网络层(L3) ping, traceroute, ip route 端口不通 传输层(L4) nc, telnet, ss, netstat 域名解析失败 应用层(L7) nslookup, dig, resolvectl 网页打不开 应用层(L7) curl, wget, browser
命令工具详解
1. ping - ICMP回显测试
# 基本用法 ping 10.10.10.47 # 常用选项 ping -c 5 10.10.10.47 # 发送5个包后停止 ping -i 0.5 10.10.10.47 # 每0.5秒发一个包 ping -W 2 10.10.10.47 # 等待响应超时时间2秒 ping -s 1000 10.10.10.47 # 指定数据包大小1000字节 ping -I eth0 10.10.10.47 # 指定出接口 # 工作原理 1. 发送 ICMP Echo Request (type 8) 2. 目标主机回复 ICMP Echo Reply (type 0) 3. 计算往返时间(RTT) # 常见错误信息 Request timeout # 无响应(防火墙阻止/主机离线) Destination Host Unreachable # 路由不可达 Network is unreachable # 本地无路由 No route to host # ARP失败/二层不通 # 设计思路 - 用于测试三层(IP层)连通性 - 依赖ICMP协议,可能被防火墙过滤 - 不代表TCP/UDP端口是否开放
2. ip - 网络配置瑞士军刀
ip addr - 地址管理
# 查看所有网络接口 ip addr show ip a # 简写 # 查看特定接口 ip addr show ens34 # 添加IP地址 sudo ip addr add 192.168.1.100/24 dev eth0 # 删除IP地址 sudo ip addr del 192.168.1.100/24 dev eth0 # 输出解释 2: ens34: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP # UP: 接口已启用 # LOWER_UP: 物理链路正常 # mtu 1500: 最大传输单元 inet 10.10.10.47/24 brd 10.10.10.255 scope global ens34 # inet: IPv4地址 # /24: 子网掩码 # brd: 广播地址 # scope global: 全局地址(非临时) # 设计思路 - 替代老旧的 ifconfig 命令 - 支持多个IP地址绑定到同一接口 - 配置立即生效但不持久(重启失效)
ip link - 链路层管理
# 查看网络接口状态 ip link show # 启用/禁用接口 sudo ip link set eth0 up sudo ip link set eth0 down # 修改MTU sudo ip link set eth0 mtu 9000 # 修改MAC地址 sudo ip link set eth0 address 00:11:22:33:44:55 # 创建VLAN接口 sudo ip link add link eth0 name eth0.10 type vlan id 10 # 删除接口 sudo ip link delete eth0.10 # 状态标志说明 UP # 管理状态启用 LOWER_UP # 物理链路正常(网线已连接) NO-CARRIER # 网线未连接 DORMANT # 接口处于待机状态 # 设计思路 - 管理数据链路层(L2)配置 - 控制接口的物理和逻辑状态
ip route - 路由管理
# 查看路由表 ip route show ip route show table main # 查看main表 ip route show table all # 查看所有路由表 # 查看特定IP的路由 ip route get 8.8.8.8 ip route get 8.8.8.8 from 10.10.10.47 # 指定源IP # 添加路由 sudo ip route add 192.168.2.0/24 via 10.10.10.1 # 通过网关 sudo ip route add 192.168.3.0/24 dev eth0 # 通过接口 sudo ip route add default via 10.10.10.1 # 默认路由 # 删除路由 sudo ip route del 192.168.2.0/24 # 修改路由 sudo ip route change 192.168.2.0/24 via 10.10.10.2 # 路由条目解释 default via 10.10.10.1 dev ens34 proto dhcp metric 100 # default: 默认路由 (0.0.0.0/0) # via: 下一跳网关 # dev: 出接口 # proto dhcp: 路由来源(dhcp/kernel/static) # metric: 路由优先级(数字越小越优先) 10.10.10.0/24 dev ens34 proto kernel scope link src 10.10.10.47 # proto kernel: 内核自动生成(直连路由) # scope link: 链路范围(同一二层网络) # src: 源地址选择 # 刷新路由缓存 sudo ip route flush cache # 设计思路 - 路由决策基于"最长前缀匹配" - metric相同时,先添加的路由优先 - 直连路由(kernel)优先级高于网关路由
ip rule - 策略路由
# 查看路由规则 ip rule show ip rule list # 输出示例及解释 0: from all lookup local # 优先级0:所有流量先查local表(本地地址) 32766: from all lookup main # 优先级32766:查main表(普通路由) 32767: from all lookup default # 优先级32767:最后查default表 # 添加规则(基于源地址) sudo ip rule add from 192.168.1.0/24 table 100 priority 100 # 添加规则(基于目标地址) sudo ip rule add to 8.8.8.8 table 50 priority 50 # 添加规则(基于接口) sudo ip rule add iif eth0 table 80 priority 80 # 添加规则(基于标记) sudo ip rule add fwmark 1 table 100 # 删除规则 sudo ip rule del priority 100 sudo ip rule del from 192.168.1.0/24 table 100 # 查看自定义路由表内容 ip route show table 100 # /etc/iproute2/rt_tables 定义表名 # 格式:表号 表名 # 示例: # 100 vpn_traffic # 200 isp1 # 201 isp2 # 设计思路 - 实现复杂的路由策略(多出口、负载均衡) - 规则按priority从小到大依次匹配 - 匹配到第一条规则后,在对应表中查路由 - 常用场景: * 多WAN口策略路由 * VPN分流 * 基于应用的路由选择
ip neigh - ARP表管理
# 查看ARP缓存 ip neigh show ip n # 简写 # 输出示例 10.10.10.1 dev ens34 lladdr 00:0c:29:xx:xx:xx REACHABLE # lladdr: 链路层地址(MAC地址) # REACHABLE: 状态正常,可达 # STALE: 条目过期但未删除 # DELAY: 等待确认 # FAILED: 无法解析 # 刷新ARP缓存 sudo ip neigh flush all sudo ip neigh flush dev ens34 # 手动添加ARP条目 sudo ip neigh add 10.10.10.50 lladdr 00:11:22:33:44:55 dev eth0 # 删除ARP条目 sudo ip neigh del 10.10.10.50 dev eth0 # 设计思路 - ARP是二层协议,用于IP到MAC的映射 - 缓存有超时机制(通常几分钟) - FAILED状态通常表示主机不在线或网络问题
3. arp - ARP缓存查看(传统工具)
# 查看ARP表 arp -a # 显示所有条目(带主机名) arp -n # 显示所有条目(仅IP) arp -e # Linux默认格式 # 输出示例 ? (10.10.10.1) at 00:0c:29:xx:xx:xx [ether] on ens34 # 删除ARP条目 sudo arp -d 10.10.10.47 # 手动添加 sudo arp -s 10.10.10.50 00:11:22:33:44:55 # 设计思路 - 老旧但兼容性好 - 功能被 ip neigh 替代 - 某些系统可能未安装
4. arping - ARP层ping
# 安装(如果没有) sudo apt install arping # Debian/Ubuntu sudo yum install arping # CentOS/RHEL # 基本用法 sudo arping -I eth0 10.10.10.47 # 检测IP冲突 sudo arping -D -I eth0 10.10.10.47 -c 2 # -D: Duplicate address detection # 如果有响应,说明IP已被占用 # 指定源MAC sudo arping -I eth0 -s 10.10.10.100 10.10.10.47 # 工作原理 - 发送ARP请求,等待ARP响应 - 不依赖IP层,即使IP配置错误也能测试 - 可以测试二层连通性 # 应用场景 1. 测试二层连通性(绕过防火墙) 2. 检测IP冲突 3. 唤醒休眠主机 4. 验证MAC地址 # 设计思路 - 比ping更底层,测试数据链路层 - 不会被防火墙的ICMP规则阻止 - 只能在同一二层网络内工作
5. tcpdump - 数据包抓取分析
# 基本抓包 sudo tcpdump -i ens34 # 抓取特定主机 sudo tcpdump -i ens34 host 10.10.10.47 # 抓取ICMP(ping) sudo tcpdump -i ens34 icmp # 抓取特定端口 sudo tcpdump -i ens34 port 80 sudo tcpdump -i ens34 port 53 # DNS # 组合条件 sudo tcpdump -i ens34 'icmp and host 10.10.10.47' sudo tcpdump -i ens34 'tcp and port 80' # 显示详细信息 sudo tcpdump -i ens34 -nn -v # -nn: 不解析主机名和端口名 # -v: 详细模式 # -vv: 更详细 # -vvv: 最详细 # 显示数据包内容 sudo tcpdump -i ens34 -X # 十六进制+ASCII sudo tcpdump -i ens34 -A # 仅ASCII # 抓取所有接口 sudo tcpdump -i any icmp # 保存到文件 sudo tcpdump -i ens34 -w capture.pcap # 读取文件 tcpdump -r capture.pcap # 限制抓包数量 sudo tcpdump -i ens34 -c 100 # 抓100个包后停止 # 常用过滤表达式 sudo tcpdump -i ens34 'src 10.10.10.47' # 源IP sudo tcpdump -i ens34 'dst 10.10.10.47' # 目标IP sudo tcpdump -i ens34 'net 10.10.10.0/24' # 网段 sudo tcpdump -i ens34 'tcp[tcpflags] & tcp-syn != 0' # SYN包 sudo tcpdump -i ens34 'icmp[icmptype] = icmp-echo' # echo request # 排除某些流量 sudo tcpdump -i ens34 'not port 22' # 排除SSH # 输出解释 11:13:10.554422 IP 10.10.10.240 > 10.10.10.47: ICMP echo request, id 44750, seq 7, length 64 # 时间戳 协议 源IP > 目标IP: 包类型, 详细信息 # 设计思路 - 基于libpcap库,工业标准 - 可以看到网络中的所有数据包(混杂模式) - 强大的过滤语法(BPF - Berkeley Packet Filter) - 是排查网络问题的终极武器 # 应用场景 1. 确认数据包是否到达 2. 分析数据包内容 3. 诊断性能问题 4. 安全分析
6. netstat - 网络状态查看(传统)
# 查看所有连接 netstat -a # 查看TCP连接 netstat -t netstat -tan # 不解析名称 # 查看UDP连接 netstat -u netstat -uan # 查看监听端口 netstat -l netstat -tlnp # TCP监听端口,显示进程 # -t: TCP # -l: listening # -n: numeric(不解析) # -p: program(显示进程,需要root) # 查看路由表 netstat -r netstat -rn # 不解析主机名 # 查看网络接口统计 netstat -i # 查看连接统计 netstat -s # 输出示例(netstat -tlnp) Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program tcp 0 0 0.0.0.0:22 0.0.0.0:* LISTEN 1234/sshd tcp 0 0 127.0.0.1:3306 0.0.0.0:* LISTEN 5678/mysqld # 字段说明 Recv-Q: 接收队列中的字节数 Send-Q: 发送队列中的字节数 Local Address: 本地地址:端口 Foreign Address: 远程地址:端口 State: 连接状态(LISTEN/ESTABLISHED/TIME_WAIT等) # 设计思路 - 老旧但兼容性好 - 功能被 ss 命令替代(更快) - 仍然广泛使用
7. ss - Socket统计(现代替代品)
# 基本用法(比netstat快很多) ss -a # 所有socket ss -t # TCP ss -u # UDP ss -l # 监听状态 # 组合使用 ss -tlnp # TCP监听,显示进程 ss -tunap # TCP+UDP,所有状态,显示进程 # 查看特定端口 ss -tlnp | grep :80 ss -tlnp sport = :80 # 使用过滤器 # 查看连接到特定IP的socket ss dst 10.10.10.47 # 查看特定状态 ss state established ss state time-wait # 显示详细信息 ss -e # 扩展信息 ss -m # 内存信息 ss -i # TCP内部信息 # 输出示例 State Recv-Q Send-Q Local Address:Port Peer Address:Port Process LISTEN 0 128 0.0.0.0:22 0.0.0.0:* users:(("sshd",pid=1234)) ESTAB 0 0 10.10.10.47:22 10.10.10.240:52341 users:(("sshd",pid=5678)) # 过滤表达式 ss dst 10.10.10.0/24 # 目标网段 ss sport gt :1024 # 源端口大于1024 ss dport eq :80 # 目标端口等于80 ss '( dport = :80 or sport = :80 )' # 逻辑组合 # 设计思路 - 直接从内核获取信息,比netstat快 - 支持强大的过滤语法 - 现代Linux推荐使用
8. nslookup - DNS查询工具
# 基本查询 nslookup example.com # 指定DNS服务器 nslookup example.com 8.8.8.8 # 查询特定记录类型 nslookup -type=A example.com # IPv4地址 nslookup -type=AAAA example.com # IPv6地址 nslookup -type=MX example.com # 邮件服务器 nslookup -type=NS example.com # 域名服务器 nslookup -type=TXT example.com # 文本记录 # 反向解析(IP到域名) nslookup 93.184.216.34 # 交互模式 nslookup > server 8.8.8.8 > set type=MX > example.com > exit # 输出示例 Server: 8.8.8.8 Address: 8.8.8.8#53 Non-authoritative answer: Name: example.com Address: 93.184.216.34 # 设计思路 - 简单易用的DNS诊断工具 - 跨平台(Windows/Linux/Mac) - 适合快速测试DNS解析
9. dig - DNS详细查询工具
# 基本查询 dig example.com # 简洁输出(仅显示答案) dig example.com +short # 指定DNS服务器 dig @8.8.8.8 example.com # 查询特定记录 dig example.com A # IPv4 dig example.com AAAA # IPv6 dig example.com MX # 邮件服务器 dig example.com NS # 域名服务器 dig example.com TXT # TXT记录 dig example.com ANY # 所有记录 # 反向DNS查询 dig -x 93.184.216.34 # 追踪DNS解析路径 dig +trace example.com # 查询权威服务器 dig @ns1.example.com example.com # 不使用递归 dig +norecurse example.com # 显示查询统计 dig example.com +stats # 批量查询 dig example.com google.com baidu.com # 输出解释 ; <<>> DiG 9.16.1 <<>> example.com ;; QUESTION SECTION: ;example.com. IN A ;; ANSWER SECTION: example.com. 86400 IN A 93.184.216.34 ;; Query time: 23 msec ;; SERVER: 8.8.8.8#53(8.8.8.8) ;; WHEN: Sun Oct 12 12:00:00 UTC 2025 ;; MSG SIZE rcvd: 56 # 字段说明 86400: TTL(Time To Live)秒数 IN: Internet类 A: 记录类型 Query time: 查询耗时 # 设计思路 - 比nslookup功能更强大 - 输出详细,便于调试 - 支持DNSSEC验证 - Linux管理员首选DNS工具
10. resolvectl - systemd DNS管理
# 查看DNS状态 resolvectl status # 查看特定接口 resolvectl status ens34 # 查询域名 resolvectl query example.com # 查看统计信息 resolvectl statistics # 刷新DNS缓存 sudo resolvectl flush-caches # 为接口设置DNS sudo resolvectl dns ens34 8.8.8.8 114.114.114.114 # 设置默认路由接口 sudo resolvectl default-route ens34 yes # 重置接口DNS配置 sudo resolvectl revert ens34 # 输出示例 Global Protocols: -LLMNR -mDNS -DNSOverTLS DNSSEC=no/unsupported resolv.conf mode: stub Link 2 (ens34) Current Scopes: DNS Protocols: +DefaultRoute +LLMNR -mDNS -DNSOverTLS DNSSEC=no/unsupported DNS Servers: 8.8.8.8 114.114.114.114 # 字段说明 Protocols: 启用的DNS协议 resolv.conf mode: - stub: 使用127.0.0.53 - static: 使用真实DNS服务器 - foreign: 外部管理 Current Scopes: 当前接口处理的查询范围 DefaultRoute: 是否用于默认DNS查询 # 设计思路 - systemd-resolved的管理接口 - 提供每接口DNS配置 - 支持DNS缓存和DNSSEC - 替代传统的/etc/resolv.conf管理方式
11. traceroute - 路由跟踪
# 基本用法 traceroute example.com traceroute 8.8.8.8 # 使用ICMP而非UDP traceroute -I 8.8.8.8 # 使用TCP traceroute -T -p 80 example.com # 不解析主机名 traceroute -n 8.8.8.8 # 设置最大跳数 traceroute -m 15 example.com # 设置超时时间 traceroute -w 2 example.com # 2秒超时 # 输出示例 traceroute to example.com (93.184.216.34), 30 hops max, 60 byte packets 1 10.10.10.1 (10.10.10.1) 1.234 ms 1.123 ms 1.045 ms 2 192.168.1.1 (192.168.1.1) 5.678 ms 5.567 ms 5.456 ms 3 * * * 4 93.184.216.34 (93.184.216.34) 23.456 ms 23.345 ms 23.234 ms # 解释 每行代表一跳路由器 三个时间值是三次探测的RTT * * * 表示该路由器不响应或超时 # 工作原理 1. 发送TTL=1的数据包,第一跳路由器返回ICMP Time Exceeded 2. 发送TTL=2的数据包,第二跳路由器返回ICMP Time Exceeded 3. 依此类推,直到到达目标或达到最大跳数 # 设计思路 - 利用IP包的TTL机制 - 每经过一跳路由器,TTL减1 - TTL=0时,路由器丢弃包并返回ICMP错误 - 通过收集这些错误信息,可以还原完整路径 # 应用场景 1. 诊断网络延迟发生在哪一跳 2. 发现网络路径 3. 检测路由环路 4. 验证路由策略是否生效
12. nc (netcat) - 网络瑞士军刀
# 测试TCP端口连通性 nc -zv 10.10.10.47 22 nc -zv 10.10.10.47 80 # -z: 扫描模式,不发送数据 # -v: 详细输出 # 批量扫描端口 nc -zv 10.10.10.47 20-80 # 设置超时 nc -zv -w 3 10.10.10.47 22 # 3秒超时 # 监听端口(服务端) nc -l -p 8888 # 另一终端连接:nc 10.10.10.47 8888 # 传输文件 # 接收端: nc -l -p 8888 > received_file.txt # 发送端: nc 10.10.10.47 8888 < file.txt # 简单的HTTP请求 echo -e "GET / HTTP/1.0\r\n\r\n" | nc example.com 80 # UDP模式 nc -u 10.10.10.47 53 # 作为代理 nc -l -p 8888 -c 'nc target_host 80' # 扫描主机存活(配合nmap风格) nc -zv -w 1 10.10.10.1-254 22 2>&1 | grep succeeded # 设计思路 - 直接操作TCP/UDP socket - 不依赖上层协议,非常灵活 - 可以手动构造任何协议的数据包 - 常用于快速测试网络服务 # 应用场景 1. 测试端口是否开放(替代telnet) 2. 简单的文件传输 3. 端口转发 4. 调试网络服务 5. 简单的聊天工具
13. curl - HTTP客户端工具
# 基本请求 curl http://example.com # 只显示HTTP头 curl -I http://example.com curl --head http://example.com # 显示详细信息 curl -v http://example.com # -v: 显示请求和响应头 # 保存到文件 curl -o output.html http://example.com curl -O http://example.com/file.zip # 保持原文件名 # 跟随重定向 curl -L http://example.com # 设置超时 curl --connect-timeout 5 --max-time 10 http://example.com # connect-timeout: 连接超时 # max-time: 总超时时间 # POST请求 curl -X POST http://example.com/api curl -d "param1=value1¶m2=value2" http://example.com/api curl -H "Content-Type: application/json" -d '{"key":"value"}' http://api.example.com # 设置User-Agent curl -A "Mozilla/5.0" http://example.com # 添加自定义头 curl -H "Authorization: Bearer token123" http://api.example.com # 使用代理 curl -x http://proxy:8080 http://example.com # 测试DNS解析时间 curl -w "@-" -o /dev/null -s http://example.com <<'EOF' time_namelookup: %{time_namelookup}\n time_connect: %{time_connect}\n time_appconnect: %{time_appconnect}\n time_pretransfer: %{time_pretransfer}\n time_starttransfer: %{time_starttransfer}\n time_total: %{time_total}\n EOF # 测试HTTPS证书 curl -vI https://example.com # 忽略SSL证书验证(不推荐用于生产) curl -k https://example.com # 设计思路 - 支持多种协议(HTTP, HTTPS, FTP, SMTP等) - 强大的自定义能力 - 可编程脚本集成 - 网络API测试必备工具
14. telnet - 远程登录/端口测试
# 测试端口(虽然名为telnet,但常用于此) telnet 10.10.10.47 22 telnet 10.10.10.47 80 # 测试SMTP服务 telnet mail.example.com 25 # 进入后可以手动发送SMTP命令 # 测试HTTP服务 telnet example.com 80 # 连接后输入: GET / HTTP/1.0 Host: example.com # 按两次回车 # 退出telnet Ctrl + ] quit # 设计思路 - 原本用于远程终端登录(不安全,已被SSH替代) - 现在主要用于测试TCP端口连通性 - 可以手动与服务交互,调试协议 - 逐渐被nc替代,但仍然常用 # 应用场景 1. 快速测试端口是否开放 2. 调试文本协议(HTTP, SMTP, POP3等) 3. 检查服务响应
15. nmap - 网络扫描工具
# 安装 sudo apt install nmap # Debian/Ubuntu sudo yum install nmap # CentOS/RHEL # 扫描单个主机 nmap 10.10.10.47 # 扫描网段 nmap 10.10.10.0/24 nmap 10.10.10.1-254 # 快速扫描(只扫描最常用的100个端口) nmap -F 10.10.10.47 # 扫描特定端口 nmap -p 22,80,443 10.10.10.47 nmap -p 1-65535 10.10.10.47 # 全端口扫描 # Ping扫描(仅检测主机是否在线) nmap -sn 10.10.10.0/24 # 跳过Ping,直接扫描端口(假设主机在线) nmap -Pn 10.10.10.47 # 当防火墙阻止ICMP时很有用 # 服务版本探测 nmap -sV 10.10.10.47 # 操作系统探测 sudo nmap -O 10.10.10.47 # 激进扫描(OS检测、版本探测、脚本扫描、traceroute) sudo nmap -A 10.10.10.47 # TCP SYN扫描(隐蔽扫描,需要root) sudo nmap -sS 10.10.10.47 # TCP连接扫描(不需要root) nmap -sT 10.10.10.47 # UDP扫描 sudo nmap -sU 10.10.10.47 # 脚本扫描 nmap --script=vuln 10.10.10.47 # 漏洞扫描 nmap --script=default 10.10.10.47 # 默认脚本 # 输出到文件 nmap -oN scan.txt 10.10.10.47 # 普通格式 nmap -oX scan.xml 10.10.10.47 # XML格式 nmap -oG scan.grep 10.10.10.47 # Grep格式 # 扫描速度控制 nmap -T0 10.10.10.47 # 极慢(偏执模式) nmap -T3 10.10.10.47 # 默认 nmap -T5 10.10.10.47 # 极快(疯狂模式) # 输出示例 PORT STATE SERVICE 22/tcp open ssh 80/tcp open http 443/tcp open https 3306/tcp closed mysql # 状态说明 open: 端口开放,有服务监听 closed: 端口关闭,但可达(收到RST响应) filtered: 被防火墙过滤,无响应 open|filtered: 无法确定(UDP常见) # 设计思路 - 强大的网络发现和安全审计工具 - 支持多种扫描技术 - 可扩展的脚本引擎(NSE) - 业界标准的扫描工具 # 应用场景 1. 网络资产发现 2. 端口扫描 3. 服务识别 4. 安全审计 5. 网络清单管理
16. ethtool - 网卡诊断工具
# 查看网卡信息 ethtool ens34 # 输出示例 Settings for ens34: Supported ports: [ TP ] Supported link modes: 10baseT/Half 10baseT/Full 100baseT/Half 100baseT/Full 1000baseT/Full Speed: 1000Mb/s Duplex: Full Port: Twisted Pair Link detected: yes # 查看网卡统计信息 ethtool -S ens34 # 查看驱动信息 ethtool -i ens34 # 测试网卡(闪烁LED灯) sudo ethtool -p ens34 10 # 闪烁10秒 # 修改速度和双工模式 sudo ethtool -s ens34 speed 100 duplex full sudo ethtool -s ens34 autoneg on # 恢复自动协商 # 查看环形缓冲区大小 ethtool -g ens34 # 修改环形缓冲区 sudo ethtool -G ens34 rx 4096 tx 4096 # 查看网卡Offload功能 ethtool -k ens34 # 禁用TSO(TCP Segmentation Offload) sudo ethtool -K ens34 tso off # 唤醒局域网(WOL)配置 sudo ethtool -s ens34 wol g # 启用WOL # 设计思路 - 直接与网卡驱动交互 - 诊断物理层和数据链路层问题 - 优化网卡性能 # 应用场景 1. 检查网线是否连接(Link detected) 2. 确认速度和双工模式 3. 查看网卡错误统计 4. 性能调优
17. iptables - 防火墙管理
# 查看规则 sudo iptables -L # 简单列表 sudo iptables -L -n -v # 详细信息,不解析 sudo iptables -t nat -L -n -v # 查看NAT表 # 表(Tables) -t filter # 默认表,过滤数据包 -t nat # 网络地址转换 -t mangle # 修改数据包 -t raw # 连接跟踪前处理 # 链(Chains) INPUT # 进入本机的数据包 OUTPUT # 本机发出的数据包 FORWARD # 经过本机转发的数据包 # 添加规则(在链末尾) sudo iptables -A INPUT -p tcp --dport 22 -j ACCEPT # -A: Append(添加) # -p: protocol # --dport: 目标端口 # -j: jump(动作) # 插入规则(在链开头) sudo iptables -I INPUT -p tcp --dport 80 -j ACCEPT # -I: Insert # 在特定位置插入 sudo iptables -I INPUT 3 -p tcp --dport 443 -j ACCEPT # 删除规则 sudo iptables -D INPUT -p tcp --dport 22 -j ACCEPT # 或按行号删除 sudo iptables -D INPUT 3 # 清空规则 sudo iptables -F # 清空filter表所有链 sudo iptables -F INPUT # 清空INPUT链 sudo iptables -t nat -F # 清空NAT表 # 设置默认策略 sudo iptables -P INPUT DROP # 默认拒绝 sudo iptables -P INPUT ACCEPT # 默认允许 # 常用规则示例 # 允许SSH sudo iptables -A INPUT -p tcp --dport 22 -j ACCEPT # 允许HTTP/HTTPS sudo iptables -A INPUT -p tcp --dport 80 -j ACCEPT sudo iptables -A INPUT -p tcp --dport 443 -j ACCEPT # 允许ping sudo iptables -A INPUT -p icmp --icmp-type echo-request -j ACCEPT # 允许已建立的连接 sudo iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT # 允许本地回环 sudo iptables -A INPUT -i lo -j ACCEPT # 允许特定IP访问 sudo iptables -A INPUT -s 10.10.10.0/24 -j ACCEPT # 拒绝特定IP sudo iptables -A INPUT -s 192.168.1.100 -j DROP # 限速(防DDOS) sudo iptables -A INPUT -p tcp --dport 80 -m limit --limit 25/minute --limit-burst 100 -j ACCEPT # 端口转发 sudo iptables -t nat -A PREROUTING -p tcp --dport 80 -j REDIRECT --to-port 8080 # SNAT(源地址转换) sudo iptables -t nat -A POSTROUTING -o eth0 -j SNAT --to-source 1.2.3.4 # MASQUERADE(动态SNAT,用于动态IP) sudo iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE # 日志记录 sudo iptables -A INPUT -j LOG --log-prefix "iptables-dropped: " # 保存规则 sudo iptables-save > /etc/iptables/rules.v4 # 或 sudo netfilter-persistent save # 恢复规则 sudo iptables-restore < /etc/iptables/rules.v4 # 规则匹配条件 -s, --source # 源地址 -d, --destination # 目标地址 -i, --in-interface # 入接口 -o, --out-interface # 出接口 -p, --protocol # 协议(tcp/udp/icmp) --sport # 源端口 --dport # 目标端口 -m state --state # 连接状态 -m mac --mac-source # 源MAC地址 -m limit # 速率限制 -m recent # 最近连接跟踪 # 动作(Targets) ACCEPT # 接受 DROP # 丢弃(无响应) REJECT # 拒绝(返回错误) LOG # 记录日志 RETURN # 返回调用链 SNAT # 源地址转换 DNAT # 目标地址转换 MASQUERADE # 伪装(动态SNAT) # 设计思路 - 基于Netfilter框架 - 规则按顺序匹配,第一个匹配的规则决定动作 - 无状态(除非使用conntrack) - 强大但复杂,逐渐被nftables替代 # 应用场景 1. 主机防火墙 2. NAT/端口转发 3. 流量整形 4. 安全策略实施
18. systemctl - 系统服务管理
# 启动服务 sudo systemctl start systemd-resolved sudo systemctl start networking # 停止服务 sudo systemctl stop systemd-resolved # 重启服务 sudo systemctl restart systemd-resolved # 重新加载配置(不重启) sudo systemctl reload systemd-resolved # 查看服务状态 systemctl status systemd-resolved # 开机自启 sudo systemctl enable systemd-resolved # 禁用开机自启 sudo systemctl disable systemd-resolved # 完全禁用服务(无法启动) sudo systemctl mask systemd-resolved # 取消禁用 sudo systemctl unmask systemd-resolved # 查看所有服务 systemctl list-units --type=service # 查看失败的服务 systemctl --failed # 查看服务依赖 systemctl list-dependencies systemd-resolved # 查看日志 sudo journalctl -u systemd-resolved sudo journalctl -u systemd-resolved -f # 实时查看 sudo journalctl -u systemd-resolved --since "1 hour ago" # 重新加载systemd配置 sudo systemctl daemon-reload # 设计思路 - systemd是现代Linux的init系统 - 并行启动,提高启动速度 - 统一的服务管理接口 - 集成日志管理(journald)
19. route - 路由表管理(传统)
# 查看路由表 route -n # 输出示例 Kernel IP routing table Destination Gateway Genmask Flags Metric Ref Use Iface 0.0.0.0 10.10.10.1 0.0.0.0 UG 100 0 0 ens34 10.10.10.0 0.0.0.0 255.255.255.0 U 100 0 0 ens34 # Flags说明 U: Up(路由有效) G: Gateway(通过网关) H: Host(主机路由) D: Dynamic(动态路由) # 添加默认路由 sudo route add default gw 10.10.10.1 # 添加网络路由 sudo route add -net 192.168.1.0 netmask 255.255.255.0 gw 10.10.10.1 # 添加主机路由 sudo route add -host 192.168.1.100 gw 10.10.10.1 # 删除路由 sudo route del -net 192.168.1.0 netmask 255.255.255.0 sudo route del default gw 10.10.10.1 # 设计思路 - 老旧命令,被 ip route 替代 - 语法相对简单但功能有限 - 仍在某些旧系统中使用
20. ifconfig - 网络接口配置(传统)
# 查看所有接口 ifconfig # 查看特定接口 ifconfig ens34 # 启用接口 sudo ifconfig ens34 up # 禁用接口 sudo ifconfig ens34 down # 配置IP地址 sudo ifconfig ens34 10.10.10.50 netmask 255.255.255.0 # 添加别名IP sudo ifconfig ens34:0 10.10.10.51 netmask 255.255.255.0 # 修改MTU sudo ifconfig ens34 mtu 9000 # 修改MAC地址 sudo ifconfig ens34 hw ether 00:11:22:33:44:55 # 查看统计信息 ifconfig ens34 # 输出示例 ens34: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500 inet 10.10.10.47 netmask 255.255.255.0 broadcast 10.10.10.255 inet6 fe80::20c:29ff:fe8d:8f6b prefixlen 64 scopeid 0x20<link> ether 00:0c:29:8d:8f:6b txqueuelen 1000 (Ethernet) RX packets 123456 bytes 78901234 (78.9 MB) RX errors 0 dropped 0 overruns 0 frame 0 TX packets 98765 bytes 12345678 (12.3 MB) TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0 # 字段说明 UP: 接口已启用 RUNNING: 接口运行中 MULTICAST: 支持组播 RX/TX packets: 接收/发送的数据包数 errors: 错误包数 dropped: 丢弃的包数 # 设计思路 - 最经典的网络配置工具 - 被 ip 命令替代 - 仍广泛使用,兼容性好
排查思路与方法论
网络问题排查通用流程
第一步:确定问题范围 ├─ 是否只影响特定服务? ├─ 是否只影响特定主机? ├─ 是否间歇性出现? └─ 何时开始出现问题? 第二步:OSI模型自底向上排查 ├─ L1物理层:网线、网卡灯、链路状态 ├─ L2数据链路层:MAC地址、ARP、交换机 ├─ L3网络层:IP地址、路由、ping ├─ L4传输层:端口、TCP/UDP连接 └─ L7应用层:DNS、HTTP、具体服务 第三步:使用排除法 ├─ 简化网络拓扑 ├─ 逐步添加复杂性 └─ 找到引入问题的环节 第四步:对比法 ├─ 正常主机 vs 问题主机 ├─ 正常时间 vs 问题时间 └─ 找出差异 第五步:抓包验证 ├─ 确认数据包是否发出 ├─ 确认数据包是否到达 ├─ 确认响应是否返回 └─ 分析数据包内容
按症状分类的排查思路
1. Ping不通(同网段)
# 排查步骤 1. 检查本地网络配置 ip addr show ip route show 2. 检查目标主机是否在线 arping -I ens34 10.10.10.47 3. 检查ARP表 ip neigh show arp -n 4. 抓包分析 sudo tcpdump -i ens34 icmp and host 10.10.10.47 5. 检查防火墙 sudo iptables -L -n -v | grep ICMP # 可能原因 - 目标主机离线 - ARP解析失败(IP冲突、网卡故障) - 防火墙阻止ICMP - 网线/交换机故障 - VLAN隔离
2. Ping不通(跨网段)
# 排查步骤 1. 检查默认路由 ip route show | grep default 2. 测试网关连通性 ping 10.10.10.1 3. 跟踪路由路径 traceroute 8.8.8.8 4. 检查策略路由 ip rule show ip route show table all 5. 检查NAT配置 sudo iptables -t nat -L -n -v # 可能原因 - 默认路由缺失或错误 - 网关不可达 - 中间路由器故障 - 策略路由错误配置 - 防火墙阻止
3. DNS解析失败
# 排查步骤 1. 测试DNS服务器连通性 ping 8.8.8.8 nc -zv 8.8.8.8 53 2. 检查DNS配置 cat /etc/resolv.conf resolvectl status 3. 手动DNS查询 nslookup example.com 8.8.8.8 dig @8.8.8.8 example.com 4. 检查systemd-resolved状态 systemctl status systemd-resolved journalctl -u systemd-resolved 5. 测试是否DNS被劫持 ip route get 8.8.8.8 # 可能原因 - /etc/resolv.conf配置错误 - DNS服务器不可达 - 防火墙阻止53端口 - systemd-resolved配置问题 - 策略路由导致DNS流量走错路径
4. 端口不通
# 排查步骤 1. 确认服务是否运行 sudo ss -tlnp | grep :80 sudo netstat -tlnp | grep :80 2. 测试端口连通性 nc -zv 10.10.10.47 80 telnet 10.10.10.47 80 3. 检查防火墙规则 sudo iptables -L -n -v | grep 80 4. 检查服务监听地址 ss -tlnp | grep :80 # 确认是0.0.0.0还是127.0.0.1 5. 抓包验证 sudo tcpdump -i any port 80 # 可能原因 - 服务未运行 - 服务只监听127.0.0.1 - 防火墙阻止端口 - SELinux/AppArmor限制 - 网络ACL限制
5. 连接慢/超时
# 排查步骤 1. 检查网络延迟 ping -c 100 target_host mtr target_host # 持续traceroute 2. 检查DNS解析时间 time nslookup example.com 3. 检查连接队列 ss -s netstat -s | grep -i listen 4. 检查MTU问题 ping -M do -s 1472 target_host # 如果失败,逐步减小包大小 5. 检查网卡统计 ethtool -S ens34 | grep -i error ifconfig ens34 | grep -i error # 可能原因 - 网络拥塞 - MTU不匹配 - DNS解析慢 - 服务响应慢 - 网卡/驱动问题
排查工具选择矩阵
问题类型 首选工具 备选工具 ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 基础连通性 ping arping 二层问题 arping, arp ip neigh 路由问题 ip route, traceroute route 端口测试 nc, nmap telnet DNS问题 dig, nslookup resolvectl 服务状态 ss, systemctl netstat 数据包分析 tcpdump wireshark 性能问题 iperf3, mtr ping, traceroute 防火墙 iptables nft 配置查看 ip ifconfig, route
实战案例分析
案例1:本地网段主机不通
问题描述
Mac (10.10.10.240) 可以ping通10.10.10.252,但无法ping通10.10.10.47
排查过程
# 1. 基础检查 - 确认配置正常 ip addr show ip route show # 2. 抓包发现异常 sudo tcpdump -i ens34 icmp # 发现:10.0.0.252发送ICMP redirect # 3. 检查路由表 ip route show # 发现:基本路由看起来正常 # 4. 检查策略路由(关键发现) ip rule show # 发现:存在多个自定义路由表(50, 80, 100) ip route show table 100 # 发现:10.10.10.0/24 dev tunnel_rn scope link # 问题根源:本地网段被路由到tunnel接口
根本原因
策略路由配置错误,table 100将本地网段10.10.10.0/24路由到了tunnel_rn接口,导致本应直连的流量被劫持到VPN隧道
解决方案
# 删除错误路由 sudo ip route del 10.10.10.0/24 dev tunnel_rn table 100 # 刷新缓存 sudo ip route flush cache # 验证 ping -c 5 10.10.10.47
经验教训
- 策略路由优先级高于普通路由表 - ip rule决定查找顺序
- VPN/隧道配置要排除本地网段 - 避免劫持本地流量
- 抓包是定位问题的关键 - ICMP redirect暴露了路由异常
- 多路由表增加复杂性 - 需要全面检查所有表
案例2:DNS解析失败
问题描述
Ubuntu系统47无法ping通example.com,nslookup无响应
排查过程
# 1. 确认DNS配置 cat /etc/resolv.conf resolvectl status # 发现:DNS服务器配置正确(8.8.8.8, 114.114.114.114) # 2. 测试DNS服务器连通性 ping -c 3 8.8.8.8 # 成功!DNS服务器可达 # 3. 测试DNS端口 nc -zv 8.8.8.8 53 # 成功!端口开放 # 4. 检查DNS流量路由 ip route get 8.8.8.8 from 10.10.10.47 # 发现:路由正常,走ens34接口 # 5. 查看systemd-resolved日志(关键发现) sudo journalctl -u systemd-resolved | tail -20 # 发现错误:Got packet on unexpected (i.e. non-localhost) IP range, ignoring.
根本原因
systemd-resolved的安全机制拒绝处理来自非localhost(127.0.0.x)的DNS响应。这是因为: - systemd-resolved期望通过本地stub(127.0.0.53)处理DNS - 但由于某些配置或之前的tunnel问题,DNS响应的源地址检查失败 - resolved认为响应来自”意外”的IP范围,出于安全考虑拒绝处理
解决方案
# 方案:禁用systemd-resolved,使用传统DNS配置 sudo systemctl stop systemd-resolved sudo systemctl disable systemd-resolved # 删除stub链接 sudo rm /etc/resolv.conf # 创建真实的resolv.conf sudo bash -c 'cat > /etc/resolv.conf << EOF nameserver 8.8.8.8 nameserver 114.114.114.114 nameserver 1.1.1.1 EOF' # 防止被覆盖 sudo chattr +i /etc/resolv.conf # 验证 nslookup example.com ping -c 3 example.com
永久配置
# 1. 确保服务保持禁用 sudo systemctl mask systemd-resolved # 2. 配置netplan不使用DHCP的DNS sudo nano /etc/netplan/01-netcfg.yaml
network: version: 2 ethernets: ens34: dhcp4: true nameservers: addresses: [8.8.8.8, 114.114.114.114] dhcp4-overrides: use-dns: false # 关键:忽略DHCP提供的DNS
sudo netplan apply
经验教训
- systemd-resolved的安全机制可能过于严格 - 在某些场景下会误杀正常流量
- 传统DNS配置更简单可靠 - 对于简单场景,/etc/resolv.conf足够
- 日志是关键 - journalctl清楚地显示了问题根源
- Ubuntu的DNS管理变化 - 从传统方式到systemd-resolved的过渡带来了复杂性
案例3:策略路由导致的问题分析
场景重现
用户执行了命令:
sudo twnode policy add-cidr vpn_traffic 10.10.10.47/24
这个命令的效果:
# 创建了策略路由规则 ip rule show 100: from all lookup 100 # 在table 100中添加了路由 ip route show table 100 10.10.10.0/24 dev tunnel_rn scope link
问题分析
设计意图 vs 实际效果:
设计意图(错误): "让10.10.10.47走VPN" 实际效果: "让整个10.10.10.0/24网段的所有流量走VPN,包括: - 10.10.10.47自己的流量 - 其他主机访问10.10.10.47的流量 - 10.10.10.47访问同网段其他主机的流量"
为什么会这样?
CIDR表示法的误解
10.10.10.47/24 不是"让47走VPN" 而是"10.10.10.0到10.10.10.255这256个地址都走VPN" 正确的单主机表示: 10.10.10.47/32 # 仅这一个IP
策略路由的工作原理
当数据包的目标地址匹配10.10.10.0/24时: Step 1: ip rule匹配 "to 10.10.10.0/24 lookup 100" Step 2: 在table 100中查找路由 Step 3: 找到 "10.10.10.0/24 dev tunnel_rn" Step 4: 数据包被发往tunnel_rn接口 结果:本地直连流量被劫持到隧道
正确的VPN配置方式
场景1:让特定主机的出站流量走VPN
# 基于源地址的策略路由 sudo ip rule add from 10.10.10.47 table 100 priority 100 # table 100中只放默认路由到VPN sudo ip route add default dev tunnel_rn table 100 # 但要保留本地网段的直连路由 sudo ip route add 10.10.10.0/24 dev ens34 table 100
场景2:让访问特定远程网段的流量走VPN
# 基于目标地址的策略路由 sudo ip rule add to 192.168.100.0/24 table 100 priority 100 # table 100中放远程网段的路由 sudo ip route add 192.168.100.0/24 dev tunnel_rn table 100
场景3:VPN分流(国内直连,国外走VPN)
# 创建两个路由表 # table 100: VPN路由 # main: 直连路由 # 国内IP段直连(示例) sudo ip route add 114.114.114.0/24 via 10.10.10.1 dev ens34 # 默认走VPN sudo ip rule add from all table 100 priority 100 sudo ip route add default dev tunnel_rn table 100 # 但保留本地网段和国内重要IP段在main表中 sudo ip rule add to 10.10.10.0/24 table main priority 50 sudo ip rule add to 114.114.114.0/24 table main priority 51
调试策略路由的方法
# 1. 查看完整的策略路由配置 ip rule show for table in $(ip rule show | grep -oP 'lookup \K\w+' | sort -u | grep -v '^main$\|^default$\|^local' | sort -u); do echo "=== Table: $table ===" ip route show table $table done # 2. 测试特定数据包的路由选择 ip route get 8.8.8.8 from 10.10.10.47 ip route get 10.10.10.252 from 10.10.10.47 # 3. 使用tcpdump验证数据包走向 # 终端1: sudo tcpdump -i ens34 icmp # 终端2: sudo tcpdump -i tunnel_rn icmp # 终端3: ping 10.10.10.252 # 观察哪个接口能看到ICMP包 # 4. 临时禁用所有策略路由测试 # 记录当前规则 ip rule show > /tmp/ip_rules_backup.txt # 删除自定义规则(保留0, 32766, 32767) for prio in $(ip rule show | grep -v -E '^(0|32766|32767):' | cut -d: -f1); do sudo ip rule del priority $prio done # 测试问题是否解决 ping 10.10.10.47 # 恢复规则(如果需要) # 从备份文件手动重建
高级概念与技巧
1. 路由决策流程
完整的数据包路由决策过程: ┌─────────────────────────────────────────┐ │ 应用程序发送数据包 │ └──────────────┬──────────────────────────┘ │ ▼ ┌─────────────────────────────────────────┐ │ Step 1: 确定源地址(如果未指定) │ │ - 查询路由表,找到出接口 │ │ - 使用出接口的主IP作为源地址 │ └──────────────┬──────────────────────────┘ │ ▼ ┌─────────────────────────────────────────┐ │ Step 2: 策略路由规则匹配 (ip rule) │ │ - 按priority从小到大检查 │ │ - 匹配条件:src/dst/iif/oif/fwmark等 │ │ - 确定使用哪个路由表 │ └──────────────┬──────────────────────────┘ │ ▼ ┌─────────────────────────────────────────┐ │ Step 3: 在指定的路由表中查找路由 │ │ - 最长前缀匹配 │ │ - 具体路由优先于默认路由 │ │ - 找到下一跳(nexthop)或出接口 │ └──────────────┬──────────────────────────┘ │ ▼ ┌─────────────────────────────────────────┐ │ Step 4: ARP解析(如果是直连网络) │ │ - 查询ARP缓存 │ │ - 如果没有,发送ARP请求 │ │ - 获取目标MAC地址 │ └──────────────┬──────────────────────────┘ │ ▼ ┌─────────────────────────────────────────┐ │ Step 5: 防火墙规则检查 (iptables) │ │ - OUTPUT链(本机发出) │ │ - POSTROUTING链(NAT) │ └──────────────┬──────────────────────────┘ │ ▼ ┌─────────────────────────────────────────┐ │ Step 6: 从网卡发送数据包 │ └─────────────────────────────────────────┘
2. MTU与MSS的关系
概念: MTU (Maximum Transmission Unit): 最大传输单元 - 数据链路层能传输的最大帧大小 - 以太网默认:1500字节 MSS (Maximum Segment Size): 最大分段大小 - TCP层单个数据段的最大大小 - MSS = MTU - IP头(20字节) - TCP头(20字节) - 以太网默认:1460字节 问题: 当路径中某个网络的MTU小于发送端时: - ICMP报文 "Fragmentation needed but DF set" - 数据包被丢弃 - 连接变慢或失败 测试MTU: # 发送不分片的大包 ping -M do -s 1472 target_host # 1472 = 1500 - 20(IP头) - 8(ICMP头) # 如果失败,逐步减小 ping -M do -s 1400 target_host 修改MTU: sudo ip link set ens34 mtu 1400 # 对于VPN/隧道,通常需要减小MTU # 因为隧道封装会增加额外的头部
3. TCP连接状态详解
TCP状态机(netstat/ss中看到的状态): LISTEN # 服务端等待连接 SYN_SENT # 客户端发送SYN后等待响应 SYN_RECEIVED # 服务端收到SYN,发送SYN-ACK ESTABLISHED # 连接建立,数据传输中 FIN_WAIT1 # 主动关闭方发送FIN FIN_WAIT2 # 主动关闭方收到ACK CLOSE_WAIT # 被动关闭方收到FIN CLOSING # 同时关闭 LAST_ACK # 被动关闭方发送FIN后等待ACK TIME_WAIT # 主动关闭方等待2MSL 三次握手: Client Server │ │ ├───── SYN ────→│ (SYN_SENT) │ │ (SYN_RECEIVED) │←─── SYN-ACK ──┤ │ │ ├───── ACK ────→│ │ │ (ESTABLISHED) 四次挥手: Client Server │ │ ├───── FIN ────→│ (FIN_WAIT1) │ │ (CLOSE_WAIT) │←──── ACK ─────┤ (FIN_WAIT2) │ │ │←──── FIN ─────┤ (LAST_ACK) │ │ ├───── ACK ────→│ (TIME_WAIT) │ │ (CLOSED) TIME_WAIT的作用: 1. 确保被动方收到最后的ACK 2. 避免旧连接的数据包干扰新连接 3. 持续时间:2MSL(通常60秒或120秒) 查看连接状态统计: ss -s netstat -s
4. 网络性能调优
# 1. 查看网卡队列长度 ethtool -g ens34 # 增大队列(减少丢包) sudo ethtool -G ens34 rx 4096 tx 4096 # 2. 启用/禁用网卡offload功能 ethtool -k ens34 # TSO (TCP Segmentation Offload) sudo ethtool -K ens34 tso on # GRO (Generic Receive Offload) sudo ethtool -K ens34 gro on # 3. 调整TCP参数 # 查看当前设置 sysctl net.ipv4.tcp_congestion_control sysctl net.core.rmem_max sysctl net.core.wmem_max # TCP拥塞控制算法 sudo sysctl -w net.ipv4.tcp_congestion_control=bbr # 增大TCP缓冲区 sudo sysctl -w net.core.rmem_max=134217728 sudo sysctl -w net.core.wmem_max=134217728 # TCP窗口缩放 sudo sysctl -w net.ipv4.tcp_window_scaling=1 # 快速回收TIME_WAIT连接(谨慎使用) sudo sysctl -w net.ipv4.tcp_tw_reuse=1 # 4. 调整连接跟踪表大小 # 查看当前大小 sysctl net.netfilter.nf_conntrack_max # 增大(高并发服务器) sudo sysctl -w net.netfilter.nf_conntrack_max=1000000 # 5. 永久保存 sudo nano /etc/sysctl.conf # 添加配置后: sudo sysctl -p
5. 网络抓包技巧
# 1. 只抓包头(减小文件大小) sudo tcpdump -i ens34 -s 96 -w capture.pcap # 2. 循环抓包(自动切换文件) sudo tcpdump -i ens34 -w capture.pcap -C 100 -W 5 # -C 100: 每个文件100MB # -W 5: 最多5个文件,循环覆盖 # 3. 按时间切分 sudo tcpdump -i ens34 -w capture-%Y%m%d-%H%M%S.pcap -G 3600 # 每小时一个文件 # 4. 只抓关键信息 # SYN包(TCP连接建立) sudo tcpdump -i ens34 'tcp[tcpflags] & tcp-syn != 0' # RST包(连接重置) sudo tcpdump -i ens34 'tcp[tcpflags] & tcp-rst != 0' # HTTP请求 sudo tcpdump -i ens34 -A 'tcp port 80 and (tcp[((tcp[12:1] & 0xf0) >> 2):4] = 0x47455420)' # 0x47455420 = "GET " # 5. 过滤特定应用 # 根据进程ID过滤(需要eBPF支持) # 使用ss获取进程的连接 ss -tnp | grep nginx # 然后根据IP:PORT组合在tcpdump中过滤 # 6. 分析大文件 # 只看统计信息 tcpdump -r large.pcap -qn | wc -l # 提取特定流 tcpdump -r large.pcap -w filtered.pcap 'host 10.10.10.47' # 7. 彩色输出(便于阅读) sudo tcpdump -i ens34 --color # 8. 保存并实时查看 sudo tcpdump -i ens34 -w capture.pcap -U # 另一终端: tcpdump -r capture.pcap -l | grep PATTERN
6. 防火墙高级应用
# 1. 连接限速(防DDoS) # 限制SSH连接频率 sudo iptables -A INPUT -p tcp --dport 22 -m state --state NEW \ -m recent --set --name SSH sudo iptables -A INPUT -p tcp --dport 22 -m state --state NEW \ -m recent --update --seconds 60 --hitcount 4 --name SSH -j DROP # 60秒内超过4次连接则拒绝 # 2. 端口敲门(Port Knocking) # 先敲3个特定端口,SSH才开放 sudo iptables -A INPUT -p tcp --dport 1234 -m recent --set --name KNOCK1 sudo iptables -A INPUT -p tcp --dport 2345 -m recent --set --name KNOCK2 sudo iptables -A INPUT -p tcp --dport 3456 -m recent --set --name KNOCK3 sudo iptables -A INPUT -p tcp --dport 22 -m recent --rcheck --name KNOCK3 \ -m recent --rcheck --name KNOCK2 -m recent --rcheck --name KNOCK1 -j ACCEPT # 3. 基于地理位置过滤(需要geoip模块) sudo apt install xtables-addons-common # 只允许中国IP访问 sudo iptables -A INPUT -m geoip --src-cc CN -j ACCEPT sudo iptables -A INPUT -j DROP # 4. 防止端口扫描 # 检测NMAP的SYN扫描 sudo iptables -A INPUT -p tcp --tcp-flags ALL NONE -j DROP sudo iptables -A INPUT -p tcp --tcp-flags ALL ALL -j DROP sudo iptables -A INPUT -p tcp --tcp-flags ALL FIN,URG,PSH -j DROP sudo iptables -A INPUT -p tcp --tcp-flags SYN,RST SYN,RST -j DROP # 5. 动态黑名单 # 自动封禁扫描器 sudo iptables -A INPUT -m recent --name portscan --update --seconds 3600 -j DROP sudo iptables -A INPUT -p tcp -m multiport --dports 23,21,110 \ -m recent --name portscan --set -j DROP # 6. 应用层过滤(L7-filter,需要额外模块) # 阻止BT流量 sudo iptables -A FORWARD -m layer7 --l7proto bittorrent -j DROP # 7. 连接跟踪优化 # 对于高并发服务器,禁用某些服务的连接跟踪 sudo iptables -t raw -A PREROUTING -p tcp --dport 80 -j NOTRACK sudo iptables -t raw -A OUTPUT -p tcp --sport 80 -j NOTRACK
常用配置文件详解
1. /etc/resolv.conf - DNS配置
# 传统DNS配置文件 cat /etc/resolv.conf # 格式: nameserver 8.8.8.8 # DNS服务器,最多3个 nameserver 114.114.114.114 search example.com # 域名搜索后缀 domain example.com # 本地域名 options timeout:2 # 查询超时(秒) options attempts:3 # 重试次数 options rotate # 轮询DNS服务器 options single-request # 避免并发查询问题 # 注意事项: # - Ubuntu使用systemd-resolved时,这个文件是符号链接 # - 动态获取IP时,可能被DHCP覆盖 # - 可以用chattr +i锁定文件
2. /etc/hosts - 本地主机名解析
# 本地DNS,优先于DNS服务器查询 cat /etc/hosts # 格式: 127.0.0.1 localhost 127.0.1.1 hostname 10.10.10.47 server1.example.com server1 10.10.10.252 server2.example.com server2 # IPv6 ::1 localhost ip6-localhost ip6-loopback # 应用场景: # 1. 本地开发环境 # 2. 绕过DNS(测试、屏蔽) # 3. 加速常访问域名 # 4. 临时名称解析 # 测试: ping server1 # 会解析为10.10.10.47
3. etc/sysconfig/network-scripts - CentOS网络配置
# CentOS/RHEL的网络配置目录 ls /etc/sysconfig/network-scripts/ # 接口配置:ifcfg-ens34 cat /etc/sysconfig/network-scripts/ifcfg-ens34
TYPE=Ethernet BOOTPROTO=static # static/dhcp/none DEVICE=ens34 ONBOOT=yes # 开机启动 IPADDR=10.10.10.47 NETMASK=255.255.255.0 GATEWAY=10.10.10.1 DNS1=8.8.8.8 DNS2=114.114.114.114 PEERDNS=no # 是否接受DHCP的DNS IPV6INIT=no # 禁用IPv6
# 路由配置:route-ens34 cat /etc/sysconfig/network-scripts/route-ens34
192.168.1.0/24 via 10.10.10.1 dev ens34 172.16.0.0/16 via 10.10.10.1 dev ens34
# 策略路由:rule-ens34 cat /etc/sysconfig/network-scripts/rule-ens34
from 10.10.10.47 table 100 to 192.168.1.0/24 table 200
# 应用配置 sudo systemctl restart network # 或 sudo nmcli device reapply ens34
4. etc/netplan - Ubuntu网络配置
# Ubuntu 18.04+使用netplan ls /etc/netplan/ # 配置文件:01-netcfg.yaml sudo nano /etc/netplan/01-netcfg.yaml
network: version: 2 renderer: networkd # 或 NetworkManager ethernets: ens34: dhcp4: false addresses: - 10.10.10.47/24 gateway4: 10.10.10.1 nameservers: addresses: - 8.8.8.8 - 114.114.114.114 search: - example.com routes: - to: 192.168.1.0/24 via: 10.10.10.1 metric: 100 routing-policy: - from: 10.10.10.47 table: 100
# 高级配置示例
network: version: 2 ethernets: ens34: dhcp4: true dhcp4-overrides: use-dns: false # 不使用DHCP的DNS use-routes: false # 不使用DHCP的路由 nameservers: addresses: [8.8.8.8, 1.1.1.1] routes: - to: default via: 10.10.10.1 metric: 100 - to: 192.168.1.0/24 via: 10.10.10.1 on-link: true # 直连路由
# 应用配置 sudo netplan generate # 生成配置 sudo netplan apply # 应用配置 sudo netplan --debug apply # 调试模式 # 测试配置(不实际应用) sudo netplan try
5. /etc/iproute2/rt_tables - 路由表定义
# 定义路由表名称和编号 cat /etc/iproute2/rt_tables
# # reserved values # 255 local 254 main 253 default 0 unspec # # local # #1 inr.ruhep # 自定义表 100 vpn 200 isp1 201 isp2
# 使用 ip route show table vpn ip route add default via 192.168.1.1 table vpn
完整排查脚本
综合网络诊断脚本
#!/bin/bash # network-diagnosis.sh - 综合网络诊断脚本 echo "==========================================" echo " Linux Network Diagnosis Script" echo "==========================================" echo "" # 检查是否为root if [ "$EUID" -ne 0 ]; then echo "Warning: Some commands require root privileges" SUDO="sudo" else SUDO="" fi # 1. 基本网络配置 echo "=== 1. Network Interfaces ===" ip addr show echo "" echo "=== 2. Routing Table ===" ip route show echo "" echo "=== 3. Default Gateway ===" ip route | grep default echo "" # 4. DNS配置 echo "=== 4. DNS Configuration ===" cat /etc/resolv.conf echo "" # 5. 连接状态 echo "=== 5. Active Connections ===" ss -tuln | head -20 echo "" # 6. 监听端口 echo "=== 6. Listening Ports ===" $SUDO ss -tlnp echo "" # 7. ARP表 echo "=== 7. ARP Table ===" ip neigh show echo "" # 8. 防火墙规则 echo "=== 8. Firewall Rules ===" $SUDO iptables -L -n -v | head -30 echo "" # 9. 策略路由 echo "=== 9. Policy Routing Rules ===" ip rule show echo "" # 10. 自定义路由表 echo "=== 10. Custom Routing Tables ===" for table in $(ip rule show | grep -oP 'lookup \K\w+'); do echo "--- Table: $table ---" ip route show table $table done echo "" # 11. 连接测试 echo "=== 11. Connectivity Tests ===" TARGETS=("8.8.8.8" "1.1.1.1" "baidu.com") for target in "${TARGETS[@]}"; do echo -n "Ping $target: " if ping -c 1 -W 2 $target &>/dev/null; then echo "OK" else echo "FAILED" fi done echo "" # 12. DNS测试 echo "=== 12. DNS Resolution Test ===" TEST_DOMAINS=("google.com" "baidu.com" "github.com") for domain in "${TEST_DOMAINS[@]}"; do echo -n "Resolve $domain: " if nslookup $domain &>/dev/null; then echo "OK" else echo "FAILED" fi done echo "" # 13. 网卡统计 echo "=== 13. Network Interface Statistics ===" for iface in $(ip -o link show | awk -F': ' '{print $2}' | grep -v lo); do echo "--- $iface ---" ethtool -S $iface 2>/dev/null | grep -E "rx_errors|tx_errors|rx_dropped|tx_dropped" || echo "ethtool not available" done echo "" # 14. systemd-resolved状态(如果存在) if systemctl is-active systemd-resolved &>/dev/null; then echo "=== 14. systemd-resolved Status ===" resolvectl status 2>/dev/null || systemd-resolve --status 2>/dev/null echo "" fi # 15. 路由跟踪测试 echo "=== 15. Route Tracing ===" echo "Trace to 8.8.8.8:" traceroute -m 5 -w 2 8.8.8.8 2>/dev/null || echo "traceroute not installed" echo "" # 16. 常见服务端口测试 echo "=== 16. Common Port Tests ===" PORTS=("22:SSH" "80:HTTP" "443:HTTPS" "53:DNS") for port_info in "${PORTS[@]}"; do IFS=':' read -r port service <<< "$port_info" echo -n "$service (port $port): " if $SUDO ss -tln | grep -q ":$port "; then echo "Listening" else echo "Not listening" fi done echo "" # 17. 系统网络参数 echo "=== 17. Key Network Parameters ===" echo "IP forwarding: $(cat /proc/sys/net/ipv4/ip_forward)" echo "ICMP echo ignore: $(cat /proc/sys/net/ipv4/icmp_echo_ignore_all)" echo "TCP congestion control: $(sysctl -n net.ipv4.tcp_congestion_control 2>/dev/null || echo 'N/A')" echo "" # 18. 网络性能指标 echo "=== 18. Network Statistics Summary ===" ss -s echo "" # 19. 最近的网络日志 echo "=== 19. Recent Network-Related Logs ===" $SUDO journalctl -u systemd-networkd -u NetworkManager -u systemd-resolved --since "10 minutes ago" --no-pager | tail -20 2>/dev/null || echo "journalctl not available or no recent logs" echo "" echo "==========================================" echo " Diagnosis Complete" echo "==========================================" echo "" echo "Recommendations:" echo "1. If connectivity issues exist, check:" echo " - Physical connection (ethtool <interface>)" echo " - IP configuration (ip addr)" echo " - Routing (ip route, ip rule)" echo " - Firewall (iptables -L)" echo "" echo "2. For DNS issues:" echo " - Check /etc/resolv.conf" echo " - Test with: dig @8.8.8.8 google.com" echo " - Check systemd-resolved logs" echo "" echo "3. For performance issues:" echo " - Use: iperf3, mtr, tcpdump" echo " - Check network statistics (ethtool -S)" echo "" # 17. 系统网络参数 echo "=== 17. Key Network Parameters ===" echo "IP forwarding: $(cat /proc/sys/net/ipv4/ip_forward)" echo "ICMP echo ignore: $(cat /proc/sys/net/ipv4/icmp_echo_ignore_all)" echo "TCP congestion control: $(sysctl -n net.ipv4.tcp_congestion_control 2>/dev/null || echo 'N/A')" echo "" # 18. 网络性能指标 echo "=== 18. Network Statistics Summary ===" ss -s echo "" # 19. 最近的网络日志 echo "=== 19. Recent Network-Related Logs ===" $SUDO journalctl -u systemd-networkd -u NetworkManager -u systemd-resolved --since "10 minutes ago" --no-pager | tail -20 2>/dev/null || echo "journalctl not available or no recent logs" echo "" echo "==========================================" echo " Diagnosis Complete" echo "==========================================" echo "" echo "Recommendations:" echo "1. If connectivity issues exist, check:" echo " - Physical connection (ethtool <interface>)" echo " - IP configuration (ip addr)" echo " - Routing (ip route, ip rule)" echo " - Firewall (iptables -L)" echo "" echo "2. For DNS issues:" echo " - Check /etc/resolv.conf" echo " - Test with: dig @8.8.8.8 google.com" echo " - Check systemd-resolved logs" echo "" echo "3. For performance issues:" echo " - Use: iperf3, mtr, tcpdump" echo " - Check network statistics (ethtool -S)" echo ""
快速故障排查脚本
#!/bin/bash # quick-network-check.sh - 快速网络检查 TARGET="${1:-8.8.8.8}" echo "Quick Network Check - Target: $TARGET" echo "=======================================" # Step 1: 本地配置 echo "[1] Local Configuration" MY_IP=$(ip -4 addr show | grep -oP '(?<=inet\s)\d+(\.\d+){3}' | grep -v 127.0.0.1 | head -1) GATEWAY=$(ip route | grep default | awk '{print $3}' | head -1) echo " My IP: $MY_IP" echo " Gateway: $GATEWAY" # Step 2: 网关连通性 echo "" echo "[2] Gateway Reachability" if ping -c 1 -W 2 $GATEWAY &>/dev/null; then echo " ✓ Gateway is reachable" else echo " ✗ Gateway is NOT reachable" echo " Suggestion: Check physical connection and ARP table" exit 1 fi # Step 3: DNS配置 echo "" echo "[3] DNS Configuration" DNS=$(grep nameserver /etc/resolv.conf | head -1 | awk '{print $2}') echo " Primary DNS: $DNS" # Step 4: DNS服务器连通性 echo "" echo "[4] DNS Server Reachability" if ping -c 1 -W 2 $DNS &>/dev/null; then echo " ✓ DNS server is reachable" else echo " ✗ DNS server is NOT reachable" fi # Step 5: 外网连通性 echo "" echo "[5] Internet Connectivity" if ping -c 1 -W 2 $TARGET &>/dev/null; then echo " ✓ Internet is reachable" else echo " ✗ Internet is NOT reachable" echo " Troubleshooting:" echo " - Check routing: ip route get $TARGET" echo " - Check firewall: sudo iptables -L -n" echo " - Trace route: traceroute $TARGET" exit 1 fi # Step 6: DNS解析 echo "" echo "[6] DNS Resolution" if nslookup google.com &>/dev/null; then echo " ✓ DNS resolution works" else echo " ✗ DNS resolution FAILED" echo " Suggestion: Check /etc/resolv.conf and systemd-resolved" exit 1 fi # Step 7: HTTP测试 echo "" echo "[7] HTTP Connectivity" if curl -s --connect-timeout 3 http://www.google.com > /dev/null 2>&1; then echo " ✓ HTTP works" else echo " ✗ HTTP failed" echo " Suggestion: Check proxy settings and firewall" fi echo "" echo "=======================================" echo "All basic checks passed! ✓"
使用方法
# 1. 保存脚本 sudo nano /usr/local/bin/network-diagnosis.sh sudo chmod +x /usr/local/bin/network-diagnosis.sh # 2. 运行诊断 sudo network-diagnosis.sh # 3. 保存输出到文件 sudo network-diagnosis.sh > /tmp/network-report.txt # 4. 快速检查特定目标 ./quick-network-check.sh 10.10.10.47
性能测试工具
iperf3 - 网络带宽测试
# 安装 sudo apt install iperf3 # Debian/Ubuntu sudo yum install iperf3 # CentOS/RHEL # 服务器端 iperf3 -s # 默认监听5201端口 # 客户端测试 iperf3 -c server_ip # TCP测试(默认) iperf3 -c server_ip -t 30 # 测试30秒 iperf3 -c server_ip -P 4 # 4个并行连接 iperf3 -c server_ip -R # 反向测试(下载) # UDP测试 iperf3 -c server_ip -u -b 100M # 100Mbps带宽 iperf3 -c server_ip -u -b 0 # 最大带宽 # 输出详细信息 iperf3 -c server_ip -V -J # JSON格式输出 # 测试特定端口 iperf3 -s -p 8080 # 服务器 iperf3 -c server_ip -p 8080 # 客户端 # 输出示例 Connecting to host 10.10.10.47, port 5201 [ 5] local 10.10.10.240 port 54321 connected to 10.10.10.47 port 5201 [ ID] Interval Transfer Bitrate Retr [ 5] 0.00-10.00 sec 1.10 GBytes 941 Mbits/sec 0 sender [ 5] 0.00-10.00 sec 1.10 GBytes 940 Mbits/sec receiver
mtr - 动态路由跟踪
# 安装 sudo apt install mtr sudo yum install mtr # 基本使用 mtr google.com # 报告模式(发送100个包后退出) mtr -r -c 100 google.com # 不解析主机名 mtr -n 8.8.8.8 # 同时使用TCP和ICMP mtr -u 8.8.8.8 # UDP mtr -T 8.8.8.8 # TCP # 输出示例 My traceroute [v0.93] hostname (10.10.10.240) 2025-10-12T12:00:00+0000 Keys: Help Display mode Restart statistics Order of fields quit Packets Pings Host Loss% Snt Last Avg Best Wrst StDev 1. 10.10.10.1 0.0% 10 1.2 1.1 1.0 1.3 0.1 2. 192.168.1.1 0.0% 10 5.6 5.5 5.2 6.1 0.3 3. 202.97.33.1 0.0% 10 12.3 12.1 11.8 12.9 0.4 4. ??? 100.0 10 0.0 0.0 0.0 0.0 0.0 # 字段说明 Loss%: 丢包率 Snt: 发送的数据包数量 Last: 最后一次的延迟 Avg: 平均延迟 Best: 最小延迟 Wrst: 最大延迟 StDev: 标准差
故障场景速查表
症状 | 可能原因 | 排查命令 | 解决方法 |
---|---|---|---|
网线插上灯不亮 | 物理层故障 | ethtool eth0==ip link show | 检查网线、交换机端口 |
ARP解析失败 | 二层不通 | arping -I eth0 10.10.10.47==ip neigh show | 检查VLAN、交换机配置 |
Ping不通同网段 | 防火墙/路由问题 | iptables -L -n==ip route show | 检查防火墙、策略路由 |
Ping不通外网 | 网关/路由问题 | ip route==traceroute 8.8.8.8 | 检查默认路由、NAT |
DNS解析失败 | DNS配置错误 | cat /etc/resolv.conf==dig @8.8.8.8 google.com | 修复DNS配置 |
端口不通 | 服务/防火墙问题 | ss -tlnp==nc -zv host port | 启动服务、开放端口 |
连接慢 | 网络拥塞/MTU问题 | mtr host==ping -M do -s 1472 host | 调整MTU、检查链路 |
TIME_WAIT过多 | 连接频繁关闭 | ss -s==sysctl net.ipv4.tcp_tw_reuse | 调整TCP参数 |
丢包严重 | 网卡/驱动问题 | ethtool -S eth0==dmesg ⎹ grep eth | 更新驱动、调整队列 |
总结
核心思维模式
1. 分层思考 ├─ 物理层(网线、灯) ├─ 数据链路层(MAC、ARP) ├─ 网络层(IP、路由) ├─ 传输层(TCP/UDP、端口) └─ 应用层(DNS、HTTP) 2. 对比法 ├─ 能通的 vs 不能通的 ├─ 之前 vs 现在 └─ 找出差异点 3. 排除法 ├─ 从简单到复杂 ├─ 逐步添加配置 └─ 定位引入问题的环节 4. 抓包验证 ├─ 数据包发出了吗? ├─ 数据包到达了吗? ├─ 响应返回了吗? └─ 内容正确吗?
记住这些原则
- 先检查物理层 - 网线、灯、链路状态
- 理解策略路由优先于普通路由 - ip rule决定一切
- 防火墙可能阻止任何流量 - 遇到问题先临时关闭测试
- DNS是独立的子系统 - 有自己的配置和故障点
- 抓包是终极武器 - 数据包不会说谎
- 配置的持久性 - 临时修改 vs 永久配置
- 日志是朋友 - journalctl、dmesg提供宝贵线索
最常用的命令组合
# 快速诊断套装 ip addr show # 查看IP配置 ip route show # 查看路由 ping -c 3 gateway # 测试网关 ping -c 3 8.8.8.8 # 测试外网 nslookup google.com # 测试DNS ss -tlnp # 查看监听端口 # 深度排查套装 ip rule show # 检查策略路由 ip route show table all # 所有路由表 sudo iptables -L -n -v # 防火墙规则 sudo tcpdump -i any icmp # 抓包分析 ip neigh show # ARP表 ethtool eth0 # 网卡状态 # 性能分析套装 mtr -r -c 100 target # 路由质量 iperf3 -c server # 带宽测试 ss -s # 连接统计 ethtool -S eth0 # 网卡统计
推荐学习路径
初级: 1. 掌握ping、ip addr、ip route基础命令 2. 理解IP地址、子网、网关概念 3. 学会查看和修改简单网络配置 中级: 4. 理解ARP、DNS工作原理 5. 掌握tcpdump基本抓包 6. 学会使用ss/netstat查看连接 7. 理解防火墙基本规则 高级: 8. 深入理解策略路由 9. 掌握iptables高级用法 10. 能够分析复杂网络拓扑 11. 性能调优和故障预防 专家: 12. eBPF和XDP 13. SDN和网络虚拟化 14. 大规模网络自动化
附录:常见问题FAQ
Q1: 为什么ping通但是ssh/http连不上?
答案: ping使用ICMP协议,而ssh/http使用TCP协议。可能的原因: - 防火墙只允许ICMP但阻止TCP端口 - 服务未运行或只监听127.0.0.1 - SELinux/AppArmor限制
排查:
# 检查端口是否监听 ss -tlnp | grep :22 # 测试TCP连接 nc -zv target_host 22 # 检查防火墙 sudo iptables -L -n -v | grep 22
Q2: 策略路由和普通路由有什么区别?
答案: - *普通路由*:只根据目标IP地址查找路由表(单一路由表) - *策略路由*:可以根据源IP、目标IP、接口、标记等多种条件,选择不同的路由表
示例:
# 普通路由 ip route add 192.168.1.0/24 via 10.10.10.1 # 策略路由 ip rule add from 10.10.10.47 table 100 ip route add default via 192.168.1.1 table 100
Q3: TIME_WAIT状态过多如何处理?
答案: TIME_WAIT是TCP正常状态,但过多会占用资源。
解决方法:
# 1. 允许TIME_WAIT socket重用(推荐) sudo sysctl -w net.ipv4.tcp_tw_reuse=1 # 2. 减少TIME_WAIT超时时间(谨慎) # 编辑 /etc/sysctl.conf net.ipv4.tcp_fin_timeout=30 # 3. 增大端口范围 sudo sysctl -w net.ipv4.ip_local_port_range="10000 65000" # 应用 sudo sysctl -p
注意: 不要使用 =tcp_tw_recycle=,它在NAT环境下会导致连接问题。
Q4: 如何永久保存iptables规则?
答案:
Debian/Ubuntu:
# 安装持久化工具 sudo apt install iptables-persistent # 保存规则 sudo netfilter-persistent save # 或手动保存 sudo iptables-save > /etc/iptables/rules.v4
CentOS/RHEL:
# 保存规则 sudo service iptables save # 或 sudo iptables-save > /etc/sysconfig/iptables
Q5: 如何查看网络接口的实时流量?
答案:
# 方法1:使用iftop(最直观) sudo apt install iftop sudo iftop -i ens34 # 方法2:使用nload sudo apt install nload nload ens34 # 方法3:使用vnstat(长期统计) sudo apt install vnstat vnstat -i ens34 # 方法4:使用ip命令(简单查看) watch -n 1 'ip -s link show ens34'
Q6: 如何测试网络的MTU大小?
答案:
# 测试到目标主机的最大MTU # 从1472开始(1500 - 20 IP头 - 8 ICMP头) ping -M do -s 1472 target_host # 如果失败,逐步减小: ping -M do -s 1400 target_host ping -M do -s 1300 target_host # 找到能通过的最大值,加上28就是MTU # 例如:1400成功,则MTU = 1400 + 28 = 1428
Q7: 如何临时禁用IPv6?
答案:
# 临时禁用 sudo sysctl -w net.ipv6.conf.all.disable_ipv6=1 sudo sysctl -w net.ipv6.conf.default.disable_ipv6=1 # 永久禁用 echo "net.ipv6.conf.all.disable_ipv6=1" | sudo tee -a /etc/sysctl.conf echo "net.ipv6.conf.default.disable_ipv6=1" | sudo tee -a /etc/sysctl.conf sudo sysctl -p
Q8: 如何监控网络连接数?
答案:
# 统计各状态的连接数 ss -s # 统计ESTABLISHED连接 ss -tan state established | wc -l # 统计TIME_WAIT连接 ss -tan state time-wait | wc -l # 实时监控 watch -n 1 'ss -s' # 按目标IP分组统计 ss -tan | awk '{print $5}' | cut -d: -f1 | sort | uniq -c | sort -rn | head
Q9: 如何追踪特定进程的网络连接?
答案:
# 查看特定进程的连接 ss -tnp | grep nginx # 或使用进程ID ss -tnp | grep "pid=1234" # 实时监控某进程的网络活动 sudo tcpdump -i any -n -p -s 0 \ '(tcp port 80 or tcp port 443)' | grep -A 5 "PID=1234" # 使用lsof sudo lsof -i -a -p 1234
Q10: 如何测试DNS服务器的响应速度?
答案:
# 使用dig测试 dig @8.8.8.8 google.com | grep "Query time" dig @114.114.114.114 google.com | grep "Query time" # 批量测试多个DNS for dns in 8.8.8.8 114.114.114.114 1.1.1.1; do echo -n "$dns: " dig @$dns google.com +stats | grep "Query time" done # 使用namebench(图形化工具) # 会测试多个DNS服务器并给出推荐 sudo apt install namebench namebench
这个完整教程涵盖了Linux网络排查的核心知识体系,从基础概念到高级技巧,从单个命令到完整流程。通过理解这些内容,你将能够:
- 系统化地排查网络问题 - 不再盲目尝试
- 理解网络的工作原理 - 知其然知其所以然
- 快速定位故障点 - 节省大量时间
- 预防常见问题 - 正确配置避免故障
记住:*网络排查的本质是理解数据包的完整旅程*。从应用程序到网卡,从本地主机到远程服务器,每一步都可能出问题。通过分层思考和系统化方法,任何网络问题都能被解决!
Comments:
Email questions, comments, and corrections to hi@smartisan.dev.
Submissions may appear publicly on this website, unless requested otherwise in your email.