Multicast DNS (mDNS) lets devices on one network link answer name lookups for each other without a DNS server, by sending ordinary DNS messages to the multicast group 224.0.0.251 (FF02::FB on IPv6) on UDP port 5353. DNS-Based Service Discovery (DNS-SD) is a naming convention that lets a client find "every printer here" with one PTR query, then learn each one's host, port and options from SRV and TXT records. Both were published by the IETF in February 2013 as RFC 6762 and RFC 6763, written by Stuart Cheshire and Marc Krochmal of Apple, and together they are what Apple ships as Bonjour and Linux ships as Avahi and systemd-resolved.
Securing them comes down to four habits: keep port 5353 off the internet, stop devices from saying more than they need to, treat every answer on the local link as unauthenticated, and if discovery must cross VLANs, use an allow list rather than a blanket reflector. This post goes one level deeper than our DNS protocol explainer and our guide to Zigbee, Thread and Matter.
Key takeaways
- mDNS is the DNS message format carried over link local multicast to 224.0.0.251 or FF02::FB on UDP 5353. Names end in
.local, which IANA lists as a special use domain reserved by RFC 6762. - Before using a name, a device probes three times, 250 ms apart, then announces. When two devices want one name, a deterministic tiebreak decides and the loser renames itself.
- DNS-SD adds no new record types. PTR lists the instances of a service type, SRV gives host and port, TXT carries key and value settings.
- mDNS assumes cooperating hosts. RFC 6762 says that where hostile hosts may share the link you need DNSSEC or IPsec, or manually configured DNS instead.
- The real risks are information disclosure through names and TXT records, spoofed answers from anyone on the link, amplification and reconnaissance when 5353 answers the internet, and reflectors that leak services between VLANs.
- The IETF's answer for crossing subnets is not a reflector but the Discovery Proxy (RFC 8766), DNS Push Notifications (RFC 8765) and the Service Registration Protocol (RFC 9665, June 2025), which moves registration to unicast DNS Update signed with SIG(0).
- LLMNR (RFC 4795) and NetBIOS name service do a similar job with weaker scoping and are common targets for credential relay. In April 2022 Microsoft said it was moving Windows toward mDNS as the only multicast name protocol on by default.
A dated timeline of zero configuration discovery
Every date below comes from the RFC itself, the IANA registry or the publisher's own page.
| Date | Event | Source |
|---|---|---|
| July 1997 | Stuart Cheshire proposes running the AppleTalk Name Binding Protocol idea over IP | RFC 6762, Appendix H |
| September 1999 | IETF Zeroconf working group chartered | RFC 6762, Appendix H |
| April 2000 | 224.0.0.251 registered with IANA for mDNS | RFC 6762, Appendix H; IANA |
| 2001 | A Mac OS 9 update adds one shot mDNS lookups for .local names | RFC 6762, Appendix H |
| August 2002 | Mac OS X 10.2 "Jaguar" ships an mDNS responder with full service discovery | RFC 6762, Appendix H |
| September 2002 | Apple releases mDNSResponder source under the Apple Public Source License | RFC 6762, Appendix H |
| June 2004 | mDNS responder software becomes available for Windows users | RFC 6762, Appendix H |
| January 2007 | LLMNR published as RFC 4795 (Informational) | RFC 4795 |
| February 2013 | RFC 6760, 6761, 6762 and 6763 published | RFC Editor |
| 31 March 2015 | CERT/CC VU#550620: some mDNS responders answer unicast queries from outside the link | CERT/CC |
| 19 August 2015 | CISA adds mDNS to its UDP amplification alert, factor 2 to 10 | CISA |
| June 2020 | DNS Push Notifications (RFC 8765) and Discovery Proxy (RFC 8766) | RFC Editor |
| September 2020 | DNS-SD privacy and security requirements (RFC 8882, Informational) | RFC Editor |
| 22 April 2022 | Microsoft announces it is ramping down NetBIOS name resolution and LLMNR | Microsoft Networking Blog |
| June 2025 | Service Registration Protocol (RFC 9665) and the DNS Update Lease option (RFC 9664) | RFC Editor |
What are mDNS and DNS-SD, and where did they come from?
Multicast DNS (RFC 6762) does DNS style lookups when there is no DNS server to ask. A client that wants the address of printer.local builds a normal DNS query, but instead of sending it to a resolver it multicasts it to everyone on the local link, and whichever device owns the name answers. The header, record types and name compression are borrowed from classic DNS (RFC 1034 and RFC 1035), which is why any tool that decodes DNS also decodes mDNS.
DNS-Based Service Discovery (RFC 6763) is a separate idea that pairs well with it. It says nothing about multicast. It is a convention for naming records so a client can ask "which instances of service X exist in domain Y?" and get back human readable names, each of which resolves to a host, a port and metadata. DNS-SD also works over ordinary unicast DNS, which is how wide area discovery and the newer proxy and registration protocols work. Over mDNS in the local. domain, you get the "plug it in and it appears" experience people know from printers and speakers.
The RFCs say where this came from. RFC 6762 opens by saying the two were "created to provide IP networking with the ease-of-use and autoconfiguration for which AppleTalk was well-known." Its Appendix H tells the history: a 1997 proposal to bring AppleTalk's Name Binding Protocol to IP, the Zeroconf working group in 1999, a Mac OS 9 resolver in 2001 and the shipping responder in Mac OS X 10.2 in August 2002. RFC 6760 was written alongside to explain to the IETF what AppleTalk NBP actually did.
Today, Apple's developer page describes Bonjour as "also known as zero-configuration networking" and says its implementation is open source under the Apache 2.0 license. Avahi describes itself as a system that "facilitates service discovery on a local network via the mDNS/DNS-SD protocol suite" and ships by default in most Linux distributions. systemd-resolved implements an mDNS resolver and responder, and Windows resolves names with mDNS too.
Zero configuration networking has three parts: get an address without DHCP (IPv4 link local addressing in RFC 3927, IPv6 autoconfiguration in RFC 4862), resolve names without a server (mDNS), and find services without a directory (DNS-SD). This post covers the second and third. Our post on ARP and IPv6 Neighbor Discovery covers the layer underneath, which has the same trust model and the same spoofing problems.
How does mDNS work on the wire?
Addresses, port and the .local domain
All mDNS traffic uses UDP port 5353, and multicast queries go to 224.0.0.251 or FF02::FB. Both groups are link local, so routers do not forward them. RFC 6762 adds two checks. Responses should be sent with IP TTL 255, and a querier must accept only responses that came from the local link, either because they were sent to the multicast group or because the unicast source is on a directly connected subnet. Without this check, the RFC says, "remote rogue hosts" could send spoofed unicast answers that look local.
Port 5353 was deliberately chosen above 1024: RFC 6762 notes no privilege is needed to use it. That makes it easy for any application to run a responder, and means any unprivileged process can, in principle, speak mDNS. Avahi's disallow-other-stacks option stops other processes from binding 5353 on the same host for this reason.
Names that end in .local are mDNS names. IANA's special use domain registry lists local. with RFC 6762 as its reference. RFC 6761 is the process document for special use names and itself covers localhost., test., invalid. and the example names; .local is reserved in RFC 6762 Section 22.1 under that process. RFC 6762 also uses mDNS for the reverse mapping domains 254.169.in-addr.arpa. and the IPv6 link local reverse domains, so link local addresses can be looked up in reverse. The systemd-resolved manual describes the matching routing: single label names go to LLMNR, names ending in .local go to mDNS on interfaces where it is enabled, and .local names are not sent to unicast DNS servers unless explicitly configured as a routing or search domain.
Queries: one shot, continuous and QU questions
RFC 6762 describes two styles of querier. A one shot querier, like the 2001 Mac OS 9 resolver, sends a query, takes the first answer and moves on; if it sends from a port other than 5353 it gets a unicast reply. A continuous querier, such as a print dialog while its window is open, keeps asking: the first two queries must be at least one second apart and the intervals after that at least double. It keeps a cache and listens to every answer on the link, including answers to other hosts' questions.
mDNS reuses the top bit of a question's class field as a "unicast response" bit. Questions with it set are called QU questions, the rest QM. A device that has just joined usually sends its first query as QU to avoid a burst of multicast answers, then switches to QM so its cache benefits everyone. Section 5.5 covers direct unicast queries to port 5353 and says responders should check that the source address is on the local subnet, because a unicast query might come from outside the link. VU#550620 in 2015 was about implementations that skipped this check.
Probing and announcing
To claim a unique name, such as its host name or a service instance name, a device first probes. It waits a random 0 to 250 ms, then sends a query of type ANY for the name, with its proposed records in the Authority section. With no conflicting answer it sends a second probe 250 ms later and a third 250 ms after that. If nothing conflicts within 250 ms of the third probe, the name is its own. Probes are sent as QU questions so a defending host can answer at once.
Then it announces: it must send at least two unsolicited multicast responses with its new records, one second apart, so every cache on the link learns them without asking. Devices announce again when data changes, for example after a TXT record edit or a new address.
RFC 6762 builds in a brake: if fifteen conflicts occur within any ten second period, the host must wait at least five seconds before each further probe. A responder that knows a record cannot collide, such as the reverse PTR for its own address, should skip probing for it.
Conflict resolution and tiebreaking
If two devices probe for the same name at the same moment, they compare their proposed records: class first, then type, then the raw uncompressed data byte by byte as unsigned values. The data that sorts later wins. The loser waits one second and probes again. RFC 6762 gives a worked example: two hosts probe for MyPrinter.local with A records 169.254.99.200 and 169.254.200.50. The third byte decides it (200 beats 99), so 169.254.200.50 wins. Read as a signed byte, 200 would be minus 56 and the wrong host would win, which is why the RFC insists on unsigned comparison.
After probing, a device that sees a conflicting response for one of its unique records must defend the name or, if the conflict persists, probe again with a new name. That is why printers become "Office Printer (2)". RFC 6762 Section 21 states the catch: the algorithm "assumes cooperating participants." A host willing to lie can always win, by answering probes or by sending responses that force others to rename.
Known answer suppression and traffic control
Multicast costs every device on the link something, and on Wi-Fi it costs more than unicast because multicast frames usually go at a low basic rate. Known answer suppression is the main control. A querier lists answers it already has in the Answer section of its query, and a responder must not answer if its record is listed with a TTL of at least half the correct value. If a print dialog already knows five printers, only a sixth, new one replies. If the list does not fit in one packet, the querier sets the truncated bit and sends more, and responders wait 400 to 500 ms to collect it.
Duplicate question and duplicate answer suppression work the same way: a host that sees an identical query or answer go out first holds back its own. Responders add a random 20 to 120 ms delay before multicast answers to shared records so they do not all transmit at once, and must not multicast the same record on an interface more than once per second.
TTLs, goodbyes and the cache-flush bit
RFC 6762 recommends a TTL of 120 seconds for records that contain or are named after a host name (A, AAAA, HINFO, SRV, reverse PTR) and 75 minutes for everything else. A querier requeries when a record is 80 percent of the way to expiry, which for 75 minute records means about one query per hour per active question.
A device shutting down cleanly sends a "goodbye" packet: its records with TTL zero. Receivers set the TTL to one second and then delete the record. For unique records, responses carry a cache-flush bit (the top bit of the record class) telling receivers to replace older records of that name and type rather than add to them. Passive Observation Of Failures (POOF) lets a cache drop records early when it sees queries for them go unanswered.
What the built in checks do and do not stop
The protections in RFC 6762 are about scope, not identity: link local groups, IP TTL 255 and source address checks. Avahi exposes the TTL check as check-response-ttl, which ignores packets unless their IP TTL is 255. These stop an attacker off the link from injecting answers. They do nothing against someone on the same Wi-Fi network, switch or VLAN, which is where most attacks on name resolution happen.
How does DNS-SD name services?
Three records: PTR, SRV and TXT
A browse is a PTR query for a service type such as _ipp._tcp.local. Each answer is a PTR record whose data is a service instance name, such as Office Printer._ipp._tcp.local. The client then asks for that instance's SRV record (target host and port) and TXT record (key and value attributes), and resolves the host name to addresses. RFC 6763 Section 12 recommends that responders include the SRV, TXT and address records in the Additional section of the PTR answer, so on a quiet network a browse and resolve takes one query and one response.
| Record | Name it sits on | What it holds | Example |
|---|---|---|---|
| PTR | _ipp._tcp.local (service type) | One service instance name per record | Office Printer._ipp._tcp.local |
| SRV | Service instance name | Priority, weight, port, target host | port 631, target office-printer.local |
| TXT | Service instance name | Key and value attributes | txtvers=1, paper=A4 |
| A and AAAA | Target host name | IPv4 and IPv6 addresses | 192.0.2.40, 2001:db8::40 |
Instance names and service names
A service instance name has three parts, Instance.Service.Domain. The Instance part is a user friendly UTF-8 label that may contain spaces, punctuation and capitals, up to 63 bytes. The Service part is an underscore prefixed application protocol name plus _tcp or _udp, where _udp means "anything other than TCP". The Domain is local. for mDNS or a unicast domain for wide area discovery.
Service names are registered with IANA under RFC 6335 and may be no more than fifteen characters, which RFC 6763 explains leaves room in the 255 byte domain name for the instance name and domain. RFC 6763 also says software should store the full instance name rather than the address and port, so a laptop can find "Living Room" again after the speaker's address changes.
TXT record rules
A DNS-SD TXT record is a list of strings, each key=value or a bare key acting as a boolean. Keys are case insensitive and should be no more than nine characters. An empty TXT record is not allowed, so an instance with nothing to say publishes a single zero byte. RFC 6763 suggests keeping the record to 200 bytes or less; under 400 bytes fits a 512 byte DNS message, and over 1300 bytes is "NOT RECOMMENDED". A txtvers key versions the attribute set, and specifications that use it require it to be the first pair.
RFC 6763's example record holds key=value, paper=A4 and passreq: short keys, short values, bare flags. TXT records are also where most information disclosure happens, because each service type decides what to publish.
Subtypes, service type enumeration and domain enumeration
Subtypes narrow a browse. A printer with a web interface can register under _http._tcp and the subtype _printer._sub._http._tcp, so a client wanting only printer web pages browses the subtype and skips every other web server.
Service type enumeration is a meta query: a PTR query for _services._dns-sd._udp.local returns one record per advertised service type. RFC 6763 Section 9 says it is for "problem diagnosis and network management tools." It is also the first query anyone mapping a network runs.
Domain enumeration (Section 11) reserves five names under _dns-sd._udp: b and db for browsing domains, r and dr for registration domains, and lb for legacy browsing. A network uses these to tell visiting clients to browse a unicast domain as well as local., which is how wide area discovery is bootstrapped.
What printers, speakers, Matter devices and AirPlay style receivers advertise
Printers are the oldest case. RFC 6763 uses _ipp._tcp as its running example and _printer._sub._http._tcp as its subtype example. IANA's service name registry also lists ipps, IPP over HTTPS on TCP port 631. Apple's Bonjour page lists a separate Bonjour Printing Specification that defines printer TXT keys, and in practice printer TXT records describe things like queue path, supported document formats, colour and duplex support and a model string.
Matter devices use DNS-SD in two roles. The open source Matter SDK (the project-chip connectedhomeip repository) defines _matterc._udp for commissionable nodes waiting to be set up, _matterd._udp for commissioners and _matter._tcp for operational nodes already in a fabric, with subtypes used to filter browses. On Wi-Fi and Ethernet these go out over mDNS; on Thread the border router carries them, as described below.
Speakers, TVs and AirPlay style receivers advertise vendor defined service types so a phone can list them in a picker. Their exact names and TXT keys are set by each vendor, but receivers tend to publish a user chosen friendly name ("Kitchen"), a model identifier and capability flags. Computers often publish file sharing services such as _smb._tcp, remote login as _ssh._tcp and sometimes _workstation._tcp. Avahi has options to stop publishing _workstation._tcp and to publish an HINFO record with OS and CPU details, which it leaves off by default "for the sake of privacy."
How does discovery cross subnets?
mDNS is link local by design. That suits a flat home network and frustrates a campus, a hotel, or a home split into trusted and IoT VLANs. There are four ways across, with very different security properties.
mDNS reflectors
A reflector listens for mDNS on several interfaces and retransmits it on the others. Avahi's enable-reflector reflects incoming mDNS requests to all local interfaces, "effectively allowing clients to browse mDNS/DNS-SD services on all networks connected to the gateway." The manual notes the unicast reply bit is lost and warns not to run multiple reflectors between the same networks because they "might cause them to play Ping Pong with mDNS packets." reflect-filters restricts reflection to listed service names, and reflect-ipv, off by default, forwards between IPv4 and IPv6.
A reflector is easy and blunt: unfiltered, it makes every service visible on every segment, and it solves only discovery, so the client still needs firewall rules to reach the device.
The Discovery Proxy (RFC 8766)
RFC 8766 (June 2020) defines "a network proxy that uses Multicast DNS to automatically populate the wide-area unicast Domain Name System namespace with records describing devices and services found on the local link." A Discovery Proxy sits on each link and is delegated a unicast DNS subdomain, for example one per floor, possibly under the private .home.arpa domain. It answers unicast queries for that subdomain by issuing mDNS on its own link. Clients anywhere browse the subdomain with ordinary DNS, guided by the domain enumeration records above. Multicast never leaves the link, the operator decides which subdomains exist and who can query them, and answers travel over unicast DNS where normal DNS controls apply.
DNS Push Notifications (RFC 8765)
Unicast DNS is poll based, a poor fit for a browse window that wants to see devices come and go. RFC 8765 lets a client open a long lived DNS Stateful Operations session (RFC 8490) over TLS over TCP, subscribe to a name and type, and be told when records change. A server advertises it with a _dns-push-tls._tcp SRV record. Paired with a Discovery Proxy, it gives a client on another subnet live browsing without multicast and over an encrypted connection.
Service Registration Protocol (RFC 9665) and Thread
RFC 9665, published in June 2025 with RFC 9664 (an EDNS(0) option to negotiate leases on DNS updates), lets a device register its DNS-SD records with a server using standard DNS Update over unicast, so it never sends or answers multicast. The RFC says this "greatly improves scalability" where multicast is a poor fit, "particularly IEEE 802.11 (Wi-Fi) and IEEE 802.15.4 networks." Registrations are signed with SIG(0) using a key the device generates, and "First Come, First Served" naming means later updates to a name must be signed with the same key, so another device cannot take it over. Registrations are leased, so stale entries expire.
Thread is the main real world user. IEEE 802.15.4 radios are low power and multicast is expensive, so Thread devices register with an SRP server on the border router, which advertises them onto Wi-Fi or Ethernet with mDNS. OpenThread's API includes both an SRP client and an SRP server module. This is how a Matter over Thread light becomes visible to a phone on Wi-Fi.
| Approach | Multicast leaves the link? | Who controls scope | Record authentication | Typical place |
|---|---|---|---|---|
| Plain mDNS | No | Nobody; whole link | None | Flat home and small office networks |
| Reflector (for example Avahi) | Yes, copied | Reflector config and filters | None | Homes and small offices with VLANs |
| Discovery Proxy (RFC 8766) | No | Operator, via DNS delegation | Unicast DNS controls | Campus and enterprise |
| DNS Push (RFC 8765) | No | DNS server | TLS on the session | With a Discovery Proxy or SRP server |
| SRP (RFC 9665) | No | SRP server | SIG(0) key per device, first come first served | Thread border routers |
How does LLMNR differ, and why do guides say to disable it?
Link-Local Multicast Name Resolution, RFC 4795, was published in January 2007 as an Informational RFC by authors at Microsoft. Queries go to 224.0.0.252 or FF02:0:0:0:0:0:1:3 on port 5355, responders also listen on TCP 5355, and TCP queries and responses use an IP TTL or hop limit of 1 so they cannot come from off link. It has no reserved domain and no service discovery layer. Windows uses it as a fallback when unicast DNS fails, typically for short single label names, and keeps an even older fallback, NetBIOS name service, on UDP 137. systemd-resolved also routes single label names to LLMNR.
That fall through is why MITRE ATT&CK lists "LLMNR/NBT-NS Poisoning and SMB Relay" as T1557.001. Conceptually: a host on the link answers a failed lookup (say, a mistyped share name) with its own address, the victim tries to authenticate to it, and the attacker captures or relays that attempt. MITRE's mitigations are to disable LLMNR, mDNS and NetBIOS by group policy "if they are not needed within an environment," filter that traffic on hosts, and enable SMB signing, which stops NTLM relay.
Microsoft's networking team wrote in April 2022 that NetBIOS name resolution and LLMNR "are rarely used today" and that leaving them on "needlessly expands the attack surface of devices." The post described NetBIOS moving to a "learning mode" in Insider builds, used only after mDNS and LLMNR fail, and set the goal of mDNS as "the only multicast name resolution protocol on by default." It also said the LLMNR default had not yet changed. Check current Windows documentation for the builds you run.
Note that MITRE lists mDNS alongside the other two. On a managed Windows estate with no need for local discovery, all three can go. Where printers, room displays and phones depend on mDNS, the work is to scope it, not remove it.
How do mDNS, LLMNR, NetBIOS, SSDP and unicast DNS-SD compare?
| Protocol | Scope | Transport | Built in security | What uses it |
|---|---|---|---|---|
| mDNS with DNS-SD (RFC 6762, 6763) | Link local, .local names | UDP 5353 to 224.0.0.251 or FF02::FB | Link scope and TTL 255 checks only; RFC points to DNSSEC or IPsec on hostile links | Printers, speakers, TVs, Matter on Wi-Fi, file sharing, all major desktop and phone OSes |
| LLMNR (RFC 4795) | Link local, mostly single label names | UDP 5355 to 224.0.0.252 or FF02::1:3; TCP 5355 | Link local multicast scope; TTL 1 on TCP; no authentication | Windows fallback after DNS fails; systemd-resolved |
| NetBIOS name service | Broadcast domain | UDP 137 | None | Legacy Windows fallback |
| SSDP (UPnP discovery) | Link local by default | UDP 1900, HTTP style messages | None | Media renderers, UPnP routers, smart TVs |
| Unicast DNS-SD (RFC 6763 with RFC 8765, 8766, 9665) | Any domain the operator delegates | DNS over UDP, TCP or TLS | DNSSEC, signed updates, TLS transport | Enterprise and campus discovery, Thread border routers |
IANA registers SSDP on port 1900. CISA's amplification alert lists SSDP at a factor of 30.8, mDNS at 2 to 10 and NetBIOS at 3.8.
What are the security risks of mDNS and DNS-SD?
Information disclosure from names and TXT records
A _services._dns-sd._udp.local browse plus a resolve per type gives a fast inventory of a network. Host names often embed a person's name ("Alices-MacBook-Pro.local"), TXT records reveal models and capabilities, and HINFO, where published, reveals OS and CPU. At home this is mostly harmless; on hotel, conference and cafe networks it is a privacy leak. RFC 8882 says DNS-SD "normally discloses information about devices offering and requesting services," and that at a public hotspot "serious privacy problems arise." Queries leak too: a device asking for a service type tells everyone what it is looking for.
Spoofed responses on the local link
Standard mDNS has no authentication. Anyone on the link can answer a query, defend a name they do not own, or announce a record pointing to their own address. RFC 6762 says that where participants are "mutually antagonistic and unwilling to cooperate," manually configured DNS is appropriate, and that where hosts cannot rule out hostile neighbours they need IPsec or DNSSEC signatures. Almost no consumer deployment does either.
The impact depends on what happens after discovery. A print dialog that prints to a spoofed printer can leak documents. A client that finds a server by mDNS and then authenticates to it can be steered to the wrong host, the same pattern as LLMNR poisoning. Services that use TLS with certificate validation, or pairing keys such as Matter's operational certificates, are far less exposed because discovery only yields an address and the next layer checks identity.
RFC 6762 closes one trap itself. If .local is in a search list and the internet is down, a relative name like www.example.com could become www.example.com.local and be answered by a local impostor, so a host must not append .local to relative names with two or more labels.
Amplification and reconnaissance when 5353 faces the internet
CERT/CC's VU#550620, published 31 March 2015, describes responders that answer unicast queries "that originate from sources outside of the local link network," which discloses device and service details and enables amplification because the response is larger than the query. Its resolution is to block inbound and outbound UDP 5353 at the WAN; its workaround is to disable mDNS where it is not needed. CISA added mDNS to its amplification alert on 19 August 2015. The Shadowserver Foundation runs an "Open mDNS" report, rated medium severity, that identifies "hosts that have the mDNS service running and accessible from the Internet," which network owners can subscribe to for their own ranges.
Reflector misconfiguration across VLANs
An unfiltered reflector on both VLANs re-exposes every trusted service to the IoT side by name and tells every IoT device where the laptops are. Add a firewall rule opened "temporarily" so casting works, and the segmentation is mostly gone. Two reflectors on the same pair of networks can also loop traffic.
Responder software is network facing code
mDNS responders parse untrusted packets from anyone on the link, often in a privileged daemon, including DNS name compression, which has a long history of parser bugs across DNS software. Run one responder per host, with the least privilege your platform supports, and patch it like any other network facing daemon.
Step by step: inspect and secure mDNS on your own network
These steps assume a Linux machine with Avahi or systemd-resolved, a Mac with the built in dns-sd tool, and a Linux router using nftables. Steps 1 and 2 only observe. Steps 4 and 5 change your router's firewall, so keep a console session open and save the current ruleset first with sudo nft list ruleset > nft-backup.conf.
Step 1: see what your network advertises
# Linux (Avahi): every service, resolved to host, address, port and TXT; exit when done
avahi-browse -a -r -t
# Resolve a .local host name
avahi-resolve -n office-printer.local
# macOS: enumerate service types, browse one, look up an instance (Control-C to stop)
dns-sd -B _services._dns-sd._udp local.
dns-sd -B _ipp._tcp local.
dns-sd -L "Office Printer" _ipp._tcp local.
dns-sd -G v4v6 office-printer.local
# systemd-resolved: per link protocol status, then lookups through it
resolvectl status
resolvectl query office-printer.local
resolvectl service "Office Printer" _ipp._tcp local
Note host names containing people's names, admin web interfaces, unexpected file sharing or SSH services, and TXT records with model or firmware strings.
Step 2: watch the traffic with tcpdump
# Replace wlan0 with your interface; -n skips reverse lookups, -vv decodes DNS fields
sudo tcpdump -i wlan0 -n -vv udp port 5353
# LLMNR and NetBIOS name service, to see whether they are still in use
sudo tcpdump -i wlan0 -n 'udp port 5355 or udp port 137'
You will see QU questions on first query, PTR answers with Additional records, announcements one second apart, and goodbye packets with TTL 0. If the second capture shows traffic where you thought LLMNR and NetBIOS were off, find the hosts sending it.
Step 3: reduce what your own hosts publish
For Avahi, edit the existing sections of /etc/avahi/avahi-daemon.conf. Every option below is documented in the avahi-daemon.conf manual page:
[server]
# Only speak mDNS on the interfaces that need it
allow-interfaces=eth0
# Refuse to let a second mDNS stack bind UDP 5353 on this host
disallow-other-stacks=yes
# Ignore incoming packets whose IP TTL is not 255
check-response-ttl=yes
[publish]
# No OS and CPU details, no generic workstation service
publish-hinfo=no
publish-workstation=no
[reflector]
enable-reflector=no
A machine that only needs to find things can set disable-publishing=yes in [publish], which runs Avahi in a querying only mode. Restart with sudo systemctl restart avahi-daemon and repeat Step 1 from another machine.
For systemd-resolved, resolved.conf documents LLMNR= and MulticastDNS=, each taking yes, no or resolve (look up names but do not respond):
# /etc/systemd/resolved.conf
[Resolve]
LLMNR=no
MulticastDNS=resolve
sudo systemctl restart systemd-resolved
resolvectl llmnr wlan0 no
Run only one mDNS responder per host: if Avahi responds, keep systemd-resolved at resolve or no. On printers, speakers and Macs, turn off the specific services you do not use (a printer's web page, file sharing) rather than mDNS itself, and rename devices so names do not include people's names.
Step 4: block UDP 5353 at the WAN
On an nftables router where wan0 faces the internet, drop mDNS, LLMNR and NetBIOS name service on that interface in both directions:
sudo nft add table inet edge
sudo nft add chain inet edge input '{ type filter hook input priority 0; policy accept; }'
sudo nft add chain inet edge forward '{ type filter hook forward priority 0; policy accept; }'
sudo nft add rule inet edge input iifname "wan0" udp dport '{ 5353, 5355, 137 }' drop
sudo nft add rule inet edge forward iifname "wan0" udp dport '{ 5353, 5355, 137 }' drop
sudo nft add rule inet edge forward oifname "wan0" udp dport '{ 5353, 5355, 137 }' drop
sudo nft list table inet edge
# Check which interfaces local listeners are bound to
sudo ss -ulpn | grep -E ':5353|:5355|:137'
If your router already drops unsolicited WAN traffic, these rules are a second layer. If you own a public address range, subscribe to Shadowserver's free reports, which include the Open mDNS report.
Step 5: a controlled reflector between an IoT VLAN and a trusted VLAN
The goal: phones and laptops on the trusted VLAN (vlan10) find the printer on the IoT VLAN (vlan20), IoT devices see only what is reflected, and traffic flows one way on the needed port. On the router:
# /etc/avahi/avahi-daemon.conf
[server]
allow-interfaces=vlan10,vlan20
disallow-other-stacks=yes
[publish]
publish-hinfo=no
publish-workstation=no
[reflector]
enable-reflector=yes
reflect-ipv=no
# Only printer service types are reflected
reflect-filters=_ipp._tcp,_ipps._tcp
reflect-filters is in the current manual page but may be missing from older Avahi builds, so check man avahi-daemon.conf on your router. It is an allow list of service names (or machine names) and is not tied to a direction, so pair it with a one way firewall:
sudo nft add table inet seg
sudo nft add chain inet seg forward '{ type filter hook forward priority 0; policy drop; }'
sudo nft add rule inet seg forward ct state established,related accept
# Trusted to IoT: only IPP and IPPS (TCP 631) to the printer
sudo nft add rule inet seg forward iifname "vlan10" oifname "vlan20" ip daddr 192.0.2.40 tcp dport 631 accept
# Both VLANs out to the internet
sudo nft add rule inet seg forward iifname "vlan10" oifname "wan0" accept
sudo nft add rule inet seg forward iifname "vlan20" oifname "wan0" accept
sudo nft list table inet seg
Add one rule per reflected service, taking the port from the SRV record you saw in Step 1. Media casting often uses several ports, some chosen at runtime, which is why many designs put casting receivers on the trusted VLAN instead. Do not run a second reflector, such as one built into an access point, between the same VLANs.
Step 6: turn off LLMNR and NetBIOS on managed Windows networks
On domain joined machines that do not need them, use Group Policy and confirm with the Step 2 capture. Microsoft's April 2022 post names the "Configure NetBIOS settings" policy under Computer Configuration, Administrative Templates, Network, DNS Client, and the EnableNetbios registry value under the Dnscache parameters key, where 0 means disabled. LLMNR is turned off by the "Turn off multicast name resolution" policy in the same folder, which Microsoft's policy reference maps to the EnableMulticast value under Software\Policies\Microsoft\Windows NT\DNSClient. Enable SMB signing too. Pilot first: older applications and printers sometimes still rely on NetBIOS names.
Common mistakes
- Leaving UDP 5353 reachable from the internet. It discloses services and enables amplification. Block it both ways at the edge.
- Turning on a reflector with no filter. It undoes VLAN segmentation for discovery and invites loops if a second reflector exists.
- Opening the firewall wide "so casting works." Discovery is half the job. Open specific ports to specific hosts, one way.
- Treating discovery as identity. An mDNS answer only means someone on the link claims a name. Authenticate the server afterwards with TLS or a pairing key.
- Running two responders on one host. Avahi and systemd-resolved both responding cause duplicate answers and odd conflicts.
- Assuming LLMNR is already off. Microsoft's 2022 post said its default had not changed. Check with a capture.
- Personal names in device names. "Alices-iPhone" is announced on every network the phone joins.
- Using
.localfor an internal unicast DNS zone. It collides with mDNS. Use a subdomain you own orhome.arpaat home. - Disabling mDNS everywhere without checking. Printers, AirPlay style receivers, Matter controllers and room systems depend on it. Scope it instead.
FAQ
What port does mDNS use?
UDP 5353, with multicast queries to 224.0.0.251 on IPv4 and FF02::FB on IPv6. A one shot query from another port gets a unicast reply.
Is mDNS the same as Bonjour?
Bonjour is Apple's implementation of mDNS and DNS-SD. Avahi, systemd-resolved and Windows implement the same RFCs and interoperate.
What is the difference between mDNS and DNS-SD?
mDNS is a transport: DNS questions and answers by multicast on one link. DNS-SD is a naming convention: PTR, SRV and TXT records that describe services. DNS-SD runs over mDNS for .local and over unicast DNS for wide area discovery.
Is mDNS a security risk?
Low on a trusted home network, moderate on shared ones. The risks are information disclosure, spoofing by anyone on the same link, and exposure if UDP 5353 is reachable from the internet. RFC 6762 says it assumes cooperating participants.
Should I disable mDNS?
Disable it on servers and managed workstations that do not need local discovery, and on any WAN interface. Keep it, scoped to the right interfaces, where printers, displays and smart home devices rely on it.
How is LLMNR different from mDNS?
LLMNR (RFC 4795) uses port 5355 and 224.0.0.252, resolves names when DNS fails and has no service discovery. mDNS uses port 5353 and the reserved .local domain and pairs with DNS-SD. LLMNR's fall through on Windows makes it a common credential relay target.
Can mDNS work across VLANs or subnets?
Not by itself, because its multicast groups are link local. Use a reflector with an allow list of service types, or a Discovery Proxy (RFC 8766) that answers unicast DNS for each link. Thread devices register with a border router using SRP (RFC 9665).
Why does my device name keep getting a number added?
That is mDNS conflict resolution: another device already held the name, so yours picked a new one. A misconfigured reflector or network loop that echoes a device's own announcements back can cause the same thing.
How do I see all mDNS services on my network?
On Linux, avahi-browse -a -r -t. On macOS, dns-sd -B _services._dns-sd._udp local. to list types, then dns-sd -B for each type.
Does Matter use mDNS?
Yes, on Wi-Fi and Ethernet. The Matter SDK defines _matterc._udp for commissionable devices, _matterd._udp for commissioners and _matter._tcp for operational devices. Thread devices register with an SRP server on the border router, which advertises them on the IP network.
Where Safeguard fits, honestly
Safeguard does not monitor network traffic, manage devices or scan firmware, so it will not tell you which printer leaks its model over mDNS or whether your router answers on UDP 5353. Those are jobs for the steps above and your network inventory. The indirect fit is the software that implements discovery: mDNS responders and DNS parsing libraries ship inside applications, container images and appliance builds as open source components. Safeguard scans repositories, container images and SBOM files with safeguard scan, shows which projects contain a given component and version, matches them against vulnerability databases and can open fix pull requests. Get the CLI at safeguard.sh/download and read the CLI docs.
Discovery stacks are rarely written from scratch, and the responders and DNS libraries behind mDNS end up in containers, desktop apps, router images and smart home hubs that get rebuilt and redeployed like any other dependency. When one of those components needs a fix, the gap between a patch existing and that patch running in every build you ship is where the risk sits, and the options below close it for the code you build yourself.
Fix it without waiting for upstream
Whatever the vulnerability, most of the risk sits in two gaps. The first is the time between a fix being published and that fix actually running in your production builds. The second, and worse, is the time before any fix exists at all, while a maintainer works out a patch and a release schedule. Waiting through both gaps is a habit, not a requirement. Safeguard gives teams three ways to close them.
1. Autonomous remediation: pull requests, not tickets
When a fixed version exists, Safeguard's Griffin models open a tested, policy gated pull request that moves the affected dependency to the safe version. You can run it on one repository or in bulk across every project that carries the vulnerable version. Remediation covers eight categories, including dependencies, licenses, security posture and findings. Reachability analysis ranks the vulnerable code paths your application actually calls first, so the first pull requests you merge are the ones that matter most. Autonomous remediation ships switched off, with every category set to Manual, so your team decides how much runs on its own and what still needs a human approval.
2. Gold Open Source: the safe version in seconds, free
gold.safeguard.sh is free and needs no login. Search any CVE or package to see affected and fixed versions, CVSS, EPSS, CISA KEV status and a recommended safe version, or use the "Am I affected?" checker. The same data is available through a free read API, README status badges and RSS threat feeds. The safeguard-sh/gold-scan-action GitHub Action can fail a build on a known exploited vulnerability, on any known vulnerability, or never, so a version you have just removed cannot quietly come back in next week's merge.
3. Gold Registry: start from components that are already fixed
registry.safeguard.sh provides hardened, drop in replacements for upstream packages and container images. Every Gold artifact is held continuously to zero exploitable critical or high CVEs, zero malware and a completed license check, with SLSA L3 or higher provenance, a Sigstore signature and a public evidence page you can hand to an auditor. An artifact loses its Gold badge if it regresses. Teams can point their own package directory at the registry so hardened equivalents resolve without changing how developers install anything.
When upstream has no fix yet, or will not ship one, Safeguard first works to get the fix accepted upstream. If the issue is severe or upstream will not move, Safeguard builds a fork, fixes the vulnerability there and publishes a hardened Gold build, so you are not stuck on a maintainer's release schedule. You can also request a hardened, compatibility tested build of a specific package. This fork and patch flow is in early access today, so ask which packages it covers before you plan around it.
| Your situation | What to use |
|---|---|
| A fixed version exists | Autonomous remediation opens the upgrade pull request; Gold Open Source confirms the safe version |
| You need to know today whether you are affected | Gold Open Source lookup and "Am I affected?" checker, free and without login |
| You want vulnerable versions to stop shipping | The Gold scan GitHub Action in CI, plus Safeguard policies and gates |
| Upstream has no fix yet, or will not ship one | A custom Gold request; fork and patch (early access) |
| You want to start clean on new projects | Pull hardened components and images from Gold Registry |
One honest limit: when the vulnerable code lives in a vendor appliance, a hosted service or an operating system runtime you do not build yourself, the fix still has to come from that vendor or distribution. The steps above apply to the open source dependencies and container images you build and ship, which is where most teams carry the largest and least tracked share of their exposure.
See how Safeguard would help
The first demo is a real Safeguard CLI session. You ask it to fix the lodash CVE in a repository; it reads the finding and the advisory, asks before each command, edits package.json to lodash 4.17.21, runs npm install and npm test with your approval, and pushes nothing. The same flow applies when a DNS or service discovery library in one of your own projects needs to move to a fixed version.
Click through it at your own pace, or open it full screen.
The second demo sets up the runner on your own machine, approves it with its device code and scans from the terminal. That suits scanning a router build tree or a home automation hub's container images on a machine inside your own network.
Click through it at your own pace, or open it full screen.
The third demo connects Claude to the Safeguard MCP server with OAuth and lets you choose which tools Claude can use. Once connected, you can ask which of your projects include a given DNS library and at which versions, answered from your own scan data.
Click through it at your own pace, or open it full screen.
Quick check
A laptop on your trusted VLAN cannot see a printer on the IoT VLAN behind the same router. Why, and what is the narrowest fix?
mDNS uses link local multicast groups that routers do not forward, so discovery stops at the VLAN boundary. The narrowest fix is a reflector that copies only the printer's service types, such as _ipp._tcp and _ipps._tcp, plus a one way firewall rule letting the trusted VLAN reach the printer on TCP 631 and nothing else. In a managed network, a Discovery Proxy (RFC 8766) avoids copying multicast at all.
Why does RFC 6762 say mDNS needs DNSSEC or IPsec on some networks, and what do most deployments do instead?
Its name conflict algorithm assumes cooperating participants, and any host on the link can answer a query or claim a name, so on a link with hostile hosts only signatures can separate trusted answers from untrusted ones. Most deployments instead keep mDNS on trusted links and rely on the next layer, such as TLS with certificate validation or pairing keys, to verify identity after discovery.
Sources
- RFC 6762, Multicast DNS (IETF, February 2013)
- RFC 6763, DNS-Based Service Discovery (IETF, February 2013)
- RFC 6761, Special-Use Domain Names (IETF, February 2013)
- RFC 6760, Requirements for a Protocol to Replace the AppleTalk Name Binding Protocol (IETF, February 2013)
- RFC 8766, Discovery Proxy for Multicast DNS-Based Service Discovery (IETF, June 2020)
- RFC 8765, DNS Push Notifications (IETF, June 2020)
- RFC 9665, Service Registration Protocol for DNS-Based Service Discovery (IETF, June 2025)
- RFC 9664, An EDNS(0) Option to Negotiate Leases on DNS Updates (IETF, June 2025)
- RFC 8882, DNS-SD Privacy and Security Requirements (IETF, September 2020)
- RFC 4795, Link-Local Multicast Name Resolution (IETF, January 2007)
- RFC 6335, IANA procedures for service names and port numbers
- IANA, IPv4 Multicast Address Space Registry
- IANA, Special-Use Domain Names registry
- IANA, Service Name and Transport Protocol Port Number Registry
- Apple Developer, Bonjour
- Avahi project
- avahi-daemon.conf manual page (Debian)
- systemd-resolved.service manual page
- resolved.conf manual page
- CERT/CC, VU#550620: mDNS implementations may respond to unicast queries originating outside the local link
- CISA, UDP-Based Amplification Attacks
- MITRE ATT&CK, T1557.001 LLMNR/NBT-NS Poisoning and SMB Relay
- Microsoft Networking Blog, Aligning on mDNS: ramping down NetBIOS name resolution and LLMNR (22 April 2022)
- Microsoft Learn, Policy CSP ADMX_DnsClient
- Shadowserver Foundation, Open mDNS Report
- OpenThread, SRP API reference
- Matter SDK (project-chip connectedhomeip), DNS-SD service naming constants
Last reviewed: 24 October 2026.