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