Private Home Lab

Self-hosted · No cloud 

Aqara and Xiaomi on an IoT VLAN with Home Assistant

VLAN isolation breaks Aqara hub discovery and Xiaomi Miio control. The fix is mDNS reflection, outbound NAT, and firewall rules in the right order.

Aqara and Xiaomi Devices on an IoT VLAN with Home Assistant

Putting your Aqara hub or Xiaomi Miio devices on a dedicated IoT VLAN is the right call for both security and privacy. The problem is that it usually breaks everything the moment you do it. Your Aqara hub vanishes from Home Assistant’s device list. Xiaomi Miio devices stop responding to commands. You end up either rolling back or punching holes in your firewall until you’re not sure what you’ve actually isolated.

This guide covers the specific mechanisms behind each failure and the three targeted fixes that solve them. An mDNS reflector for Aqara hub discovery. Outbound NAT for Xiaomi Miio cross-subnet control. Firewall rules that block cloud while keeping local HA communication intact.

I’ve also drawn on V2EX community discussions, particularly around the June 2022 Mi Home server outage (米家崩了, “Mi Home collapsed”), where Chinese homelab users documented in real time which devices survived cloud blocking and which didn’t. That empirical data is more useful than any vendor documentation.


Why VLAN isolation breaks things, and what specifically breaks

The mDNS problem and Aqara hub discovery

Aqara hubs (M2, M3, E1) advertise their presence using mDNS (Multicast DNS, port UDP 5353). When Home Assistant scans for HomeKit Controller or Matter devices, it listens for mDNS announcements on the local network.

mDNS uses link-local multicast at 224.0.0.251. Multicast traffic does not cross VLAN boundaries unless something actively forwards it. When your Aqara hub is on 192.168.20.0/24 (IoT VLAN) and Home Assistant is on 192.168.1.0/24 (main LAN), the hub’s mDNS announcements never reach HA. The HomeKit Controller integration shows nothing. Matter commissioning hangs at discovery.

This is the most common failure report I see in HA community threads, and it has nothing to do with authentication or permissions. The hub is there. HA simply cannot hear it.

The same issue applies to the Aqara FP2 (which uses HomeKit over Wi-Fi, not Zigbee) and to any Matter device on your IoT VLAN.

The UDP source IP problem and Xiaomi Miio devices

Xiaomi Miio (米家 Miio) Wi-Fi devices, including smart plugs, air purifiers, robot vacuums, and many lights, use a UDP-based local protocol on port 54321. The devices filter incoming UDP packets by source IP. They only accept commands from a host on the same subnet, a behavior documented in the OpenMiHome binary protocol notes.

When Home Assistant sits on 192.168.1.x and the Miio device is on 192.168.20.x, the device rejects HA’s commands silently. No error in the logs, no timeout feedback. The device just ignores the traffic because the source IP doesn’t match its own subnet.

The same behavior affects the hass-xiaomi-miot integration in local mode. Local mode requires that the HA instance and the Mi devices share a subnet, and the integration falls back silently to cloud polling when the subnet check fails.

What keeps working with Zigbee via a local gateway

This is the good news, and the Chinese homelab community documented it clearly during the June 2022 Mi Home server outage.

When Mi Home servers went down that month, users on V2EX (thread t/860266) logged their experience in real time. The pattern was consistent. 绑定了本地网关的Zigbee设备 (Zigbee devices bound to a local gateway) kept responding to commands through the entire outage. Temperature sensors updated. Lights toggled. Door sensors reported open and closed. Meanwhile, Wi-Fi devices that routed commands through Mi Home’s MQTT cloud went completely silent.

The implication for VLAN design is significant. Zigbee devices that pair through an Aqara hub communicate over Zigbee radio to the hub. The hub then speaks HomeKit or Matter to HA over the local network. The Zigbee layer is already local. As long as the hub itself can reach HA (which requires solving the mDNS problem, nothing else), your entire Zigbee device fleet works with no additional configuration per device.

Put another way, once you fix hub discovery, every Zigbee sensor, switch, and actuator behind that hub comes along for free.


The architecture that works

The design principle, called “隐私设备子网隔离” (privacy device subnet isolation) by Chinese homelab users who arrived at this through iteration, is straightforward:

  • IoT VLAN (e.g. 192.168.20.0/24) holds all Aqara and Xiaomi devices
  • WAN access from the IoT VLAN is blocked at the firewall
  • LAN-internal traffic is allowed selectively, HA host to IoT VLAN and IoT VLAN to HA host
  • An mDNS reflector on the router bridges mDNS between VLANs
  • Outbound NAT (masquerade) rewrites HA’s source IP for traffic toward Xiaomi Miio devices

This is not a complicated architecture. The three pieces (mDNS reflector, outbound NAT, and firewall rules) are independent and can be applied incrementally.

IoT VLAN with WAN blocked and LAN-internal traffic allowed

The firewall policy for the IoT VLAN has two goals. Devices cannot reach the internet, but HA can still reach them and they can reply to HA.

A typical rule order:

  1. Allow IoT VLAN to HA host IP (so devices can reply to HA queries and send state updates)
  2. Allow HA host IP to IoT VLAN (so HA can send commands and poll devices)
  3. Block IoT VLAN to WAN (the cloud blocking rule)
  4. Block IoT VLAN to other LAN subnets (optional, depends on whether you want IoT devices talking to your main LAN)

The order matters. Rule 1 must precede rule 3, otherwise the reply traffic from IoT devices back to HA gets dropped by the WAN block rule if your firewall applies rules sequentially.

mDNS reflector on the router

An mDNS reflector listens for mDNS multicast on one interface and rebroadcasts it on another. Every router platform handles this differently.

OpenWrt. Install the avahi-daemon package. Edit /etc/avahi/avahi-daemon.conf and set allow-interfaces to include both your main LAN interface (e.g. br-lan) and your IoT VLAN interface (e.g. br-iot). Restart avahi. That is the full configuration for most setups.

pfSense and OPNsense. Both include a built-in mDNS repeater service. In pfSense, look for the mDNS/Avahi repeater package under Services. In OPNsense, install the mdnsrepeater plugin via System → Firmware → Plugins. Select the interfaces you want to bridge (LAN and IoT VLAN) and enable it.

Ubiquiti UniFi. Go to Settings → Networks → Advanced → mDNS, or Settings → Routing → mDNS on newer firmware. Enable mDNS for the IoT network. UniFi calls it “Multicast DNS” and handles reflection automatically between networks when enabled. The default mode forwards a predefined list of common services, with “All” forwarding everything and “Custom” letting you pick. If you are on older firmware that does not show this option, the workaround is the avahi-daemon approach via SSH on the UDM.

After enabling mDNS reflection, restart the avahi or mDNS repeater service and watch the HA integrations page. The Aqara hub should appear within 30 to 60 seconds if the hub is powered and advertising.

Outbound NAT for Xiaomi Miio

For Xiaomi Miio devices and hass-xiaomi-miot in local mode, the fix is outbound NAT. Configure the firewall to rewrite the source IP of traffic from HA’s host, when that traffic is destined for the IoT VLAN, to an IP within the IoT VLAN subnet.

The router needs an address in the IoT VLAN subnet (which it typically has as the gateway address, e.g. 192.168.20.1). The NAT rule rewrites HA’s source IP (192.168.1.x) to 192.168.20.1 for packets going to 192.168.20.0/24. The Miio device receives the packet, sees a source IP in its own subnet, accepts it, and replies to 192.168.20.1. The router’s NAT table tracks the connection and forwards the reply back to HA.

In pfSense and OPNsense, this is an outbound NAT rule under Firewall → NAT → Outbound. Create a rule with Interface set to the IoT VLAN, Source set to the HA host IP, Destination set to the IoT VLAN network, and Translation set to Interface Address.

In OpenWrt, add a masquerade rule for traffic from the HA host IP toward the IoT subnet. With nftables (OpenWrt 22.03 and newer):

nft add rule ip nat POSTROUTING ip saddr 192.168.1.50 ip daddr 192.168.20.0/24 masquerade

Replace 192.168.1.50 with your HA host’s IP. Rules added this way are volatile and disappear on reboot. Make them persistent by adding the rule to /etc/nftables.d/ (or /etc/firewall.user on older fw3 builds) so it reloads on every restart.


Step-by-step setup

1. Create your IoT VLAN and assign devices

Create a VLAN (this guide uses 192.168.20.0/24 as the example subnet throughout) on your router, and configure your access point(s) to broadcast a separate SSID mapped to this VLAN. Connect all Aqara hubs and Xiaomi Wi-Fi devices to the IoT SSID.

If you are using Aqara hubs, move them first. Your Zigbee sensors will follow automatically. They communicate with the hub over Zigbee radio, not over Wi-Fi, so their network connectivity is only through the hub.

Zigbee-only devices (sensors, switches, wall modules) do not need Wi-Fi access. They do not have IP addresses on your network. The hub does.

2. Enable mDNS reflection

Apply the mDNS reflector configuration for your router platform as described above. Verify it is working before moving on.

Quick test, from the HA host, run:

avahi-browse -rt _hap._tcp

If you see the Aqara hub listed with its IP (e.g. 192.168.20.x), mDNS reflection is working. If you do not have avahi-browse on the HA host, install avahi-utils or check from a machine on the main LAN.

If the hub does not appear, confirm the avahi or mDNS repeater service is running on the router and that both interface names are specified correctly. A common mistake on OpenWrt is using bridge interface names (br-iot) versus physical VLAN interface names (eth0.20). Check ip link output to confirm which name avahi sees.

3. Add the outbound NAT rule for Xiaomi Miio (if applicable)

If you are using Xiaomi Wi-Fi devices with the native Miio integration or hass-xiaomi-miot in local mode, add the outbound NAT rule now.

You can confirm whether this is needed by trying HA device control first. If a Xiaomi switch or plug responds to toggle commands from the HA UI, NAT is either already working or not required. If it is silent, add the NAT rule and test again.

For hass-xiaomi-miot specifically, check the integration’s logs for messages like “local connection failed, falling back to cloud.” That is the signal that local mode is not working. For broader context on the Xiaomi local-control story outside China, see our explainer on Xiaomi Home Assistant local control outside China.

4. Firewall rules to block cloud while keeping local HA control

Apply the firewall rules in this order (adapt to your platform’s rule ordering semantics):

# Allow HA host to reach IoT VLAN
ALLOW src=192.168.1.50/32 dst=192.168.20.0/24

# Allow IoT VLAN to reach HA host (replies and state push)
ALLOW src=192.168.20.0/24 dst=192.168.1.50/32

# Allow IoT VLAN to reach router DNS (optional but recommended)
ALLOW src=192.168.20.0/24 dst=192.168.20.1/32 port=53

# Block IoT VLAN from reaching the internet
BLOCK src=192.168.20.0/24 dst=0.0.0.0/0 (WAN)

# Block IoT VLAN from reaching other LAN subnets (optional)
BLOCK src=192.168.20.0/24 dst=192.168.1.0/24

For the Aqara hub specifically, the ports HA needs to communicate with it cross-VLAN are TCP 80 (initial HTTP handshake for setup), UDP 1900 (UPnP discovery, optional), and UDP 5353 (mDNS). If you want tighter rules rather than a broad allow from HA to the IoT VLAN, you can scope these to the hub’s specific IP instead.

For HomeKit Controller pairing, the Aqara hub advertises its HomeKit Accessory Protocol service over mDNS on UDP 5353, then negotiates an ephemeral TCP port that HA uses for the ongoing pairing session. The practical implication is that you do not need to pin a specific high port. Allow TCP from the HA host to the hub’s IP on the IoT VLAN, and the HAP session will establish on whatever port the hub advertised. If you want a deeper look at the M2 setup path specifically, see our Aqara Hub M2 + Home Assistant full local control guide.

5. Verify Aqara hub discovery and Xiaomi device control

After applying all three configurations:

  1. In HA, go to Settings → Devices & Services → Add Integration → HomeKit Controller (or Matter if you are using an M3). The hub should appear in the discovered devices list within a minute.

  2. If using the Xiaomi Miio or hass-xiaomi-miot integration, open the integration and check whether devices show as “Available” with a local connection indicator. Trigger a toggle and confirm the device responds.

  3. Check the HA logs for any “timeout” or “unreachable” errors on Aqara or Xiaomi entities. Absence of errors after a few minutes of normal use is the best confirmation.


What still needs cloud after this setup

Blocking WAN for your IoT VLAN cuts cloud telemetry, but a few functions genuinely require cloud access and will break.

OTA firmware updates. Both Aqara and Xiaomi push firmware through their own cloud infrastructure. With WAN blocked, you lose the ability to update hub firmware through the Aqara Home or Mi Home app. For Aqara hubs running in HomeKit mode, this is mostly acceptable, because the hub runs local-first. If you want to retain update access, either temporarily unblock WAN for the hub’s IP during maintenance windows, or run a split DNS approach where update domains resolve internally (complex, not covered here).

Initial Aqara hub setup. The Aqara hub requires a cloud account and app for initial provisioning. Do the initial setup before moving the hub to the IoT VLAN. Once provisioned and paired to HA, the hub operates locally with WAN blocked.

Matter commissioning for new devices. Matter commissioning for an Aqara hub acting as a Matter bridge requires a working network path during the commissioning window. After commissioning, ongoing operation is local. For the trade-offs between Aqara HomeKit mode and Matter mode on the M3 and M100, the wider context is covered in our explainer on whether Aqara works without internet.

Mi Home remote access and voice assistant integrations. If you use Google Home or Alexa with Mi Home, those stop working with WAN blocked. This is expected. The whole point is local-first.

What does work reliably after cloud blocking: all Zigbee devices via Aqara hub, all HomeKit Controller automations, all Matter entities already commissioned, and all Miio devices with the NAT rule applied.


Verifying cloud is actually blocked

Setting firewall rules is not the same as confirming traffic is blocked. Two verification methods.

DNS-level check. From a device on the IoT VLAN (use your phone connected to the IoT SSID), try to resolve a known Xiaomi/Aqara cloud domain:

nslookup ot.io.mi.com 8.8.8.8

If the IoT VLAN can reach 8.8.8.8, your WAN block rule has a hole. You have allowed DNS traffic to the internet. Plug it by adding an explicit block for port 53 UDP/TCP to external DNS servers, and use only your router’s internal DNS for the IoT VLAN.

Packet capture. If you have tcpdump access on the router or a mirrored port, capture traffic from the IoT VLAN’s interface and filter for outbound WAN traffic:

tcpdump -i eth1 -n 'not net 192.168.0.0/16 and src net 192.168.20.0/24'

Substitute the correct interface and subnets for your setup. Any traffic appearing here is IoT VLAN traffic escaping to the internet. Common offenders include Xiaomi devices polling ot.io.mi.com (Mi Home cloud), Aqara devices reaching aiot-coap.aqara.com (Aqara’s device registration endpoint), and NTP traffic to time.is or pool.ntp.org.

NTP is worth allowing. Blocking NTP for IoT devices causes time-drift in automations and log timestamps. Either allow UDP 123 outbound for the IoT VLAN to a known NTP server, or run a local NTP server (your router likely already does this) and configure IoT devices to use it.


Pulling this together

The architecture that works, an IoT VLAN with WAN blocked, an mDNS reflector on the router, and outbound NAT for Xiaomi Miio, is the same one that Chinese homelab users arrived at independently through trial and error, and the same one documented (in pieces) across HA community threads, OPNsense forums, and Chinese V2EX discussions.

The reason no single English guide covered it is that the three failure modes (mDNS, UDP source filtering, cloud dependency) look like one problem but require three separate fixes. Once you understand why each breaks, the solution is mechanical.

Your Zigbee devices, once the hub is visible to HA, run completely locally with WAN blocked. That is the setup documented in the V2EX outage thread. Zigbee devices via local gateway, resilient to cloud failure, isolated from the internet.


FAQ

Why does my Aqara hub stop working in Home Assistant after I put it on a VLAN?

The hub uses mDNS to announce itself, and mDNS does not cross VLAN boundaries. Home Assistant cannot find the hub because multicast traffic is being dropped by the switch or router between VLANs. The fix is an mDNS reflector on the router. See the setup steps above.

How do I block Xiaomi devices from reaching the internet while keeping Home Assistant control?

Add a firewall rule that blocks the IoT VLAN from reaching WAN, then add explicit allow rules for traffic between the HA host and the IoT VLAN. The block must come after the allow rules in your firewall’s rule order, otherwise reply traffic from devices back to HA gets dropped too.

Do Aqara Zigbee devices still work if I block the hub’s internet access?

Yes. This is the key finding from the June 2022 Mi Home outage. Zigbee devices connected through local Aqara gateways kept responding throughout the cloud outage. The Zigbee layer is already local. Block WAN for the hub and your Zigbee sensors, switches, and actuators keep working through HA.

What ports does the Aqara hub need open to work with Home Assistant?

UDP 5353 for mDNS is the load-bearing one — that is the discovery channel. TCP 80 covers the initial HTTP setup path, and UDP 1900 covers UPnP discovery if your integration uses it. The HomeKit Accessory Protocol session that HA uses for ongoing control runs over an ephemeral TCP port the hub advertises in its mDNS record, so you do not need to pin a specific high port. Allow TCP from the HA host to the hub’s IP on the IoT VLAN and HAP will find its own port.

How do I set up mDNS reflection for Aqara Matter devices on a separate IoT VLAN?

The same mDNS reflector that fixes Aqara HomeKit Controller discovery also resolves Matter cross-VLAN issues. Matter uses mDNS for both commissioning and ongoing communication. Configure your router’s avahi daemon or mDNS repeater plugin to include both the main LAN and IoT VLAN interfaces, as described in step 2 above.

.
On this page
.

Read Next

If you found this useful, try these.