How to Put Smart-Home Devices on Their Own VLAN (and Still Reach Them from the Server)

An IoT network of its own: cameras and plugs can't see your laptops, but the server still sees them. VLANs, Netplan and three firewall rules.

A £12 smart plug runs firmware nobody will ever update, on the same network as your laptop, your phone and your server. A VLAN is a second, separate network carried over the same cables and Wi-Fi: devices on it can reach the internet (or not) and the server, but not each other's neighbours on the main network. The server gets a foot in both — a tagged interface — so Home Assistant, Frigate and MQTT work as before while the devices themselves are penned in.

Quick reference

PieceWhat
Needsa router or firewall that does VLANs (OpenWrt, pfSense/OPNsense, UniFi, Omada, MikroTik) and VLAN-aware Wi-Fi
Planmain LAN 192.168.1.0/24 (VLAN 1), IoT 192.168.20.0/24 (VLAN 20)
ServerNetplan VLAN interface enp3s0.20 with an IP in the IoT range
Rules on the routerIoT → internet: allow (or deny per device); IoT → main LAN: deny; main LAN → IoT: allow; IoT → server's IoT IP (MQTT, Frigate): allow
DiscoverymDNS reflector / Avahi on the router for HomeKit, Chromecast, Sonos

1. Create the VLAN on the router

Every platform differs, but the shape is the same:

  1. Networks → add: name IoT, VLAN ID 20, subnet 192.168.20.0/24, DHCP on.
  2. Wi-Fi → add SSID Home-IoT mapped to VLAN 20 (2.4 GHz only is fine; most devices can't do 5 GHz).
  3. Switch ports: the port to the server becomes a trunk carrying VLAN 1 untagged and VLAN 20 tagged. Ports for wired cameras: VLAN 20 untagged.

Consumer ISP routers can't do this; OpenWrt on a supported router, or a small managed switch plus a VLAN-aware access point, is the usual upgrade.

2. Give the server a tagged interface

sudo nano /etc/netplan/50-cloud-init.yaml

network:
version: 2
ethernets:
enp3s0:
dhcp4: true
vlans:
enp3s0.20:
id: 20
link: enp3s0
addresses: [192.168.20.2/24]

sudo netplan try → Enter. ip a now shows enp3s0.20 with 192.168.20.2. The server is on both networks. (If the server runs Docker with network_mode: host for Home Assistant, it immediately sees IoT broadcasts too.)

3. Firewall rules on the router

Rules live on the router, where traffic between VLANs is decided. In order:

  1. Allow IoT → 192.168.20.2 (the server's IoT address), TCP 1883 (MQTT), 8123 (Home Assistant), 8554 (Frigate RTSP restream if used).
  2. Allow established/related — replies to connections the main LAN started.
  3. Deny IoT → 192.168.1.0/24 (everything else on the main network).
  4. Allow or Deny IoT → internet. Many cameras and plugs work with no internet once they're on local integrations (ESPHome, Tasmota, Zigbee2MQTT, Frigate); block it and the firmware can't phone home. Devices that need the cloud (a voice assistant) get a per-device allow.
  5. Main LAN → IoT: allow (your laptop can still open a camera's web page).

The server's own UFW (tutorial 6) adds a second layer: sudo ufw allow in on enp3s0.20 to any port 1883 proto tcp, and nothing else on that interface.

4. Move the devices

Reconnect each plug, bulb hub and camera to the Home-IoT SSID (or its VLAN-20 switch port). Update their fixed IPs in Home Assistant, Frigate (RTSP URLs) and Zigbee2MQTT if they changed. Zigbee devices don't care — they talk to the coordinator stick on the server, not the network.

5. Discovery across the boundary

Some things rely on mDNS/multicast, which VLANs block by design: HomeKit accessories, Chromecast/Google Home, Sonos, AirPlay, printers. Options:

Home Assistant on the server with host networking sees both VLANs' broadcasts directly, so its discovery keeps working.

Checks

From a laptop on the main LAN: ping 192.168.20.50 (a camera) works. From inside the IoT network (a phone on Home-IoT): 192.168.1.50 times out, 192.168.20.2:8123 loads Home Assistant. From the server: mosquitto_sub still shows devices chattering.

Troubleshooting

Server's VLAN interface has no traffic. The switch port isn't a trunk with VLAN 20 tagged, or the VLAN ID differs.

Devices get no IP on the IoT SSID. DHCP isn't enabled on the VLAN 20 network, or the AP isn't passing the tag.

Home Assistant lost devices after the move. Their IPs changed; reserve them on the IoT DHCP and update integrations.

Casting from the phone stopped working. mDNS across VLANs — the reflector, or move the TV.

Everything slow on IoT. Cheap devices on 2.4 GHz contending; that's not the VLAN. Check channel overlap.

Wrapping up

A VLAN on the router, a tagged interface on the server, three firewall rules, the devices moved to their own SSID. The plugs and cameras can reach the broker and nothing else, the laptops are out of their reach, and Home Assistant and Frigate don't notice a difference. Reflect mDNS for the things you cast to, or keep those on the main network.

Call us