使用Openwrt做DHCP服务器跨VLAN分配IP地址

/ 0评 / 0

作者的话

家里这套网络架构折腾了好几轮:最早是锐捷三层交换机自己发 DHCP,当小路由用;后来 OpenWrt 越来越多服务挂在上面,就开始想把 DHCP 统一收拢到 OpenWrt 上——毕竟做 DNS、DHCP、各种旁路服务,还是路由器更顺手。

这篇文章记录的是:在 “锐捷三层交换机 + OpenWrt” 的架构下,仅迁移 IPv4 DHCP 到 OpenWrt 的过程。三层交换机继续负责 VLAN 间路由,出口仍然走 OpenWrt,最终实现的是:

  • 每个 VLAN 里的客户端从 OpenWrt 拿 IP;
  • IPv4 网关仍然是三层交换机的各 VLAN 接口;
  • 拓扑、路由几乎不动,只是改了 DHCP 角色和转发路径。

本篇文章内容由AI生成,但是所有流程均为实际操作。

摘要

需求:

最终方案:

  1. 三层交换机:

    • 关闭自身 DHCP Server,删除所有 ip dhcp pool
    • 在各 VLAN 三层接口上配置:

      ip helper-address 192.168.10.3

      把各 VLAN 的 DHCP 广播中继到 OpenWrt;

    • 默认路由仍然指向 OpenWrt(不变)。
  2. OpenWrt:

    • LAN(192.168.10.0/24)正常用 /etc/config/dhcp
    • 对其它 VLAN(20/30/40/50)的地址池,使用 dnsmasq 原生配置 写入 /etc/dnsmasq.conf

      • dhcp-range 定义地址段;
      • dhcp-option 3 指定各 VLAN 的网关(交换机的三层接口 IP);
      • dhcp-option 6 指定 DNS 服务器。
  3. 验证:

    • 各 VLAN 客户端释放 / 重新获取 IP;
    • IP 段、网关、DNS 均符合预期;
    • 出口路由、VLAN 间路由与迁移前一致。

1. 拓扑背景与目标

先简单抽象一下拓扑(IPv4 部分):

迁移目标:

这意味着:
地址分配在 OpenWrt,三层路由在交换机。


2. DHCP 设计:为什么要用 DHCP Relay

在这种架构里,每个 VLAN 的三层网关在交换机上,而 OpenWrt 只接在 VLAN10。
如果想让 VLAN20/30/40/50 的 DHCP 请求都跑到 OpenWrt,有两种思路:

  1. 把 OpenWrt “拉进”每个 VLAN(在 OpenWrt 上创建 eth2.20 / eth2.30 … 子接口);
  2. 让三层交换机做 DHCP Relay,把各 VLAN 的 DHCP 广播封装后单播到 OpenWrt。

这里选的是 第二种,原因是:

核心机制:

所以,OpenWrt 不需要有 VLAN20 的接口,只要理解 “giaddr 属于哪个网段,就用哪个地址池”。


3. 三层交换机配置:关掉 DHCP,开 Relay

3.1 删除交换机上的 DHCP 池

原来配置类似:

service dhcp

ip dhcp pool VLAN20
  network 192.168.20.0 255.255.255.0 192.168.20.100 192.168.20.254
  dns-server 114.114.114.114
  default-router 192.168.20.1

ip dhcp pool VLAN30
  ...

迁移的时候,需要:

configure terminal
 no ip dhcp pool VLAN20
 no ip dhcp pool VLAN30
 no ip dhcp pool VLAN40
 no ip dhcp pool VLAN50
 no service dhcp

这样交换机就不会再给任何 VLAN 发 IPv4 地址了,避免出现“两个 DHCP Server 争抢”的情况。

3.2 在各 VLAN 接口上配置 ip helper-address

VLAN20 在现网中类似:

interface VLAN 20
 ip directed-broadcast
 ip address 192.168.20.1 255.255.255.0
 ! 之前就已经预留了 helper 的能力
 ! ip helper-address 192.168.10.3

现在需要给其它 VLAN 也加上 helper(以 20/30/40/50 为例):

interface VLAN 20
 ip directed-broadcast
 ip address 192.168.20.1 255.255.255.0
 ip helper-address 192.168.10.3

interface VLAN 30
 ip address 192.168.30.1 255.255.255.0
 ip helper-address 192.168.10.3

interface VLAN 40
 ip address 192.168.40.1 255.255.255.0
 ip helper-address 192.168.10.3

interface VLAN 50
 ip address 192.168.50.1 255.255.255.0
 ip helper-address 192.168.10.3

说明:

默认路由保持原样:

ip route 0.0.0.0 0.0.0.0 VLAN 10 192.168.10.3

这样,三层交换机仍然把所有出网流量丢给 OpenWrt。

💡 若要进一步提高安全性,可以在三层交换机上开启 DHCP Snooping,将接入口标记为 untrusted,把连接 OpenWrt 的口标记为 trusted,防止“野路由”乱发 DHCP,这里不展开。


4. OpenWrt:用 dnsmasq 同时服务多个网段

这里有一个小坑:用纯 UCI(/etc/config/dhcp)给“远端子网”分地址非常别扭
OpenWrt 的 start / limit 通常是基于“接口自己的 IP 网段”推导出来的,而我们现在这些网段(192.168.20/30/40/50)OpenWrt 并没有本地接口。

实测下来,最稳妥的方案是:

4.1 保持 LAN 的 DHCP 配置

/etc/config/dhcp 中,lan 部分类似:

config dhcp 'lan'
    option interface 'lan'
    option start '100'
    option limit '150'
    option leasetime '12h'

这段负责 192.168.10.0/24 的 DHCP 分配,不需要动。

4.2 在 /etc/dnsmasq.conf 里为 VLAN20/30/40/50 增加地址池

假设 IPv4 规划如下:

/etc/dnsmasq.conf 增加:

# VLAN20  HomeUser  192.168.20.0/24
dhcp-range=home,192.168.20.100,192.168.20.254,255.255.255.0,8h
dhcp-option=tag:home,3,192.168.20.1
dhcp-option=tag:home,6,114.114.114.114

# VLAN30  IOT  192.168.30.0/24
dhcp-range=iot,192.168.30.100,192.168.30.254,255.255.255.0,12h
dhcp-option=tag:iot,3,192.168.30.1
dhcp-option=tag:iot,6,114.114.114.114,8.8.8.8

# VLAN40  Guest 192.168.40.0/24
dhcp-range=guest,192.168.40.100,192.168.40.254,255.255.255.0,12h
dhcp-option=tag:guest,3,192.168.40.1
dhcp-option=tag:guest,6,192.168.10.3,114.114.114.114

# VLAN50  示例 192.168.50.0/24
dhcp-range=vlan50,192.168.50.100,192.168.50.254,255.255.255.0,8h
dhcp-option=tag:vlan50,3,192.168.50.1
dhcp-option=tag:vlan50,6,192.168.10.3,114.114.114.114

几个关键点:

最后,重启 dnsmasq:

/etc/init.d/dnsmasq restart

如果担心配置没加载,可以 logread -e dnsmasq 看一下新 range 是否被识别。


5. 验证流程与一些小坑

5.1 各 VLAN 客户端验证

以 VLAN20 为例:

  1. 找一台挂在 VLAN20 的机器,释放旧租约:

    • Windows: ipconfig /releaseipconfig /renew
    • Linux: dhclient -rdhclient -v
  2. 获取到新地址后检查:

    • IP 是否在 192.168.20.100–254 内;
    • 网关是否为 192.168.20.1
    • DNS 是否符合 /etc/dnsmasq.conf 里的设置。
  3. 测试连通性:

    • ping 192.168.20.1(三层交换机 VLAN20 网关);
    • ping 192.168.10.3(OpenWrt LAN);
    • ping 114.114.114.114
    • ping 外网域名

VLAN30/40/50 同理。

5.2 OpenWrt 侧检查

5.3 三层交换机侧检查


6. 一点经验小结

这次迁移 IPv4 DHCP 到 OpenWrt,踩到的几个点,简单记一下:

  1. 不要急着动 IP 结构,先只换 DHCP

    • 三层交换机继续做网关 + 路由,拓扑不动;
    • 只把地址分配这一块搬到 OpenWrt,整体风险会小很多。
  2. 远端网段的 DHCP 池,UCI 写法不如直接 dnsmasq.conf 来得直接

    • option start / option limit 这套对“非本机接口网段”其实不太友好;
    • 原生 dhcp-range 语法反而更清晰 —— 网段是什么就写什么。
  3. 记得删掉交换机原来的 ip dhcp pool

    • 否则你会遇到“有时拿到 OpenWrt 发的 IP,有时拿到交换机发的 IP”的鬼故事。
  4. DHCP Relay 的核心得靠 giaddr

    • OpenWrt 不知道 VLAN20/30/40 这些名字,它只看 giaddr 在哪个网段,然后用对应池;
    • 这也是为什么网关一定要写成各 VLAN 的 SVI IP。

整体看下来,这种“DHCP 在 OpenWrt,路由在三层交换机”的结构,对家庭/小工作室挺舒服的:
一个地方集中管理 DHCP/DNS,又不牺牲三层交换的性能与拓扑弹性——如果你也刚好是锐捷 + OpenWrt 的组合,或许可以参考一下这套折腾路线。

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

这个站点使用 Akismet 来减少垃圾评论。了解你的评论数据如何被处理