Skip to main content
RunBook Academy

OPNsenseXVII · DHCPDHCP relay

DHCP relay across VLANs — when the DHCP server is not on the same VLAN

Intermediate⏱ ~13 mintcpdumpdhcpdumppfctl

What you'll learn

  • Explain why DHCP needs a relay when the server is on a different VLAN
  • Configure OPNsense as a DHCP relay agent on a VLAN interface
  • Recognise the role of option 82 in relaying across VLANs
  • Identify the failure modes of DHCP relay in production
  • Choose between local DHCP server and central DHCP with relay

Prerequisites

Verified against OPNsense 25.x · FreeBSD 14.x · PF (FreeBSD packet filter) FreeBSD 14.x · Unbound 1.20+ · Kea DHCP OPNsense 25.x plugin · WireGuard in-kernel + OPNsense plugin · strongSwan (IPsec plugin) OPNsense 25.x plugin · OpenVPN 2.6.x · Suricata 7.x · 2026-08-14

Not yet marked complete on this device.

DHCP is a broadcast protocol. A client sends a Discover to 255.255.255.255; every host on the segment hears it, including any DHCP server on the segment. A router does not forward broadcasts — so a client on VLAN 10 cannot reach a DHCP server on VLAN 20 directly. The solution: a DHCP relay that converts the broadcast into a unicast and forwards it to the configured DHCP server.

This lesson covers how DHCP relay works, how to configure OPNsense as a relay agent, and the production failure modes that come from misconfigured relay.

Why DHCP needs a relay

A DHCP Discover is sent to the limited broadcast address 255.255.255.255. The IP TTL is 1, but more importantly, routers do not forward directed broadcasts (most modern routing protocols drop them) and limited broadcasts are scoped to the local link.

The implication:

  • A DHCP server on VLAN 10 can serve clients on VLAN 10 directly.
  • A DHCP server on VLAN 20 cannot serve clients on VLAN 10 directly (the Discover never reaches it).
  • A DHCP server on the firewall itself (e.g. the OPNsense LAN interface) cannot serve clients on a separate VLAN that has no DHCP server, unless a relay forwards the request.

The DHCP relay agent on the router (or firewall) intercepts the DHCP broadcast, converts it to a unicast packet addressed to the configured DHCP server, and forwards it. The server responds to the relay, which converts the unicast back to a broadcast (or unicast) on the client’s segment.

The relay flow

A typical DHCP relay exchange with the DHCP server on a different VLAN:

Client (VLAN 10)         Relay (firewall)         DHCP Server (VLAN 20 or WAN)
  | --- Discover broadcast -->      |                            |
  |   (chaddr = MAC, giaddr=0)      |                            |
  |                                  | --- Discover unicast ----> |
  |                                  |   (giaddr = relay IP)      |
  |                                  | <-- Offer unicast -------- |
  | <-- Offer broadcast ----------- |                            |
  | --- Request broadcast --------> |                            |
  |                                  | --- Request unicast -----> |
  |                                  | <-- ACK unicast ---------- |
  | <-- ACK broadcast ------------- |                            |

Three things to notice:

  1. The relay sets giaddr (the gateway IP address field in the DHCP message) to its own IP on the relay interface. The DHCP server uses this to know which subnet the request came from.
  2. The Discover goes out as a unicast to the configured server, not as a broadcast. The relay knows the server’s IP because it is configured.
  3. The server’s response goes back to the relay, which then delivers it to the client on the original segment.
Read-only / SafeDHCP relay exchange
$ tcpdump -nei igb1.10 port 67 or port 68 -vvv
12:34:56.789012 0.0.0.0.68 > 255.255.255.255.67: DHCP, length 308
12:34:56.789012   message-type 1 (discover)
12:34:56.789012   client-id option 1, length 7: ether aa:bb:cc:11:22:33
12:34:56.789012   DHCP option 82, length 14:
12:34:56.789012     RelayAgent Circuit ID: 0a (VLAN 10)
12:34:56.789012     RelayAgent Remote ID: a4:5e:60:dd:ee:ff
12:34:56.789020 192.168.10.1.67 > 192.168.20.5.67: DHCP, length 320
12:34:56.789020   message-type 1 (discover)
12:34:56.789020   gateway-ip 192.168.10.1
12:34:56.789020   DHCP option 82, length 14:
12:34:56.789020     RelayAgent Circuit ID: 0a (VLAN 10)
12:34:56.789020     RelayAgent Remote ID: a4:5e:60:dd:ee:ff

Illustrative output

OPNsense as a DHCP relay

OPNsense can act as a DHCP relay agent. The configuration is under Services → DHCPv4 → Relay:

  • Enable: yes.
  • Interface(s): the interface(s) on which to relay. Typically the VLAN interfaces that do not have a local DHCP server.
  • Relay destination: the IP of the DHCP server (could be the OPNsense itself, or a separate server on another VLAN).

The relay listens for DHCP broadcasts on the configured interfaces and forwards them to the destination as unicasts.

For a typical estate where OPNsense is both the gateway and the DHCP server:

  • VLAN 10 has OPNsense’s DHCP server running on the firewall’s VLAN 10 IP — no relay needed.
  • VLAN 20 has no local DHCP server; OPNsense relays VLAN 20 DHCP requests to a central DHCP server on VLAN 30.

Or, the operator centralises DHCP on a separate server entirely (e.g. Windows Server, a Linux server running ISC DHCP, or a cloud-managed DHCP service). All VLANs relay to the central server.

The role of option 82

When a relay forwards a DHCP request, it adds option 82 (Relay Agent Information). The sub-options carry:

  • Sub-option 1 (Circuit ID): the VLAN or interface identifier. Configurable.
  • Sub-option 2 (Remote ID): typically the relay’s MAC or a configured identifier.

The DHCP server uses option 82 to:

  1. Select the correct scope. If the relay is on VLAN 20, option 82’s circuit ID is “VLAN 20”; the server leases from the VLAN 20 scope.
  2. Apply scope-specific options. Different VLANs may have different gateway, DNS, or DHCP options (e.g. VLAN 10 gets internal DNS, VLAN 20 gets public DNS).
  3. Verify the relay is trusted. Some servers reject requests without option 82 or with unexpected option 82 values.

Without option 82, the DHCP server sees only the relay’s IP and cannot distinguish VLAN 20 from VLAN 30 — it leases from the wrong scope, and clients get the wrong addresses.

Centralised DHCP vs local DHCP

Two architectural patterns:

PatternProsCons
Local DHCP on each VLANSimple, no relay, no extra hopEach VLAN has its own scope to maintain; no central inventory
Centralised DHCP with relaySingle source of truth; easier inventory and auditRelay adds a hop; option 82 must be configured correctly

For small estates (1-3 VLANs), local DHCP is simpler. For medium and large estates (5+ VLANs), centralised DHCP with relay reduces maintenance and provides a single point of audit.

OPNsense supports both. The operator chooses based on the estate’s needs.

Common DHCP relay failure modes

Five failure modes appear repeatedly:

  1. Relay enabled but destination wrong. The relay forwards DHCP requests to an unreachable IP. Clients never receive a lease. Fix: verify the destination IP is reachable from the relay.

  2. Local DHCP server also enabled on the relay interface. Both the local server and the relay respond. Clients get offers from both; the result is unpredictable. Fix: disable the local server on the relay interface.

  3. Option 82 not preserved end-to-end. A second relay or firewall in the path strips option 82. The server cannot identify the originating VLAN. Fix: configure all devices in the path to preserve option 82.

  4. Firewall rule blocking DHCP. The DHCP relay forwards unicast packets to the server; a firewall rule on the server’s interface may block the return path. Fix: permit UDP 67/68 between the relay and the server.

  5. VLAN interface not configured on the relay. The relay listens on the parent interface but not the VLAN subinterface. DHCP Discover from the VLAN segment never reaches the relay. Fix: explicitly add the VLAN interface to the relay configuration.

Verification

The verification pattern:

# On the firewall, confirm the relay is running and listening
sockstat -l | grep :67

# Capture DHCP on the relay interface
tcpdump -nei igb1.10 port 67 or port 68 -vvv

# From a client on the VLAN, request a lease
dhclient -r <iface>; dhclient <iface>

# Verify the lease
ifconfig <iface> | grep inet

The captures should show:

  • Discover broadcast from the client (giaddr = 0).
  • Discover unicast from the relay to the server (giaddr = relay IP).
  • Offer unicast from the server to the relay.
  • Offer broadcast (or unicast) from the relay to the client.
  • Request and ACK following the same path.

If any packet is missing, the relay or server has a problem.

Summary

  • DHCP is a broadcast protocol; a router does not forward broadcasts, so DHCP needs a relay when the server is on a different VLAN.
  • The relay converts the broadcast to a unicast, sets giaddr to its own IP, optionally adds option 82, and forwards to the configured server.
  • OPNsense can act as a DHCP relay agent; configure the interface(s) and destination under Services → DHCPv4 → Relay.
  • Option 82 (Relay Agent Information) carries the circuit ID and remote ID, which the server uses to select the correct scope.
  • Do not enable both the local DHCP server and the relay on the same interface.

Knowledge check · 4 questions

  1. Q1. You have VLANs 10, 20, and 30 on OPNsense. VLAN 10 has a local DHCP server. VLANs 20 and 30 do not. Where do you configure DHCP relay on OPNsense?

  2. Q2. The DHCP relay agent is a stateful component that maintains lease information; if the relay restarts, all leases on the relayed VLANs are lost.

  3. Q3. Which of the following are valid DHCP relay failure modes? Select all that apply.

  4. Q4. A client on VLAN 20 is supposed to get an IP from the 192.168.20.0/24 subnet via DHCP relay. It receives an IP from 192.168.10.0/24 (the VLAN 10 subnet). What is the most likely cause?

Passing score: 75%. Answers are checked in this browser.