Configure Avahi Daemon as an mDNS Reflector on Linux: Cross-VLAN Discovery for AirPlay, Chromecast, and Printers

Networking tutorial - IT technology blog
Networking tutorial - IT technology blog

It is 2:15 AM on a Sunday morning. The network team just finished segmenting the office LAN, moving 45 IoT devices, 12 network printers, and 8 conference room TVs onto isolated subnets. Ten minutes later, the alert queue blows up: executives cannot cast slides to Chromecast displays, staff cannot discover HP printers, and Apple AirPlay mirroring has vanished across all MacBooks.

The culprit? Multicast DNS (mDNS). It runs over UDP port 5353 using link-local multicast address 224.0.0.251 (IPv4) or ff02::fb (IPv6) with a Time-to-Live (TTL) of 1. By specification, L3 routers discard these packets at subnet boundaries. Splitting a flat network into VLANs instantly breaks zero-configuration discovery.

Instead of collapsing your security boundaries, you can run the Avahi daemon as an mDNS reflector on a multihomed Linux router, gateway, or lightweight Proxmox LXC container.

Quick start (5 min)

If you are managing an active outage, here is the emergency deployment procedure for Debian and Ubuntu hosts connected to your trunked VLAN interfaces.

1. Install Avahi and mDNS Utilities

sudo apt update && sudo apt install -y avahi-daemon avahi-utils

2. Enable the Reflector Feature

Open the primary configuration file:

sudo nano /etc/avahi/avahi-daemon.conf

Set enable-reflector=yes under the [reflector] block and configure host limits:

[server]
host-name=mdns-gateway
use-ipv4=yes
use-ipv6=yes
check-response-ttl=no

[reflector]
enable-reflector=yes

[rlimits]
rlimit-core=0
rlimit-data=4194304
rlimit-fsize=0
rlimit-nofile=768
rlimit-stack=4194304
rlimit-nproc=3

3. Restart the Daemon and Verify

sudo systemctl restart avahi-daemon
sudo systemctl status avahi-daemon

Query active service advertisements across all interfaces:

# Browse all discovered services on the network
avahi-browse -a -t -r

# Or filter specifically for Google Cast and AirPlay
avahi-browse -t _googlecast._tcp
avahi-browse -t _airplay._tcp

Devices on different VLAN interfaces should now populate service lists within 3 to 5 seconds.

Deep dive

Understanding how Avahi bridges multicast domains helps prevent broadcast storms, high CPU load, and asymmetric routing failures.

How mDNS Works Across Subnet Boundaries

Apple Bonjour, Google Cast, and modern network printers broadcast service records via DNS Service Discovery (DNS-SD). Because mDNS packets carry TTL=1, standard routers silently drop them.

When reflection is active, Avahi acts as an application-layer proxy:

  1. Avahi joins multicast group 224.0.0.251:5353 across all configured network interfaces.
  2. A laptop on VLAN 10 (192.168.10.45) broadcasts an mDNS query for _googlecast._tcp.local.
  3. Avahi captures this packet on interface eth0.10.
  4. The daemon rewrites the link-local header and retransmits the query out of eth0.20 (IoT VLAN) and eth0.30 (Printer VLAN).
  5. A Chromecast Ultra on VLAN 20 (192.168.20.110) receives the reflected query and sends an mDNS response with its IP and port.
  6. Avahi captures the response on eth0.20 and reflects it back into eth0.10, completing discovery.

Host Firewall Rules (iptables and nftables)

If your Linux gateway runs a local firewall, incoming UDP 5353 traffic will get dropped before Avahi can process it.

# iptables rules for IPv4 and IPv6 multicast DNS
sudo iptables -A INPUT -p udp --dport 5353 -d 224.0.0.251 -j ACCEPT
sudo iptables -A INPUT -p udp --dport 5353 -s 192.168.0.0/16 -j ACCEPT
sudo ip6tables -A INPUT -p udp --dport 5353 -d ff02::fb -j ACCEPT

For systems managed by UFW:

sudo ufw allow in proto udp to 224.0.0.251 port 5353
sudo ufw allow in proto udp to any port 5353 comment 'mDNS unicast replies'

Advanced configuration

A default reflector repeats every broadcast across every interface. In corporate environments, this creates security exposures and floods low-bandwidth Wi-Fi channels.

1. Restricting Interfaces

Avahi binds to all active NICs by default, including public WAN interfaces and WireGuard tunnels. Lock reflection down to internal VLANs inside /etc/avahi/avahi-daemon.conf:

[server]
# Bind only to Workstations (10), IoT (20), and Printers (30)
allow-interfaces=eth0.10,eth0.20,eth0.30
deny-interfaces=eth0,wg0,tun0

2. Unicast Routing (The Post-Discovery Trap)

Discovery is only the handshake. Once an iPhone discovers a smart TV, it opens direct unicast TCP and UDP sockets to stream media. If your router blocks inter-VLAN forwarding, discovery succeeds on screen, but streaming instantly times out.

Make sure your inter-VLAN firewall permits the actual payload streams:

  • AirPlay / Apple TV: TCP 7000 (control/mirroring), TCP 7100, TCP 5000 (audio), and UDP 6000–6009 (RTP stream).
  • Google Cast: TCP 8008 (HTTP control), TCP 8009 (HTTPS control), TCP 8443, and UDP 1900 (SSDP fallback).
  • IPP & Raw Printing: TCP 631 (IPP/IPPS) and TCP 9100 (RAW JetDirect).
# Allow workstation VLAN (192.168.10.0/24) to stream to IoT devices (192.168.20.0/24)
sudo iptables -A FORWARD -s 192.168.10.0/24 -d 192.168.20.0/24 -p tcp -m multiport --dports 5000,7000,7100,8008,8009,8443 -j ACCEPT
sudo iptables -A FORWARD -s 192.168.10.0/24 -d 192.168.20.0/24 -p udp --dport 6000:6009 -j ACCEPT
sudo iptables -A FORWARD -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT

Practical troubleshooting

Diagnosing Missing Packets with tcpdump

When a device refuses to show up, verify that multicast packets are hitting the gateway:

# Watch for live mDNS queries across all interfaces
sudo tcpdump -n -i any port 5353 -vv

Look for query packets arriving on eth0.10 and confirm matching egress packets appear on eth0.20 within milliseconds.

Avoiding Broadcast Storms and Reflection Loops

  • Never run two reflectors on the same VLAN pair: If two gateways bridge the same subnets with enable-reflector=yes, they will bounce queries in an infinite feedback loop. This pegs CPU cores at 100% and crashes managed switches.
  • Check IGMP Snooping on switches: Managed L2 switches drop multicast frames if no IGMP querier is active on the VLAN. Verify that your core switch has an active IGMP querier enabled for each VLAN.
  • Turn off local service publishing: If the gateway host does not host printers or file shares itself, add disable-publishing=yes under [publish] to conserve memory and reduce background traffic.
Share: