ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

Linux网络设置与DHCP实战:从基础配置到故障排查全解析

Linux网络设置与DHCP实战:从基础配置到故障排查全解析 装好系统打开虚拟机第一件事就是联网。可现实往往是ip a一看没有地址ping网关不通DNS 解析超时甚至dhclient跑起来也毫无反应。这些东西看起来是“基础”但真正能把 Linux 网络设置和 DHCP 讲透、把坑踩平写清楚的内容反而很少。作为常年跟服务器和网络设备打交道的人我把这些经验按实际工作的思路整理成文希望能帮各位少走弯路。这篇文章围绕 Linux 网络设置与 DHCP 展开会讲清楚网卡配置、网络管理服务的选型、DHCP 的原理与报文交互细节以及服务端和客户端的实操配置最后是一堆亲手排查过的问题。适合刚入门 Linux 的运维、网络初学者也适合被虚拟机或实体机网络配置折磨过的兄弟参考。1. 从整体视角理解Linux网络设置1.1 先搞清楚Linux网络配置的“骨架”很多新手一上来就敲命令但没过多久就发现这次配置重启之后没了。原因很简单命令改的是内核运行时状态配置文件才是重启后依然生效的东西。理解 Linux 网络配置首先得知道你用的发行版到底读哪个配置文件。Debian/Ubuntu 老系统通常用/etc/network/interfaces里面以auto eth0、iface eth0 inet static这样的块状结构写完网卡配置。RHEL/CentOS 系则是/etc/sysconfig/network-scripts/ifcfg-eth0用BOOTPROTOdhcp、ONBOOTyes这种键值对表示。现在的 Ubuntu 从 17.10 开始全面转向/etc/netplan/*.yaml用 YAML 描述网络接口和 DHCP 开关。不同体系之间没有谁绝对更好只是设计思路不同。interfaces 和 ifcfg 都是纯文本直白式重启网络服务即可生效netplan 则是一个渲染层底层可以对接 NetworkManager 或 systemd-networkd适合批量管理和自动化。Arch 系用户可能更熟悉 systemd-networkd 的.network文件配置风格和 ifcfg 类似但更现代。判断当前系统用哪种方式最靠谱的是看发行版文档或者检查系统里实际存在的目录。比如 Debian 系/etc/network/interfaces如果还在多半就是旧式管理Ubuntu 桌面版默认装 NetworkManager服务器版用 netplan。这个判断在远程操作时尤其重要因为你可能只有一次改错就失联的机会。1.2 网络管理服务之争NetworkManager、systemd-networkd与纯静态配置Debian/Ubuntu 桌面环境下NetworkManager 几乎是事实标准它的优势是自动感知网络变化插网线、连 Wi-Fi 都无需手动处理。服务器场景下很多人倾向关掉 NetworkManager改用 systemd-networkd 或纯手写配置因为 NetworkManager 在无桌面环境下有时候会莫名其妙覆盖你写的内容尤其在云镜像里容易出问题。我的习惯是笔记本、台式机、测试虚拟机用 NetworkManager图省事生产服务器和跑核心服务的容器宿主机能用 systemd-networkd 或直接/etc/netplan手动管理就不用 NetworkManager越少自动干预越稳。不要理解为“谁比谁高级”而是你要清楚当前环境里到底是谁在控制网卡。如果你要判断当前网络是不是由 NetworkManager 管理可以用nmcli device status能看到设备状态和连接名。如果这个命令不存在或显示设备未托管说明网络可能由 systemd-networkd 或 netplan 接管继续排查时方向就不一样了。1.3 判断“网络通不通”的正确姿势网络排查不要一上来就ping baidu.com一旦失败你根本分不清是网卡、IP、网关还是 DNS 的问题。我的排查顺序固定是先ip a看接口状态和 IP再ip route看默认路由然后ping网关最后才nslookup或dig解析域名。ip a里如果看到state UP说明链路层正常state DOWN说明网卡没起来或者没接网线如果有inet行说明拿到了 IP没有则可能 DHCP 没跑通。ip route里必须有default via x.x.x.x dev eth0否则数据包出不去。DNS 解析这个环节往往被忽略但问题率很高。resolvectl status可以看当前系统 DNS 配置来源nslookup baidu.com能验证解析。最高频的坑是/etc/resolv.conf被 NetworkManager 或 dhclient 覆盖你手写的 DNS 重启后就没影了。2. DHCP工作原理不只是“自动获取IP”那么简单2.1 DHCP为什么存在手动配置的痛点试想一个办公室有几十台电脑如果每台机器都要网络管理员手工分配 IP、子网掩码、网关、DNS然后逐个登录系统去写工作量巨大不说还特别容易写错。IP 冲突、网关笔误、子网掩码不对哪个都能让你一上午白干。DHCPDynamic Host Configuration Protocol就是为了解决这个痛点而生的。DHCP 做的事情本质上是一个“自动出租 IP”的管理员。它维护一个地址池有人需要 IP 就借给他租期到了自动收回再分配。办公电脑、员工手机、访客 Wi-Fi、虚拟机、物联网终端几乎只要是用网线或无线接入的终端都在靠 DHCP 拿地址。它能统一的参数不只是 IP还能顺带下发子网掩码、网关、DNS、域名、租约时长、甚至引导文件和启动服务器。这正是它强大之处终端零配置网络管理员只需要在一台服务器上维护配置所有终端开机即用。2.2 一次完整的DHCP租约过程DORA从客户端角度看一次完整的 DHCP 获取过程可以用四个报文概括业内叫 DORADiscover、Offer、Request、Acknowledge。第一步客户端不知道谁是 DHCP 服务器所以用广播方式发送 DHCP Discover 报文源 IP 是 0.0.0.0目的 IP 是 255.255.255.255同时填上自己的 MAC 地址。第二步收到 Discover 的 DHCP 服务器从地址池选一个可用地址回一个 DHCP Offer里面带有建议分配的 IP、掩码、网关、租期等参数。第三步客户端如果收到多个 Offer会选一个一般是第一个到达的并广播发送 DHCP Request知会所有服务器“我要用这个地址”。第四步被选中的服务器回一个 DHCP Acknowledge确认租约生效其他没被选中的服务器则收回自己的 Offer。整个过程很像你进餐厅找座位你先大声问“有没有空位”Discover多家服务员都说“有空位”Offer你挑了靠窗的位置Request服务员确认“就这个位置是你的”Acknowledge。不同的是这个位置是带时限的。客户端并不是等到租期结束才续约。按照协议规定过了 50% 租期T1 时间点客户端会通过单播向当初分配地址的服务器发起 Request 续租服务器如果同意就重新 Ack。到了 87.5% 租期T2 时间点如果还没续上客户端会改用广播去找任意一台 DHCP 服务器确保不会因为原服务器宕机就掉线。这种情况在排障时很常见明明 IP 还显示着但租约时间已经过去一大半客户端会悄悄发起续租日志里能看到。2.3 深入理解DHCP报文与关键选项说报文结构可能有点枯燥但理解了关键选项你排查问题就会快很多。DHCP 报文基于 UDP 传输客户端端口 68服务器端口 67。报文里除了 MAC 地址和 IP 地址字段外剩下的核心信息全部放在 Options选项里。最常见的选项包括Option 1子网掩码、Option 3默认网关、Option 6DNS 服务器、Option 15域名后缀、Option 51租期时长、Option 53DHCP 报文类型用来区分 Discover 还是 Request 等、Option 54服务器标识告诉客户端应该找哪台服务器续租、Option 55客户端请求参数列表表示客户端希望拿到哪些配置。如果你做 DHCP 服务器配置其实就是在声明这些选项怎么发。例如option routers 192.168.1.1对应 Option 3option domain-name-servers 8.8.8.8对应 Option 6default-lease-time 600对应 Option 51 的默认值。理解了这个映射关系看 tcpdump 抓包时才不会一头雾水。我在实际排障中抓包最多的场景就是客户端拿不到 IP。用tcpdump -i eth0 port 67 or port 68 -n抓 DHCP 报文如果只看到 Discover 发出、没有任何 Offer 回来说明客户端和服务器之间二层链路有问题或者服务器地址池已满、策略拒绝。如果能看到 Offer 但是客户端不回 Request通常是客户端收到多个 Offer 后选择了另一个或者本机防火墙拦截了报文。2.4 广播与中继DHCP如何跨网段工作DHCP 最初的设计依赖广播而广播报文默认不会跨路由器转发。这意味着一个 DHCP 服务器只能服务同一个广播域内的客户端没法给多个不同子网的终端发地址。想解决这个问题一般有两个方案每个子网放一台 DHCP 服务器或者配置 DHCP 中继。DHCP 中继的原理很简洁子网内的客户端广播 Discover中继设备通常就是路由器或者三层交换机收到后把报文转成单播转发给指定 DHCP 服务器服务器回包后再由中继广播给客户端。中继在转发时会填上giaddr字段这个字段记录客户端所在子网的网关地址DHCP 服务器根据它判断应该从哪个地址池分配 IP。配置中继的开销远小于在每个网段养一台 DHCP 服务器所以现在绝大多数单位都是“DHCP 服务器集中部署 三层设备做中继”的架构。Linux 系统上可以用自带工具dhcrelay开启中继功能命令很简单比如dhcrelay -i eth0 192.168.1.10后面这个 IP 是 DHCP 服务器地址。如果客户端在 eth0 所连网段中继会把请求转发给 192.168.1.10。忽略掉这个环节等你遇到“为什么这个网段能拿到 IP那个网段拿不到”的时候再回来理解中继就晚了。3. Linux下DHCP服务端与客户端配置实操3.1 环境准备与软件安装想在 Linux 上搭 DHCP 服务器Debian/Ubuntu 用isc-dhcp-server包RHEL/CentOS 系用dhcp包。老牌开源社区现在更推荐 Kea功能更现代、支持数据库存储和 REST API不过传统站点依然大量使用 ISC DHCP因为简单稳定、文档多。安装方式以 Ubuntu 为例sudo apt update sudo apt install isc-dhcp-server安装完成后有两个关键文件配置文件/etc/dhcp/dhcpd.conf以及指定 DHCP 服务监听哪个网卡的/etc/default/isc-dhcp-serverDebian/Ubuntu或/etc/sysconfig/dhcpdRHEL/CentOS。很多人改完配置发现服务起不来多半就是第二个文件里没填对接口名。这里有一个容易忽略的点isc-dhcp-server默认依赖启动时读取配置文件如果dhcpd.conf有语法错误服务会直接启动失败。所以建议每次改完都跑一遍dhcpd -t -cf /etc/dhcp/dhcpd.conf做语法测试输出Configuration file syntax seems ok再重启服务。3.2 手写一份最简DHCP配置并启动一份最简可用的配置可以这样写subnet 192.168.10.0 netmask 255.255.255.0 { range 192.168.10.50 192.168.10.200; option routers 192.168.10.1; option domain-name-servers 223.5.5.5, 8.8.8.8; option domain-name example.local; default-lease-time 600; max-lease-time 7200; }subnet和netmask是本地网段定义range是地址池范围option routers下发默认网关option domain-name-servers下发 DNS。default-lease-time是客户端默认租期单位秒600 秒可以快速看到续租行为适合测试max-lease-time是客户端主动请求延长租期时允许的最大值。写完后指定监听网卡比如网卡是ens33echo INTERFACESv4ens33 | sudo tee /etc/default/isc-dhcp-server sudo systemctl restart isc-dhcp-server sudo systemctl status isc-dhcp-server看到active (running)之后模拟一个客户端请求。最简单的方式是找同一网段另一台 Linux 机器临时执行dhclient ens33然后ip a看是否拿到 IP。如果拿到任务完成。如果拿不到直接看 DHCP 服务器日志路径在/var/log/syslog或/var/log/messages搜索dhcpd关键字通常会直接告诉你地址池是否为空、是否有冲突、是否收到请求。3.3 客户端怎么“抢”地址dhclient与NetworkManager的配合客户端主动发起 DHCP 获取最常见的是dhclient命令。dhclient ens33就是让ens33网卡强行走一遍 DHCP 流程dhclient -r ens33则是主动释放 IP。这个过程是广撒网式的客户端广播 Discover等拿到 Ack 后向配置文件中写入地址操作完成后网卡才具备完整的通信参数。不过现代 Linux 桌面环境大多数不会直接调用dhclient而是让 NetworkManager 接管。在 NetworkManager 里网卡的 IPv4 方法如果设为“自动DHCP”默认就会发起 DHCP 请求。命令行下可以用nmcli来检查或者修改nmcli connection show nmcli connection modify Wired connection 1 ipv4.method auto nmcli connection up Wired connection 1这里特别提醒如果系统里同时存在 NetworkManager 和 dhclient你手动执行dhclient抢到一个 IP可能和 NetworkManager 管理的不一致导致路由表混乱。所以服务器上如果明确用 NetworkManager 管理网络就不要手动再跑dhclient去干预。反过来如果你习惯纯静态配置最好把 NetworkManager 的对应网卡改成“仅手动”避免它隔三差五自动获取地址。怎么判断当前网卡的 DHCP 是否已启用两条渠道看一是在 NetworkManager 里看连接配置nmcli connection show 连接名 | grep ipv4.method输出auto就是 DHCP二是看系统里的网络配置文件比如 netplan 的 YAML 是否写了dhcp4: true或者 ifcfg 文件里是否有BOOTPROTOdhcp。明白了这个判断逻辑你就知道为什么改完配置文件有时不生效——因为另一个服务可能在悄悄覆盖它。3.4 场景进阶固定IP分配与多网段中继配置实际生产环境里有些设备必须拿到固定不变的 IP比如打印机、门禁控制器、仓库扫码枪。DHCP 服务器可以用 MAC 地址绑定实现“同一台设备永远拿同一个地址”达到静态效果但无需在设备上手工配置。在dhcpd.conf中可以用host声明来固定分配host printer-room1 { hardware ethernet 00:1B:44:11:3A:B7; fixed-address 192.168.10.10; }这段配置表示如果客户端 MAC 是00:1B:44:11:3A:B7就给他分配192.168.10.10。注意这个地址不能在range之外或者说即便在range内也能保证该 MAC 每次优先拿到这个 IP。如果又想让别人也用这个地址地址池和固定分配范围最好做明确划分避免冲突。多网段场景下DHCP 中继是更常见的做法。假设 DHCP 服务器在192.168.10.0/24另一个部门网段是192.168.20.0/24只要在通往192.168.20.0/24的三层交换机或路由器上启用 DHCP 中继指向 DHCP 服务器即可。Linux 上的配置方式如下dhcrelay -i eth0 -i eth1 192.168.10.5其中eth0和eth1是中继设备上两个不同网段的接口192.168.10.5是 DHCP 服务器地址。客户端在eth1侧广播 Discover经中继转发给服务器服务器从192.168.20.0/24对应的地址池分配 IP再经中继回传。整套流程要求 DHCP 服务器配置里必须有与giaddr匹配的subnet声明否则服务器不知道该从哪个池子拿地址会直接忽略请求。4. 踩坑实录Linux网络与DHCP的常见问题排查4.1 虚拟机网络模式的“坑”虚拟机网络设置是新手最容易懵的地方因为 VMware Workstation 和 VirtualBox 默认给了三种模式NAT、桥接、仅主机。NAT 模式下虚拟机通过宿主机共享网络上网本质是宿主机做了一层地址转换虚拟机默认从虚拟网卡分配的 DHCP 地址通常和宿主机物理网卡不在一个网段。桥接模式则相当于虚拟机直接插到交换机上能和局域网内其他设备互通但 IP 必须和局域网处于同一网段。问题常见在虚拟机用 NAT 模式能上网但局域网里的其他设备就是访问不到虚拟机这是模式本身决定的不是配置错了。想被外部访问应该用桥接模式并保证虚拟机和宿主机同网段。仅主机模式则完全没有外部网络只适合做隔离测试环境。另外在虚拟机里配置 DHCP 服务端时要格外小心虚拟机的虚拟网卡可能同时拿到多个地址比如 VMware 的 VMware Network Adapter VMnet8 和 VMnet1。你要确认 DHCP 服务监听的网卡是否和虚拟机内部网卡一致否则客户端在虚拟网卡侧发送请求服务端却在另一个接口上等待自然收不到任何请求。4.2 上游网关设备的DHCP冲突怎么办办公网络里经常碰上这种情况运营商或公司统一发放的光猫、路由器默认开启了 DHCP但你为了统一管理又在内部自建了一台 Linux DHCP 服务器。这时两台 DHCP 设备同时响应客户端的 Discover客户端可能随机选择其中一个 OfferIP 范围和网关就会混乱。解决思路不是急着关掉上游设备的 DHCP——很多设备根本没有关闭选项而是通过规划规避冲突。第一把 Linux DHCP 服务器的地址池设置在一个与上游 DHCP 完全不同的网段或者在同一网段内错开后半段地址池让上游只分配前半段自建服务器只分配后半段。第二如果目标设备需要特殊参数比如固定 IP、特殊 DNS可以在自建 DHCP 服务器里对这些 MAC 做 host 绑定只要客户端优先收到自建服务器的 Offer 就能按预期分配。这个场景在实验环境里尤其要留意你的笔记本电脑同时连着公司 Wi-Fi 和一台直连 Linux 服务器这时笔记本上的 DHCP 客户端可能会收到两个来源的 Offer容易造成路由冲突。排查时用ip route看默认路由走了哪个接口必要时临时禁用其中一个接口。4.3 常见问题速查表我把日常运维和教学里最高频的 DHCP 相关问题整理成速查表遇到问题直接对着找原因。症状可能原因排查命令/方法解决方向客户端拿不到 IPDHCP 服务未启动、接口监听错误、地址池耗尽systemctl status isc-dhcp-server、dhcpd -t -cf检查配置、查看日志确认监听的网卡正确检查地址池剩余量拿到 IP 但与预期网段不符另一台 DHCP 设备也在响应或者中继配置指向错误抓包看 Offer 来源tcpdump -i 接口 port 67 or port 68 -n隔离上游 DHCP或调整地址池范围IP 能拿到但上不了网网关下发错误、路由缺失ip route看默认路由ping 网关测试修正 DHCP 配置中的option routersDNS 解析异常下发的 DNS 不可达或/etc/resolv.conf被覆盖resolvectl status、nslookup测试在 DHCP 配置中指定可达 DNS或锁住 resolv.confIP 冲突日志提示 conflict地址池与静态 IP 重叠查看/var/lib/dhcp/dhcpd.leases租约文件排除冲突 IP重新规划静态与动态地址段DHCP 服务启动失败配置文件语法错误、监听接口不存在dhcpd -t -cf /etc/dhcp/dhcpd.conf逐行检查配置文件确认接口名每次排查问题我强烈建议先看日志再抓包最后才改配置。日志会告诉你服务端是否看到了请求抓包会告诉你报文走到哪一步断了这两步做完大部分问题原因已经清楚了。4.4 配置DNS时常见的隐蔽问题热搜里有“linux中配置dns出现的问题”正好展开说一下。Linux 的 DNS 配置文件通常是/etc/resolv.conf但它的内容经常不是管理员直接写的而是由 dhclient、NetworkManager 或 systemd-resolved 动态生成。在 DHCP 环境里如果 DHCP 服务器下发的 DNS 选项有问题客户端解析就会跟着出问题。我遇到过最头疼的一种情况/etc/resolv.conf里写的 DNS 看起来是223.5.5.5但实际在用的根本不是它因为 systemd-resolved 把真正的解析请求改道到本地 127.0.0.53 了。你nslookup能通但换到某些老命令就失败排查了半天才发现是 DNS 查询流程转了好几层。解决思路是先搞清楚当前系统用的是哪套 DNS 栈。resolvectl status能看到全局和服务级别的 DNS 设置systemd-resolve --status在老系统上也可以。如果不想让 DHCP 下发的 DNS 干扰你的静态配置可以考虑在 netplan 或 NetworkManager 里显式指定 DNS并在/etc/resolv.conf里加options或改成静态文件但前提是你确认没有其他服务会覆盖它。5. 进阶方向DHCP Snooping、抓包与更稳的网络管理5.1 从网络安全角度看DHCPDHCP 默认没有认证机制任何设备都能在局域网里广播 DHCP Offer一旦有人伪造 DHCP 服务器下发恶意网关或 DNS客户端流量就可能被劫持。这是典型的中间人攻击手法在企业内网安全里必须防范。最常见的防御手段是在接入交换机上启用 DHCP Snooping。它的作用简单说就是划分信任与不信任端口连接合法 DHCP 服务器的端口标记为信任其余接终端设备的端口不信任。不信任端口收到的 DHCP Offer 会被直接丢弃这样伪造的服务器就发不出报文。这个功能还能顺带做 IP-MAC 绑定审计记录 DHCP 地址分配情况排障时查dhcp snooping binding能看到谁在用哪个地址。Linux 环境下虽然没有 Cisco 交换机那种 DHCP Snooping 配置但可以借助 ebtables、nftables 或 iptables 控制 DHCP 报文的方向和来源。比如在网关主机上放行udp dst port 67只允许从合法 DHCP 服务器接口进入其余一律丢弃。对于大多数自建实验环境虽然不需要做到企业级防护但要清楚这个风险存在。5.2 抓包定位DHCP问题的最佳实践排查 DHCP 问题最有效的手段就是抓包。我习惯用tcpdump抓取 67/68 端口的所有报文然后观察四个阶段是否完整。sudo tcpdump -i eth0 port 67 or port 68 -n抓包结果里IP 0.0.0.0.bootpc 255.255.255.255.bootps是 DiscoverIP 192.168.1.1.bootps 255.255.255.255.bootpc是 OfferIP 0.0.0.0.bootpc 255.255.255.255.bootps是 RequestIP 192.168.1.1.bootps 255.255.255.255.bootpc是 Ack。只要这四个报文顺序完整说明二层和三层的转发链路没问题如果中途断掉看断在哪个环节就能定位问题方向。还要注意DHCP 的 Offer 和 Ack 既可能是广播也可能是单播取决于客户端在 Discover 里是否设置了广播标志位。我在抓包时经常看到 Offer 是单播发给客户端的这时如果抓包点不在同一台客户端机器上可能会漏看误以为服务器没回包。所以条件允许时最好直接在客户端上抓包或者用-e配合观察 MAC 地址确认报文去向。5.3 从静态配置到DHCP再回到可预测的自动化对于一台只有几个静态 IP 的服务器手写配置完全可以接受但面对几十台、上百台终端时DHCP 带来的简化是值得投入的。反过来当你把 DHCP 玩熟了也会发现它并不是唯一答案云环境里很多企业直接使用云平台的 DHCP 服务和元数据服务而不是自己搭建容器网络里DHCP 用得很少CNI 插件会直接分配 IP数据中心里有时候会用 IPAM 系统统一管理地址规划DHCP 只是其中一个分配通道。我的建议是先把手动配置、DHCP 服务端、DHCP 中继、常见排障这个流程完整走一遍理解清楚地址的来龙去脉再去碰自动化工具。没有这个基础你用 Ansible、Terraform 或者云平台的网络模块再方便出了问题也很难定位到根因。操作多了之后我觉得最值钱的不是背下那些配置项而是养成一套稳定的排查思路。先确认网卡状态再确认 IP 和路由然后验证 DNS最后才动配置。改 DHCP 配置之前先dhcpd -t做语法检查重启服务后立刻看日志客户端拿不到地址就去抓包看报文断在哪一步。这套流程救过我很多次希望你也能用上。如果手边有闲置的旧电脑或者虚拟机建议搭一个小实验环境配一台 DHCP 服务器再配两台客户端把 DORA 四个过程完整抓一遍你会对这些机制有比看文章深得多的理解。
返回列表