Compare commits
2 Commits
436cc7ccc9
...
2c6ea8b9a4
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
2c6ea8b9a4 | ||
|
|
cf40c72e7e |
@@ -50,15 +50,19 @@ rec {
|
||||
|
||||
defaultConfig = {
|
||||
# Caddy reverse proxy: when reverseProxy.enable = true, contribute this
|
||||
# service's virtual host block to the Caddy config. The TLS wildcard
|
||||
# cert is handled via a (cloudflare_tls) snippet defined in globalConfig.
|
||||
# services.caddy.virtualHosts.${fqdn} = lib.mkIf cfg.reverseProxy.enable {
|
||||
# extraConfig = ''
|
||||
# import cloudflare_tls
|
||||
# reverse_proxy ${upstreamUrl}
|
||||
# ${cfg.reverseProxy.extraCaddyConfig}
|
||||
# '';
|
||||
# };
|
||||
# service's named-matcher block into the shared wildcard virtual host.
|
||||
# The TLS block stays in the caddy module itself; all services merge
|
||||
# their handle blocks into the same "*.${domain}" extraConfig via the
|
||||
# lines type (which concatenates automatically).
|
||||
services.caddy.virtualHosts."*.${cfg.reverseProxy.domain}" = lib.mkIf cfg.reverseProxy.enable {
|
||||
extraConfig = ''
|
||||
@${name} host ${fqdn}
|
||||
handle @${name} {
|
||||
reverse_proxy ${upstreamUrl}
|
||||
${cfg.reverseProxy.extraCaddyConfig}
|
||||
}
|
||||
'';
|
||||
};
|
||||
|
||||
# Open firewall
|
||||
networking.firewall = lib.mkIf cfg.openFirewall {
|
||||
@@ -112,11 +116,19 @@ rec {
|
||||
# # "d ${cfg.configDir}/server-files 0775 ${name} ${name} - -"
|
||||
# # "d ${cfg.configDir}/user-files 0775 ${name} ${name} - -"
|
||||
# ];
|
||||
}
|
||||
// moduleConfig;
|
||||
};
|
||||
in
|
||||
{ lib, ... }:
|
||||
{
|
||||
imports = [
|
||||
# defaultConfig and moduleConfig are kept as separate inline modules so
|
||||
# the NixOS module system handles all merging (mkIf, mkForce, mkMerge,
|
||||
# etc.) correctly, rather than merging raw attrsets with // or
|
||||
# recursiveUpdate which can silently clobber mkIf wrappers.
|
||||
{ config = lib.mkIf cfg.enable defaultConfig; }
|
||||
{ config = lib.mkIf cfg.enable moduleConfig; }
|
||||
];
|
||||
|
||||
options.${namespace}.${domain}.${name} = lib.mkOption {
|
||||
type = lib.types.submodule {
|
||||
options = {
|
||||
@@ -167,8 +179,6 @@ rec {
|
||||
};
|
||||
default = { };
|
||||
};
|
||||
|
||||
config = lib.mkIf cfg.enable defaultConfig;
|
||||
};
|
||||
|
||||
# container
|
||||
|
||||
@@ -42,78 +42,6 @@ let
|
||||
tls {
|
||||
dns cloudflare {$CLOUDFLARE_DNS_API_TOKEN}
|
||||
}
|
||||
|
||||
@authentik host authentik.mjallen.dev
|
||||
handle @authentik {
|
||||
reverse_proxy http://10.0.1.3:${toString config.${namespace}.services.authentik.port}
|
||||
}
|
||||
|
||||
@cache host cache.mjallen.dev
|
||||
handle @cache {
|
||||
reverse_proxy http://10.0.1.3:${toString config.${namespace}.services.attic.port}
|
||||
}
|
||||
|
||||
@cloud host cloud.mjallen.dev
|
||||
handle @cloud {
|
||||
reverse_proxy http://10.0.1.3:${toString config.${namespace}.services.nextcloud.port} {
|
||||
header_up Host {upstream_hostport}
|
||||
}
|
||||
|
||||
header {
|
||||
Strict-Transport-Security "max-age=63072000; includeSubDomains; preload"
|
||||
X-Robots-Tag "noindex, nofollow"
|
||||
}
|
||||
}
|
||||
|
||||
@gitea host gitea.mjallen.dev
|
||||
handle @gitea {
|
||||
reverse_proxy http://10.0.1.3:${toString config.${namespace}.services.gitea.port}
|
||||
}
|
||||
|
||||
@homeassistant host hass.mjallen.dev
|
||||
handle @homeassistant {
|
||||
reverse_proxy http://nuc-nixos.local:8123
|
||||
}
|
||||
|
||||
@immich host immich.mjallen.dev
|
||||
handle @immich {
|
||||
reverse_proxy http://10.0.1.3:${toString config.${namespace}.services.immich.port}
|
||||
}
|
||||
|
||||
@jellyfin host jellyfin.mjallen.dev
|
||||
handle @jellyfin {
|
||||
reverse_proxy http://10.0.1.3:${toString config.${namespace}.services.jellyfin.port}
|
||||
}
|
||||
|
||||
@jellyseerr host jellyseerr.mjallen.dev
|
||||
handle @jellyseerr {
|
||||
reverse_proxy http://10.0.1.3:${toString config.${namespace}.services.jellyseerr.port}
|
||||
}
|
||||
|
||||
@lubelogger host lubelogger.mjallen.dev
|
||||
handle @lubelogger {
|
||||
reverse_proxy http://10.0.1.3:${toString config.${namespace}.services.lubelogger.port}
|
||||
}
|
||||
|
||||
@matrix host matrix.mjallen.dev
|
||||
handle @matrix {
|
||||
reverse_proxy http://10.0.1.3:${toString config.${namespace}.services.matrix.port}
|
||||
}
|
||||
|
||||
@ntfy host ntfy.mjallen.dev
|
||||
handle @ntfy {
|
||||
reverse_proxy http://10.0.1.3:${toString config.${namespace}.services.ntfy.port}
|
||||
}
|
||||
|
||||
@office host office.mjallen.dev
|
||||
handle @office {
|
||||
reverse_proxy http://10.0.1.3:${toString config.${namespace}.services.collabora.port}
|
||||
}
|
||||
|
||||
@termix host termix.mjallen.dev
|
||||
handle @termix {
|
||||
reverse_proxy http://10.0.1.3:${toString config.${namespace}.services.termix.port}
|
||||
}
|
||||
'';
|
||||
};
|
||||
};
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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.";
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
@@ -21,6 +21,7 @@ let
|
||||
extraOptions = [ "--device=/dev/dri" ];
|
||||
volumes = [
|
||||
"${cfg.configDir}/tunarr:/config/tunarr"
|
||||
"${cfg.configDir}/tunarr:/root/.local/share/tunarr"
|
||||
"${cfg.dataDir}/movies:/libraries/movies"
|
||||
"${cfg.dataDir}/tv:/libraries/tv"
|
||||
"${cfg.configDir}/transcode:/transcode"
|
||||
|
||||
@@ -162,6 +162,7 @@ in
|
||||
3001
|
||||
3333
|
||||
5201 # iperf
|
||||
5432 # postgresql
|
||||
8400
|
||||
9200 # elasticsearch / attic
|
||||
9233
|
||||
@@ -197,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";
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user