SYSTEMD.DNSSD(5)

๐Ÿ’– SYSTEMD.DNSSD(5) ๐Ÿ’–

okay bestie, welcome to systemd.dnssd โ€” the manual page for DNS-SD configuration โœจ (that's section 5 of the systemd manual, iykyk)


๐ŸŒธ NAME ๐ŸŒธ

systemd.dnssd โ€” DNS-SD configuration ๐Ÿ’…

๐Ÿฆ‹ SYNOPSIS ๐Ÿฆ‹

network_service.dnssd

โœจ DESCRIPTION โœจ

So the actual DNS-SD setup? That's not this file's job โ€” it's handled by systemd-resolved(8). This page is just about how you configure it, bestie ๐Ÿซถ

Your main network service file must have the extension .dnssd. Any other extension? Ignored. Not it. Bye ๐Ÿ‘‹

Now, where do these .dnssd files even live? They get read from a whole lil squad of directories:

  • /usr/lib/systemd/dnssd โ€” the system network directory ๐Ÿ 
  • /usr/local/lib/systemd/dnssd โ€” also system network ๐Ÿ’ซ
  • /run/systemd/dnssd โ€” the volatile runtime network directory โšก
  • /etc/systemd/dnssd โ€” the local administration network directory ๐Ÿ‘‘

And here's the tea: all of these config files get collectively sorted and processed in lexicographic order, no matter which directory they came from. So yes, they're all mixed together in one big alphabetical lineup ๐Ÿ“š

But โ€” and this is important โ€” files with identical filenames replace each other. Priority goes like this:

  • Files in /etc/ have the highest priority ๐Ÿ‘‘
  • Files in /run/ take precedence over files with the same name in /usr/lib/ ๐Ÿ”ฅ

So if you ever need to override a system-supplied config file with your own local one? That's exactly how you do it. Slay ๐Ÿ’…


Now, alongside your network service file foo.dnssd, a "drop-in" directory named foo.dnssd.d/ may also exist. Cute, right? ๐ŸŽ€

Every file in that directory with the suffix .conf gets parsed after the main file itself is parsed. This is literally so useful when you want to alter or add config settings without having to touch the main config file at all. Obsessed ๐Ÿ™ˆ

Heads up bestie: each drop-in file must have appropriate section headers. No headers, no vibes, no parsing. ๐Ÿ˜ญ

And it doesn't stop at /etc/systemd/dnssd โ€” you can also place drop-in .d directories in /usr/lib/systemd/dnssd or /run/systemd/dnssd. The precedence chain goes:

  1. Drop-in files in /etc/ take precedence over those in /run/
  2. Which in turn take precedence over those in /usr/lib/ or /usr/local/lib/ ๐ŸŒˆ
  3. And drop-in files under any of these directories take precedence over the main network service file, wherever that main file happens to live ๐Ÿ‘‘

๐ŸŒŸ [SERVICE] SECTION OPTIONS ๐ŸŒŸ

Your network service file contains a [Service] section, and this is where you specify a discoverable network service that gets announced on a local network via Multicast DNS broadcasts ๐Ÿ“กโœจ

๐Ÿ’œ Name=

An instance name of the network service, as defined in section 4.1.1 of RFC 6763[1]. Like, for example, "webserver" ๐Ÿ•ธ๏ธ

The option supports simple specifier expansion. The following expansions are understood:

โœจ Table 1. Specifiers available โœจ

okay so these are the little magic tokens that get swapped out when your config gets read. bestie, write them exactly like this, they are case-sensitive and the capital letters are not a typo ๐Ÿ’…

  • %a โ€” Architecture. A short string identifying the architecture of the local system. A string such as x86, x86-64 or arm64. See the architectures defined for ConditionArchitecture= in systemd.unit(5) for a full list.
  • %A โ€” Operating system image version. The operating system image version identifier of the running system, as read from the IMAGE_VERSION= field of /etc/os-release. If not set, resolves to an empty string. See os-release(5) for more information.
  • %b โ€” Boot ID. The boot ID of the running system, formatted as string. See random(4) for more information.
  • %B โ€” Operating system build ID. The operating system build identifier of the running system, as read from the BUILD_ID= field of /etc/os-release. If not set, resolves to an empty string. See os-release(5) for more information.
  • %H โ€” Host name. The hostname of the running system.
  • %m โ€” Machine ID. The machine ID of the running system, formatted as string. See machine-id(5) for more information.
  • %M โ€” Operating system image identifier. The operating system image identifier of the running system, as read from the IMAGE_ID= field of /etc/os-release. If not set, resolves to an empty string. See os-release(5) for more information.
  • %o โ€” Operating system ID. The operating system identifier of the running system, as read from the ID= field of /etc/os-release. See os-release(5) for more information.
  • %v โ€” Kernel release. Identical to uname -r output.
  • %w โ€” Operating system version ID. The operating system version identifier of the running system, as read from the VERSION_ID= field of /etc/os-release. If not set, resolves to an empty string. See os-release(5) for more information.
  • %W โ€” Operating system variant ID. The operating system variant identifier of the running system, as read from the VARIANT_ID= field of /etc/os-release. If not set, resolves to an empty string. See os-release(5) for more information.
  • %% โ€” Single percent sign. Use "%%" in place of "%" to specify a single percent sign.

Added in version 236.


๐Ÿฆ‹ Type=

A type of the network service as defined in the section 4.1.2 of RFC 6763, e.g. "_http._tcp". ๐ŸŒˆ

Added in version 236.

๐ŸŽ€ SubType=

A subtype of the network service as defined in the section 7.1 of RFC 6763, e.g. "_printer". โœจ

Added in version 256.

๐Ÿ’– Port=

An IP port number of the network service.

Added in version 236.

๐Ÿ”ฅ Priority=

A priority number set in SRV resource records corresponding to the network service.

Added in version 236.

โญ Weight=

A weight number set in SRV resource records corresponding to the network service.

Added in version 236.

๐Ÿ“ TxtText=

A whitespace-separated list of arbitrary key/value pairs conveying additional information about the named service in the corresponding TXT resource record, e.g. "path=/portal/index.html". Keys and values can contain C-style escape sequences which get translated upon reading configuration files.

This option together with TxtData= may be specified more than once, in which case multiple TXT resource records will be created for the service. If the empty string is assigned to this option, the list is reset and all prior assignments will have no effect. ๐Ÿซถ

Added in version 236.

๐Ÿงš TxtData=

A whitespace-separated list of arbitrary key/value pairs conveying additional information about the named service in the corresponding TXT resource record where values are base64-encoded string representing any binary data, e.g. "data=YW55IGJpbmFyeSBkYXRhCg==". Keys can contain C-style escape sequences which get translated upon reading configuration files.

  • this one, together with TxtText=, can be dropped in more than once</p> โ€” and every time you do, a whole new TXT resource record gets born for the service, fr fr. And if you assign the empty string to it? The list gets reset and every assignment you made before that justโ€ฆ โœจ doesn't exist anymore โœจ. Poof.

Added in version 236. ๐ŸŽ€


๐ŸŒธ EXAMPLES ๐ŸŒธ

๐Ÿ’– Example 1. HTTP service

Bestie, look at this gorgeous little file:

# /etc/systemd/dnssd/http.dnssd
[Service]
Name=%H
Type=_http._tcp
Port=80
TxtText=path=/stats/index.html t=temperature_sensor

So what this does: it makes the http server running on the host discoverable in the local network โ€” given MulticastDNS is enabled on the network interface. That's the whole vibe. mDNS on, you're seen. mDNS off, you're a ghost. ๐Ÿ‘ป

Now, the utility resolvectl should be able to resolve the service to the host's name, like:

$ resolvectl service meteo._http._tcp.local
meteo._http._tcp.local: meteo.local:80 [priority=0, weight=0]
                        169.254.208.106%senp0s21f0u2u4
                        fe80::213:3bff:fe49:8aa%senp0s21f0u2u4
                        path=/stats/index.html
                        t=temperature_sensor
                        (meteo/_http._tcp/local)

-- Information acquired via protocol mDNS/IPv6 in 4.0ms.
-- Data is authenticated: yes

literally the whole service, right there, no cap. ๐Ÿ˜ญ

And Avahi running on a different host in the same local network should see the service as well, bestie โ€” it's not just us:

$ avahi-browse -a -r
+ enp3s0 IPv6 meteo                                         Web Site             local
+ enp3s0 IPv4 meteo                                         Web Site             local
= enp3s0 IPv6 meteo                                         Web Site             local
   hostname = [meteo.local]
   address = [fe80::213:3bff:fe49:8aa]
   port = [80]
   txt = ["path=/stats/index.html" "t=temperature_sensor"]
= enp3s0 IPv4 meteo                                         Web Site             local
   hostname = [meteo.local]
   address = [169.254.208.106]
   port = [80]
   txt = ["path=/stats/index.html" "t=temperature_sensor"]

the way it just shows up in both IPv6 and IPv4?? iconic. ๐Ÿ‘‘


๐Ÿ” SEE ALSO ๐Ÿ”

systemd(1), systemd-resolved.service(8), resolvectl(1) โ€” go read those next, they're the besties of this page. ๐Ÿซถ


๐Ÿ“ NOTES ๐Ÿ“

  1. RFC 6763 โ€” https://tools.ietf.org/html/rfc6763

okay that's the whole page, you made it to the end!! ๐ŸŽ‰ this was written for systemd 262.1, and the page itself is SYSTEMD.DNSSD(5) โ€” that's the version and the date vibe, bestie, and now you're fully caught up on DNS-SD configs. go forth and advertise your services. slay. ๐Ÿ’…โœจ

๐Ÿ“ฆ where this page comes from
  • arch rolling: systemd 262.1-1 ยท LGPL-2.1-or-later AND CC0-1.0 AND GPL-2.0-or-later AND MIT-0
  • ๐Ÿ’– girlified by deepseek-ai/DeepSeek-V4.1-Flash on : a language model's rewrite of the original, under its terms