diff --git a/modules/disk-health.nix b/hosts/nixos/hs/disk-health.nix similarity index 100% rename from modules/disk-health.nix rename to hosts/nixos/hs/disk-health.nix diff --git a/hosts/nixos/hs/system.nix b/hosts/nixos/hs/system.nix index 7511228..e1fecce 100644 --- a/hosts/nixos/hs/system.nix +++ b/hosts/nixos/hs/system.nix @@ -4,11 +4,11 @@ ./disk-config.nix ./containers.nix # Host-specific container definitions ./proxy.nix # Host-specific Traefik dynamic configuration + ./disk-health.nix # Host-specific disk health monitoring ../../../modules/tailscale.nix ../../../modules/podman.nix ../../../modules/traefik.nix ../../../modules/samba.nix - ../../../modules/disk-health.nix ../../../modules/borg.nix ]; @@ -222,6 +222,29 @@ # Enable experimental nix features nix.settings.experimental-features = [ "nix-command" "flakes" ]; + # Samba file sharing configuration + services.samba-custom = { + enable = true; + serverString = "hs NAS Server"; + workgroup = "WORKGROUP"; + shares = { + Media = { + path = "/mnt/storage/Media"; + comment = "Media Storage"; + browseable = true; + readOnly = false; + guestOk = false; + createMask = "0644"; + directoryMask = "0755"; + forceUser = "yanlin"; + forceGroup = "users"; + validUsers = [ "yanlin" ]; + }; + }; + enableWSDD = true; + openFirewall = false; + }; + # Borg backup configuration services.borgbackup-custom = { enable = true; diff --git a/modules/samba.nix b/modules/samba.nix index 02472ef..90343a2 100644 --- a/modules/samba.nix +++ b/modules/samba.nix @@ -1,63 +1,164 @@ -{ config, pkgs, lib, ... }: +{ config, lib, pkgs, ... }: + +with lib; + +let + cfg = config.services.samba-custom; +in { - # Enable Samba service - services.samba = { - enable = true; - - # Enable SMB protocol versions - package = pkgs.samba4Full; - - # Modern Samba configuration using settings - settings = { - global = { - # Server identification - workgroup = "WORKGROUP"; - "server string" = "hs NAS Server"; - - # Security settings - security = "user"; - "map to guest" = "never"; - - # Performance optimizations - "socket options" = "TCP_NODELAY IPTOS_LOWDELAY SO_RCVBUF=524288 SO_SNDBUF=524288"; - deadtime = "30"; - "use sendfile" = "yes"; - - # Logging - "log file" = "/var/log/samba/log.%m"; - "max log size" = "1000"; - "log level" = "0"; - - # Disable printer sharing - "load printers" = "no"; - printing = "bsd"; - "printcap name" = "/dev/null"; - "disable spoolss" = "yes"; - }; - - # Define shares - Media = { - path = "/mnt/storage/Media"; - browseable = "yes"; - "read only" = "no"; - "guest ok" = "no"; - "create mask" = "0644"; - "directory mask" = "0755"; - "force user" = "yanlin"; - "force group" = "users"; - "valid users" = "yanlin"; - comment = "Media Storage"; - }; + options.services.samba-custom = { + enable = mkEnableOption "Samba file sharing service"; + + workgroup = mkOption { + type = types.str; + default = "WORKGROUP"; + description = "SMB workgroup name"; + }; + + serverString = mkOption { + type = types.str; + default = "NixOS Samba Server"; + description = "Server description string"; + }; + + shares = mkOption { + type = types.attrsOf (types.submodule { + options = { + path = mkOption { + type = types.str; + description = "Path to the shared directory"; + }; + + comment = mkOption { + type = types.str; + default = ""; + description = "Share description comment"; + }; + + browseable = mkOption { + type = types.bool; + default = true; + description = "Whether share is browseable"; + }; + + readOnly = mkOption { + type = types.bool; + default = false; + description = "Whether share is read-only"; + }; + + guestOk = mkOption { + type = types.bool; + default = false; + description = "Allow guest access"; + }; + + createMask = mkOption { + type = types.str; + default = "0644"; + description = "File creation mask"; + }; + + directoryMask = mkOption { + type = types.str; + default = "0755"; + description = "Directory creation mask"; + }; + + forceUser = mkOption { + type = types.nullOr types.str; + default = null; + description = "Force files to be owned by this user"; + }; + + forceGroup = mkOption { + type = types.nullOr types.str; + default = null; + description = "Force files to be owned by this group"; + }; + + validUsers = mkOption { + type = types.listOf types.str; + default = []; + description = "List of valid users for this share"; + }; + }; + }); + default = {}; + description = "Samba share definitions"; + }; + + enableWSDD = mkOption { + type = types.bool; + default = true; + description = "Enable Web Service Discovery (WSD) for SMB discovery"; + }; + + openFirewall = mkOption { + type = types.bool; + default = false; + description = "Open firewall ports for Samba"; }; }; - - # Enable SMB discovery - services.samba-wsdd = { - enable = true; - openFirewall = false; # Keep firewall closed as requested + + config = mkIf cfg.enable { + # Enable Samba service + services.samba = { + enable = true; + + # Enable SMB protocol versions + package = pkgs.samba4Full; + + # Modern Samba configuration using settings + settings = { + global = { + # Server identification + workgroup = cfg.workgroup; + "server string" = cfg.serverString; + + # Security settings + security = "user"; + "map to guest" = "never"; + + # Performance optimizations + "socket options" = "TCP_NODELAY IPTOS_LOWDELAY SO_RCVBUF=524288 SO_SNDBUF=524288"; + deadtime = "30"; + "use sendfile" = "yes"; + + # Logging + "log file" = "/var/log/samba/log.%m"; + "max log size" = "1000"; + "log level" = "0"; + + # Disable printer sharing + "load printers" = "no"; + printing = "bsd"; + "printcap name" = "/dev/null"; + "disable spoolss" = "yes"; + }; + + # Generate share configurations + } // (mapAttrs (name: share: { + path = share.path; + 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; + "valid users" = concatStringsSep " " share.validUsers; + comment = share.comment; + } // (optionalAttrs (share.forceUser != null) { + "force user" = share.forceUser; + }) // (optionalAttrs (share.forceGroup != null) { + "force group" = share.forceGroup; + })) cfg.shares); + }; + + # Enable SMB discovery + services.samba-wsdd = mkIf cfg.enableWSDD { + enable = true; + openFirewall = cfg.openFirewall; + }; }; - - # Configure SMB users - requires manual setup after deployment - # Run: sudo smbpasswd -a yanlin }