python3Packages.orjson: Disable failing tests on 32 bit
[NixPkgs.git] / nixos / modules / services / networking / avahi-daemon.nix
blob56113bd34594d87d2d67b14e9c2f3b94c526736a
1 { config, lib, pkgs, ... }:
3 with lib;
5 let
6   cfg = config.services.avahi;
8   yesNo = yes : if yes then "yes" else "no";
10   avahiDaemonConf = with cfg; pkgs.writeText "avahi-daemon.conf" ''
11     [server]
12     ${# Users can set `networking.hostName' to the empty string, when getting
13       # a host name from DHCP.  In that case, let Avahi take whatever the
14       # current host name is; setting `host-name' to the empty string in
15       # `avahi-daemon.conf' would be invalid.
16       optionalString (hostName != "") "host-name=${hostName}"}
17     browse-domains=${concatStringsSep ", " browseDomains}
18     use-ipv4=${yesNo ipv4}
19     use-ipv6=${yesNo ipv6}
20     ${optionalString (interfaces!=null) "allow-interfaces=${concatStringsSep "," interfaces}"}
21     ${optionalString (domainName!=null) "domain-name=${domainName}"}
22     allow-point-to-point=${yesNo allowPointToPoint}
23     ${optionalString (cacheEntriesMax!=null) "cache-entries-max=${toString cacheEntriesMax}"}
25     [wide-area]
26     enable-wide-area=${yesNo wideArea}
28     [publish]
29     disable-publishing=${yesNo (!publish.enable)}
30     disable-user-service-publishing=${yesNo (!publish.userServices)}
31     publish-addresses=${yesNo (publish.userServices || publish.addresses)}
32     publish-hinfo=${yesNo publish.hinfo}
33     publish-workstation=${yesNo publish.workstation}
34     publish-domain=${yesNo publish.domain}
36     [reflector]
37     enable-reflector=${yesNo reflector}
38     ${extraConfig}
39   '';
42   options.services.avahi = {
43     enable = mkOption {
44       type = types.bool;
45       default = false;
46       description = lib.mdDoc ''
47         Whether to run the Avahi daemon, which allows Avahi clients
48         to use Avahi's service discovery facilities and also allows
49         the local machine to advertise its presence and services
50         (through the mDNS responder implemented by `avahi-daemon').
51       '';
52     };
54     hostName = mkOption {
55       type = types.str;
56       default = config.networking.hostName;
57       defaultText = literalExpression "config.networking.hostName";
58       description = lib.mdDoc ''
59         Host name advertised on the LAN. If not set, avahi will use the value
60         of {option}`config.networking.hostName`.
61       '';
62     };
64     domainName = mkOption {
65       type = types.str;
66       default = "local";
67       description = lib.mdDoc ''
68         Domain name for all advertisements.
69       '';
70     };
72     browseDomains = mkOption {
73       type = types.listOf types.str;
74       default = [ ];
75       example = [ "0pointer.de" "zeroconf.org" ];
76       description = lib.mdDoc ''
77         List of non-local DNS domains to be browsed.
78       '';
79     };
81     ipv4 = mkOption {
82       type = types.bool;
83       default = true;
84       description = lib.mdDoc "Whether to use IPv4.";
85     };
87     ipv6 = mkOption {
88       type = types.bool;
89       default = config.networking.enableIPv6;
90       defaultText = literalExpression "config.networking.enableIPv6";
91       description = lib.mdDoc "Whether to use IPv6.";
92     };
94     interfaces = mkOption {
95       type = types.nullOr (types.listOf types.str);
96       default = null;
97       description = lib.mdDoc ''
98         List of network interfaces that should be used by the {command}`avahi-daemon`.
99         Other interfaces will be ignored. If `null`, all local interfaces
100         except loopback and point-to-point will be used.
101       '';
102     };
104     openFirewall = mkOption {
105       type = types.bool;
106       default = true;
107       description = lib.mdDoc ''
108         Whether to open the firewall for UDP port 5353.
109       '';
110     };
112     allowPointToPoint = mkOption {
113       type = types.bool;
114       default = false;
115       description= lib.mdDoc ''
116         Whether to use POINTTOPOINT interfaces. Might make mDNS unreliable due to usually large
117         latencies with such links and opens a potential security hole by allowing mDNS access from Internet
118         connections.
119       '';
120     };
122     wideArea = mkOption {
123       type = types.bool;
124       default = true;
125       description = lib.mdDoc "Whether to enable wide-area service discovery.";
126     };
128     reflector = mkOption {
129       type = types.bool;
130       default = false;
131       description = lib.mdDoc "Reflect incoming mDNS requests to all allowed network interfaces.";
132     };
134     extraServiceFiles = mkOption {
135       type = with types; attrsOf (either str path);
136       default = {};
137       example = literalExpression ''
138         {
139           ssh = "''${pkgs.avahi}/etc/avahi/services/ssh.service";
140           smb = '''
141             <?xml version="1.0" standalone='no'?><!--*-nxml-*-->
142             <!DOCTYPE service-group SYSTEM "avahi-service.dtd">
143             <service-group>
144               <name replace-wildcards="yes">%h</name>
145               <service>
146                 <type>_smb._tcp</type>
147                 <port>445</port>
148               </service>
149             </service-group>
150           ''';
151         }
152       '';
153       description = lib.mdDoc ''
154         Specify custom service definitions which are placed in the avahi service directory.
155         See the {manpage}`avahi.service(5)` manpage for detailed information.
156       '';
157     };
159     publish = {
160       enable = mkOption {
161         type = types.bool;
162         default = false;
163         description = lib.mdDoc "Whether to allow publishing in general.";
164       };
166       userServices = mkOption {
167         type = types.bool;
168         default = false;
169         description = lib.mdDoc "Whether to publish user services. Will set `addresses=true`.";
170       };
172       addresses = mkOption {
173         type = types.bool;
174         default = false;
175         description = lib.mdDoc "Whether to register mDNS address records for all local IP addresses.";
176       };
178       hinfo = mkOption {
179         type = types.bool;
180         default = false;
181         description = lib.mdDoc ''
182           Whether to register a mDNS HINFO record which contains information about the
183           local operating system and CPU.
184         '';
185       };
187       workstation = mkOption {
188         type = types.bool;
189         default = false;
190         description = lib.mdDoc ''
191           Whether to register a service of type "_workstation._tcp" on the local LAN.
192         '';
193       };
195       domain = mkOption {
196         type = types.bool;
197         default = false;
198         description = lib.mdDoc "Whether to announce the locally used domain name for browsing by other hosts.";
199       };
200     };
202     nssmdns = mkOption {
203       type = types.bool;
204       default = false;
205       description = lib.mdDoc ''
206         Whether to enable the mDNS NSS (Name Service Switch) plug-in.
207         Enabling it allows applications to resolve names in the `.local'
208         domain by transparently querying the Avahi daemon.
209       '';
210     };
212     cacheEntriesMax = mkOption {
213       type = types.nullOr types.int;
214       default = null;
215       description = lib.mdDoc ''
216         Number of resource records to be cached per interface. Use 0 to
217         disable caching. Avahi daemon defaults to 4096 if not set.
218       '';
219     };
221     extraConfig = mkOption {
222       type = types.lines;
223       default = "";
224       description = lib.mdDoc ''
225         Extra config to append to avahi-daemon.conf.
226       '';
227     };
228   };
230   config = mkIf cfg.enable {
231     users.users.avahi = {
232       description = "avahi-daemon privilege separation user";
233       home = "/var/empty";
234       group = "avahi";
235       isSystemUser = true;
236     };
238     users.groups.avahi = {};
240     system.nssModules = optional cfg.nssmdns pkgs.nssmdns;
241     system.nssDatabases.hosts = optionals cfg.nssmdns (mkMerge [
242       (mkBefore [ "mdns_minimal [NOTFOUND=return]" ]) # before resolve
243       (mkAfter [ "mdns" ]) # after dns
244     ]);
246     environment.systemPackages = [ pkgs.avahi ];
248     environment.etc = (mapAttrs' (n: v: nameValuePair
249       "avahi/services/${n}.service"
250       { ${if types.path.check v then "source" else "text"} = v; }
251     ) cfg.extraServiceFiles);
253     systemd.sockets.avahi-daemon = {
254       description = "Avahi mDNS/DNS-SD Stack Activation Socket";
255       listenStreams = [ "/run/avahi-daemon/socket" ];
256       wantedBy = [ "sockets.target" ];
257     };
259     systemd.tmpfiles.rules = [ "d /run/avahi-daemon - avahi avahi -" ];
261     systemd.services.avahi-daemon = {
262       description = "Avahi mDNS/DNS-SD Stack";
263       wantedBy = [ "multi-user.target" ];
264       requires = [ "avahi-daemon.socket" ];
266       # Make NSS modules visible so that `avahi_nss_support ()' can
267       # return a sensible value.
268       environment.LD_LIBRARY_PATH = config.system.nssModules.path;
270       path = [ pkgs.coreutils pkgs.avahi ];
272       serviceConfig = {
273         NotifyAccess = "main";
274         BusName = "org.freedesktop.Avahi";
275         Type = "dbus";
276         ExecStart = "${pkgs.avahi}/sbin/avahi-daemon --syslog -f ${avahiDaemonConf}";
277       };
278     };
280     services.dbus.enable = true;
281     services.dbus.packages = [ pkgs.avahi ];
283     networking.firewall.allowedUDPPorts = mkIf cfg.openFirewall [ 5353 ];
284   };