at 16.09-beta 6.3 kB view raw
1# Avahi daemon. 2{ config, lib, utils, pkgs, ... }: 3 4with lib; 5 6let 7 8 cfg = config.services.avahi; 9 10 # We must escape interfaces due to the systemd interpretation 11 subsystemDevice = interface: 12 "sys-subsystem-net-devices-${utils.escapeSystemdPath interface}.device"; 13 14 avahiDaemonConf = with cfg; pkgs.writeText "avahi-daemon.conf" '' 15 [server] 16 ${# Users can set `networking.hostName' to the empty string, when getting 17 # a host name from DHCP. In that case, let Avahi take whatever the 18 # current host name is; setting `host-name' to the empty string in 19 # `avahi-daemon.conf' would be invalid. 20 if hostName != "" 21 then "host-name=${hostName}" 22 else ""} 23 browse-domains=${concatStringsSep ", " browseDomains} 24 use-ipv4=${if ipv4 then "yes" else "no"} 25 use-ipv6=${if ipv6 then "yes" else "no"} 26 ${optionalString (interfaces!=null) "allow-interfaces=${concatStringsSep "," interfaces}"} 27 ${optionalString (domainName!=null) "domain-name=${domainName}"} 28 29 [wide-area] 30 enable-wide-area=${if wideArea then "yes" else "no"} 31 32 [publish] 33 disable-publishing=${if publish.enable then "no" else "yes"} 34 disable-user-service-publishing=${if publish.userServices then "no" else "yes"} 35 publish-addresses=${if publish.userServices || publish.addresses then "yes" else "no"} 36 publish-hinfo=${if publish.hinfo then "yes" else "no"} 37 publish-workstation=${if publish.workstation then "yes" else "no"} 38 publish-domain=${if publish.domain then "yes" else "no"} 39 ''; 40 41in 42 43{ 44 45 ###### interface 46 47 options = { 48 49 services.avahi = { 50 51 enable = mkOption { 52 default = false; 53 description = '' 54 Whether to run the Avahi daemon, which allows Avahi clients 55 to use Avahi's service discovery facilities and also allows 56 the local machine to advertise its presence and services 57 (through the mDNS responder implemented by `avahi-daemon'). 58 ''; 59 }; 60 61 hostName = mkOption { 62 type = types.str; 63 description = '' 64 Host name advertised on the LAN. If not set, avahi will use the value 65 of config.networking.hostName. 66 ''; 67 }; 68 69 domainName = mkOption { 70 type = types.str; 71 default = "local"; 72 description = '' 73 Domain name for all advertisements. 74 ''; 75 }; 76 77 browseDomains = mkOption { 78 default = [ "0pointer.de" "zeroconf.org" ]; 79 description = '' 80 List of non-local DNS domains to be browsed. 81 ''; 82 }; 83 84 ipv4 = mkOption { 85 default = true; 86 description = ''Whether to use IPv4''; 87 }; 88 89 ipv6 = mkOption { 90 default = false; 91 description = ''Whether to use IPv6''; 92 }; 93 94 interfaces = mkOption { 95 type = types.nullOr (types.listOf types.str); 96 default = null; 97 description = '' 98 List of network interfaces that should be used by the <command>avahi-daemon</command>. 99 Other interfaces will be ignored. If <literal>null</literal> all local interfaces 100 except loopback and point-to-point will be used. 101 ''; 102 }; 103 104 wideArea = mkOption { 105 default = true; 106 description = ''Whether to enable wide-area service discovery.''; 107 }; 108 109 publish = { 110 enable = mkOption { 111 default = false; 112 description = ''Whether to allow publishing in general.''; 113 }; 114 115 userServices = mkOption { 116 default = false; 117 description = ''Whether to publish user services. Will set <literal>addresses=true</literal>.''; 118 }; 119 120 addresses = mkOption { 121 default = false; 122 description = ''Whether to register mDNS address records for all local IP addresses.''; 123 }; 124 125 hinfo = mkOption { 126 default = false; 127 description = '' 128 Whether to register an mDNS HINFO record which contains information about the 129 local operating system and CPU. 130 ''; 131 }; 132 133 workstation = mkOption { 134 default = false; 135 description = ''Whether to register a service of type "_workstation._tcp" on the local LAN.''; 136 }; 137 138 domain = mkOption { 139 default = false; 140 description = ''Whether to announce the locally used domain name for browsing by other hosts.''; 141 }; 142 143 }; 144 145 nssmdns = mkOption { 146 default = false; 147 description = '' 148 Whether to enable the mDNS NSS (Name Service Switch) plug-in. 149 Enabling it allows applications to resolve names in the `.local' 150 domain by transparently querying the Avahi daemon. 151 ''; 152 }; 153 154 }; 155 156 }; 157 158 159 ###### implementation 160 161 config = mkIf cfg.enable { 162 163 services.avahi.hostName = mkDefault config.networking.hostName; 164 165 users.extraUsers = singleton 166 { name = "avahi"; 167 uid = config.ids.uids.avahi; 168 description = "`avahi-daemon' privilege separation user"; 169 home = "/var/empty"; 170 }; 171 172 users.extraGroups = singleton 173 { name = "avahi"; 174 gid = config.ids.gids.avahi; 175 }; 176 177 system.nssModules = optional cfg.nssmdns pkgs.nssmdns; 178 179 environment.systemPackages = [ pkgs.avahi ]; 180 181 systemd.services.avahi-daemon = 182 let 183 deps = optionals (cfg.interfaces!=null) (map subsystemDevice cfg.interfaces); 184 in 185 { description = "Avahi daemon"; 186 wantedBy = [ "ip-up.target" ]; 187 bindsTo = deps; 188 after = deps; 189 before = [ "ip-up.target" ]; 190 # Receive restart event after resume 191 partOf = [ "post-resume.target" ]; 192 193 path = [ pkgs.coreutils pkgs.avahi ]; 194 195 preStart = "mkdir -p /var/run/avahi-daemon"; 196 197 script = 198 '' 199 # Make NSS modules visible so that `avahi_nss_support ()' can 200 # return a sensible value. 201 export LD_LIBRARY_PATH="${config.system.nssModules.path}" 202 203 exec ${pkgs.avahi}/sbin/avahi-daemon --syslog -f "${avahiDaemonConf}" 204 ''; 205 }; 206 207 services.dbus.enable = true; 208 services.dbus.packages = [ pkgs.avahi ]; 209 210 # Enabling Avahi without exposing it in the firewall doesn't make 211 # sense. 212 networking.firewall.allowedUDPPorts = [ 5353 ]; 213 214 }; 215 216}