12 KiB
Shelly DHCP Investigation
Date: 2026-04-17
Update: the Kea reservation workaround was applied during this pass.
Scope
This document investigates why Shelly-Server is live at 192.168.100.127 even though OPNsense at 192.168.100.254 has a reservation for the device at 192.168.100.75 and is expected to be the only authoritative DHCP server on the LAN.
No destructive changes were made during this pass. All checks were read-only diagnostics.
Executive Summary
The strongest current evidence does not point to a confirmed rogue DHCP server.
It also does not support the idea that OPNsense is holding an old reservation for a replaced Shelly unit.
The stronger explanation is:
Shelly-Serveris configured for DHCP, not a static IP.- The device is live and reports itself as
192.168.100.127. - The firewall still has a static reservation for the device's factory MAC
34:94:54:73:E2:28at192.168.100.75. - On the LAN,
192.168.100.127resolves to a different MAC,02:0F:B5:73:E2:28, not the Shelly factory MAC. - That observed MAC is locally administered and preserves only the last three bytes of the Shelly MAC.
This strongly suggests an intermediate bridge/router/AP behavior that rewrites the client MAC on the wire. If that is true, OPNsense may still be the DHCP server, but the reservation on 34:94:54:73:E2:28 will never match because the DHCP server sees 02:0F:B5:73:E2:28 instead.
If you had replaced the Shelly and forgotten to update the reservation, the reservation MAC and the live device's own reported MAC would differ. In this case they match, so the reservation appears tied to the correct physical Shelly, just not to the effective MAC seen on the LAN.
Confirmed Facts
1. OPNsense LAN identity
- LAN interface IP in OPNsense config:
192.168.100.254/24 - The local Windows host on the same subnet has:
- IPv4 address
192.168.100.134 - default gateway
192.168.100.254 - DHCP server
192.168.100.254 - DNS server
192.168.100.254
- IPv4 address
This confirms that normal clients on the LAN are getting DHCP from the firewall.
2. Shelly device runtime state
Direct HTTP inspection of the live device at http://192.168.100.127/ returned:
- device name
Shelly-Server - device type
SHEM/ Shelly EM - factory MAC
34945473E228 - Wi-Fi SSID
Shellynet - IP
192.168.100.127 - Wi-Fi mode
ipv4_method: dhcp - MQTT connected
true
This rules out a device-side static IP configuration.
3. OPNsense reservation and DNS state
OPNsense config contains a reservation for:
- IP
192.168.100.75 - MAC
34:94:54:73:e2:28 - hostname
Shelly-Server
The live Shelly web API reports the same factory MAC, 34:94:54:73:E2:28.
That means the reservation is mapped to the correct Shelly hardware identity.
Firewall DNS answers currently conflict:
Shelly-Server.maddo.science -> 192.168.100.75shellyem-34945473E228.maddo.science -> 192.168.100.127- reverse lookup of
192.168.100.127returnsshellyem-34945473E228.maddo.science
That means the firewall has both:
- a static name tied to the reserved IP
- a learned live record tied to the current IP
4. Local ARP evidence
Known Shelly devices on the same subnet resolve normally to their vendor MACs:
192.168.100.62 -> 24-4C-AB-41-87-35192.168.100.76 -> 24-4C-AB-41-6D-0C192.168.100.96 -> 34-94-54-78-06-1B
But the live Shelly-Server IP resolves as:
192.168.100.127 -> 02-0F-B5-73-E2-28
The first octet 02 marks this as a locally administered MAC, not the Shelly factory OUI. The last three bytes 73-E2-28 match the device suffix.
That is the key anomaly in this investigation.
Interpretation
The observed facts fit this model best:
Shelly-Serveris connected through something onShellynetthat rewrites or virtualizes the client MAC on the LAN side.- OPNsense may still be handing out the lease, but it is likely handing it to
02:0F:B5:73:E2:28, not to34:94:54:73:E2:28. - Because the reservation is keyed to the factory MAC, the reservation at
192.168.100.75is bypassed. - The device then receives a dynamic address inside the general pool, which explains
192.168.100.127.
So the most likely correction is not "replace the old reservation MAC with the new device MAC." The factory MAC already matches. The only MAC mismatch is between the factory MAC and the translated on-wire MAC observed for the live IP.
This explanation is more consistent with the evidence than a rogue DHCP server because:
- the local host is using
192.168.100.254as DHCP correctly - the firewall DNS has a live learned name for
192.168.100.127 - the on-wire MAC for
192.168.100.127does not match the reservation MAC
Alternative Explanation
A second DHCP server is still possible, but current evidence is weaker for that theory.
For a rogue DHCP explanation to fit all observations, one of these would also need to be true:
- the firewall is somehow learning dynamic DNS records for a lease it did not issue
- or the second DHCP domain is bridged into the LAN in a way that still produces the rewritten local MAC pattern
That is possible, but it is not the simplest explanation from the data collected so far.
Likely Root Causes
1. Wireless bridge or router mode on the Shellynet path
Examples:
- Wi-Fi extender in router mode
- client bridge with MAC NAT
- WISP mode
- AP/client isolation feature that synthesizes per-client LAN MACs
- travel router or embedded bridge in front of the Shelly
2. Reservation keyed to the wrong effective MAC
If the DHCP server sees 02:0F:B5:73:E2:28 on the wire, a reservation for 34:94:54:73:E2:28 will never apply.
3. Stale naming and reservation state on the firewall
The static host entry for Shelly-Server.maddo.science still points to .75, while the firewall also knows a live dynamic name at .127. That split-brain state makes troubleshooting harder even if DHCP itself is still on the firewall.
What I Could Not Prove In This Pass
- I did not directly read the active DHCP lease database from OPNsense because the available SSH wrapper restricted several generic shell commands.
- I did not capture a DHCP exchange packet trace from the firewall.
- I did not inspect the AP/controller behind
Shellynetbecause that system is not exposed through the current toolset.
So the exact point where the MAC changes is still unverified.
Recommended Next Checks
Highest value checks
-
Inspect the device or controller that provides
Shellynet.- Determine whether it is a pure bridge, router, repeater, WISP client, or extender.
- Look for features such as MAC NAT, proxy ARP, client isolation, wireless bridge translation, or MAC cloning.
-
Check the live DHCP lease table on OPNsense for
192.168.100.127.- Confirm which MAC the firewall associates with that lease.
- Check whether the hostname is
shellyem-34945473E228.
-
Run a packet capture during a DHCP renew from the Shelly.
- Capture on the LAN side of the firewall for UDP
67/68. - Confirm whether the DHCP client identifier or source MAC is
34:94:54:73:E2:28or02:0F:B5:73:E2:28.
- Capture on the LAN side of the firewall for UDP
Good follow-up checks
-
Search the AP client list for both MACs:
34:94:54:73:E2:2802:0F:B5:73:E2:28
-
Check whether any other Shelly devices on
Shellynetshow the same MAC translation pattern. -
Verify whether
Shellynetis bridged directly onto192.168.100.0/24or routed/NATed by an intermediate device.
Proposed Fixes
Plain-English Explanation
The simplest reading of the evidence is this:
- the Shelly itself is fine
- OPNsense is probably still the DHCP server
- the
Shellynetextender is likely changing how the Shelly appears on the network - because of that, OPNsense does not match the Shelly to its reservation at
192.168.100.75 - the Shelly then gets a normal dynamic IP instead, currently
192.168.100.127
So the real problem is probably not the Shelly and not Home Assistant.
The likely problem is the Wi-Fi extender path.
Recommended Solution
The best solution is to stop using the extender path for this Shelly if possible.
Preferred order:
- Move
Shelly-Serveronto a normal Wi-Fi network that is bridged directly to the main LAN. - If that is not possible, reconfigure the extender so it behaves as a simple bridge or access point and does not rewrite client identity.
- Only if neither is possible, use a DHCP reservation for the effective MAC currently seen on the LAN as a workaround.
Best Fix
Move the Shelly off Shellynet and onto a normal SSID served directly by the main Wi-Fi infrastructure.
Why this is the best fix:
- it should let OPNsense see the Shelly's real MAC again
- it should make the existing reservation at
192.168.100.75work normally - it removes the weird translation behavior from the network path
- it is simpler and more robust than working around the extender behavior
After moving the Shelly to a normal SSID:
- reboot the Shelly or renew its network connection
- verify that it takes
192.168.100.75 - verify that
Shelly-Server.maddo.scienceresolves correctly - verify that Home Assistant still sees live MQTT updates
Good Workaround
If the extender must stay in place, use the MAC that the LAN is actually seeing for the live IP.
Current observed effective MAC:
02:0F:B5:73:E2:28
That workaround would mean:
- update the OPNsense reservation to use
02:0F:B5:73:E2:28instead of34:94:54:73:E2:28 - keep the reserved IP as
192.168.100.75 - reconnect or reboot the Shelly
- verify whether it then gets
192.168.100.75
Current state after applying the workaround:
- reservation IP:
192.168.100.75 - reserved effective MAC:
02:0F:B5:73:E2:28 - hostname:
Shelly-Server - Kea description:
Shelly-Server via Shellynet extender workaround; physical MAC 34:94:54:73:e2:28 - firewall config backup created before change:
/conf/config.xml.pre-shellynet-workaround-20260417
This workaround may succeed, but it has a risk:
- if the extender changes that translated MAC later, the reservation will break again
What I Recommend You Actually Do
If you want the most reliable outcome with the least long-term confusion:
- first try to get
Shelly-ServeroffShellynet - if that is not realistic, reserve
192.168.100.75for02:0F:B5:73:E2:28as a workaround - once it works, keep both MACs documented:
- physical Shelly MAC:
34:94:54:73:E2:28 - effective LAN-side MAC through extender:
02:0F:B5:73:E2:28
- physical Shelly MAC:
What Not To Do
- do not assume the reservation is stale because of a replaced Shelly; the current Shelly reports the same physical MAC stored in OPNsense
- do not delete historical information about the physical MAC; it is still the real hardware identity of the device
- do not assume Home Assistant is the problem; it is working correctly because MQTT is working
Preferred fix
Remove the MAC-rewriting hop from the Shelly path.
That means:
- put the Shelly on a normal bridged SSID
- or reconfigure the
Shellynetinfrastructure so the original client MAC reaches the firewall unchanged
If the original MAC reaches OPNsense, the existing reservation at 192.168.100.75 should be able to work as intended.
Acceptable workaround
If the Shellynet path must stay as-is, create the reservation for the effective on-wire MAC actually seen by DHCP, after confirming it is stable.
Based on current evidence, that candidate MAC is:
02:0F:B5:73:E2:28
This is only a workaround. If that translated MAC is generated dynamically by the bridge and can change, it is not a robust long-term fix.
It should not be documented as an "old Shelly MAC." It is better treated as an observed effective LAN-side MAC associated with the current path to Shelly-Server.
Cleanup after the root issue is fixed
- Align firewall DNS so there is only one canonical name/IP for this device.
- Remove or update stale static entries that still point
Shelly-Serverat.75if the intended address changes. - Re-test Home Assistant entity availability and direct web access after the network path is corrected.
Working Conclusion
The current evidence supports this working conclusion:
OPNsense at 192.168.100.254 is still likely the real DHCP authority, but Shelly-Server is probably not presenting its factory MAC to that DHCP server. Instead, something on the Shellynet path appears to be rewriting the MAC to 02:0F:B5:73:E2:28, causing the firewall to hand out a dynamic lease at 192.168.100.127 and bypass the reservation for 192.168.100.75.
That makes this look less like a rogue DHCP server problem and more like a MAC translation or bridging mode problem that breaks DHCP reservations.