diff --git a/nixos/modules/services/network-filesystems/glusterfs.nix b/nixos/modules/services/network-filesystems/glusterfs.nix index e7f52bc4a7d1..15777d45f785 100644 --- a/nixos/modules/services/network-filesystems/glusterfs.nix +++ b/nixos/modules/services/network-filesystems/glusterfs.nix @@ -41,6 +41,57 @@ in default = "INFO"; }; + useRpcbind = mkOption { + type = types.bool; + description = '' + Enable use of rpcbind. This is required for Gluster's NFS functionality. + + You may want to turn it off to reduce the attack surface for DDoS reflection attacks. + + See https://davelozier.com/glusterfs-and-rpcbind-portmap-ddos-reflection-attacks/ + and https://bugzilla.redhat.com/show_bug.cgi?id=1426842 for details. + ''; + default = true; + }; + + enableGlustereventsd = mkOption { + type = types.bool; + description = "Whether to enable the GlusterFS Events Daemon"; + default = true; + }; + + killMode = mkOption { + type = types.enum ["control-group" "process" "mixed" "none"]; + description = '' + The systemd KillMode to use for glusterd. + + glusterd spawns other daemons like gsyncd. + If you want these to stop when glusterd is stopped (e.g. to ensure + that NixOS config changes are reflected even for these sub-daemons), + set this to 'control-group'. + If however you want running volume processes (glusterfsd) and thus + gluster mounts not be interrupted when glusterd is restarted + (for example, when you want to restart them manually at a later time), + set this to 'process'. + ''; + default = "control-group"; + }; + + stopKillTimeout = mkOption { + type = types.str; + description = '' + The systemd TimeoutStopSec to use. + + After this time after having been asked to shut down, glusterd + (and depending on the killMode setting also its child processes) + are killed by systemd. + + The default is set low because GlusterFS (as of 3.10) is known to + not tell its children (like gsyncd) to terminate at all. + ''; + default = "5s"; + }; + extraFlags = mkOption { type = types.listOf types.str; description = "Extra flags passed to the GlusterFS daemon"; @@ -89,7 +140,7 @@ in config = mkIf cfg.enable { environment.systemPackages = [ pkgs.glusterfs ]; - services.rpcbind.enable = true; + services.rpcbind.enable = cfg.useRpcbind; environment.etc = mkIf (cfg.tlsSettings != null) { "ssl/glusterfs.pem".source = cfg.tlsSettings.tlsPem; @@ -104,9 +155,8 @@ in wantedBy = [ "multi-user.target" ]; - requires = [ "rpcbind.service" ]; - after = [ "rpcbind.service" "network.target" "local-fs.target" ]; - before = [ "network-online.target" ]; + requires = lib.optional cfg.useRpcbind "rpcbind.service"; + after = [ "network.target" "local-fs.target" ] ++ lib.optional cfg.useRpcbind [ "rpcbind.service" ]; preStart = '' install -m 0755 -d /var/log/glusterfs @@ -130,11 +180,12 @@ in PIDFile="/run/glusterd.pid"; LimitNOFILE=65536; ExecStart="${glusterfs}/sbin/glusterd -p /run/glusterd.pid --log-level=${cfg.logLevel} ${toString cfg.extraFlags}"; - KillMode="process"; + KillMode=cfg.killMode; + TimeoutStopSec=cfg.stopKillTimeout; }; }; - systemd.services.glustereventsd = { + systemd.services.glustereventsd = mkIf cfg.enableGlustereventsd { inherit restartTriggers; description = "Gluster Events Notifier"; @@ -143,6 +194,10 @@ in after = [ "syslog.target" "network.target" ]; + preStart = '' + install -m 0755 -d /var/log/glusterfs + ''; + serviceConfig = { Type="simple"; Environment="PYTHONPATH=${glusterfs}/usr/lib/python2.7/site-packages";