diff --git a/modules/nixos/services/samba/default.nix b/modules/nixos/services/samba/default.nix index eba5259..37a068b 100755 --- a/modules/nixos/services/samba/default.nix +++ b/modules/nixos/services/samba/default.nix @@ -7,52 +7,44 @@ with lib; let cfg = config.${namespace}.samba; - sambaShares = + + makeShare = + name: share: let - make = - name: share: - nameValuePair "${name}" { - path = share.sharePath; - public = if share.enableTimeMachine then "no" else "yes"; - browseable = if share.browseable then "yes" else "no"; - writable = "yes"; - "force group" = "jallen-nas"; - "read only" = if share.readOnly then "yes" else "no"; - "guest ok" = if share.guestOk then "yes" else "no"; - "create mask" = share.createMask; - "directory mask" = share.directoryMask; - "fruit:aapl" = if share.enableTimeMachine then "yes" else "no"; - "fruit:time machine" = if share.enableTimeMachine then "yes" else "no"; - "vfs objects" = "catia fruit streams_xattr"; - "fruit:time machine max size" = share.timeMachineMaxSize; - }; + isTimeMachine = share.enableTimeMachine; + baseAttrs = { + path = share.sharePath; + browseable = if share.browseable then "yes" else "no"; + "read only" = if share.readOnly then "yes" else "no"; + "guest ok" = if share.guestOk then "yes" else "no"; + "create mask" = share.createMask; + "directory mask" = share.directoryMask; + } + // optionalAttrs (cfg.forceGroup != "") { "force group" = cfg.forceGroup; }; + + timeMachineAttrs = { + "vfs objects" = "catia fruit streams_xattr"; + "fruit:aapl" = "yes"; + "fruit:time machine" = "yes"; + } + // optionalAttrs (share.timeMachineMaxSize != "") { + "fruit:time machine max size" = share.timeMachineMaxSize; + }; in - mapAttrs' make cfg.shares; + nameValuePair name (baseAttrs // optionalAttrs isTimeMachine timeMachineAttrs); + + sambaShares = mapAttrs' makeShare cfg.shares; in { imports = [ ./options.nix ]; config = mkIf cfg.enable { - # make shares visible for Windows clients + # Make shares visible for Windows clients via WS-Discovery services.samba-wsdd = { enable = true; openFirewall = true; }; - services.netatalk = { - enable = cfg.enableTimeMachine; - settings = { - time-machine = { - path = cfg.timeMachinePath; - "valid users" = "whoever"; - "time machine" = cfg.enableTimeMachine; - }; - }; - }; - - networking.firewall.enable = true; - networking.firewall.allowPing = true; - services.samba = { enable = true; openFirewall = true; @@ -60,17 +52,19 @@ in nmbd.enable = true; settings = { global = { - "workgroup" = "WORKGROUP"; - "server string" = "Jallen-NAS"; - "netbios name" = "Jallen-NAS"; - "security" = "user"; - #"use sendfile" = "yes"; - #"max protocol" = "smb2"; - # note: localhost is the ipv6 localhost ::1 - "hosts allow" = "10.0.1. 127.0.0.1 localhost"; + workgroup = "WORKGROUP"; + "server string" = config.networking.hostName; + "netbios name" = config.networking.hostName; + security = "user"; + "hosts allow" = cfg.hostsAllow; "hosts deny" = "0.0.0.0/0"; "guest account" = "nobody"; "map to guest" = "bad user"; + } + // optionalAttrs cfg.enableTimeMachine { + # Required globals for macOS Time Machine over SMB3 + "fruit:aapl" = "yes"; + "fruit:model" = "MacSamba"; }; } // sambaShares; diff --git a/modules/nixos/services/samba/options.nix b/modules/nixos/services/samba/options.nix index 50b8961..a04b404 100755 --- a/modules/nixos/services/samba/options.nix +++ b/modules/nixos/services/samba/options.nix @@ -2,69 +2,88 @@ with lib; { options.${namespace}.samba = { - enable = mkEnableOption "nas samba service"; + enable = mkEnableOption "NAS samba service"; - autoStart = mkOption { - type = types.bool; - default = true; + hostsAllow = mkOption { + type = types.str; + default = "127.0.0.1 localhost"; + description = "Space-separated list of hosts/subnets allowed to connect (e.g. \"10.0.1. 127.0.0.1 localhost\")."; }; + + forceGroup = mkOption { + type = types.str; + default = ""; + description = "If non-empty, force all file creation to use this group."; + }; + enableTimeMachine = mkOption { type = types.bool; default = false; + description = "Whether to enable Time Machine support via SMB3."; }; + timeMachinePath = mkOption { type = types.str; default = ""; - }; - hostsAllow = mkOption { - type = types.str; - default = ""; + description = "Path to the Time Machine backup directory (used as the default Time Machine share path)."; }; shares = mkOption { type = types.attrsOf ( types.submodule { options = { - public = mkOption { - type = types.bool; - default = false; - }; sharePath = mkOption { type = types.str; default = ""; + description = "Absolute path on disk to expose as this share."; }; + readOnly = mkOption { type = types.bool; default = false; + description = "Whether the share is read-only."; }; + browseable = mkOption { type = types.bool; default = true; + description = "Whether the share appears in network browse lists."; }; + guestOk = mkOption { type = types.bool; default = true; + description = "Whether unauthenticated (guest) access is permitted."; }; + createMask = mkOption { type = types.str; - default = "0774"; + default = "0664"; + description = "Permission mask applied to newly created files."; }; + directoryMask = mkOption { type = types.str; default = "0775"; + description = "Permission mask applied to newly created directories."; }; + enableTimeMachine = mkOption { type = types.bool; default = false; + description = "Whether this share is a Time Machine target."; }; + timeMachineMaxSize = mkOption { type = types.str; - default = "0K"; + default = ""; + description = "Maximum size for this Time Machine share (e.g. \"1T\"). Empty means unlimited."; }; }; } ); default = { }; + description = "Attribute set of Samba shares to export."; }; }; } diff --git a/systems/x86_64-linux/jallen-nas/default.nix b/systems/x86_64-linux/jallen-nas/default.nix index f1a47dc..958304a 100755 --- a/systems/x86_64-linux/jallen-nas/default.nix +++ b/systems/x86_64-linux/jallen-nas/default.nix @@ -198,42 +198,24 @@ in # ################################################### samba = { - enable = false; - hostsAllow = "10.0.1."; + enable = true; + hostsAllow = "10.0.1. 127.0.0.1 localhost"; + forceGroup = "jallen-nas"; enableTimeMachine = true; timeMachinePath = "/media/nas/main/timemachine"; shares = { - "3d_printer" = { - public = true; - sharePath = "/media/nas/main/3d_printer"; - }; - Backup = { - public = true; - sharePath = "/media/nas/main/backup"; - }; - Documents = { - public = true; - sharePath = "/media/nas/main/documents"; - }; - isos = { - public = true; - sharePath = "/media/nas/main/isos"; - }; + "3d_printer".sharePath = "/media/nas/main/documents/3d-models"; + Backup.sharePath = "/media/nas/main/backup"; + Documents.sharePath = "/media/nas/main/documents"; + isos.sharePath = "/media/nas/main/documents/isos"; + app_data.sharePath = "/media/nas/main/appdata"; TimeMachine = { - public = false; sharePath = "/media/nas/main/timemachine"; + guestOk = false; enableTimeMachine = true; timeMachineMaxSize = "1T"; }; - app_data = { - public = true; - sharePath = "/media/nas/main/ssd_app_data"; - }; - nix-config = { - public = true; - sharePath = "/home/matt/nix-config"; - }; }; };