at 18.09-beta 7.4 kB view raw
1# Avahi daemon. 2{ config, lib, pkgs, ... }: 3 4with lib; 5 6let 7 8 cfg = config.services.avahi; 9 10 yesNo = yes : if yes then "yes" else "no"; 11 12 avahiDaemonConf = with cfg; pkgs.writeText "avahi-daemon.conf" '' 13 [server] 14 ${# Users can set `networking.hostName' to the empty string, when getting 15 # a host name from DHCP. In that case, let Avahi take whatever the 16 # current host name is; setting `host-name' to the empty string in 17 # `avahi-daemon.conf' would be invalid. 18 optionalString (hostName != "") "host-name=${hostName}"} 19 browse-domains=${concatStringsSep ", " browseDomains} 20 use-ipv4=${yesNo ipv4} 21 use-ipv6=${yesNo ipv6} 22 ${optionalString (interfaces!=null) "allow-interfaces=${concatStringsSep "," interfaces}"} 23 ${optionalString (domainName!=null) "domain-name=${domainName}"} 24 allow-point-to-point=${yesNo allowPointToPoint} 25 ${optionalString (cacheEntriesMax!=null) "cache-entries-max=${toString cacheEntriesMax}"} 26 27 [wide-area] 28 enable-wide-area=${yesNo wideArea} 29 30 [publish] 31 disable-publishing=${yesNo (!publish.enable)} 32 disable-user-service-publishing=${yesNo (!publish.userServices)} 33 publish-addresses=${yesNo (publish.userServices || publish.addresses)} 34 publish-hinfo=${yesNo publish.hinfo} 35 publish-workstation=${yesNo publish.workstation} 36 publish-domain=${yesNo publish.domain} 37 38 [reflector] 39 enable-reflector=${yesNo reflector} 40 ${extraConfig} 41 ''; 42 43in 44 45{ 46 47 ###### interface 48 49 options = { 50 51 services.avahi = { 52 53 enable = mkOption { 54 default = false; 55 description = '' 56 Whether to run the Avahi daemon, which allows Avahi clients 57 to use Avahi's service discovery facilities and also allows 58 the local machine to advertise its presence and services 59 (through the mDNS responder implemented by `avahi-daemon'). 60 ''; 61 }; 62 63 hostName = mkOption { 64 type = types.str; 65 description = '' 66 Host name advertised on the LAN. If not set, avahi will use the value 67 of config.networking.hostName. 68 ''; 69 }; 70 71 domainName = mkOption { 72 type = types.str; 73 default = "local"; 74 description = '' 75 Domain name for all advertisements. 76 ''; 77 }; 78 79 browseDomains = mkOption { 80 default = [ ]; 81 example = [ "0pointer.de" "zeroconf.org" ]; 82 description = '' 83 List of non-local DNS domains to be browsed. 84 ''; 85 }; 86 87 ipv4 = mkOption { 88 default = true; 89 description = ''Whether to use IPv4''; 90 }; 91 92 ipv6 = mkOption { 93 default = false; 94 description = ''Whether to use IPv6''; 95 }; 96 97 interfaces = mkOption { 98 type = types.nullOr (types.listOf types.str); 99 default = null; 100 description = '' 101 List of network interfaces that should be used by the <command>avahi-daemon</command>. 102 Other interfaces will be ignored. If <literal>null</literal> all local interfaces 103 except loopback and point-to-point will be used. 104 ''; 105 }; 106 107 allowPointToPoint = mkOption { 108 default = false; 109 description= '' 110 Whether to use POINTTOPOINT interfaces. Might make mDNS unreliable due to usually large 111 latencies with such links and opens a potential security hole by allowing mDNS access from Internet 112 connections. Use with care and YMMV! 113 ''; 114 }; 115 116 wideArea = mkOption { 117 default = true; 118 description = ''Whether to enable wide-area service discovery.''; 119 }; 120 121 reflector = mkOption { 122 default = false; 123 description = ''Reflect incoming mDNS requests to all allowed network interfaces.''; 124 }; 125 126 publish = { 127 enable = mkOption { 128 default = false; 129 description = ''Whether to allow publishing in general.''; 130 }; 131 132 userServices = mkOption { 133 default = false; 134 description = ''Whether to publish user services. Will set <literal>addresses=true</literal>.''; 135 }; 136 137 addresses = mkOption { 138 default = false; 139 description = ''Whether to register mDNS address records for all local IP addresses.''; 140 }; 141 142 hinfo = mkOption { 143 default = false; 144 description = '' 145 Whether to register an mDNS HINFO record which contains information about the 146 local operating system and CPU. 147 ''; 148 }; 149 150 workstation = mkOption { 151 default = false; 152 description = ''Whether to register a service of type "_workstation._tcp" on the local LAN.''; 153 }; 154 155 domain = mkOption { 156 default = false; 157 description = ''Whether to announce the locally used domain name for browsing by other hosts.''; 158 }; 159 160 }; 161 162 nssmdns = mkOption { 163 default = false; 164 description = '' 165 Whether to enable the mDNS NSS (Name Service Switch) plug-in. 166 Enabling it allows applications to resolve names in the `.local' 167 domain by transparently querying the Avahi daemon. 168 ''; 169 }; 170 171 cacheEntriesMax = mkOption { 172 default = null; 173 type = types.nullOr types.int; 174 description = '' 175 Number of resource records to be cached per interface. Use 0 to 176 disable caching. Avahi daemon defaults to 4096 if not set. 177 ''; 178 }; 179 180 extraConfig = mkOption { 181 default = ""; 182 type = types.lines; 183 description = '' 184 Extra config to append to avahi-daemon.conf. 185 ''; 186 }; 187 188 }; 189 190 }; 191 192 193 ###### implementation 194 195 config = mkIf cfg.enable { 196 197 services.avahi.hostName = mkDefault config.networking.hostName; 198 199 users.users = singleton 200 { name = "avahi"; 201 uid = config.ids.uids.avahi; 202 description = "`avahi-daemon' privilege separation user"; 203 home = "/var/empty"; 204 }; 205 206 users.groups = singleton 207 { name = "avahi"; 208 gid = config.ids.gids.avahi; 209 }; 210 211 system.nssModules = optional cfg.nssmdns pkgs.nssmdns; 212 213 environment.systemPackages = [ pkgs.avahi ]; 214 215 systemd.sockets.avahi-daemon = 216 { description = "Avahi mDNS/DNS-SD Stack Activation Socket"; 217 listenStreams = [ "/var/run/avahi-daemon/socket" ]; 218 wantedBy = [ "sockets.target" ]; 219 }; 220 221 systemd.services.avahi-daemon = 222 { description = "Avahi mDNS/DNS-SD Stack"; 223 wantedBy = [ "multi-user.target" ]; 224 requires = [ "avahi-daemon.socket" ]; 225 226 serviceConfig."NotifyAccess" = "main"; 227 serviceConfig."BusName" = "org.freedesktop.Avahi"; 228 serviceConfig."Type" = "dbus"; 229 230 path = [ pkgs.coreutils pkgs.avahi ]; 231 232 preStart = "mkdir -p /var/run/avahi-daemon"; 233 234 script = 235 '' 236 # Make NSS modules visible so that `avahi_nss_support ()' can 237 # return a sensible value. 238 export LD_LIBRARY_PATH="${config.system.nssModules.path}" 239 240 exec ${pkgs.avahi}/sbin/avahi-daemon --syslog -f "${avahiDaemonConf}" 241 ''; 242 }; 243 244 services.dbus.enable = true; 245 services.dbus.packages = [ pkgs.avahi ]; 246 247 # Enabling Avahi without exposing it in the firewall doesn't make 248 # sense. 249 networking.firewall.allowedUDPPorts = [ 5353 ]; 250 251 }; 252 253}