尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

Linux网络基础:从TCP/UDP协议到数据包流与实战排错

Linux网络基础:从TCP/UDP协议到数据包流与实战排错 1. 项目概述为什么从网络基础开始如果你刚接触Linux或者已经用了一段时间但总觉得网络配置、服务部署、故障排查这些事儿有点“玄学”那咱们的起点就对了。我见过太多人一上来就折腾iptables、nginx配置或者docker网络结果遇到点问题就卡壳根本原因就是对脚下的地基——网络基础——没摸清楚。这次咱们不搞那些花里胡哨的就扎扎实实地把Linux下的网络基础给捋明白。这就像学武功内功心法没练好招式再漂亮也是花架子一碰就倒。所谓“网络基础”在Linux的语境下核心就是理解数据包是怎么在你的机器里“流动”的。从你敲下ping www.baidu.com开始到屏幕上显示出响应时间这中间经历了什么你的网卡、内核协议栈、路由表、防火墙规则是如何协同工作的弄懂这些以后无论是配个静态IP、开个端口转发还是分析一个网络服务的连接问题你都能心里有数知道该从哪儿下手。咱们的目标是让你不仅能照着教程把命令敲对更能明白为什么这么敲以及敲错了该怎么自己找原因。2. 核心概念拆解协议、端口与套接字2.1 TCP与UDP两种截然不同的“快递服务”网络通信就像寄快递TCP和UDP是两家风格完全不同的快递公司。TCP传输控制协议像是顺丰的保价服务。它追求的是“可靠”。在你寄出包裹发送数据前它会先打电话三次握手跟收件方确认“喂你在家吗我要寄个东西给你。”对方说“在的你来吧。”然后你才把东西寄出。寄出后它还会要求收件方签收回执ACK确认如果没收到回执它会再寄一次。整个过程保证了包裹不丢、不错、按顺序到达。但代价就是“慢”和“重”因为每次通信都有不少“确认”的开销。你浏览网页HTTP/HTTPS、收发邮件SMTP/POP3、远程登录SSH用的都是TCP因为这些场景下数据的完整性和正确性比速度更重要。UDP用户数据报协议则像是街边叫个跑腿小哥。你把包裹数据报塞给他告诉他地址目标IP和端口他就出发了。他不会提前联系收件方也不管对方收没收到更不保证包裹顺序。速度快、开销小是它的优点但可能丢件、可能送错。在线视频流、语音通话VoIP、DNS查询这些应用就用UDP因为偶尔丢一两个数据包视频花屏一下、语音卡顿一下是可以接受的但延迟必须低。注意很多人误以为TCP绝对比UDP好。其实不然选择哪种协议完全取决于应用场景。需要可靠传输选TCP追求低延迟、能容忍部分丢失的选UDP。像一些实时游戏宁愿接受偶尔的角色瞬移丢包也不能接受因为等待重传而导致的卡顿高延迟。2.2 端口网络世界的“门牌号”想象一下你的电脑IP地址是一栋大楼里面有很多房间应用程序。数据包到了大楼它怎么知道该进哪个房间呢靠的就是端口号。端口号是一个16位的整数范围是0-65535。它和IP地址一起构成了一个完整的通信端点IP:Port。一些端口被约定俗成地分配给了知名服务22端口SSH服务的大门用于安全远程登录。80端口HTTP服务的大门用于网页浏览。443端口HTTPS服务的大门用于加密的网页浏览。53端口DNS服务的大门用于域名解析。你可以用netstat或更现代的ss命令来查看你机器上哪些“门”开着谁在进出ss -tuln这个命令会列出所有**监听Listen**状态的TCP和UDP端口。-t代表TCP-u代表UDP-l代表监听-n代表用数字显示端口和IP不进行域名解析这样更快。2.3 套接字Socket编程视角的“通信端点”从程序员的角度看网络通信的起点和终点不是IP或端口而是套接字。你可以把套接字理解为一个“通信插座”。应用程序通过创建一个套接字将其绑定到一个本地IP和端口上然后通过这个插座来发送和接收数据。在Linux中一切皆文件套接字也是一种特殊的文件类型。当你创建一个TCP服务时流程大致是这样的创建一个套接字socket()系统调用。给这个套接字绑定一个IP地址和端口bind()。开始监听连接listen()。接受客户端的连接accept()这会为这个连接创建一个新的套接字用于通信。通过新的套接字读写数据read()/write()或send()/recv()。理解套接字对于后续使用tcpdump抓包分析、或者编写网络程序都至关重要。它是最底层的抽象之一。3. Linux网络栈数据流走读现在让我们追踪一个数据包的生命周期看看它从网线进入你的Linux主机到被应用程序接收中间都经历了哪些“关卡”。这个过程就是“协议栈数据流”。3.1 数据包接收流程以TCP为例网卡与驱动数据包首先到达物理网卡。网卡驱动会将其从硬件缓冲区拷贝到内核内存中的一个数据结构——sk_buffsocket buffer简称skb中。这是内核网络子系统的核心数据结构承载着数据包的所有信息和内容。链路层L2内核检查数据包的以太网帧头查看目标MAC地址是否匹配本机网卡MAC地址或广播/多播地址。如果不匹配则丢弃除非网卡处于混杂模式像tcpdump那样。网络层L3剥离以太网帧头检查IP包头。核心动作是路由。内核根据数据包的目标IP地址查询路由表决定这个包是发给本机目标IP是本机的某个IP地址。需要转发目标IP是其他机器且本机开启了IP转发功能/proc/sys/net/ipv4/ip_forward。无法送达没有匹配的路由返回“Destination Unreachable”的ICMP错误。查询路由表的命令是ip route show或老式的route -n。传输层L4如果数据包是发给本机的内核继续处理TCP或UDP头部。对于TCP包这里会进行复杂的连接状态管理如三次握手、四次挥手、序列号检查、ACK确认等。最终内核根据目标端口号找到是哪个监听中的套接字在等待这个数据。套接字缓冲区数据被放入对应套接字的接收缓冲区。应用程序通过read()等系统调用从自己的套接字缓冲区中读取数据。应用层L7应用程序拿到原始数据按照HTTP、DNS等应用层协议进行解析和处理。3.2 关键工具tcpdump与ss要直观地看到这个过程离不开抓包工具tcpdump。例如抓取所有经过eth0网卡、目标端口是80的TCP流量sudo tcpdump -i eth0 -nn tcp port 80-i eth0指定网卡。-nn不解析主机名和端口服务名显示IP和数字端口避免干扰且更快。tcp port 80过滤表达式只抓TCP且端口为80的包。通过tcpdump你可以亲眼看到三次握手SYN, SYN-ACK, ACK、数据传输PSH, ACK、四次挥手FIN, ACK的每一个包这对于调试网络问题是无价之宝。而ss命令则是观察连接状态的利器。ss -t state established可以查看所有已建立的TCP连接ss -t state time-wait可以查看处于TIME-WAIT状态的连接这对于分析服务器连接数过高的问题非常有用。3.3 数据包发送流程发送流程是接收的逆过程但同样重要。应用程序调用write()或send()将数据写入套接字发送缓冲区。内核协议栈在合适的时机缓冲区满、或应用程序显式要求刷新将数据封装成TCP/UDP段、IP包、以太网帧最后通过网卡驱动发送到网络上。发送路径同样会经过路由表查询决定从哪个网卡出去和可能的Netfilter如iptables过滤。4. 核心配置与操作实战理解了原理我们来看看在Linux上最常操作的几个网络配置点。4.1 网络接口配置IP地址、网关、DNS现代Linux主要使用iproute2工具集ip命令来配置网络传统的ifconfig、route命令已逐渐被淘汰。1. 查看网络接口信息ip addr show # 或简写为 ip a这会列出所有网络接口的详细信息包括状态UP/DOWN、MAC地址、IPv4/IPv6地址等。2. 临时配置IP地址和网关sudo ip addr add 192.168.1.100/24 dev eth0 # 给eth0添加一个IP sudo ip link set eth0 up # 启用eth0接口 sudo ip route add default via 192.168.1.1 dev eth0 # 设置默认网关这种方式配置在重启后会失效。3. 永久性配置以Ubuntu/Debian系为例配置文件通常在/etc/netplan/目录下新版Ubuntu或/etc/network/interfaces旧版。以Netplan为例编辑/etc/netplan/01-netcfg.yamlnetwork: version: 2 ethernets: eth0: dhcp4: no # 禁用DHCP addresses: [192.168.1.100/24] gateway4: 192.168.1.1 nameservers: addresses: [8.8.8.8, 114.114.114.114]保存后应用配置sudo netplan apply。DNS配置则主要写在/etc/resolv.conf文件里但注意现在这个文件通常由systemd-resolved或NetworkManager管理直接修改可能被覆盖。更推荐的做法是在Netplan或NetworkManager的配置中指定DNS服务器。4.2 路由表管理路由表决定了数据包何去何从。查看路由表ip route show # 或简写为 ip r输出可能像这样default via 192.168.1.1 dev eth0 proto dhcp metric 100 192.168.1.0/24 dev eth0 proto kernel scope link src 192.168.1.100 metric 100第一行默认路由。所有目标地址不在其他路由规则中的包都通过eth0发给网关192.168.1.1。第二行直连路由。发往192.168.1.0/24网段的包直接通过eth0发出不需要网关。添加一条静态路由比如让你访问10.10.0.0/16网段走另一个网关sudo ip route add 10.10.0.0/16 via 192.168.1.254 dev eth04.3 防火墙初探Netfilter与iptables/nftablesLinux内核的防火墙框架叫Netfilter而iptables是用户空间最著名的用来配置Netfilter规则的工具。它通过定义一系列的“表”Tables和“链”Chains来过滤、修改数据包。一个最简单的例子开放本机的22端口SSHsudo iptables -A INPUT -p tcp --dport 22 -j ACCEPT sudo iptables -A OUTPUT -p tcp --sport 22 -j ACCEPT-A INPUT在INPUT链末尾追加一条规则。INPUT链处理发往本机的数据包。-p tcp匹配TCP协议。--dport 22匹配目标端口为22。-j ACCEPT执行的动作是“接受”。但请注意iptables规则默认是“拒绝所有”如果你只加了上面两条规则那么除了SSH其他所有入站连接都会被拒绝。一个常见的做法是先设置默认策略为DROP然后按需开放sudo iptables -P INPUT DROP sudo iptables -P FORWARD DROP sudo iptables -P OUTPUT ACCEPT # 通常允许所有出站 # 然后开始添加允许的规则如允许已建立的连接、允许回环接口、允许SSH等 sudo iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT sudo iptables -A INPUT -i lo -j ACCEPT sudo iptables -A INPUT -p tcp --dport 22 -j ACCEPT重要提示在远程服务器上操作防火墙规则时务必通过本地控制台或确保当前会话不会被阻断的方式进行。一个常见的“自杀”操作是在远程SSH连接中执行了iptables -P INPUT DROP却没有先允许SSH端口导致连接立刻中断且无法恢复。安全做法是使用cron设置一个定时任务在几分钟后恢复规则或者使用at命令。现代Linux发行版正在逐步转向nftables作为iptables的替代品它语法更统一性能更好。但iptables的知识在现阶段依然非常重要。5. 网络诊断与排错实战指南理论懂了配置会了但网络还是不通怎么办下面是一个系统性的排查思路和工具箱。5.1 分层排查法从底层到上层第1层物理与链路层“网线插好了吗”检查接口状态ip link show eth0。确保状态是UP而不是DOWN。检查物理连接网线、网卡指示灯。可以用ethtool eth0查看网卡协商的速度、双工模式。检查ARPip neigh show或arp -n。查看是否学习到了网关或同网段其他主机的MAC地址。如果看不到网关的MAC说明二层通信可能有问题。第2/3层网络层“能ping通网关吗”检查IP配置ip addr show确认IP和掩码配置正确。检查路由ip route show确认默认网关设置正确。测试连通性ping 127.0.0.1环回测试检查本机协议栈是否正常。ping 本机IP检查本机网卡配置是否生效。ping 同网段其他主机IP检查二层交换机通信。ping 网关IP检查能否到达网关这是通往外部网络的第一步。如果这里不通问题大概率在本地网络或网关本身。第4层传输层“端口开放了吗”本地监听检查ss -tuln | grep :80检查本机80端口是否处于LISTEN状态。远程端口探测telnet 目标IP 端口或nc -zv 目标IP 端口。如果连接超时可能是对方防火墙阻止如果连接被拒绝说明目标端口没有服务监听。跟踪路由traceroute 目标IP或tracepath 目标IP。查看数据包在到达目标前在哪一跳丢失有助于定位是哪个中间路由器出了问题。第5-7层应用层“服务本身正常吗”检查应用程序日志如/var/log/nginx/error.log。使用应用层工具测试如curl -I http://目标IP测试Web服务dig DNS服务器 域名测试DNS解析。5.2 必备诊断工具速查表工具命令主要用途常用示例与说明ping测试网络连通性ICMP协议ping -c 4 8.8.8.8发送4个包测试到谷歌DNS的连通性。注意很多服务器禁pingping不通不代表TCP/UDP端口不通。traceroute/tracepath追踪数据包路径traceroute www.baidu.com查看访问百度经过的所有路由器。mtrpingtraceroute的增强版mtr -r -c 10 www.baidu.com持续测试并报告到目标主机的丢包和延迟比单次traceroute更准。ss查看套接字统计信息ss -tlnp查看所有TCP监听端口及对应的进程PID。ss -t state established查看所有已建立的连接。netstat老牌网络统计工具功能逐渐被ss取代netstat -tulnp功能类似ss -tulnp但输出格式不同。tcpdump网络抓包终极调试利器sudo tcpdump -i any -nn host 192.168.1.1抓取所有与192.168.1.1通信的包。-w file.pcap可保存供Wireshark分析。nc(netcat)瑞士军刀TCP/UDP读写测试nc -l -p 8080在本地8080端口开启监听。nc -zv host 22测试主机22端口是否开放。dig/nslookupDNS查询工具dig www.baidu.com或nslookup www.baidu.com查询域名解析结果。dig输出更详细。ethtool查询和设置网卡参数ethtool eth0查看网卡驱动、速度、双工模式等信息。ip强大的网络配置工具集ip addr,ip route,ip link,ip neigh分别管理地址、路由、链路、ARP。5.3 常见问题与排查实录问题1能ping通IP但无法访问域名网页打不开。排查思路这几乎肯定是DNS问题。步骤cat /etc/resolv.conf检查DNS服务器配置是否正确。ping 8.8.8.8如果能通说明网络是好的。nslookup www.baidu.com或dig www.baidu.com看能否解析出IP。如果解析失败尝试指定公共DNS测试dig 8.8.8.8 www.baidu.com。如果指定后能解析说明是本机配置的DNS服务器有问题。检查防火墙是否错误地拦截了出站的53端口UDP/TCP请求。问题2本地服务如Nginx已启动但外部无法访问。排查思路从服务本身、防火墙、路由三个方向排查。步骤检查服务监听ss -tlnp | grep :80确认服务是否在0.0.0.0:80监听所有IP或指定IP上监听而不是127.0.0.1:80仅本地可访问。检查本地防火墙sudo iptables -L -n -v查看INPUT链规则是否允许80端口。可以临时清空规则测试sudo iptables -F INPUT(危险仅限测试环境且要记得恢复或设置默认允许策略)。检查云主机安全组/网络ACL如果你用的是云服务器阿里云、AWS等服务器的虚拟防火墙安全组规则必须放行对应端口。这是新手最常踩的坑从外部测试在另一台机器上用telnet 你的服务器公网IP 80测试。问题3SSH连接服务器非常慢但连接上之后操作速度正常。可能原因DNS反查。SSH服务端默认会尝试解析客户端的IP地址成主机名如果DNS服务器配置不当或网络不好这个反查就会超时。解决在服务端的SSH配置文件中禁用反查。编辑/etc/ssh/sshd_config找到并修改UseDNS no然后重启SSH服务sudo systemctl restart sshd。网络问题的排查就是一个“分而治之”的过程。从底层到高层从本地到远程一步步缩小范围。养成使用tcpdump抓包分析的习惯很多疑难杂症都会在数据包面前原形毕露。记住网络是分层的问题也往往是分层的耐心和清晰的思路是最好的工具。
返回列表