diff --git a/nixos/doc/manual/release-notes/rl-1909.xml b/nixos/doc/manual/release-notes/rl-1909.xml
index d7ae05086ed1..c476327ba6ff 100644
--- a/nixos/doc/manual/release-notes/rl-1909.xml
+++ b/nixos/doc/manual/release-notes/rl-1909.xml
@@ -259,6 +259,18 @@
(/var/lib/systemd/timesync), if required.
-
+
+
+ The package avahi is now built to look up service
+ definitions from /etc/avahi/services instead of its
+ output directory in the nix store. Accordingly the module
+ now supports custom service definitions via
+ , which are then placed
+ in the aforementioned directory. See
+ avahi.service5
+ for more information on custom service definitions.
+
+
+
diff --git a/nixos/modules/misc/ids.nix b/nixos/modules/misc/ids.nix
index f1118f472e44..14ba5a573b18 100644
--- a/nixos/modules/misc/ids.nix
+++ b/nixos/modules/misc/ids.nix
@@ -44,7 +44,7 @@
vsftpd = 7;
ftp = 8;
bitlbee = 9;
- avahi = 10;
+ #avahi = 10; # removed 2019-05-22
nagios = 11;
atd = 12;
postfix = 13;
@@ -358,7 +358,7 @@
vsftpd = 7;
ftp = 8;
bitlbee = 9;
- avahi = 10;
+ #avahi = 10; # removed 2019-05-22
#nagios = 11; # unused
atd = 12;
postfix = 13;
diff --git a/nixos/modules/services/networking/avahi-daemon.nix b/nixos/modules/services/networking/avahi-daemon.nix
index 4c91a0c415b6..ddcfe3d77e2f 100644
--- a/nixos/modules/services/networking/avahi-daemon.nix
+++ b/nixos/modules/services/networking/avahi-daemon.nix
@@ -1,10 +1,8 @@
-# Avahi daemon.
{ config, lib, pkgs, ... }:
with lib;
let
-
cfg = config.services.avahi;
yesNo = yes : if yes then "yes" else "no";
@@ -39,215 +37,245 @@ let
enable-reflector=${yesNo reflector}
${extraConfig}
'';
-
in
-
{
-
- ###### interface
-
- options = {
-
- services.avahi = {
-
- enable = mkOption {
- default = false;
- description = ''
- Whether to run the Avahi daemon, which allows Avahi clients
- to use Avahi's service discovery facilities and also allows
- the local machine to advertise its presence and services
- (through the mDNS responder implemented by `avahi-daemon').
- '';
- };
-
- hostName = mkOption {
- type = types.str;
- description = ''
- Host name advertised on the LAN. If not set, avahi will use the value
- of config.networking.hostName.
- '';
- };
-
- domainName = mkOption {
- type = types.str;
- default = "local";
- description = ''
- Domain name for all advertisements.
- '';
- };
-
- browseDomains = mkOption {
- default = [ ];
- example = [ "0pointer.de" "zeroconf.org" ];
- description = ''
- List of non-local DNS domains to be browsed.
- '';
- };
-
- ipv4 = mkOption {
- default = true;
- description = ''Whether to use IPv4'';
- };
-
- ipv6 = mkOption {
- default = false;
- description = ''Whether to use IPv6'';
- };
-
- interfaces = mkOption {
- type = types.nullOr (types.listOf types.str);
- default = null;
- description = ''
- List of network interfaces that should be used by the avahi-daemon.
- Other interfaces will be ignored. If null all local interfaces
- except loopback and point-to-point will be used.
- '';
- };
-
- allowPointToPoint = mkOption {
- default = false;
- description= ''
- Whether to use POINTTOPOINT interfaces. Might make mDNS unreliable due to usually large
- latencies with such links and opens a potential security hole by allowing mDNS access from Internet
- connections. Use with care and YMMV!
- '';
- };
-
- wideArea = mkOption {
- default = true;
- description = ''Whether to enable wide-area service discovery.'';
- };
-
- reflector = mkOption {
- default = false;
- description = ''Reflect incoming mDNS requests to all allowed network interfaces.'';
- };
-
- publish = {
- enable = mkOption {
- default = false;
- description = ''Whether to allow publishing in general.'';
- };
-
- userServices = mkOption {
- default = false;
- description = ''Whether to publish user services. Will set addresses=true.'';
- };
-
- addresses = mkOption {
- default = false;
- description = ''Whether to register mDNS address records for all local IP addresses.'';
- };
-
- hinfo = mkOption {
- default = false;
- description = ''
- Whether to register an mDNS HINFO record which contains information about the
- local operating system and CPU.
- '';
- };
-
- workstation = mkOption {
- default = false;
- description = ''Whether to register a service of type "_workstation._tcp" on the local LAN.'';
- };
-
- domain = mkOption {
- default = false;
- description = ''Whether to announce the locally used domain name for browsing by other hosts.'';
- };
-
- };
-
- nssmdns = mkOption {
- default = false;
- description = ''
- Whether to enable the mDNS NSS (Name Service Switch) plug-in.
- Enabling it allows applications to resolve names in the `.local'
- domain by transparently querying the Avahi daemon.
- '';
- };
-
- cacheEntriesMax = mkOption {
- default = null;
- type = types.nullOr types.int;
- description = ''
- Number of resource records to be cached per interface. Use 0 to
- disable caching. Avahi daemon defaults to 4096 if not set.
- '';
- };
-
- extraConfig = mkOption {
- default = "";
- type = types.lines;
- description = ''
- Extra config to append to avahi-daemon.conf.
- '';
- };
-
+ options.services.avahi = {
+ enable = mkOption {
+ type = types.bool;
+ default = false;
+ description = ''
+ Whether to run the Avahi daemon, which allows Avahi clients
+ to use Avahi's service discovery facilities and also allows
+ the local machine to advertise its presence and services
+ (through the mDNS responder implemented by `avahi-daemon').
+ '';
};
+ hostName = mkOption {
+ type = types.str;
+ default = config.networking.hostName;
+ defaultText = literalExample "config.networking.hostName";
+ description = ''
+ Host name advertised on the LAN. If not set, avahi will use the value
+ of .
+ '';
+ };
+
+ domainName = mkOption {
+ type = types.str;
+ default = "local";
+ description = ''
+ Domain name for all advertisements.
+ '';
+ };
+
+ browseDomains = mkOption {
+ type = types.listOf types.str;
+ default = [ ];
+ example = [ "0pointer.de" "zeroconf.org" ];
+ description = ''
+ List of non-local DNS domains to be browsed.
+ '';
+ };
+
+ ipv4 = mkOption {
+ type = types.bool;
+ default = true;
+ description = "Whether to use IPv4.";
+ };
+
+ ipv6 = mkOption {
+ type = types.bool;
+ default = false;
+ description = "Whether to use IPv6.";
+ };
+
+ interfaces = mkOption {
+ type = types.nullOr (types.listOf types.str);
+ default = null;
+ description = ''
+ List of network interfaces that should be used by the avahi-daemon.
+ Other interfaces will be ignored. If null, all local interfaces
+ except loopback and point-to-point will be used.
+ '';
+ };
+
+ openFirewall = mkOption {
+ type = types.bool;
+ default = true;
+ description = ''
+ Whether to open the firewall for UDP port 5353.
+ '';
+ };
+
+ allowPointToPoint = mkOption {
+ type = types.bool;
+ default = false;
+ description= ''
+ Whether to use POINTTOPOINT interfaces. Might make mDNS unreliable due to usually large
+ latencies with such links and opens a potential security hole by allowing mDNS access from Internet
+ connections.
+ '';
+ };
+
+ wideArea = mkOption {
+ type = types.bool;
+ default = true;
+ description = "Whether to enable wide-area service discovery.";
+ };
+
+ reflector = mkOption {
+ type = types.bool;
+ default = false;
+ description = "Reflect incoming mDNS requests to all allowed network interfaces.";
+ };
+
+ extraServiceFiles = mkOption {
+ type = with types; attrsOf (either str path);
+ default = {};
+ example = literalExample ''
+ {
+ ssh = "''${pkgs.avahi}/etc/avahi/services/ssh.service";
+ smb = '''
+
+
+
+ %h
+
+ _smb._tcp
+ 445
+
+
+ ''';
+ }
+ '';
+ description = ''
+ Specify custom service definitions which are placed in the avahi service directory.
+ See the avahi.service
+ 5 manpage for detailed information.
+ '';
+ };
+
+ publish = {
+ enable = mkOption {
+ type = types.bool;
+ default = false;
+ description = "Whether to allow publishing in general.";
+ };
+
+ userServices = mkOption {
+ type = types.bool;
+ default = false;
+ description = "Whether to publish user services. Will set addresses=true.";
+ };
+
+ addresses = mkOption {
+ type = types.bool;
+ default = false;
+ description = "Whether to register mDNS address records for all local IP addresses.";
+ };
+
+ hinfo = mkOption {
+ type = types.bool;
+ default = false;
+ description = ''
+ Whether to register a mDNS HINFO record which contains information about the
+ local operating system and CPU.
+ '';
+ };
+
+ workstation = mkOption {
+ type = types.bool;
+ default = false;
+ description = ''
+ Whether to register a service of type "_workstation._tcp" on the local LAN.
+ '';
+ };
+
+ domain = mkOption {
+ type = types.bool;
+ default = false;
+ description = "Whether to announce the locally used domain name for browsing by other hosts.";
+ };
+ };
+
+ nssmdns = mkOption {
+ type = types.bool;
+ default = false;
+ description = ''
+ Whether to enable the mDNS NSS (Name Service Switch) plug-in.
+ Enabling it allows applications to resolve names in the `.local'
+ domain by transparently querying the Avahi daemon.
+ '';
+ };
+
+ cacheEntriesMax = mkOption {
+ type = types.nullOr types.int;
+ default = null;
+ description = ''
+ Number of resource records to be cached per interface. Use 0 to
+ disable caching. Avahi daemon defaults to 4096 if not set.
+ '';
+ };
+
+ extraConfig = mkOption {
+ type = types.lines;
+ default = "";
+ description = ''
+ Extra config to append to avahi-daemon.conf.
+ '';
+ };
};
-
- ###### implementation
-
config = mkIf cfg.enable {
+ users.users.avahi = {
+ description = "avahi-daemon privilege separation user";
+ home = "/var/empty";
+ group = "avahi";
+ isSystemUser = true;
+ };
- services.avahi.hostName = mkDefault config.networking.hostName;
-
- users.users = singleton
- { name = "avahi";
- uid = config.ids.uids.avahi;
- description = "`avahi-daemon' privilege separation user";
- home = "/var/empty";
- };
-
- users.groups = singleton
- { name = "avahi";
- gid = config.ids.gids.avahi;
- };
+ users.groups.avahi = {};
system.nssModules = optional cfg.nssmdns pkgs.nssmdns;
environment.systemPackages = [ pkgs.avahi ];
- systemd.sockets.avahi-daemon =
- { description = "Avahi mDNS/DNS-SD Stack Activation Socket";
- listenStreams = [ "/run/avahi-daemon/socket" ];
- wantedBy = [ "sockets.target" ];
- };
-
- systemd.services.avahi-daemon =
- { description = "Avahi mDNS/DNS-SD Stack";
- wantedBy = [ "multi-user.target" ];
- requires = [ "avahi-daemon.socket" ];
-
- serviceConfig."NotifyAccess" = "main";
- serviceConfig."BusName" = "org.freedesktop.Avahi";
- serviceConfig."Type" = "dbus";
-
- path = [ pkgs.coreutils pkgs.avahi ];
-
- preStart = "mkdir -p /run/avahi-daemon";
-
- script =
- ''
- # Make NSS modules visible so that `avahi_nss_support ()' can
- # return a sensible value.
- export LD_LIBRARY_PATH="${config.system.nssModules.path}"
-
- exec ${pkgs.avahi}/sbin/avahi-daemon --syslog -f "${avahiDaemonConf}"
- '';
+ environment.etc = (mapAttrs' (n: v: nameValuePair
+ "avahi/services/${n}.service"
+ { ${if types.path.check v then "source" else "text"} = v; }
+ ) cfg.extraServiceFiles);
+
+ systemd.sockets.avahi-daemon = {
+ description = "Avahi mDNS/DNS-SD Stack Activation Socket";
+ listenStreams = [ "/run/avahi-daemon/socket" ];
+ wantedBy = [ "sockets.target" ];
+ };
+
+ systemd.tmpfiles.rules = [ "d /run/avahi-daemon - avahi avahi -" ];
+
+ systemd.services.avahi-daemon = {
+ description = "Avahi mDNS/DNS-SD Stack";
+ wantedBy = [ "multi-user.target" ];
+ requires = [ "avahi-daemon.socket" ];
+
+ # Make NSS modules visible so that `avahi_nss_support ()' can
+ # return a sensible value.
+ environment.LD_LIBRARY_PATH = config.system.nssModules.path;
+
+ path = [ pkgs.coreutils pkgs.avahi ];
+
+ serviceConfig = {
+ NotifyAccess = "main";
+ BusName = "org.freedesktop.Avahi";
+ Type = "dbus";
+ ExecStart = "${pkgs.avahi}/sbin/avahi-daemon --syslog -f ${avahiDaemonConf}";
};
+ };
services.dbus.enable = true;
services.dbus.packages = [ pkgs.avahi ];
- # Enabling Avahi without exposing it in the firewall doesn't make
- # sense.
- networking.firewall.allowedUDPPorts = [ 5353 ];
-
+ networking.firewall.allowedUDPPorts = mkIf cfg.openFirewall [ 5353 ];
};
-
}
diff --git a/nixos/tests/avahi.nix b/nixos/tests/avahi.nix
index 56b21a401551..ae4f54d5266a 100644
--- a/nixos/tests/avahi.nix
+++ b/nixos/tests/avahi.nix
@@ -15,6 +15,7 @@ import ./make-test.nix ({ pkgs, ... } : {
publish.enable = true;
publish.userServices = true;
publish.workstation = true;
+ extraServiceFiles.ssh = "${pkgs.avahi}/etc/avahi/services/ssh.service";
};
};
in {
@@ -56,5 +57,11 @@ import ./make-test.nix ({ pkgs, ... } : {
$one->succeed("getent hosts two.local >&2");
$two->succeed("getent hosts one.local >&2");
$two->succeed("getent hosts two.local >&2");
+
+ # extra service definitions
+ $one->succeed("avahi-browse -r -t _ssh._tcp | tee out >&2");
+ $one->succeed("test `wc -l < out` -gt 0");
+ $two->succeed("avahi-browse -r -t _ssh._tcp | tee out >&2");
+ $two->succeed("test `wc -l < out` -gt 0");
'';
})
diff --git a/pkgs/development/libraries/avahi/default.nix b/pkgs/development/libraries/avahi/default.nix
index 28302fbbe32f..76010dacc5e2 100644
--- a/pkgs/development/libraries/avahi/default.nix
+++ b/pkgs/development/libraries/avahi/default.nix
@@ -50,6 +50,8 @@ stdenv.mkDerivation rec {
# autoipd won't build on darwin
++ stdenv.lib.optional stdenv.isDarwin "--disable-autoipd";
+ NIX_CFLAGS_COMPILE = "-DAVAHI_SERVICE_DIR=\"/etc/avahi/services\"";
+
preBuild = stdenv.lib.optionalString stdenv.isDarwin ''
sed -i '20 i\
#define __APPLE_USE_RFC_2292' \