mirror of
https://github.com/gensokyo-zone/infrastructure.git
synced 2026-02-09 04:19:19 -08:00
style: alejandra $(fd -e nix)
This commit is contained in:
parent
97d9eecd3c
commit
e63304937d
91 changed files with 1422 additions and 1102 deletions
1
.gitignore
vendored
1
.gitignore
vendored
|
|
@ -6,3 +6,4 @@
|
||||||
.terraform
|
.terraform
|
||||||
.DS_Store
|
.DS_Store
|
||||||
.envrc.conf
|
.envrc.conf
|
||||||
|
.idea
|
||||||
|
|
|
||||||
|
|
@ -45,7 +45,7 @@ in {
|
||||||
cron = "0 0 * * *";
|
cron = "0 0 * * *";
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
workflow_dispatch = { };
|
workflow_dispatch = {};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -65,7 +65,7 @@ in {
|
||||||
displayName = "flake update build";
|
displayName = "flake update build";
|
||||||
environment = ["CACHIX_SIGNING_KEY" "GITHUB_REF"];
|
environment = ["CACHIX_SIGNING_KEY" "GITHUB_REF"];
|
||||||
command = let
|
command = let
|
||||||
filteredHosts = [ "hakurei" "reimu" "aya" "tei" "litterbox" "mediabox" ];
|
filteredHosts = ["hakurei" "reimu" "aya" "tei" "litterbox" "mediabox"];
|
||||||
gcBetweenHosts = false;
|
gcBetweenHosts = false;
|
||||||
nodeBuildString = concatMapStringsSep " && " (node: "nix build --show-trace -Lf . nixosConfigurations.${node}.config.system.build.toplevel -o result-${node}" + optionalString gcBetweenHosts " && nix-collect-garbage -d") filteredHosts;
|
nodeBuildString = concatMapStringsSep " && " (node: "nix build --show-trace -Lf . nixosConfigurations.${node}.config.system.build.toplevel -o result-${node}" + optionalString gcBetweenHosts " && nix-collect-garbage -d") filteredHosts;
|
||||||
hostPath = builtins.getEnv "PATH";
|
hostPath = builtins.getEnv "PATH";
|
||||||
|
|
|
||||||
|
|
@ -12,26 +12,28 @@
|
||||||
(hasSuffix ".adoc" path || baseNameOf path == "docinfo.html")
|
(hasSuffix ".adoc" path || baseNameOf path == "docinfo.html")
|
||||||
|| type == "directory";
|
|| type == "directory";
|
||||||
};
|
};
|
||||||
in stdenvNoCC.mkDerivation {
|
in
|
||||||
pname = "genso-docs";
|
stdenvNoCC.mkDerivation {
|
||||||
version = "dev";
|
pname = "genso-docs";
|
||||||
inherit src;
|
version = "dev";
|
||||||
|
inherit src;
|
||||||
|
|
||||||
ASCIIDOCTOR_OPTS = [
|
ASCIIDOCTOR_OPTS = [
|
||||||
"-a" "docinfo=shared"
|
"-a"
|
||||||
];
|
"docinfo=shared"
|
||||||
|
];
|
||||||
|
|
||||||
nativeBuildInputs = [ asciidoctor ];
|
nativeBuildInputs = [asciidoctor];
|
||||||
passAsFile = [ "buildCommand" ];
|
passAsFile = ["buildCommand"];
|
||||||
buildCommand = ''
|
buildCommand = ''
|
||||||
install -d "$out"
|
install -d "$out"
|
||||||
ASCIIDOCTOR_SRCS=(
|
ASCIIDOCTOR_SRCS=(
|
||||||
$(find "$src" -type f -name '*.adoc' -not -path "$src/inc/*")
|
$(find "$src" -type f -name '*.adoc' -not -path "$src/inc/*")
|
||||||
)
|
)
|
||||||
asciidoctor \
|
asciidoctor \
|
||||||
$ASCIIDOCTOR_OPTS \
|
$ASCIIDOCTOR_OPTS \
|
||||||
-a docinfodir="$src/" \
|
-a docinfodir="$src/" \
|
||||||
-a inc="$src/_inc/" \
|
-a inc="$src/_inc/" \
|
||||||
-b html -R "$src" -D "$out" "''${ASCIIDOCTOR_SRCS[@]}"
|
-b html -R "$src" -D "$out" "''${ASCIIDOCTOR_SRCS[@]}"
|
||||||
'';
|
'';
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -10,16 +10,15 @@
|
||||||
templateUsers = filterAttrs (_: userIs "peeps") templateSystem.config.users.users;
|
templateUsers = filterAttrs (_: userIs "peeps") templateSystem.config.users.users;
|
||||||
mkNodeUsers = users: let
|
mkNodeUsers = users: let
|
||||||
nodeUsers = mapAttrsToList (_: mkNodeUser) templateUsers;
|
nodeUsers = mapAttrsToList (_: mkNodeUser) templateUsers;
|
||||||
in sortOn (user: user.uid) nodeUsers;
|
in
|
||||||
|
sortOn (user: user.uid) nodeUsers;
|
||||||
mkNodeUser = user: {
|
mkNodeUser = user: {
|
||||||
inherit (user) name uid;
|
inherit (user) name uid;
|
||||||
authorizedKeys = user.openssh.authorizedKeys.keys;
|
authorizedKeys = user.openssh.authorizedKeys.keys;
|
||||||
};
|
};
|
||||||
mkNode = {
|
mkNode = {name}: {
|
||||||
name,
|
|
||||||
}: {
|
|
||||||
users = mkNodeUsers templateUsers;
|
users = mkNodeUsers templateUsers;
|
||||||
};
|
};
|
||||||
in {
|
in {
|
||||||
reisen = mkNode { name = "reisen"; };
|
reisen = mkNode {name = "reisen";};
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -11,7 +11,7 @@
|
||||||
inherit (config.services) tailscale;
|
inherit (config.services) tailscale;
|
||||||
inherit (config) networking;
|
inherit (config) networking;
|
||||||
cfg = config.networking.access;
|
cfg = config.networking.access;
|
||||||
cidrModule = { config, ... }: {
|
cidrModule = {config, ...}: {
|
||||||
options = with lib.types; {
|
options = with lib.types; {
|
||||||
all = mkOption {
|
all = mkOption {
|
||||||
type = listOf str;
|
type = listOf str;
|
||||||
|
|
@ -19,11 +19,11 @@
|
||||||
};
|
};
|
||||||
v4 = mkOption {
|
v4 = mkOption {
|
||||||
type = listOf str;
|
type = listOf str;
|
||||||
default = [ ];
|
default = [];
|
||||||
};
|
};
|
||||||
v6 = mkOption {
|
v6 = mkOption {
|
||||||
type = listOf str;
|
type = listOf str;
|
||||||
default = [ ];
|
default = [];
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
config.all = mkOptionDefault (
|
config.all = mkOptionDefault (
|
||||||
|
|
@ -35,12 +35,14 @@ in {
|
||||||
options.networking.access = with lib.types; {
|
options.networking.access = with lib.types; {
|
||||||
cidrForNetwork = mkOption {
|
cidrForNetwork = mkOption {
|
||||||
type = attrsOf (submodule cidrModule);
|
type = attrsOf (submodule cidrModule);
|
||||||
default = { };
|
default = {};
|
||||||
};
|
};
|
||||||
localaddrs = {
|
localaddrs = {
|
||||||
enable = mkEnableOption "localaddrs" // {
|
enable =
|
||||||
default = networking.firewall.interfaces.local.nftables.enable;
|
mkEnableOption "localaddrs"
|
||||||
};
|
// {
|
||||||
|
default = networking.firewall.interfaces.local.nftables.enable;
|
||||||
|
};
|
||||||
stateDir = mkOption {
|
stateDir = mkOption {
|
||||||
type = path;
|
type = path;
|
||||||
default = "/var/lib/localaddrs";
|
default = "/var/lib/localaddrs";
|
||||||
|
|
@ -87,10 +89,11 @@ in {
|
||||||
};
|
};
|
||||||
localaddrs = {
|
localaddrs = {
|
||||||
nftablesInclude = mkBefore (''
|
nftablesInclude = mkBefore (''
|
||||||
define localrange6 = 2001:568::/29
|
define localrange6 = 2001:568::/29
|
||||||
'' + optionalString cfg.localaddrs.enable ''
|
''
|
||||||
include "${cfg.localaddrs.stateDir}/*.nft"
|
+ optionalString cfg.localaddrs.enable ''
|
||||||
'');
|
include "${cfg.localaddrs.stateDir}/*.nft"
|
||||||
|
'');
|
||||||
reloadScript = let
|
reloadScript = let
|
||||||
localaddrs-reload = pkgs.writeShellScript "localaddrs-reload" ''
|
localaddrs-reload = pkgs.writeShellScript "localaddrs-reload" ''
|
||||||
${config.systemd.package}/bin/systemctl reload localaddrs 2>/dev/null ||
|
${config.systemd.package}/bin/systemctl reload localaddrs 2>/dev/null ||
|
||||||
|
|
@ -101,7 +104,7 @@ in {
|
||||||
};
|
};
|
||||||
moduleArgAttrs = {
|
moduleArgAttrs = {
|
||||||
inherit (cfg) cidrForNetwork localaddrs;
|
inherit (cfg) cidrForNetwork localaddrs;
|
||||||
mkSnakeOil = pkgs.callPackage ../../packages/snakeoil.nix { };
|
mkSnakeOil = pkgs.callPackage ../../packages/snakeoil.nix {};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -111,7 +114,8 @@ in {
|
||||||
interfaces.local = {
|
interfaces.local = {
|
||||||
nftables.conditions = [
|
nftables.conditions = [
|
||||||
"ip saddr { ${concatStringsSep ", " cfg.cidrForNetwork.local.v4} }"
|
"ip saddr { ${concatStringsSep ", " cfg.cidrForNetwork.local.v4} }"
|
||||||
(mkIf networking.enableIPv6
|
(
|
||||||
|
mkIf networking.enableIPv6
|
||||||
"ip6 saddr { $localrange6, ${concatStringsSep ", " cfg.cidrForNetwork.local.v6} }"
|
"ip6 saddr { $localrange6, ${concatStringsSep ", " cfg.cidrForNetwork.local.v6} }"
|
||||||
)
|
)
|
||||||
];
|
];
|
||||||
|
|
@ -169,12 +173,12 @@ in {
|
||||||
in {
|
in {
|
||||||
localaddrs = mkIf cfg.localaddrs.enable {
|
localaddrs = mkIf cfg.localaddrs.enable {
|
||||||
unitConfig = {
|
unitConfig = {
|
||||||
After = [ "network-online.target" ];
|
After = ["network-online.target"];
|
||||||
};
|
};
|
||||||
serviceConfig = rec {
|
serviceConfig = rec {
|
||||||
StateDirectory = "localaddrs";
|
StateDirectory = "localaddrs";
|
||||||
ExecStart = mkMerge [
|
ExecStart = mkMerge [
|
||||||
[ "${localaddrs}" ]
|
["${localaddrs}"]
|
||||||
(mkIf networking.nftables.enable (mkAfter [
|
(mkIf networking.nftables.enable (mkAfter [
|
||||||
"${localaddrs-nftables}"
|
"${localaddrs-nftables}"
|
||||||
]))
|
]))
|
||||||
|
|
@ -188,7 +192,7 @@ in {
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
nftables = mkIf (networking.nftables.enable && cfg.localaddrs.enable) rec {
|
nftables = mkIf (networking.nftables.enable && cfg.localaddrs.enable) rec {
|
||||||
wants = [ "localaddrs.service" ];
|
wants = ["localaddrs.service"];
|
||||||
serviceConfig = {
|
serviceConfig = {
|
||||||
ExecReload = mkBefore [
|
ExecReload = mkBefore [
|
||||||
"+${cfg.localaddrs.reloadScript}"
|
"+${cfg.localaddrs.reloadScript}"
|
||||||
|
|
@ -196,7 +200,7 @@ in {
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
nginx = mkIf (config.services.nginx.enable && cfg.localaddrs.enable) rec {
|
nginx = mkIf (config.services.nginx.enable && cfg.localaddrs.enable) rec {
|
||||||
wants = [ "localaddrs.service" ];
|
wants = ["localaddrs.service"];
|
||||||
after = wants;
|
after = wants;
|
||||||
serviceConfig = {
|
serviceConfig = {
|
||||||
ExecReload = mkBefore [
|
ExecReload = mkBefore [
|
||||||
|
|
|
||||||
|
|
@ -1,64 +1,79 @@
|
||||||
{ pkgs, config, utils, lib, ... }: let
|
{
|
||||||
|
pkgs,
|
||||||
|
config,
|
||||||
|
utils,
|
||||||
|
lib,
|
||||||
|
...
|
||||||
|
}: let
|
||||||
inherit (lib.attrsets) mapAttrsToList mapAttrs' nameValuePair filterAttrsRecursive;
|
inherit (lib.attrsets) mapAttrsToList mapAttrs' nameValuePair filterAttrsRecursive;
|
||||||
inherit (lib.lists) singleton;
|
inherit (lib.lists) singleton;
|
||||||
inherit (lib.modules) mkIf mkMerge mkForce;
|
inherit (lib.modules) mkIf mkMerge mkForce;
|
||||||
inherit (lib.options) mkOption mkEnableOption;
|
inherit (lib.options) mkOption mkEnableOption;
|
||||||
cfg = config.services.cloudflared;
|
cfg = config.services.cloudflared;
|
||||||
settingsFormat = pkgs.formats.json { };
|
settingsFormat = pkgs.formats.json {};
|
||||||
in {
|
in {
|
||||||
options.services.cloudflared = with lib.types; {
|
options.services.cloudflared = with lib.types; {
|
||||||
tunnels = let
|
tunnels = let
|
||||||
tunnelModule = { config, ... }: {
|
tunnelModule = {config, ...}: {
|
||||||
options = {
|
options = {
|
||||||
extraTunnel = {
|
extraTunnel = {
|
||||||
enable = mkEnableOption "extra tunnels" // {
|
enable =
|
||||||
default = config.extraTunnel.ingress != { };
|
mkEnableOption "extra tunnels"
|
||||||
};
|
// {
|
||||||
|
default = config.extraTunnel.ingress != {};
|
||||||
|
};
|
||||||
ingress = mkOption {
|
ingress = mkOption {
|
||||||
inherit (settingsFormat) type;
|
inherit (settingsFormat) type;
|
||||||
default = { };
|
default = {};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
in mkOption {
|
in
|
||||||
type = attrsOf (submodule tunnelModule);
|
mkOption {
|
||||||
};
|
type = attrsOf (submodule tunnelModule);
|
||||||
|
};
|
||||||
};
|
};
|
||||||
config.systemd.services = let
|
config.systemd.services = let
|
||||||
filterConfig = filterAttrsRecursive (_: v: ! builtins.elem v [ null [ ] { } ]);
|
filterConfig = filterAttrsRecursive (_: v: ! builtins.elem v [null [] {}]);
|
||||||
mapIngress = hostname: ingress: {
|
mapIngress = hostname: ingress:
|
||||||
inherit hostname;
|
{
|
||||||
} // filterConfig (filterConfig ingress);
|
inherit hostname;
|
||||||
in mkIf cfg.enable (mapAttrs' (uuid: tunnel: let
|
}
|
||||||
RuntimeDirectory = "cloudflared-tunnel-${uuid}";
|
// filterConfig (filterConfig ingress);
|
||||||
configPath = "/run/${RuntimeDirectory}/config.yml";
|
in
|
||||||
settings = {
|
mkIf cfg.enable (mapAttrs' (uuid: tunnel: let
|
||||||
tunnel = uuid;
|
RuntimeDirectory = "cloudflared-tunnel-${uuid}";
|
||||||
credentials-file = tunnel.credentialsFile;
|
configPath = "/run/${RuntimeDirectory}/config.yml";
|
||||||
ingress = mapAttrsToList mapIngress tunnel.ingress
|
settings = {
|
||||||
++ mapAttrsToList mapIngress tunnel.extraTunnel.ingress
|
tunnel = uuid;
|
||||||
++ singleton { service = tunnel.default; };
|
credentials-file = tunnel.credentialsFile;
|
||||||
};
|
ingress =
|
||||||
in nameValuePair "cloudflared-tunnel-${uuid}" (mkMerge [
|
mapAttrsToList mapIngress tunnel.ingress
|
||||||
{
|
++ mapAttrsToList mapIngress tunnel.extraTunnel.ingress
|
||||||
after = mkIf config.services.tailscale.enable [ "tailscale-autoconnect.service" ];
|
++ singleton {service = tunnel.default;};
|
||||||
serviceConfig = {
|
|
||||||
RestartSec = 10;
|
|
||||||
};
|
};
|
||||||
}
|
in
|
||||||
(mkIf tunnel.extraTunnel.enable {
|
nameValuePair "cloudflared-tunnel-${uuid}" (mkMerge [
|
||||||
serviceConfig = {
|
{
|
||||||
inherit RuntimeDirectory;
|
after = mkIf config.services.tailscale.enable ["tailscale-autoconnect.service"];
|
||||||
ExecStart = mkForce [
|
serviceConfig = {
|
||||||
"${cfg.package}/bin/cloudflared tunnel --config=${configPath} --no-autoupdate run"
|
RestartSec = 10;
|
||||||
];
|
};
|
||||||
ExecStartPre = [
|
}
|
||||||
(pkgs.writeShellScript "cloudflared-tunnel-${uuid}-prepare" ''
|
(mkIf tunnel.extraTunnel.enable {
|
||||||
${utils.genJqSecretsReplacementSnippet settings configPath}
|
serviceConfig = {
|
||||||
'')
|
inherit RuntimeDirectory;
|
||||||
];
|
ExecStart = mkForce [
|
||||||
};
|
"${cfg.package}/bin/cloudflared tunnel --config=${configPath} --no-autoupdate run"
|
||||||
})
|
];
|
||||||
])) cfg.tunnels);
|
ExecStartPre = [
|
||||||
|
(pkgs.writeShellScript "cloudflared-tunnel-${uuid}-prepare" ''
|
||||||
|
${utils.genJqSecretsReplacementSnippet settings configPath}
|
||||||
|
'')
|
||||||
|
];
|
||||||
|
};
|
||||||
|
})
|
||||||
|
]))
|
||||||
|
cfg.tunnels);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -11,7 +11,7 @@
|
||||||
cfg = config.services.github-runners;
|
cfg = config.services.github-runners;
|
||||||
nixosConfig = config;
|
nixosConfig = config;
|
||||||
enabledRunners = filterAttrs (_: runner: runner.enable) cfg;
|
enabledRunners = filterAttrs (_: runner: runner.enable) cfg;
|
||||||
runnerModule = { config, ... }: {
|
runnerModule = {config, ...}: {
|
||||||
options = with lib.types; {
|
options = with lib.types; {
|
||||||
networkNamespace.name = mkOption {
|
networkNamespace.name = mkOption {
|
||||||
type = nullOr str;
|
type = nullOr str;
|
||||||
|
|
@ -19,7 +19,7 @@
|
||||||
};
|
};
|
||||||
serviceSettings = mkOption {
|
serviceSettings = mkOption {
|
||||||
type = unmerged.type;
|
type = unmerged.type;
|
||||||
default = { };
|
default = {};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
config = {
|
config = {
|
||||||
|
|
@ -58,8 +58,10 @@ in {
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
config = {
|
config = {
|
||||||
systemd.services = mapAttrs' (name: runner: nameValuePair "github-runner-${name}" (
|
systemd.services = mapAttrs' (name: runner:
|
||||||
unmerged.merge runner.serviceSettings
|
nameValuePair "github-runner-${name}" (
|
||||||
)) enabledRunners;
|
unmerged.merge runner.serviceSettings
|
||||||
|
))
|
||||||
|
enabledRunners;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -17,29 +17,43 @@ in {
|
||||||
default = config.networking.domain;
|
default = config.networking.domain;
|
||||||
};
|
};
|
||||||
homekit = {
|
homekit = {
|
||||||
enable = mkEnableOption "homekit" // {
|
enable =
|
||||||
default = cfg.config.homekit or [ ] != [ ];
|
mkEnableOption "homekit"
|
||||||
|
// {
|
||||||
|
default = cfg.config.homekit or [] != [];
|
||||||
|
};
|
||||||
|
openFirewall =
|
||||||
|
mkEnableOption "homekit ports"
|
||||||
|
// {
|
||||||
|
default = cfg.openFirewall;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
googleAssistant.enable =
|
||||||
|
mkEnableOption "Google Assistant"
|
||||||
|
// {
|
||||||
|
default = cfg.config.google_assistant or {} != {};
|
||||||
};
|
};
|
||||||
openFirewall = mkEnableOption "homekit ports" // {
|
androidTv.enable =
|
||||||
default = cfg.openFirewall;
|
mkEnableOption "Android TV"
|
||||||
|
// {
|
||||||
|
default = elem "androidtv" cfg.extraComponents;
|
||||||
|
};
|
||||||
|
brother.enable =
|
||||||
|
mkEnableOption "brother"
|
||||||
|
// {
|
||||||
|
default = elem "brother" cfg.extraComponents;
|
||||||
};
|
};
|
||||||
};
|
|
||||||
googleAssistant.enable = mkEnableOption "Google Assistant" // {
|
|
||||||
default = cfg.config.google_assistant or { } != { };
|
|
||||||
};
|
|
||||||
androidTv.enable = mkEnableOption "Android TV" // {
|
|
||||||
default = elem "androidtv" cfg.extraComponents;
|
|
||||||
};
|
|
||||||
brother.enable = mkEnableOption "brother" // {
|
|
||||||
default = elem "brother" cfg.extraComponents;
|
|
||||||
};
|
|
||||||
cast = {
|
cast = {
|
||||||
enable = mkEnableOption "Chromecast" // {
|
enable =
|
||||||
default = elem "cast" cfg.extraComponents;
|
mkEnableOption "Chromecast"
|
||||||
};
|
// {
|
||||||
openFirewall = mkEnableOption "Chromecast ports" // {
|
default = elem "cast" cfg.extraComponents;
|
||||||
default = cfg.openFirewall;
|
};
|
||||||
};
|
openFirewall =
|
||||||
|
mkEnableOption "Chromecast ports"
|
||||||
|
// {
|
||||||
|
default = cfg.openFirewall;
|
||||||
|
};
|
||||||
};
|
};
|
||||||
finalPackage = mkOption {
|
finalPackage = mkOption {
|
||||||
type = types.path;
|
type = types.path;
|
||||||
|
|
@ -50,7 +64,7 @@ in {
|
||||||
config = {
|
config = {
|
||||||
networking.firewall = let
|
networking.firewall = let
|
||||||
homekitTcp = mkIf cfg.homekit.enable (
|
homekitTcp = mkIf cfg.homekit.enable (
|
||||||
map ({ port, ... }: port) cfg.config.homekit or [ ]
|
map ({port, ...}: port) cfg.config.homekit or []
|
||||||
);
|
);
|
||||||
|
|
||||||
castUdpRanges = mkIf cfg.cast.enable [
|
castUdpRanges = mkIf cfg.cast.enable [
|
||||||
|
|
@ -59,21 +73,23 @@ in {
|
||||||
to = 60999;
|
to = 60999;
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
in mkIf cfg.enable {
|
in
|
||||||
interfaces.local = {
|
mkIf cfg.enable {
|
||||||
allowedTCPPorts = mkIf (!cfg.homekit.openFirewall) homekitTcp;
|
interfaces.local = {
|
||||||
allowedUDPPortRanges = mkIf (!cfg.cast.openFirewall) castUdpRanges;
|
allowedTCPPorts = mkIf (!cfg.homekit.openFirewall) homekitTcp;
|
||||||
|
allowedUDPPortRanges = mkIf (!cfg.cast.openFirewall) castUdpRanges;
|
||||||
|
};
|
||||||
|
allowedTCPPorts = mkIf cfg.homekit.openFirewall homekitTcp;
|
||||||
|
allowedUDPPortRanges = mkIf cfg.cast.openFirewall castUdpRanges;
|
||||||
};
|
};
|
||||||
allowedTCPPorts = mkIf cfg.homekit.openFirewall homekitTcp;
|
|
||||||
allowedUDPPortRanges = mkIf cfg.cast.openFirewall castUdpRanges;
|
|
||||||
};
|
|
||||||
|
|
||||||
# MDNS
|
# MDNS
|
||||||
services.avahi = mkIf (cfg.enable && cfg.homekit.enable) {
|
services.avahi = mkIf (cfg.enable && cfg.homekit.enable) {
|
||||||
enable = mkDefault true;
|
enable = mkDefault true;
|
||||||
publish.enable = let
|
publish.enable = let
|
||||||
homekitNames = map (homekit: toLower homekit.name) cfg.config.homekit or [ ];
|
homekitNames = map (homekit: toLower homekit.name) cfg.config.homekit or [];
|
||||||
in mkIf (elem config.networking.hostName homekitNames) false;
|
in
|
||||||
|
mkIf (elem config.networking.hostName homekitNames) false;
|
||||||
};
|
};
|
||||||
|
|
||||||
systemd.services.home-assistant = mkIf (cfg.enable && cfg.mutableUiConfig) {
|
systemd.services.home-assistant = mkIf (cfg.enable && cfg.mutableUiConfig) {
|
||||||
|
|
@ -101,12 +117,13 @@ in {
|
||||||
use_x_forwarded_for = "true";
|
use_x_forwarded_for = "true";
|
||||||
trusted_proxies = let
|
trusted_proxies = let
|
||||||
inherit (config.networking.access) cidrForNetwork;
|
inherit (config.networking.access) cidrForNetwork;
|
||||||
in cidrForNetwork.loopback.all
|
in
|
||||||
++ cidrForNetwork.local.all
|
cidrForNetwork.loopback.all
|
||||||
++ optionals config.services.tailscale.enable cidrForNetwork.tail.all
|
++ cidrForNetwork.local.all
|
||||||
++ [
|
++ optionals config.services.tailscale.enable cidrForNetwork.tail.all
|
||||||
"200::/7"
|
++ [
|
||||||
];
|
"200::/7"
|
||||||
|
];
|
||||||
};
|
};
|
||||||
recorder = {
|
recorder = {
|
||||||
db_url = mkIf config.services.postgresql.enable (mkDefault "postgresql://@/hass");
|
db_url = mkIf config.services.postgresql.enable (mkDefault "postgresql://@/hass");
|
||||||
|
|
@ -157,61 +174,75 @@ in {
|
||||||
package = let
|
package = let
|
||||||
inherit (cfg.package) python;
|
inherit (cfg.package) python;
|
||||||
# https://github.com/pysnmp/pysnmp/issues/51
|
# https://github.com/pysnmp/pysnmp/issues/51
|
||||||
needsPyasn1pin = if lib.versionOlder python.pkgs.pysnmplib.version "6.0"
|
needsPyasn1pin =
|
||||||
|
if lib.versionOlder python.pkgs.pysnmplib.version "6.0"
|
||||||
then true
|
then true
|
||||||
else lib.warn "pyasn1 pin likely no longer needed" false;
|
else lib.warn "pyasn1 pin likely no longer needed" false;
|
||||||
pyasn1prefix = "${python.pkgs.pysnmp-pyasn1}/${python.sitePackages}";
|
pyasn1prefix = "${python.pkgs.pysnmp-pyasn1}/${python.sitePackages}";
|
||||||
home-assistant = pkgs.home-assistant.override {
|
home-assistant = pkgs.home-assistant.override {
|
||||||
packageOverrides = self: super: {
|
packageOverrides = self: super: {
|
||||||
brother = super.brother.overridePythonAttrs (old: {
|
brother = super.brother.overridePythonAttrs (old: {
|
||||||
dontCheckRuntimeDeps = if old.dontCheckRuntimeDeps or false
|
dontCheckRuntimeDeps =
|
||||||
|
if old.dontCheckRuntimeDeps or false
|
||||||
then lib.warn "brother override no longer needed" true
|
then lib.warn "brother override no longer needed" true
|
||||||
else true;
|
else true;
|
||||||
});
|
});
|
||||||
mpd2 = super.mpd2.overridePythonAttrs (old: {
|
mpd2 = super.mpd2.overridePythonAttrs (old: {
|
||||||
patches = old.patches or [ ] ++ [
|
patches =
|
||||||
../../packages/mpd2-skip-flaky-test.patch
|
old.patches
|
||||||
];
|
or []
|
||||||
disabledTests = unique (old.disabledTests or [ ] ++ [
|
++ [
|
||||||
"test_idle_timeout"
|
../../packages/mpd2-skip-flaky-test.patch
|
||||||
]);
|
];
|
||||||
|
disabledTests = unique (old.disabledTests
|
||||||
|
or []
|
||||||
|
++ [
|
||||||
|
"test_idle_timeout"
|
||||||
|
]);
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
in home-assistant.overrideAttrs (old: {
|
in
|
||||||
makeWrapperArgs = old.makeWrapperArgs ++ optional (cfg.brother.enable && needsPyasn1pin) "--prefix PYTHONPATH : ${pyasn1prefix}";
|
home-assistant.overrideAttrs (old: {
|
||||||
disabledTests = unique (old.disabledTests or [ ] ++ [
|
makeWrapperArgs = old.makeWrapperArgs ++ optional (cfg.brother.enable && needsPyasn1pin) "--prefix PYTHONPATH : ${pyasn1prefix}";
|
||||||
"test_check_config"
|
disabledTests = unique (old.disabledTests
|
||||||
]);
|
or []
|
||||||
});
|
++ [
|
||||||
|
"test_check_config"
|
||||||
|
]);
|
||||||
|
});
|
||||||
finalPackage = let
|
finalPackage = let
|
||||||
inherit (lib.strings) hasSuffix removeSuffix splitString;
|
inherit (lib.strings) hasSuffix removeSuffix splitString;
|
||||||
inherit (lib.lists) head;
|
inherit (lib.lists) head;
|
||||||
inherit (lib.attrsets) attrNames filterAttrs;
|
inherit (lib.attrsets) attrNames filterAttrs;
|
||||||
inherit (config.systemd.services.home-assistant.serviceConfig) ExecStart;
|
inherit (config.systemd.services.home-assistant.serviceConfig) ExecStart;
|
||||||
isHassDrv = drv: context: hasSuffix "-${cfg.package.name}.drv" drv && context.outputs or [ ] == [ "out" ];
|
isHassDrv = drv: context: hasSuffix "-${cfg.package.name}.drv" drv && context.outputs or [] == ["out"];
|
||||||
drvs = filterAttrs isHassDrv (builtins.getContext ExecStart);
|
drvs = filterAttrs isHassDrv (builtins.getContext ExecStart);
|
||||||
isImpure = builtins ? currentSystem;
|
isImpure = builtins ? currentSystem;
|
||||||
in mkIf cfg.enable (mkOptionDefault (
|
in
|
||||||
if isImpure then import (head (attrNames drvs))
|
mkIf cfg.enable (mkOptionDefault (
|
||||||
else removeSuffix "/bin/hass" (head (splitString " " ExecStart))
|
if isImpure
|
||||||
));
|
then import (head (attrNames drvs))
|
||||||
extraPackages = python3Packages: with python3Packages; mkMerge [
|
else removeSuffix "/bin/hass" (head (splitString " " ExecStart))
|
||||||
[
|
));
|
||||||
psycopg2
|
extraPackages = python3Packages:
|
||||||
securetar
|
with python3Packages;
|
||||||
getmac # for upnp integration
|
mkMerge [
|
||||||
python-otbr-api
|
[
|
||||||
(aiogithubapi.overrideAttrs (_: {doInstallCheck = false;}))
|
psycopg2
|
||||||
]
|
securetar
|
||||||
(mkIf cfg.homekit.enable [
|
getmac # for upnp integration
|
||||||
aiohomekit
|
python-otbr-api
|
||||||
])
|
(aiogithubapi.overrideAttrs (_: {doInstallCheck = false;}))
|
||||||
(mkIf cfg.androidTv.enable [
|
]
|
||||||
adb-shell
|
(mkIf cfg.homekit.enable [
|
||||||
androidtvremote2
|
aiohomekit
|
||||||
])
|
])
|
||||||
];
|
(mkIf cfg.androidTv.enable [
|
||||||
|
adb-shell
|
||||||
|
androidtvremote2
|
||||||
|
])
|
||||||
|
];
|
||||||
extraComponents = mkMerge [
|
extraComponents = mkMerge [
|
||||||
[
|
[
|
||||||
"automation"
|
"automation"
|
||||||
|
|
@ -232,8 +263,8 @@ in {
|
||||||
"google_assistant"
|
"google_assistant"
|
||||||
"google_cloud"
|
"google_cloud"
|
||||||
])
|
])
|
||||||
(map ({ platform, ... }: platform) cfg.config.media_player or [ ])
|
(map ({platform, ...}: platform) cfg.config.media_player or [])
|
||||||
(map ({ platform, ... }: platform) cfg.config.tts or [ ])
|
(map ({platform, ...}: platform) cfg.config.tts or [])
|
||||||
];
|
];
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,4 @@
|
||||||
{
|
{lib, ...}: let
|
||||||
lib,
|
|
||||||
...
|
|
||||||
}: let
|
|
||||||
inherit (lib.options) mkOption;
|
inherit (lib.options) mkOption;
|
||||||
in {
|
in {
|
||||||
options.services.jackett = with lib.types; {
|
options.services.jackett = with lib.types; {
|
||||||
|
|
|
||||||
|
|
@ -60,13 +60,14 @@ in {
|
||||||
|
|
||||||
services.kanidm = {
|
services.kanidm = {
|
||||||
server.unencrypted = {
|
server.unencrypted = {
|
||||||
domain = mkBefore [ cfg.server.frontend.domain ];
|
domain = mkBefore [cfg.server.frontend.domain];
|
||||||
package = let
|
package = let
|
||||||
cert = mkSnakeOil {
|
cert = mkSnakeOil {
|
||||||
name = "kanidm-cert";
|
name = "kanidm-cert";
|
||||||
inherit (cfg.server.unencrypted) domain;
|
inherit (cfg.server.unencrypted) domain;
|
||||||
};
|
};
|
||||||
in mkOptionDefault cert;
|
in
|
||||||
|
mkOptionDefault cert;
|
||||||
};
|
};
|
||||||
clientSettings = mkIf cfg.enableServer {
|
clientSettings = mkIf cfg.enableServer {
|
||||||
uri = mkDefault cfg.serverSettings.origin;
|
uri = mkDefault cfg.serverSettings.origin;
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,4 @@
|
||||||
{
|
{lib, ...}: let
|
||||||
lib,
|
|
||||||
...
|
|
||||||
}: let
|
|
||||||
inherit (lib.options) mkOption;
|
inherit (lib.options) mkOption;
|
||||||
in {
|
in {
|
||||||
options.services.lidarr = with lib.types; {
|
options.services.lidarr = with lib.types; {
|
||||||
|
|
|
||||||
|
|
@ -8,7 +8,7 @@
|
||||||
inherit (lib.modules) mkIf mkMerge mkDefault mkOptionDefault;
|
inherit (lib.modules) mkIf mkMerge mkDefault mkOptionDefault;
|
||||||
inherit (lib.lists) singleton;
|
inherit (lib.lists) singleton;
|
||||||
cfg = config.services.mediatomb;
|
cfg = config.services.mediatomb;
|
||||||
mediaDirModule = { config, ... }: {
|
mediaDirModule = {config, ...}: {
|
||||||
options = with lib.types; {
|
options = with lib.types; {
|
||||||
mountPoint = mkOption {
|
mountPoint = mkOption {
|
||||||
type = nullOr str;
|
type = nullOr str;
|
||||||
|
|
@ -26,16 +26,23 @@
|
||||||
paths = let
|
paths = let
|
||||||
paths = map (path: "${config.path}/${path}") config.subdirectories;
|
paths = map (path: "${config.path}/${path}") config.subdirectories;
|
||||||
path = singleton config.path;
|
path = singleton config.path;
|
||||||
in mkOptionDefault (if config.subdirectories != null then paths else path);
|
in
|
||||||
|
mkOptionDefault (
|
||||||
|
if config.subdirectories != null
|
||||||
|
then paths
|
||||||
|
else path
|
||||||
|
);
|
||||||
recursive = mkDefault true;
|
recursive = mkDefault true;
|
||||||
hidden-files = mkDefault false;
|
hidden-files = mkDefault false;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
in {
|
in {
|
||||||
options.services.mediatomb = with lib.types; {
|
options.services.mediatomb = with lib.types; {
|
||||||
confine = mkEnableOption "containment" // {
|
confine =
|
||||||
default = true;
|
mkEnableOption "containment"
|
||||||
};
|
// {
|
||||||
|
default = true;
|
||||||
|
};
|
||||||
mediaDirectories = mkOption {
|
mediaDirectories = mkOption {
|
||||||
type = listOf (submodule mediaDirModule);
|
type = listOf (submodule mediaDirModule);
|
||||||
};
|
};
|
||||||
|
|
@ -47,9 +54,13 @@ in {
|
||||||
};
|
};
|
||||||
config.systemd.services.mediatomb = mkIf cfg.enable {
|
config.systemd.services.mediatomb = mkIf cfg.enable {
|
||||||
confinement.enable = mkIf cfg.confine (mkDefault true);
|
confinement.enable = mkIf cfg.confine (mkDefault true);
|
||||||
bindsTo = map (dir: mkIf (dir.mountPoint != null)
|
bindsTo =
|
||||||
"${utils.escapeSystemdPath dir.mountPoint}.mount"
|
map (
|
||||||
) cfg.mediaDirectories;
|
dir:
|
||||||
|
mkIf (dir.mountPoint != null)
|
||||||
|
"${utils.escapeSystemdPath dir.mountPoint}.mount"
|
||||||
|
)
|
||||||
|
cfg.mediaDirectories;
|
||||||
unitConfig.RequiresMountsFor = mkMerge (
|
unitConfig.RequiresMountsFor = mkMerge (
|
||||||
map (dir: dir.paths) cfg.mediaDirectories
|
map (dir: dir.paths) cfg.mediaDirectories
|
||||||
);
|
);
|
||||||
|
|
|
||||||
|
|
@ -8,18 +8,19 @@
|
||||||
in {
|
in {
|
||||||
options.services.mosquitto = with lib.types; {
|
options.services.mosquitto = with lib.types; {
|
||||||
listeners = let
|
listeners = let
|
||||||
listenerModule = { ... }: {
|
listenerModule = {...}: {
|
||||||
options = {
|
options = {
|
||||||
openFirewall = mkEnableOption "firewall";
|
openFirewall = mkEnableOption "firewall";
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
in mkOption {
|
in
|
||||||
type = listOf (submodule listenerModule);
|
mkOption {
|
||||||
};
|
type = listOf (submodule listenerModule);
|
||||||
|
};
|
||||||
};
|
};
|
||||||
config = {
|
config = {
|
||||||
networking.firewall.allowedTCPPorts = mkIf cfg.enable (mkMerge (
|
networking.firewall.allowedTCPPorts = mkIf cfg.enable (mkMerge (
|
||||||
map (listener: mkIf listener.openFirewall [ listener.port ]) cfg.listeners
|
map (listener: mkIf listener.openFirewall [listener.port]) cfg.listeners
|
||||||
));
|
));
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -19,7 +19,12 @@
|
||||||
enabledNamespaces = filter (ns: ns.enable) (attrValues networking.namespaces);
|
enabledNamespaces = filter (ns: ns.enable) (attrValues networking.namespaces);
|
||||||
ip = "${pkgs.iproute2}/bin/ip";
|
ip = "${pkgs.iproute2}/bin/ip";
|
||||||
ip-n = namespace: "${ip} -n ${escapeShellArg namespace.name}";
|
ip-n = namespace: "${ip} -n ${escapeShellArg namespace.name}";
|
||||||
namespaceInterfaceModule = { config, namespace, name, ... }: {
|
namespaceInterfaceModule = {
|
||||||
|
config,
|
||||||
|
namespace,
|
||||||
|
name,
|
||||||
|
...
|
||||||
|
}: {
|
||||||
options = with lib.types; {
|
options = with lib.types; {
|
||||||
name = mkOption {
|
name = mkOption {
|
||||||
type = str;
|
type = str;
|
||||||
|
|
@ -41,8 +46,8 @@
|
||||||
};
|
};
|
||||||
config = {
|
config = {
|
||||||
serviceSettings = rec {
|
serviceSettings = rec {
|
||||||
bindsTo = [ "${namespace.unitName}.service" ];
|
bindsTo = ["${namespace.unitName}.service"];
|
||||||
partOf = [ "${namespace.unitName}.target" ];
|
partOf = ["${namespace.unitName}.target"];
|
||||||
after = bindsTo;
|
after = bindsTo;
|
||||||
stopIfChanged = false;
|
stopIfChanged = false;
|
||||||
restartIfChanged = false;
|
restartIfChanged = false;
|
||||||
|
|
@ -63,7 +68,11 @@
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
groupModule = { config, namespace, ... }: {
|
groupModule = {
|
||||||
|
config,
|
||||||
|
namespace,
|
||||||
|
...
|
||||||
|
}: {
|
||||||
options = with lib.types; {
|
options = with lib.types; {
|
||||||
id = mkOption {
|
id = mkOption {
|
||||||
type = int;
|
type = int;
|
||||||
|
|
@ -78,8 +87,8 @@
|
||||||
};
|
};
|
||||||
config = {
|
config = {
|
||||||
serviceSettings = rec {
|
serviceSettings = rec {
|
||||||
bindsTo = [ "${namespace.unitName}.service" ];
|
bindsTo = ["${namespace.unitName}.service"];
|
||||||
partOf = [ "${namespace.unitName}.target" ];
|
partOf = ["${namespace.unitName}.target"];
|
||||||
after = bindsTo;
|
after = bindsTo;
|
||||||
stopIfChanged = false;
|
stopIfChanged = false;
|
||||||
restartIfChanged = false;
|
restartIfChanged = false;
|
||||||
|
|
@ -100,17 +109,23 @@
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
namespaceModule = { config, name, ... }: let
|
namespaceModule = {
|
||||||
|
config,
|
||||||
|
name,
|
||||||
|
...
|
||||||
|
}: let
|
||||||
linkGroupServices = optional (config.linkGroup != null) "${config.linkGroup.serviceName}.service";
|
linkGroupServices = optional (config.linkGroup != null) "${config.linkGroup.serviceName}.service";
|
||||||
interfaceServices = mapAttrsToList (_: interface: "${interface.serviceName}.service") config.interfaces;
|
interfaceServices = mapAttrsToList (_: interface: "${interface.serviceName}.service") config.interfaces;
|
||||||
submoduleArgs = { ... }: {
|
submoduleArgs = {...}: {
|
||||||
config._module.args.namespace = config;
|
config._module.args.namespace = config;
|
||||||
};
|
};
|
||||||
in {
|
in {
|
||||||
options = with lib.types; {
|
options = with lib.types; {
|
||||||
enable = mkEnableOption "network namespace" // {
|
enable =
|
||||||
default = true;
|
mkEnableOption "network namespace"
|
||||||
};
|
// {
|
||||||
|
default = true;
|
||||||
|
};
|
||||||
resolvConf = mkOption {
|
resolvConf = mkOption {
|
||||||
type = lines;
|
type = lines;
|
||||||
default = ''
|
default = ''
|
||||||
|
|
@ -186,8 +201,9 @@
|
||||||
groupModule
|
groupModule
|
||||||
submoduleArgs
|
submoduleArgs
|
||||||
];
|
];
|
||||||
idOrModule = coercedTo int (id: { inherit id; }) module;
|
idOrModule = coercedTo int (id: {inherit id;}) module;
|
||||||
in nullOr idOrModule;
|
in
|
||||||
|
nullOr idOrModule;
|
||||||
default = null;
|
default = null;
|
||||||
};
|
};
|
||||||
interfaces = mkOption {
|
interfaces = mkOption {
|
||||||
|
|
@ -195,7 +211,7 @@
|
||||||
namespaceInterfaceModule
|
namespaceInterfaceModule
|
||||||
submoduleArgs
|
submoduleArgs
|
||||||
]);
|
]);
|
||||||
default = { };
|
default = {};
|
||||||
};
|
};
|
||||||
path = mkOption {
|
path = mkOption {
|
||||||
type = path;
|
type = path;
|
||||||
|
|
@ -226,8 +242,8 @@
|
||||||
};
|
};
|
||||||
config = {
|
config = {
|
||||||
serviceSettings = {
|
serviceSettings = {
|
||||||
wants = [ "network.target" ];
|
wants = ["network.target"];
|
||||||
after = [ "network.target" ];
|
after = ["network.target"];
|
||||||
stopIfChanged = false;
|
stopIfChanged = false;
|
||||||
restartIfChanged = false;
|
restartIfChanged = false;
|
||||||
serviceConfig = {
|
serviceConfig = {
|
||||||
|
|
@ -245,12 +261,12 @@
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
targetSettings = {
|
targetSettings = {
|
||||||
wantedBy = [ "multi-user.target" ];
|
wantedBy = ["multi-user.target"];
|
||||||
bindsTo = [ "${config.unitName}.service" ];
|
bindsTo = ["${config.unitName}.service"];
|
||||||
requires = linkGroupServices ++ interfaceServices;
|
requires = linkGroupServices ++ interfaceServices;
|
||||||
wants = mkMerge [
|
wants = mkMerge [
|
||||||
(mkIf config.dhcpcd.enable [ "${config.dhcpcd.serviceName}.service" ])
|
(mkIf config.dhcpcd.enable ["${config.dhcpcd.serviceName}.service"])
|
||||||
(mkIf config.nftables.enable [ "${config.nftables.serviceName}.service" ])
|
(mkIf config.nftables.enable ["${config.nftables.serviceName}.service"])
|
||||||
];
|
];
|
||||||
};
|
};
|
||||||
configFiles = {
|
configFiles = {
|
||||||
|
|
@ -312,21 +328,22 @@
|
||||||
addrs6 = access.cidrForNetwork.local.v6 ++ optionals tailscale.enable access.cidrForNetwork.tail.v6;
|
addrs6 = access.cidrForNetwork.local.v6 ++ optionals tailscale.enable access.cidrForNetwork.tail.v6;
|
||||||
daddr4 = ''{ ${concatStringsSep ", " addrs4} }'';
|
daddr4 = ''{ ${concatStringsSep ", " addrs4} }'';
|
||||||
daddr6 = ''{ ${concatStringsSep ", " addrs6} }'';
|
daddr6 = ''{ ${concatStringsSep ", " addrs6} }'';
|
||||||
in mkIf config.nftables.rejectLocaladdrs (mkMerge [
|
in
|
||||||
''ct state { established, related } accept''
|
mkIf config.nftables.rejectLocaladdrs (mkMerge [
|
||||||
''
|
''ct state { established, related } accept''
|
||||||
ip daddr ${daddr4} ip protocol tcp reject with tcp reset
|
''
|
||||||
ip daddr ${daddr4} drop
|
ip daddr ${daddr4} ip protocol tcp reject with tcp reset
|
||||||
''
|
ip daddr ${daddr4} drop
|
||||||
(mkIf networking.enableIPv6 ''
|
''
|
||||||
ip6 daddr ${daddr6} ip6 nexthdr tcp reject with tcp reset
|
(mkIf networking.enableIPv6 ''
|
||||||
ip6 daddr ${daddr6} drop
|
ip6 daddr ${daddr6} ip6 nexthdr tcp reject with tcp reset
|
||||||
'')
|
ip6 daddr ${daddr6} drop
|
||||||
]);
|
'')
|
||||||
|
]);
|
||||||
serviceSettings = rec {
|
serviceSettings = rec {
|
||||||
bindsTo = [ "${config.unitName}.service" ];
|
bindsTo = ["${config.unitName}.service"];
|
||||||
partOf = [ "${config.unitName}.target" ];
|
partOf = ["${config.unitName}.target"];
|
||||||
wants = mkIf config.nftables.rejectLocaladdrs [ "localaddrs.service" ];
|
wants = mkIf config.nftables.rejectLocaladdrs ["localaddrs.service"];
|
||||||
after = mkMerge [
|
after = mkMerge [
|
||||||
bindsTo
|
bindsTo
|
||||||
wants
|
wants
|
||||||
|
|
@ -346,7 +363,7 @@
|
||||||
"${pkgs.nftables}/bin/nft -f ${config.configPath}/rules.nft"
|
"${pkgs.nftables}/bin/nft -f ${config.configPath}/rules.nft"
|
||||||
];
|
];
|
||||||
ExecReload = mkMerge [
|
ExecReload = mkMerge [
|
||||||
(mkIf config.nftables.rejectLocaladdrs [ "+${access.localaddrs.reloadScript}" ])
|
(mkIf config.nftables.rejectLocaladdrs ["+${access.localaddrs.reloadScript}"])
|
||||||
[
|
[
|
||||||
"${pkgs.nftables}/bin/nft flush ruleset"
|
"${pkgs.nftables}/bin/nft flush ruleset"
|
||||||
"${pkgs.nftables}/bin/nft -f ${config.configPath}/rules.nft"
|
"${pkgs.nftables}/bin/nft -f ${config.configPath}/rules.nft"
|
||||||
|
|
@ -360,12 +377,15 @@
|
||||||
};
|
};
|
||||||
dhcpcd = {
|
dhcpcd = {
|
||||||
serviceSettings = rec {
|
serviceSettings = rec {
|
||||||
bindsTo = [ "${config.unitName}.service" ];
|
bindsTo = ["${config.unitName}.service"];
|
||||||
partOf = [ "${config.unitName}.target" ];
|
partOf = ["${config.unitName}.target"];
|
||||||
wants = linkGroupServices ++ interfaceServices;
|
wants = linkGroupServices ++ interfaceServices;
|
||||||
after = bindsTo ++ wants ++ [
|
after =
|
||||||
(mkIf config.nftables.enable "${config.nftables.serviceName}.service")
|
bindsTo
|
||||||
];
|
++ wants
|
||||||
|
++ [
|
||||||
|
(mkIf config.nftables.enable "${config.nftables.serviceName}.service")
|
||||||
|
];
|
||||||
stopIfChanged = false;
|
stopIfChanged = false;
|
||||||
unitConfig.ConditionCapability = "CAP_NET_ADMIN";
|
unitConfig.ConditionCapability = "CAP_NET_ADMIN";
|
||||||
serviceConfig = {
|
serviceConfig = {
|
||||||
|
|
@ -407,15 +427,21 @@
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
serviceModule = { config, name, ... }: let
|
serviceModule = {
|
||||||
|
config,
|
||||||
|
name,
|
||||||
|
...
|
||||||
|
}: let
|
||||||
cfg = config.networkNamespace;
|
cfg = config.networkNamespace;
|
||||||
hasNs = cfg.name != null;
|
hasNs = cfg.name != null;
|
||||||
ns = networking.namespaces.${cfg.name};
|
ns = networking.namespaces.${cfg.name};
|
||||||
in {
|
in {
|
||||||
options.networkNamespace = with lib.types; {
|
options.networkNamespace = with lib.types; {
|
||||||
enable = mkEnableOption "netns" // {
|
enable =
|
||||||
default = cfg.name != null;
|
mkEnableOption "netns"
|
||||||
};
|
// {
|
||||||
|
default = cfg.name != null;
|
||||||
|
};
|
||||||
bindResolvConf = mkOption {
|
bindResolvConf = mkOption {
|
||||||
type = nullOr path;
|
type = nullOr path;
|
||||||
};
|
};
|
||||||
|
|
@ -446,15 +472,13 @@
|
||||||
path = mkDefault (
|
path = mkDefault (
|
||||||
ns.path
|
ns.path
|
||||||
);
|
);
|
||||||
bindResolvConf = mkDefault (
|
bindResolvConf = mkDefault "${ns.configPath}/resolv.conf";
|
||||||
"${ns.configPath}/resolv.conf"
|
|
||||||
);
|
|
||||||
})
|
})
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
(mkIf cfg.enable rec {
|
(mkIf cfg.enable rec {
|
||||||
wants = mkIf hasNs [ "${ns.unitName}.target" ];
|
wants = mkIf hasNs ["${ns.unitName}.target"];
|
||||||
bindsTo = mkIf hasNs [ "${ns.unitName}.service" ];
|
bindsTo = mkIf hasNs ["${ns.unitName}.service"];
|
||||||
after = mkMerge [
|
after = mkMerge [
|
||||||
bindsTo
|
bindsTo
|
||||||
(mkIf (hasNs && cfg.afterOnline) [
|
(mkIf (hasNs && cfg.afterOnline) [
|
||||||
|
|
@ -475,7 +499,7 @@ in {
|
||||||
options = with lib.types; {
|
options = with lib.types; {
|
||||||
networking.namespaces = mkOption {
|
networking.namespaces = mkOption {
|
||||||
type = attrsOf (submodule namespaceModule);
|
type = attrsOf (submodule namespaceModule);
|
||||||
default = { };
|
default = {};
|
||||||
};
|
};
|
||||||
systemd.services = mkOption {
|
systemd.services = mkOption {
|
||||||
type = attrsOf (submodule serviceModule);
|
type = attrsOf (submodule serviceModule);
|
||||||
|
|
@ -483,19 +507,25 @@ in {
|
||||||
};
|
};
|
||||||
config = {
|
config = {
|
||||||
systemd = {
|
systemd = {
|
||||||
services = listToAttrs (concatMap (ns:
|
services = listToAttrs (concatMap (
|
||||||
singleton (nameValuePair ns.unitName (unmerged.merge ns.serviceSettings))
|
ns:
|
||||||
++ optional (ns.linkGroup != null) (nameValuePair ns.linkGroup.serviceName (unmerged.merge ns.linkGroup.serviceSettings))
|
singleton (nameValuePair ns.unitName (unmerged.merge ns.serviceSettings))
|
||||||
++ mapAttrsToList (_: interface: nameValuePair interface.serviceName (unmerged.merge interface.serviceSettings)) ns.interfaces
|
++ optional (ns.linkGroup != null) (nameValuePair ns.linkGroup.serviceName (unmerged.merge ns.linkGroup.serviceSettings))
|
||||||
++ optional ns.dhcpcd.enable (nameValuePair ns.dhcpcd.serviceName (unmerged.merge ns.dhcpcd.serviceSettings))
|
++ mapAttrsToList (_: interface: nameValuePair interface.serviceName (unmerged.merge interface.serviceSettings)) ns.interfaces
|
||||||
++ optional ns.nftables.enable (nameValuePair ns.nftables.serviceName (unmerged.merge ns.nftables.serviceSettings))
|
++ optional ns.dhcpcd.enable (nameValuePair ns.dhcpcd.serviceName (unmerged.merge ns.dhcpcd.serviceSettings))
|
||||||
) enabledNamespaces);
|
++ optional ns.nftables.enable (nameValuePair ns.nftables.serviceName (unmerged.merge ns.nftables.serviceSettings))
|
||||||
targets = listToAttrs (map (ns: nameValuePair ns.unitName (
|
)
|
||||||
unmerged.merge ns.targetSettings
|
enabledNamespaces);
|
||||||
)) enabledNamespaces);
|
targets = listToAttrs (map (ns:
|
||||||
|
nameValuePair ns.unitName (
|
||||||
|
unmerged.merge ns.targetSettings
|
||||||
|
))
|
||||||
|
enabledNamespaces);
|
||||||
};
|
};
|
||||||
environment.etc = mkMerge (map (ns:
|
environment.etc = mkMerge (map (
|
||||||
mapAttrs' (name: file: nameValuePair "${ns.configDir}/${name}" (unmerged.merge file)) ns.configFiles
|
ns:
|
||||||
) enabledNamespaces);
|
mapAttrs' (name: file: nameValuePair "${ns.configDir}/${name}" (unmerged.merge file)) ns.configFiles
|
||||||
|
)
|
||||||
|
enabledNamespaces);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -8,17 +8,21 @@
|
||||||
inherit (lib.modules) mkIf mkMerge mkOptionDefault;
|
inherit (lib.modules) mkIf mkMerge mkOptionDefault;
|
||||||
inherit (inputs.self.lib.lib) eui64;
|
inherit (inputs.self.lib.lib) eui64;
|
||||||
inherit (config) networking services;
|
inherit (config) networking services;
|
||||||
networkModule = { config, ... }: {
|
networkModule = {config, ...}: {
|
||||||
options = with lib.types; {
|
options = with lib.types; {
|
||||||
mdns = {
|
mdns = {
|
||||||
enable = mkEnableOption "SLAAC" // {
|
enable =
|
||||||
default = config.matchConfig.Type or null == "ether" && services.resolved.enable;
|
mkEnableOption "SLAAC"
|
||||||
};
|
// {
|
||||||
|
default = config.matchConfig.Type or null == "ether" && services.resolved.enable;
|
||||||
|
};
|
||||||
};
|
};
|
||||||
slaac = {
|
slaac = {
|
||||||
enable = mkEnableOption "SLAAC" // {
|
enable =
|
||||||
default = config.matchConfig.Type or null == "ether" && networking.enableIPv6;
|
mkEnableOption "SLAAC"
|
||||||
};
|
// {
|
||||||
|
default = config.matchConfig.Type or null == "ether" && networking.enableIPv6;
|
||||||
|
};
|
||||||
postfix = mkOption {
|
postfix = mkOption {
|
||||||
type = str;
|
type = str;
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,8 @@
|
||||||
{ lib, config, ... }:
|
{
|
||||||
|
lib,
|
||||||
let
|
config,
|
||||||
|
...
|
||||||
|
}: let
|
||||||
inherit (lib) types;
|
inherit (lib) types;
|
||||||
inherit (lib.options) mkOption mkEnableOption;
|
inherit (lib.options) mkOption mkEnableOption;
|
||||||
inherit (lib.modules) mkIf;
|
inherit (lib.modules) mkIf;
|
||||||
|
|
@ -13,11 +15,13 @@ let
|
||||||
doDocker = config.virtualisation.docker.enable && cfg.generateDockerRules;
|
doDocker = config.virtualisation.docker.enable && cfg.generateDockerRules;
|
||||||
|
|
||||||
mkPorts = cond: ports: ranges: action: let
|
mkPorts = cond: ports: ranges: action: let
|
||||||
portStrings = (map (range: "${toString range.from}-${toString range.to}") ranges)
|
portStrings =
|
||||||
++ (map toString ports);
|
(map (range: "${toString range.from}-${toString range.to}") ranges)
|
||||||
in optionalString (portStrings != []) ''
|
++ (map toString ports);
|
||||||
${cond} dport { ${concatStringsSep "," portStrings} } ${action}
|
in
|
||||||
'';
|
optionalString (portStrings != []) ''
|
||||||
|
${cond} dport { ${concatStringsSep "," portStrings} } ${action}
|
||||||
|
'';
|
||||||
|
|
||||||
ruleset = ''
|
ruleset = ''
|
||||||
table inet filter {
|
table inet filter {
|
||||||
|
|
@ -32,18 +36,21 @@ let
|
||||||
ct state established,related accept
|
ct state established,related accept
|
||||||
|
|
||||||
iifname { ${
|
iifname { ${
|
||||||
concatStringsSep "," (["lo"] ++ fwcfg.trustedInterfaces)
|
concatStringsSep "," (["lo"] ++ fwcfg.trustedInterfaces)
|
||||||
} } accept
|
} } accept
|
||||||
|
|
||||||
${mkPorts "tcp" fwcfg.allowedTCPPorts fwcfg.allowedTCPPortRanges "accept"}
|
${mkPorts "tcp" fwcfg.allowedTCPPorts fwcfg.allowedTCPPortRanges "accept"}
|
||||||
${mkPorts "udp" fwcfg.allowedUDPPorts fwcfg.allowedUDPPortRanges "accept"}
|
${mkPorts "udp" fwcfg.allowedUDPPorts fwcfg.allowedUDPPortRanges "accept"}
|
||||||
|
|
||||||
${
|
${
|
||||||
concatStringsSep "\n" (mapAttrsToList (name: ifcfg: concatMapStringsSep "\n" (cond:
|
concatStringsSep "\n" (mapAttrsToList (name: ifcfg:
|
||||||
mkPorts "${cond} tcp" ifcfg.allowedTCPPorts ifcfg.allowedTCPPortRanges "accept"
|
concatMapStringsSep "\n" (
|
||||||
|
cond:
|
||||||
|
mkPorts "${cond} tcp" ifcfg.allowedTCPPorts ifcfg.allowedTCPPortRanges "accept"
|
||||||
+ mkPorts "${cond} udp" ifcfg.allowedUDPPorts ifcfg.allowedUDPPortRanges "accept"
|
+ mkPorts "${cond} udp" ifcfg.allowedUDPPorts ifcfg.allowedUDPPortRanges "accept"
|
||||||
) (optionals ifcfg.nftables.enable ifcfg.nftables.conditions)) fwcfg.interfaces)
|
) (optionals ifcfg.nftables.enable ifcfg.nftables.conditions))
|
||||||
}
|
fwcfg.interfaces)
|
||||||
|
}
|
||||||
|
|
||||||
# DHCPv6
|
# DHCPv6
|
||||||
ip6 daddr fe80::/64 udp dport 546 accept
|
ip6 daddr fe80::/64 udp dport 546 accept
|
||||||
|
|
@ -65,10 +72,10 @@ let
|
||||||
policy ${cfg.forwardPolicy}
|
policy ${cfg.forwardPolicy}
|
||||||
|
|
||||||
${optionalString doDocker ''
|
${optionalString doDocker ''
|
||||||
oifname docker0 ct state invalid drop
|
oifname docker0 ct state invalid drop
|
||||||
oifname docker0 ct state established,related accept
|
oifname docker0 ct state established,related accept
|
||||||
iifname docker0 accept
|
iifname docker0 accept
|
||||||
''}
|
''}
|
||||||
|
|
||||||
${cfg.extraForward}
|
${cfg.extraForward}
|
||||||
|
|
||||||
|
|
@ -85,14 +92,23 @@ let
|
||||||
''}
|
''}
|
||||||
${cfg.extraConfig}
|
${cfg.extraConfig}
|
||||||
'';
|
'';
|
||||||
interfaceModule = { config, name, ... }: {
|
interfaceModule = {
|
||||||
|
config,
|
||||||
|
name,
|
||||||
|
...
|
||||||
|
}: {
|
||||||
options = {
|
options = {
|
||||||
nftables = {
|
nftables = {
|
||||||
enable = mkEnableOption "nftables firewall" // {
|
enable =
|
||||||
default =
|
mkEnableOption "nftables firewall"
|
||||||
config.allowedTCPPorts != [ ] || config.allowedTCPPortRanges != [ ]
|
// {
|
||||||
|| config.allowedUDPPorts != [ ] || config.allowedUDPPortRanges != [ ];
|
default =
|
||||||
};
|
config.allowedTCPPorts
|
||||||
|
!= []
|
||||||
|
|| config.allowedTCPPortRanges != []
|
||||||
|
|| config.allowedUDPPorts != []
|
||||||
|
|| config.allowedUDPPortRanges != [];
|
||||||
|
};
|
||||||
conditions = mkOption {
|
conditions = mkOption {
|
||||||
type = types.listOf types.str;
|
type = types.listOf types.str;
|
||||||
default = "iifname ${name}";
|
default = "iifname ${name}";
|
||||||
|
|
@ -100,7 +116,6 @@ let
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
in {
|
in {
|
||||||
options = {
|
options = {
|
||||||
networking.nftables = {
|
networking.nftables = {
|
||||||
|
|
|
||||||
|
|
@ -9,7 +9,7 @@
|
||||||
inherit (lib.lists) optionals;
|
inherit (lib.lists) optionals;
|
||||||
inherit (config.services) tailscale;
|
inherit (config.services) tailscale;
|
||||||
inherit (config.networking.access) cidrForNetwork localaddrs;
|
inherit (config.networking.access) cidrForNetwork localaddrs;
|
||||||
localModule = { config, ... }: {
|
localModule = {config, ...}: {
|
||||||
options.local = with lib.types; {
|
options.local = with lib.types; {
|
||||||
enable = mkOption {
|
enable = mkOption {
|
||||||
type = bool;
|
type = bool;
|
||||||
|
|
@ -37,16 +37,23 @@
|
||||||
cidrForNetwork.loopback.all
|
cidrForNetwork.loopback.all
|
||||||
++ cidrForNetwork.local.all
|
++ cidrForNetwork.local.all
|
||||||
++ optionals tailscale.enable cidrForNetwork.tail.all;
|
++ optionals tailscale.enable cidrForNetwork.tail.all;
|
||||||
allows = concatMapStringsSep "\n" mkAllow allowAddresses + optionalString localaddrs.enable ''
|
allows =
|
||||||
include ${localaddrs.stateDir}/*.nginx.conf;
|
concatMapStringsSep "\n" mkAllow allowAddresses
|
||||||
|
+ optionalString localaddrs.enable ''
|
||||||
|
include ${localaddrs.stateDir}/*.nginx.conf;
|
||||||
|
'';
|
||||||
|
in
|
||||||
|
mkBefore ''
|
||||||
|
${allows}
|
||||||
|
deny all;
|
||||||
'';
|
'';
|
||||||
in mkBefore ''
|
|
||||||
${allows}
|
|
||||||
deny all;
|
|
||||||
'';
|
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
locationModule = { config, virtualHost, ... }: {
|
locationModule = {
|
||||||
|
config,
|
||||||
|
virtualHost,
|
||||||
|
...
|
||||||
|
}: {
|
||||||
imports = [
|
imports = [
|
||||||
localModule
|
localModule
|
||||||
];
|
];
|
||||||
|
|
@ -58,13 +65,13 @@
|
||||||
emitDenyGlobal = virtualHost.local.emitDenyGlobal;
|
emitDenyGlobal = virtualHost.local.emitDenyGlobal;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
hostModule = { config, ... }: {
|
hostModule = {config, ...}: {
|
||||||
imports = [ localModule ];
|
imports = [localModule];
|
||||||
|
|
||||||
options = with lib.types; {
|
options = with lib.types; {
|
||||||
locations = mkOption {
|
locations = mkOption {
|
||||||
type = attrsOf (submoduleWith {
|
type = attrsOf (submoduleWith {
|
||||||
modules = [ locationModule ];
|
modules = [locationModule];
|
||||||
shorthandOnlyDefinesConfig = true;
|
shorthandOnlyDefinesConfig = true;
|
||||||
specialArgs = {
|
specialArgs = {
|
||||||
virtualHost = config;
|
virtualHost = config;
|
||||||
|
|
@ -83,7 +90,7 @@ in {
|
||||||
options = with lib.types; {
|
options = with lib.types; {
|
||||||
services.nginx.virtualHosts = mkOption {
|
services.nginx.virtualHosts = mkOption {
|
||||||
type = attrsOf (submoduleWith {
|
type = attrsOf (submoduleWith {
|
||||||
modules = [ hostModule ];
|
modules = [hostModule];
|
||||||
shorthandOnlyDefinesConfig = true;
|
shorthandOnlyDefinesConfig = true;
|
||||||
specialArgs = {
|
specialArgs = {
|
||||||
nixosConfig = config;
|
nixosConfig = config;
|
||||||
|
|
|
||||||
|
|
@ -2,13 +2,12 @@
|
||||||
config,
|
config,
|
||||||
lib,
|
lib,
|
||||||
...
|
...
|
||||||
}:
|
}: let
|
||||||
let
|
|
||||||
inherit (lib.options) mkOption mkEnableOption;
|
inherit (lib.options) mkOption mkEnableOption;
|
||||||
inherit (lib.modules) mkIf mkMerge mkBefore mkDefault;
|
inherit (lib.modules) mkIf mkMerge mkBefore mkDefault;
|
||||||
inherit (config) networking;
|
inherit (config) networking;
|
||||||
inherit (config.services) vouch-proxy tailscale;
|
inherit (config.services) vouch-proxy tailscale;
|
||||||
vouchModule = { config, ... }: {
|
vouchModule = {config, ...}: {
|
||||||
options = with lib.types; {
|
options = with lib.types; {
|
||||||
vouch = {
|
vouch = {
|
||||||
enable = mkEnableOption "vouch auth proxy";
|
enable = mkEnableOption "vouch auth proxy";
|
||||||
|
|
@ -49,15 +48,20 @@ let
|
||||||
vouch = mkIf vouch-proxy.enable {
|
vouch = mkIf vouch-proxy.enable {
|
||||||
proxyOrigin = let
|
proxyOrigin = let
|
||||||
inherit (vouch-proxy.settings.vouch) listen port;
|
inherit (vouch-proxy.settings.vouch) listen port;
|
||||||
host = if listen == "0.0.0.0" || listen == "[::]" then "localhost" else listen;
|
host =
|
||||||
in mkDefault "http://${host}:${toString port}";
|
if listen == "0.0.0.0" || listen == "[::]"
|
||||||
|
then "localhost"
|
||||||
|
else listen;
|
||||||
|
in
|
||||||
|
mkDefault "http://${host}:${toString port}";
|
||||||
authUrl = mkDefault vouch-proxy.authUrl;
|
authUrl = mkDefault vouch-proxy.authUrl;
|
||||||
url = mkDefault vouch-proxy.url;
|
url = mkDefault vouch-proxy.url;
|
||||||
doubleProxy = mkDefault false;
|
doubleProxy = mkDefault false;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
vouch.proxyOrigin = mkIf (tailscale.enable && !vouch-proxy.enable) (mkDefault
|
vouch.proxyOrigin = mkIf (tailscale.enable && !vouch-proxy.enable) (
|
||||||
|
mkDefault
|
||||||
"http://login.tail.${networking.domain}"
|
"http://login.tail.${networking.domain}"
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
@ -96,22 +100,23 @@ let
|
||||||
set $vouch_url $vouch_scheme://${config.vouch.tailDomain};
|
set $vouch_url $vouch_scheme://${config.vouch.tailDomain};
|
||||||
}
|
}
|
||||||
'';
|
'';
|
||||||
in mkMerge [
|
in
|
||||||
(mkBefore ''
|
mkMerge [
|
||||||
set $vouch_url ${config.vouch.url};
|
(mkBefore ''
|
||||||
set $vouch_scheme $scheme;
|
set $vouch_url ${config.vouch.url};
|
||||||
'')
|
set $vouch_scheme $scheme;
|
||||||
(mkIf config.local.trusted (mkBefore ''
|
'')
|
||||||
if ($http_x_forwarded_proto) {
|
(mkIf config.local.trusted (mkBefore ''
|
||||||
set $vouch_scheme $http_x_forwarded_proto;
|
if ($http_x_forwarded_proto) {
|
||||||
}
|
set $vouch_scheme $http_x_forwarded_proto;
|
||||||
''))
|
}
|
||||||
(mkIf (config.local.enable or false) localVouchUrl)
|
''))
|
||||||
(mkIf (config.local.enable or false && tailscale.enable) tailVouchUrl)
|
(mkIf (config.local.enable or false) localVouchUrl)
|
||||||
''
|
(mkIf (config.local.enable or false && tailscale.enable) tailVouchUrl)
|
||||||
return 302 $vouch_url/login?url=$vouch_scheme://$http_host$request_uri&vouch-failcount=$auth_resp_failcount&X-Vouch-Token=$auth_resp_jwt&error=$auth_resp_err;
|
''
|
||||||
''
|
return 302 $vouch_url/login?url=$vouch_scheme://$http_host$request_uri&vouch-failcount=$auth_resp_failcount&X-Vouch-Token=$auth_resp_jwt&error=$auth_resp_err;
|
||||||
];
|
''
|
||||||
|
];
|
||||||
};
|
};
|
||||||
"/validate" = {
|
"/validate" = {
|
||||||
recommendedProxySettings = false;
|
recommendedProxySettings = false;
|
||||||
|
|
|
||||||
|
|
@ -1,10 +1,7 @@
|
||||||
{
|
{lib, ...}: let
|
||||||
lib,
|
|
||||||
...
|
|
||||||
}: let
|
|
||||||
inherit (lib.modules) mkIf;
|
inherit (lib.modules) mkIf;
|
||||||
inherit (lib.options) mkOption mkEnableOption;
|
inherit (lib.options) mkOption mkEnableOption;
|
||||||
wsModule = { config, ... }: {
|
wsModule = {config, ...}: {
|
||||||
options = with lib.types; {
|
options = with lib.types; {
|
||||||
proxy.websocket.enable = mkEnableOption "websocket proxy";
|
proxy.websocket.enable = mkEnableOption "websocket proxy";
|
||||||
};
|
};
|
||||||
|
|
@ -16,8 +13,8 @@
|
||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
hostModule = { config, ... }: {
|
hostModule = {config, ...}: {
|
||||||
imports = [ wsModule ];
|
imports = [wsModule];
|
||||||
|
|
||||||
options = with lib.types; {
|
options = with lib.types; {
|
||||||
locations = mkOption {
|
locations = mkOption {
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,4 @@
|
||||||
{
|
{lib, ...}: let
|
||||||
lib,
|
|
||||||
...
|
|
||||||
}: let
|
|
||||||
inherit (lib.options) mkOption;
|
inherit (lib.options) mkOption;
|
||||||
in {
|
in {
|
||||||
options.services.plex = with lib.types; {
|
options.services.plex = with lib.types; {
|
||||||
|
|
|
||||||
|
|
@ -1,11 +1,12 @@
|
||||||
{ config, lib, ... }:
|
{
|
||||||
|
config,
|
||||||
with lib;
|
lib,
|
||||||
|
...
|
||||||
let
|
}:
|
||||||
|
with lib; let
|
||||||
cfg = config.networking.policyrouting;
|
cfg = config.networking.policyrouting;
|
||||||
|
|
||||||
ruleOpts = { ... }: {
|
ruleOpts = {...}: {
|
||||||
options = {
|
options = {
|
||||||
prio = mkOption {
|
prio = mkOption {
|
||||||
type = types.int;
|
type = types.int;
|
||||||
|
|
@ -15,37 +16,44 @@ let
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
in {
|
||||||
in
|
|
||||||
{
|
|
||||||
options = {
|
options = {
|
||||||
networking.policyrouting = {
|
networking.policyrouting = {
|
||||||
enable = mkEnableOption "Declarative Policy-Routing";
|
enable = mkEnableOption "Declarative Policy-Routing";
|
||||||
rules = mkOption {
|
rules = mkOption {
|
||||||
type = with types; listOf (submodule ruleOpts);
|
type = with types; listOf (submodule ruleOpts);
|
||||||
default = [ ];
|
default = [];
|
||||||
};
|
};
|
||||||
rules6 = mkOption {
|
rules6 = mkOption {
|
||||||
type = with types; listOf (submodule ruleOpts);
|
type = with types; listOf (submodule ruleOpts);
|
||||||
default = [ ];
|
default = [];
|
||||||
};
|
};
|
||||||
rules4 = mkOption {
|
rules4 = mkOption {
|
||||||
type = with types; listOf (submodule ruleOpts);
|
type = with types; listOf (submodule ruleOpts);
|
||||||
default = [ ];
|
default = [];
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
config = mkIf cfg.enable {
|
config = mkIf cfg.enable {
|
||||||
networking.policyrouting.rules = [
|
networking.policyrouting.rules = [
|
||||||
{ rule = "lookup main"; prio = 32000; }
|
{
|
||||||
|
rule = "lookup main";
|
||||||
|
prio = 32000;
|
||||||
|
}
|
||||||
];
|
];
|
||||||
networking.localCommands = ''
|
networking.localCommands = ''
|
||||||
set -x
|
set -x
|
||||||
ip -6 rule flush
|
ip -6 rule flush
|
||||||
ip -4 rule flush
|
ip -4 rule flush
|
||||||
${concatMapStringsSep "\n" ({ prio, rule }: "ip -6 rule add ${rule} prio ${toString prio}") (cfg.rules ++ cfg.rules6)}
|
${concatMapStringsSep "\n" ({
|
||||||
${concatMapStringsSep "\n" ({ prio, rule }: "ip -4 rule add ${rule} prio ${toString prio}") (cfg.rules ++ cfg.rules4)}
|
prio,
|
||||||
|
rule,
|
||||||
|
}: "ip -6 rule add ${rule} prio ${toString prio}") (cfg.rules ++ cfg.rules6)}
|
||||||
|
${concatMapStringsSep "\n" ({
|
||||||
|
prio,
|
||||||
|
rule,
|
||||||
|
}: "ip -4 rule add ${rule} prio ${toString prio}") (cfg.rules ++ cfg.rules4)}
|
||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -10,19 +10,24 @@
|
||||||
inherit (config) networking;
|
inherit (config) networking;
|
||||||
cfg = config.services.postgresql;
|
cfg = config.services.postgresql;
|
||||||
formatHost = host:
|
formatHost = host:
|
||||||
if hasInfix "/" host then host
|
if hasInfix "/" host
|
||||||
else if hasInfix ":" host then "${host}/128"
|
then host
|
||||||
else if hasInfix "." host then "${host}/32"
|
else if hasInfix ":" host
|
||||||
|
then "${host}/128"
|
||||||
|
else if hasInfix "." host
|
||||||
|
then "${host}/32"
|
||||||
else throw "unsupported IP address ${host}";
|
else throw "unsupported IP address ${host}";
|
||||||
ensureUserModule = { config, ... }: {
|
ensureUserModule = {config, ...}: {
|
||||||
options = with lib.types; {
|
options = with lib.types; {
|
||||||
authentication = {
|
authentication = {
|
||||||
enable = mkEnableOption "TCP connections" // {
|
enable =
|
||||||
default = config.authentication.hosts != [ ];
|
mkEnableOption "TCP connections"
|
||||||
};
|
// {
|
||||||
|
default = config.authentication.hosts != [];
|
||||||
|
};
|
||||||
hosts = mkOption {
|
hosts = mkOption {
|
||||||
type = listOf str;
|
type = listOf str;
|
||||||
default = [ ];
|
default = [];
|
||||||
};
|
};
|
||||||
method = mkOption {
|
method = mkOption {
|
||||||
type = str;
|
type = str;
|
||||||
|
|
@ -47,13 +52,15 @@
|
||||||
authentication = {
|
authentication = {
|
||||||
hosts = let
|
hosts = let
|
||||||
inherit (networking.access) cidrForNetwork;
|
inherit (networking.access) cidrForNetwork;
|
||||||
in mkMerge [
|
in
|
||||||
(mkIf config.authentication.tailscale.allow cidrForNetwork.tail.all)
|
mkMerge [
|
||||||
(mkIf config.authentication.local.allow (cidrForNetwork.loopback.all ++ cidrForNetwork.local.all))
|
(mkIf config.authentication.tailscale.allow cidrForNetwork.tail.all)
|
||||||
];
|
(mkIf config.authentication.local.allow (cidrForNetwork.loopback.all ++ cidrForNetwork.local.all))
|
||||||
|
];
|
||||||
authentication = mkMerge (map (host: ''
|
authentication = mkMerge (map (host: ''
|
||||||
host ${config.authentication.database} ${config.name} ${formatHost host} ${config.authentication.method}
|
host ${config.authentication.database} ${config.name} ${formatHost host} ${config.authentication.method}
|
||||||
'') config.authentication.hosts);
|
'')
|
||||||
|
config.authentication.hosts);
|
||||||
};
|
};
|
||||||
authentication.database = mkIf config.ensureDBOwnership (
|
authentication.database = mkIf config.ensureDBOwnership (
|
||||||
mkOptionDefault config.name
|
mkOptionDefault config.name
|
||||||
|
|
@ -70,11 +77,13 @@ in {
|
||||||
enableTCPIP = mkIf (any (user: user.authentication.enable) cfg.ensureUsers) (
|
enableTCPIP = mkIf (any (user: user.authentication.enable) cfg.ensureUsers) (
|
||||||
mkDefault true
|
mkDefault true
|
||||||
);
|
);
|
||||||
authentication = mkMerge (map (user:
|
authentication = mkMerge (map (
|
||||||
mkIf user.authentication.enable user.authentication.authentication
|
user:
|
||||||
) cfg.ensureUsers);
|
mkIf user.authentication.enable user.authentication.authentication
|
||||||
|
)
|
||||||
|
cfg.ensureUsers);
|
||||||
};
|
};
|
||||||
config.networking.firewall.interfaces.local = mkIf cfg.enable {
|
config.networking.firewall.interfaces.local = mkIf cfg.enable {
|
||||||
allowedTCPPorts = mkIf (any (user: user.authentication.local.allow) cfg.ensureUsers) [ cfg.port ];
|
allowedTCPPorts = mkIf (any (user: user.authentication.local.allow) cfg.ensureUsers) [cfg.port];
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,4 @@
|
||||||
{
|
{lib, ...}: let
|
||||||
lib,
|
|
||||||
...
|
|
||||||
}: let
|
|
||||||
inherit (lib.options) mkOption;
|
inherit (lib.options) mkOption;
|
||||||
in {
|
in {
|
||||||
options.services.prowlarr = with lib.types; {
|
options.services.prowlarr = with lib.types; {
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,4 @@
|
||||||
{
|
{lib, ...}: let
|
||||||
lib,
|
|
||||||
...
|
|
||||||
}: let
|
|
||||||
inherit (lib.options) mkOption;
|
inherit (lib.options) mkOption;
|
||||||
in {
|
in {
|
||||||
options.services.radarr = with lib.types; {
|
options.services.radarr = with lib.types; {
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,4 @@
|
||||||
{
|
{lib, ...}: let
|
||||||
lib,
|
|
||||||
...
|
|
||||||
}: let
|
|
||||||
inherit (lib.options) mkOption;
|
inherit (lib.options) mkOption;
|
||||||
in {
|
in {
|
||||||
options.services.readarr = with lib.types; {
|
options.services.readarr = with lib.types; {
|
||||||
|
|
|
||||||
|
|
@ -11,14 +11,17 @@
|
||||||
inherit (config.services) samba-wsdd;
|
inherit (config.services) samba-wsdd;
|
||||||
cfg = config.services.samba;
|
cfg = config.services.samba;
|
||||||
settingValue = value:
|
settingValue = value:
|
||||||
if builtins.isList value then concatMapStringsSep ", " settingValue value
|
if builtins.isList value
|
||||||
else if value == true then "yes"
|
then concatMapStringsSep ", " settingValue value
|
||||||
else if value == false then "no"
|
else if value == true
|
||||||
|
then "yes"
|
||||||
|
else if value == false
|
||||||
|
then "no"
|
||||||
else toString value;
|
else toString value;
|
||||||
in {
|
in {
|
||||||
options.services.samba = with lib.types; let
|
options.services.samba = with lib.types; let
|
||||||
settingPrimitive = oneOf [ str int bool ];
|
settingPrimitive = oneOf [str int bool];
|
||||||
settingType = oneOf [ settingPrimitive (listOf settingPrimitive) ];
|
settingType = oneOf [settingPrimitive (listOf settingPrimitive)];
|
||||||
in {
|
in {
|
||||||
ldap = {
|
ldap = {
|
||||||
enable = mkEnableOption "LDAP";
|
enable = mkEnableOption "LDAP";
|
||||||
|
|
@ -64,7 +67,11 @@ in {
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
idmap = let
|
idmap = let
|
||||||
idmapModule = { config, name, ... }: {
|
idmapModule = {
|
||||||
|
config,
|
||||||
|
name,
|
||||||
|
...
|
||||||
|
}: {
|
||||||
options = {
|
options = {
|
||||||
backend = mkOption {
|
backend = mkOption {
|
||||||
type = str;
|
type = str;
|
||||||
|
|
@ -89,7 +96,7 @@ in {
|
||||||
};
|
};
|
||||||
settings = mkOption {
|
settings = mkOption {
|
||||||
type = attrsOf settingType;
|
type = attrsOf settingType;
|
||||||
default = { };
|
default = {};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
config = {
|
config = {
|
||||||
|
|
@ -117,7 +124,7 @@ in {
|
||||||
};
|
};
|
||||||
settings = mkOption {
|
settings = mkOption {
|
||||||
type = attrsOf settingType;
|
type = attrsOf settingType;
|
||||||
default = { };
|
default = {};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -139,35 +146,36 @@ in {
|
||||||
})
|
})
|
||||||
];
|
];
|
||||||
settings = mkMerge ([
|
settings = mkMerge ([
|
||||||
{
|
{
|
||||||
"use sendfile" = mkOptionDefault true;
|
"use sendfile" = mkOptionDefault true;
|
||||||
}
|
}
|
||||||
(mkIf (cfg.passdb.smbpasswd.path != null) {
|
(mkIf (cfg.passdb.smbpasswd.path != null) {
|
||||||
"passdb backend" = mkOptionDefault "smbpasswd:${cfg.passdb.smbpasswd.path}";
|
"passdb backend" = mkOptionDefault "smbpasswd:${cfg.passdb.smbpasswd.path}";
|
||||||
})
|
})
|
||||||
(mkIf cfg.ldap.enable {
|
(mkIf cfg.ldap.enable {
|
||||||
"passdb backend" = mkOptionDefault ''ldapsam:"${cfg.ldap.url}"'';
|
"passdb backend" = mkOptionDefault ''ldapsam:"${cfg.ldap.url}"'';
|
||||||
"ldap ssl" = mkIf (hasPrefix "ldaps://" cfg.ldap.url) (mkOptionDefault "off");
|
"ldap ssl" = mkIf (hasPrefix "ldaps://" cfg.ldap.url) (mkOptionDefault "off");
|
||||||
"ldap admin dn" = mkOptionDefault "name=anonymous,${cfg.ldap.baseDn}";
|
"ldap admin dn" = mkOptionDefault "name=anonymous,${cfg.ldap.baseDn}";
|
||||||
"ldap suffix" = mkOptionDefault cfg.ldap.baseDn;
|
"ldap suffix" = mkOptionDefault cfg.ldap.baseDn;
|
||||||
})
|
})
|
||||||
(mkIf (cfg.ldap.enable && true) {
|
(mkIf (cfg.ldap.enable && true) {
|
||||||
"ntlm auth" = mkOptionDefault "disabled";
|
"ntlm auth" = mkOptionDefault "disabled";
|
||||||
"encrypt passwords" = mkOptionDefault false;
|
"encrypt passwords" = mkOptionDefault false;
|
||||||
})
|
})
|
||||||
(mkIf cfg.usershare.enable {
|
(mkIf cfg.usershare.enable {
|
||||||
"usershare allow guests" = mkOptionDefault true;
|
"usershare allow guests" = mkOptionDefault true;
|
||||||
"usershare max shares" = mkOptionDefault 16;
|
"usershare max shares" = mkOptionDefault 16;
|
||||||
"usershare owner only" = mkOptionDefault true;
|
"usershare owner only" = mkOptionDefault true;
|
||||||
"usershare template share" = mkOptionDefault cfg.usershare.templateShare;
|
"usershare template share" = mkOptionDefault cfg.usershare.templateShare;
|
||||||
"usershare path" = mkOptionDefault cfg.usershare.path;
|
"usershare path" = mkOptionDefault cfg.usershare.path;
|
||||||
"usershare prefix allow list" = mkOptionDefault [ cfg.usershare.path ];
|
"usershare prefix allow list" = mkOptionDefault [cfg.usershare.path];
|
||||||
})
|
})
|
||||||
(mkIf cfg.guest.enable {
|
(mkIf cfg.guest.enable {
|
||||||
"map to guest" = mkOptionDefault "Bad User";
|
"map to guest" = mkOptionDefault "Bad User";
|
||||||
"guest account" = mkOptionDefault cfg.guest.user;
|
"guest account" = mkOptionDefault cfg.guest.user;
|
||||||
})
|
})
|
||||||
] ++ mapAttrsToList (_: idmap: mapAttrs' (key: value: nameValuePair "idmap config ${idmap.domain} : ${key}" (mkOptionDefault value)) idmap.settings) cfg.idmap.domains);
|
]
|
||||||
|
++ mapAttrsToList (_: idmap: mapAttrs' (key: value: nameValuePair "idmap config ${idmap.domain} : ${key}" (mkOptionDefault value)) idmap.settings) cfg.idmap.domains);
|
||||||
extraConfig = mkMerge (mapAttrsToList (key: value: ''${key} = ${settingValue value}'') cfg.settings);
|
extraConfig = mkMerge (mapAttrsToList (key: value: ''${key} = ${settingValue value}'') cfg.settings);
|
||||||
shares.${cfg.usershare.templateShare} = mkIf cfg.usershare.enable {
|
shares.${cfg.usershare.templateShare} = mkIf cfg.usershare.enable {
|
||||||
"-valid" = false;
|
"-valid" = false;
|
||||||
|
|
@ -194,12 +202,12 @@ in {
|
||||||
|
|
||||||
networking.firewall.interfaces.local = {
|
networking.firewall.interfaces.local = {
|
||||||
allowedTCPPorts = mkMerge [
|
allowedTCPPorts = mkMerge [
|
||||||
(mkIf (cfg.enable && !cfg.openFirewall) [ 139 445 ])
|
(mkIf (cfg.enable && !cfg.openFirewall) [139 445])
|
||||||
(mkIf (samba-wsdd.enable && !samba-wsdd.openFirewall) [ 5357 ])
|
(mkIf (samba-wsdd.enable && !samba-wsdd.openFirewall) [5357])
|
||||||
];
|
];
|
||||||
allowedUDPPorts = mkMerge [
|
allowedUDPPorts = mkMerge [
|
||||||
(mkIf (cfg.enable && !cfg.openFirewall) [ 137 138 ])
|
(mkIf (cfg.enable && !cfg.openFirewall) [137 138])
|
||||||
(mkIf (samba-wsdd.enable && !samba-wsdd.openFirewall) [ 3702 ])
|
(mkIf (samba-wsdd.enable && !samba-wsdd.openFirewall) [3702])
|
||||||
];
|
];
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,4 @@
|
||||||
{
|
{lib, ...}: let
|
||||||
lib,
|
|
||||||
...
|
|
||||||
}: let
|
|
||||||
inherit (lib.options) mkOption;
|
inherit (lib.options) mkOption;
|
||||||
in {
|
in {
|
||||||
options.services.sonarr = with lib.types; {
|
options.services.sonarr = with lib.types; {
|
||||||
|
|
|
||||||
|
|
@ -76,30 +76,35 @@ in {
|
||||||
inherit owner;
|
inherit owner;
|
||||||
inherit (shared) group mode;
|
inherit (shared) group mode;
|
||||||
};
|
};
|
||||||
setupFiles = singleton {
|
setupFiles =
|
||||||
${cfg.rootDir} = toplevel;
|
singleton {
|
||||||
${cfg.binDir} = toplevel;
|
${cfg.rootDir} = toplevel;
|
||||||
${cfg.binDir + "/users"} = shared;
|
${cfg.binDir} = toplevel;
|
||||||
${cfg.dataDir} = toplevel;
|
${cfg.binDir + "/users"} = shared;
|
||||||
${cfg.sharedDataDir} = shared;
|
${cfg.dataDir} = toplevel;
|
||||||
${cfg.workingDir} = toplevel;
|
${cfg.sharedDataDir} = shared;
|
||||||
${cfg.sharedWorkingDir} = shared;
|
${cfg.workingDir} = toplevel;
|
||||||
} ++ map (owner: {
|
${cfg.sharedWorkingDir} = shared;
|
||||||
${cfg.dataDir + "/${owner}"} = personal owner;
|
}
|
||||||
${cfg.workingDir + "/${owner}"} = personal owner;
|
++ map (owner: {
|
||||||
}) cfg.users;
|
${cfg.dataDir + "/${owner}"} = personal owner;
|
||||||
userBinFiles = listToAttrs (map (user: nameValuePair "${cfg.binDir}/users/${user}.bat" {
|
${cfg.workingDir + "/${owner}"} = personal owner;
|
||||||
inherit (toplevel) owner group;
|
})
|
||||||
mode = "0755";
|
cfg.users;
|
||||||
type = "copy";
|
userBinFiles = listToAttrs (map (user:
|
||||||
src = pkgs.writeTextFile {
|
nameValuePair "${cfg.binDir}/users/${user}.bat" {
|
||||||
name = "steam-${user}.bat";
|
inherit (toplevel) owner group;
|
||||||
executable = true;
|
mode = "0755";
|
||||||
text = ''
|
type = "copy";
|
||||||
setx GENSO_STEAM_USER ${user}
|
src = pkgs.writeTextFile {
|
||||||
'';
|
name = "steam-${user}.bat";
|
||||||
};
|
executable = true;
|
||||||
}) cfg.users);
|
text = ''
|
||||||
|
setx GENSO_STEAM_USER ${user}
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
})
|
||||||
|
cfg.users);
|
||||||
in {
|
in {
|
||||||
enable = mkIf (cfg.enable || cfg.setup) true;
|
enable = mkIf (cfg.enable || cfg.setup) true;
|
||||||
files = mkMerge [
|
files = mkMerge [
|
||||||
|
|
|
||||||
|
|
@ -14,7 +14,11 @@
|
||||||
inherit (lib.meta) getExe;
|
inherit (lib.meta) getExe;
|
||||||
inherit (config.services.steam) accountSwitch;
|
inherit (config.services.steam) accountSwitch;
|
||||||
cfg = config.services.steam.beatsaber;
|
cfg = config.services.steam.beatsaber;
|
||||||
versionModule = { config, name, ... }: {
|
versionModule = {
|
||||||
|
config,
|
||||||
|
name,
|
||||||
|
...
|
||||||
|
}: {
|
||||||
options = with lib.types; {
|
options = with lib.types; {
|
||||||
version = mkOption {
|
version = mkOption {
|
||||||
type = str;
|
type = str;
|
||||||
|
|
@ -23,11 +27,12 @@
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
mkSharePath = path: mkWinPath (
|
mkSharePath = path:
|
||||||
"%GENSO_SMB_SHARED_MOUNT%"
|
mkWinPath (
|
||||||
+ "/${accountSwitch.sharePath}"
|
"%GENSO_SMB_SHARED_MOUNT%"
|
||||||
+ "/${removePrefix (accountSwitch.rootDir + "/") path}"
|
+ "/${accountSwitch.sharePath}"
|
||||||
);
|
+ "/${removePrefix (accountSwitch.rootDir + "/") path}"
|
||||||
|
);
|
||||||
vars = ''
|
vars = ''
|
||||||
if "%GENSO_STEAM_INSTALL%" == "" set "GENSO_STEAM_INSTALL=C:\Program Files (x86)\Steam"
|
if "%GENSO_STEAM_INSTALL%" == "" set "GENSO_STEAM_INSTALL=C:\Program Files (x86)\Steam"
|
||||||
if "%GENSO_STEAM_LIBRARY_BS%" == "" set "GENSO_STEAM_LIBRARY_BS=%GENSO_STEAM_INSTALL%"
|
if "%GENSO_STEAM_LIBRARY_BS%" == "" set "GENSO_STEAM_LIBRARY_BS=%GENSO_STEAM_INSTALL%"
|
||||||
|
|
@ -102,9 +107,11 @@
|
||||||
in {
|
in {
|
||||||
options.services.steam.beatsaber = with lib.types; {
|
options.services.steam.beatsaber = with lib.types; {
|
||||||
enable = mkEnableOption "beatsaber scripts";
|
enable = mkEnableOption "beatsaber scripts";
|
||||||
setup = mkEnableOption "beatsaber data" // {
|
setup =
|
||||||
default = accountSwitch.setup;
|
mkEnableOption "beatsaber data"
|
||||||
};
|
// {
|
||||||
|
default = accountSwitch.setup;
|
||||||
|
};
|
||||||
group = mkOption {
|
group = mkOption {
|
||||||
type = str;
|
type = str;
|
||||||
default = "beatsaber";
|
default = "beatsaber";
|
||||||
|
|
@ -114,7 +121,7 @@ in {
|
||||||
};
|
};
|
||||||
versions = mkOption {
|
versions = mkOption {
|
||||||
type = attrsOf (submodule versionModule);
|
type = attrsOf (submodule versionModule);
|
||||||
default = { };
|
default = {};
|
||||||
};
|
};
|
||||||
users = mkOption {
|
users = mkOption {
|
||||||
type = listOf str;
|
type = listOf str;
|
||||||
|
|
@ -127,7 +134,7 @@ in {
|
||||||
bsUsers = filterAttrs (_: userIs cfg.group) config.users.users;
|
bsUsers = filterAttrs (_: userIs cfg.group) config.users.users;
|
||||||
allVersions = mapAttrsToList (_: version: version.version) cfg.versions;
|
allVersions = mapAttrsToList (_: version: version.version) cfg.versions;
|
||||||
in {
|
in {
|
||||||
defaultVersion = mkIf (allVersions != [ ]) (mkOptionDefault (
|
defaultVersion = mkIf (allVersions != []) (mkOptionDefault (
|
||||||
head allVersions
|
head allVersions
|
||||||
));
|
));
|
||||||
users = mkOptionDefault (
|
users = mkOptionDefault (
|
||||||
|
|
@ -140,24 +147,27 @@ in {
|
||||||
mkbeatsabersh
|
mkbeatsabersh
|
||||||
];
|
];
|
||||||
};
|
};
|
||||||
systemd.services = mkIf cfg.setup (listToAttrs (map (user: nameValuePair "steam-setup-beatsaber-${user}" {
|
systemd.services = mkIf cfg.setup (listToAttrs (map (user:
|
||||||
script = mkMerge (mapAttrsToList (_: version: ''
|
nameValuePair "steam-setup-beatsaber-${user}" {
|
||||||
${getExe mkbeatsaber} ${version.version} ${user}
|
script = mkMerge (mapAttrsToList (_: version: ''
|
||||||
'') cfg.versions);
|
${getExe mkbeatsaber} ${version.version} ${user}
|
||||||
path = [
|
'')
|
||||||
pkgs.coreutils
|
cfg.versions);
|
||||||
];
|
path = [
|
||||||
wantedBy = [
|
pkgs.coreutils
|
||||||
"multi-user.target"
|
];
|
||||||
];
|
wantedBy = [
|
||||||
after = [
|
"multi-user.target"
|
||||||
"tmpfiles.service"
|
];
|
||||||
];
|
after = [
|
||||||
serviceConfig = {
|
"tmpfiles.service"
|
||||||
RemainAfterExit = mkOptionDefault true;
|
];
|
||||||
User = mkOptionDefault user;
|
serviceConfig = {
|
||||||
};
|
RemainAfterExit = mkOptionDefault true;
|
||||||
}) cfg.users));
|
User = mkOptionDefault user;
|
||||||
|
};
|
||||||
|
})
|
||||||
|
cfg.users));
|
||||||
services.tmpfiles = let
|
services.tmpfiles = let
|
||||||
toplevel = {
|
toplevel = {
|
||||||
owner = mkDefault "admin";
|
owner = mkDefault "admin";
|
||||||
|
|
@ -187,77 +197,92 @@ in {
|
||||||
"AppData"
|
"AppData"
|
||||||
"UserData"
|
"UserData"
|
||||||
];
|
];
|
||||||
setupFiles = [
|
setupFiles =
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"${accountSwitch.sharedDataDir}/BeatSaber" = toplevel;
|
||||||
|
"${accountSwitch.binDir}/beatsaber" = shared;
|
||||||
|
}
|
||||||
|
(listToAttrs (
|
||||||
|
map (
|
||||||
|
folder:
|
||||||
|
nameValuePair "${accountSwitch.sharedDataDir}/BeatSaber/${folder}" shared
|
||||||
|
)
|
||||||
|
sharedFolders
|
||||||
|
))
|
||||||
|
]
|
||||||
|
++ concatMap (
|
||||||
|
owner:
|
||||||
|
singleton {
|
||||||
|
"${accountSwitch.dataDir}/${owner}/BeatSaber" = personal owner;
|
||||||
|
"${accountSwitch.dataDir}/${owner}/BeatSaber/AppData" = personal owner;
|
||||||
|
"${accountSwitch.dataDir}/${owner}/BeatSaber/UserData" = personal owner;
|
||||||
|
}
|
||||||
|
++ mapAttrsToList (_: version: {
|
||||||
|
"${accountSwitch.dataDir}/${owner}/BeatSaber/${version.version}" = personal owner;
|
||||||
|
})
|
||||||
|
cfg.versions
|
||||||
|
)
|
||||||
|
accountSwitch.users
|
||||||
|
++ mapAttrsToList (_: version: {
|
||||||
|
"${accountSwitch.sharedDataDir}/BeatSaber/${version.version}" = shared;
|
||||||
|
})
|
||||||
|
cfg.versions;
|
||||||
|
versionBinFiles =
|
||||||
|
mapAttrs' (
|
||||||
|
_: version:
|
||||||
|
nameValuePair
|
||||||
|
"${accountSwitch.binDir}/beatsaber/${replaceStrings ["."] ["_"] version.version}.bat"
|
||||||
|
{
|
||||||
|
inherit (bin) owner group mode type;
|
||||||
|
src = pkgs.writeTextFile {
|
||||||
|
name = "beatsaber-${version.version}.bat";
|
||||||
|
executable = true;
|
||||||
|
text = ''
|
||||||
|
setx GENSO_STEAM_BS_VERSION ${version.version}
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
}
|
||||||
|
)
|
||||||
|
cfg.versions;
|
||||||
|
binFiles =
|
||||||
{
|
{
|
||||||
"${accountSwitch.sharedDataDir}/BeatSaber" = toplevel;
|
"${accountSwitch.binDir}/beatsaber/mount.bat" = {
|
||||||
"${accountSwitch.binDir}/beatsaber" = shared;
|
inherit (bin) owner group mode type;
|
||||||
}
|
src = pkgs.writeTextFile {
|
||||||
(listToAttrs (
|
name = "beatsaber-mount.bat";
|
||||||
map (folder:
|
executable = true;
|
||||||
nameValuePair "${accountSwitch.sharedDataDir}/BeatSaber/${folder}" shared
|
text = mountbeatsaber;
|
||||||
) sharedFolders
|
};
|
||||||
))
|
};
|
||||||
] ++ concatMap (owner:
|
"${accountSwitch.binDir}/beatsaber/launch.bat" = {
|
||||||
singleton {
|
inherit (bin) owner group mode type;
|
||||||
"${accountSwitch.dataDir}/${owner}/BeatSaber" = personal owner;
|
src = pkgs.writeTextFile {
|
||||||
"${accountSwitch.dataDir}/${owner}/BeatSaber/AppData" = personal owner;
|
name = "beatsaber-launch.bat";
|
||||||
"${accountSwitch.dataDir}/${owner}/BeatSaber/UserData" = personal owner;
|
executable = true;
|
||||||
} ++ mapAttrsToList (_: version: {
|
text = launchbeatsaber;
|
||||||
"${accountSwitch.dataDir}/${owner}/BeatSaber/${version.version}" = personal owner;
|
};
|
||||||
}) cfg.versions
|
};
|
||||||
) accountSwitch.users
|
"${accountSwitch.binDir}/beatsaber/fpfc.bat" = {
|
||||||
++ mapAttrsToList (_: version: {
|
inherit (bin) owner group mode type;
|
||||||
"${accountSwitch.sharedDataDir}/BeatSaber/${version.version}" = shared;
|
src = pkgs.writeTextFile {
|
||||||
}) cfg.versions;
|
name = "beatsaber-fpfc.bat";
|
||||||
versionBinFiles = mapAttrs' (_: version: nameValuePair
|
executable = true;
|
||||||
"${accountSwitch.binDir}/beatsaber/${replaceStrings [ "." ] [ "_" ] version.version}.bat"
|
text = fpfcbeatsaber;
|
||||||
{
|
};
|
||||||
inherit (bin) owner group mode type;
|
};
|
||||||
src = pkgs.writeTextFile {
|
"${accountSwitch.binDir}/beatsaber/ModAssistant.exe" = {
|
||||||
name = "beatsaber-${version.version}.bat";
|
inherit (toplevel) owner group;
|
||||||
executable = true;
|
mode = "0755";
|
||||||
text = ''
|
type = "copy";
|
||||||
setx GENSO_STEAM_BS_VERSION ${version.version}
|
src = pkgs.fetchurl {
|
||||||
'';
|
url = "https://github.com/Assistant/ModAssistant/releases/download/v1.1.32/ModAssistant.exe";
|
||||||
|
hash = "sha256-ozu2gYFiz+2BjptqL80DmUopbahbyGKFO1IPd7BhVPM=";
|
||||||
|
executable = true;
|
||||||
|
};
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
) cfg.versions;
|
// versionBinFiles;
|
||||||
binFiles = {
|
|
||||||
"${accountSwitch.binDir}/beatsaber/mount.bat" = {
|
|
||||||
inherit (bin) owner group mode type;
|
|
||||||
src = pkgs.writeTextFile {
|
|
||||||
name = "beatsaber-mount.bat";
|
|
||||||
executable = true;
|
|
||||||
text = mountbeatsaber;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
"${accountSwitch.binDir}/beatsaber/launch.bat" = {
|
|
||||||
inherit (bin) owner group mode type;
|
|
||||||
src = pkgs.writeTextFile {
|
|
||||||
name = "beatsaber-launch.bat";
|
|
||||||
executable = true;
|
|
||||||
text = launchbeatsaber;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
"${accountSwitch.binDir}/beatsaber/fpfc.bat" = {
|
|
||||||
inherit (bin) owner group mode type;
|
|
||||||
src = pkgs.writeTextFile {
|
|
||||||
name = "beatsaber-fpfc.bat";
|
|
||||||
executable = true;
|
|
||||||
text = fpfcbeatsaber;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
"${accountSwitch.binDir}/beatsaber/ModAssistant.exe" = {
|
|
||||||
inherit (toplevel) owner group;
|
|
||||||
mode = "0755";
|
|
||||||
type = "copy";
|
|
||||||
src = pkgs.fetchurl {
|
|
||||||
url = "https://github.com/Assistant/ModAssistant/releases/download/v1.1.32/ModAssistant.exe";
|
|
||||||
hash = "sha256-ozu2gYFiz+2BjptqL80DmUopbahbyGKFO1IPd7BhVPM=";
|
|
||||||
executable = true;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
} // versionBinFiles;
|
|
||||||
in {
|
in {
|
||||||
enable = mkIf (cfg.enable || cfg.setup) true;
|
enable = mkIf (cfg.enable || cfg.setup) true;
|
||||||
files = mkMerge [
|
files = mkMerge [
|
||||||
|
|
|
||||||
|
|
@ -18,11 +18,17 @@
|
||||||
systemdFiles = filter (file: file.systemd.enable) files;
|
systemdFiles = filter (file: file.systemd.enable) files;
|
||||||
setupFiles = filter (file: !file.systemd.enable) files;
|
setupFiles = filter (file: !file.systemd.enable) files;
|
||||||
bindFiles = filter (file: file.type == "bind") files;
|
bindFiles = filter (file: file.type == "bind") files;
|
||||||
fileModule = { config, name, ... }: {
|
fileModule = {
|
||||||
|
config,
|
||||||
|
name,
|
||||||
|
...
|
||||||
|
}: {
|
||||||
options = with lib.types; {
|
options = with lib.types; {
|
||||||
enable = mkEnableOption "file" // {
|
enable =
|
||||||
default = true;
|
mkEnableOption "file"
|
||||||
};
|
// {
|
||||||
|
default = true;
|
||||||
|
};
|
||||||
mkdirParent = mkEnableOption "mkdir";
|
mkdirParent = mkEnableOption "mkdir";
|
||||||
bindReadOnly = mkEnableOption "mount -oro";
|
bindReadOnly = mkEnableOption "mount -oro";
|
||||||
relativeSymlink = mkEnableOption "ln -sr";
|
relativeSymlink = mkEnableOption "ln -sr";
|
||||||
|
|
@ -32,8 +38,11 @@
|
||||||
default = name;
|
default = name;
|
||||||
};
|
};
|
||||||
type = mkOption {
|
type = mkOption {
|
||||||
type = enum [ "directory" "symlink" "link" "copy" "bind" ];
|
type = enum ["directory" "symlink" "link" "copy" "bind"];
|
||||||
default = if config.src != null then "symlink" else "directory";
|
default =
|
||||||
|
if config.src != null
|
||||||
|
then "symlink"
|
||||||
|
else "directory";
|
||||||
};
|
};
|
||||||
mode = mkOption {
|
mode = mkOption {
|
||||||
type = str;
|
type = str;
|
||||||
|
|
@ -71,7 +80,7 @@
|
||||||
};
|
};
|
||||||
config = let
|
config = let
|
||||||
acls = concatStringsSep "," config.acls;
|
acls = concatStringsSep "," config.acls;
|
||||||
enableAcls = config.type == "directory" && config.acls != [ ];
|
enableAcls = config.type == "directory" && config.acls != [];
|
||||||
systemdAclRule = "a+ ${config.path} - - - - ${acls}";
|
systemdAclRule = "a+ ${config.path} - - - - ${acls}";
|
||||||
systemdRule = {
|
systemdRule = {
|
||||||
directory = [
|
directory = [
|
||||||
|
|
@ -168,7 +177,7 @@
|
||||||
systemd = {
|
systemd = {
|
||||||
rules = mkMerge [
|
rules = mkMerge [
|
||||||
systemdRule.${config.type}
|
systemdRule.${config.type}
|
||||||
(mkIf enableAcls [ systemdAclRule ])
|
(mkIf enableAcls [systemdAclRule])
|
||||||
];
|
];
|
||||||
mountSettings = mkIf (config.type == "bind") {
|
mountSettings = mkIf (config.type == "bind") {
|
||||||
enable = mkDefault config.enable;
|
enable = mkDefault config.enable;
|
||||||
|
|
@ -191,16 +200,21 @@
|
||||||
};
|
};
|
||||||
in {
|
in {
|
||||||
options.services.tmpfiles = with lib.types; {
|
options.services.tmpfiles = with lib.types; {
|
||||||
enable = mkEnableOption "extended tmpfiles" // {
|
enable =
|
||||||
default = cfg.files != { };
|
mkEnableOption "extended tmpfiles"
|
||||||
};
|
// {
|
||||||
|
default = cfg.files != {};
|
||||||
|
};
|
||||||
user = mkOption {
|
user = mkOption {
|
||||||
type = str;
|
type = str;
|
||||||
default = if config.proxmoxLXC.privileged or true then "root" else "admin";
|
default =
|
||||||
|
if config.proxmoxLXC.privileged or true
|
||||||
|
then "root"
|
||||||
|
else "admin";
|
||||||
};
|
};
|
||||||
files = mkOption {
|
files = mkOption {
|
||||||
type = attrsOf (submodule fileModule);
|
type = attrsOf (submodule fileModule);
|
||||||
default = { };
|
default = {};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
config = {
|
config = {
|
||||||
|
|
@ -209,15 +223,19 @@ in {
|
||||||
map (file: file.systemd.rules) systemdFiles
|
map (file: file.systemd.rules) systemdFiles
|
||||||
);
|
);
|
||||||
services.tmpfiles = {
|
services.tmpfiles = {
|
||||||
path = [ pkgs.coreutils pkgs.acl ];
|
path = [pkgs.coreutils pkgs.acl];
|
||||||
script = mkMerge (
|
script = mkMerge (
|
||||||
[ ''
|
[
|
||||||
EXITCODE=0
|
''
|
||||||
'' ]
|
EXITCODE=0
|
||||||
|
''
|
||||||
|
]
|
||||||
++ map (file: file.setup.script) setupFiles
|
++ map (file: file.setup.script) setupFiles
|
||||||
++ [ ''
|
++ [
|
||||||
exit $EXITCODE
|
''
|
||||||
'' ]
|
exit $EXITCODE
|
||||||
|
''
|
||||||
|
]
|
||||||
);
|
);
|
||||||
wantedBy = [
|
wantedBy = [
|
||||||
"sysinit.target"
|
"sysinit.target"
|
||||||
|
|
|
||||||
|
|
@ -13,28 +13,33 @@
|
||||||
userMatchBlock = user: let
|
userMatchBlock = user: let
|
||||||
inherit (user.openssh) matchBlock;
|
inherit (user.openssh) matchBlock;
|
||||||
criteria = mapAttrsToList toSshdCriteria matchBlock.criteria;
|
criteria = mapAttrsToList toSshdCriteria matchBlock.criteria;
|
||||||
in mkAfter ''
|
in
|
||||||
Match ${concatStringsSep " " criteria}
|
mkAfter ''
|
||||||
${matchBlock.settingsConfig}
|
Match ${concatStringsSep " " criteria}
|
||||||
'';
|
${matchBlock.settingsConfig}
|
||||||
userModule = { config, ... }: let
|
'';
|
||||||
|
userModule = {config, ...}: let
|
||||||
toSshdValue = value:
|
toSshdValue = value:
|
||||||
if value == true then "yes"
|
if value == true
|
||||||
else if value == false then "no"
|
then "yes"
|
||||||
|
else if value == false
|
||||||
|
then "no"
|
||||||
else toString value;
|
else toString value;
|
||||||
toSshdConf = key: value: "${key} ${toSshdValue value}";
|
toSshdConf = key: value: "${key} ${toSshdValue value}";
|
||||||
in {
|
in {
|
||||||
options = with lib.types; {
|
options = with lib.types; {
|
||||||
openssh.matchBlock = {
|
openssh.matchBlock = {
|
||||||
enable = mkEnableOption "match block" // {
|
enable =
|
||||||
default = config.openssh.matchBlock.settings != { };
|
mkEnableOption "match block"
|
||||||
};
|
// {
|
||||||
|
default = config.openssh.matchBlock.settings != {};
|
||||||
|
};
|
||||||
criteria = mkOption {
|
criteria = mkOption {
|
||||||
type = attrsOf str;
|
type = attrsOf str;
|
||||||
};
|
};
|
||||||
settings = mkOption {
|
settings = mkOption {
|
||||||
type = attrsOf (oneOf [ str path bool int ]);
|
type = attrsOf (oneOf [str path bool int]);
|
||||||
default = { };
|
default = {};
|
||||||
};
|
};
|
||||||
settingsConfig = mkOption {
|
settingsConfig = mkOption {
|
||||||
type = lines;
|
type = lines;
|
||||||
|
|
|
||||||
|
|
@ -5,11 +5,20 @@
|
||||||
lib,
|
lib,
|
||||||
...
|
...
|
||||||
}: let
|
}: let
|
||||||
inherit (lib) mkIf mkMerge mkDefault mkOptionDefault mkOption mkEnableOption types
|
inherit
|
||||||
getExe;
|
(lib)
|
||||||
|
mkIf
|
||||||
|
mkMerge
|
||||||
|
mkDefault
|
||||||
|
mkOptionDefault
|
||||||
|
mkOption
|
||||||
|
mkEnableOption
|
||||||
|
types
|
||||||
|
getExe
|
||||||
|
;
|
||||||
nixosConfig = config;
|
nixosConfig = config;
|
||||||
cfg = config.services.vouch-proxy;
|
cfg = config.services.vouch-proxy;
|
||||||
settingsFormat = pkgs.formats.json { };
|
settingsFormat = pkgs.formats.json {};
|
||||||
in {
|
in {
|
||||||
options.services.vouch-proxy = with types; {
|
options.services.vouch-proxy = with types; {
|
||||||
enable = mkEnableOption "vouch";
|
enable = mkEnableOption "vouch";
|
||||||
|
|
@ -35,7 +44,7 @@ in {
|
||||||
};
|
};
|
||||||
enableSettingsSecrets = mkEnableOption "genJqSecretsReplacementSnippet";
|
enableSettingsSecrets = mkEnableOption "genJqSecretsReplacementSnippet";
|
||||||
settings = let
|
settings = let
|
||||||
settingsModule = { ... }: {
|
settingsModule = {...}: {
|
||||||
freeformType = settingsFormat.type;
|
freeformType = settingsFormat.type;
|
||||||
options = {
|
options = {
|
||||||
vouch = {
|
vouch = {
|
||||||
|
|
@ -98,13 +107,14 @@ in {
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
in mkOption {
|
in
|
||||||
type = submodule settingsModule;
|
mkOption {
|
||||||
default = { };
|
type = submodule settingsModule;
|
||||||
};
|
default = {};
|
||||||
|
};
|
||||||
extraSettings = mkOption {
|
extraSettings = mkOption {
|
||||||
inherit (settingsFormat) type;
|
inherit (settingsFormat) type;
|
||||||
default = { };
|
default = {};
|
||||||
};
|
};
|
||||||
settingsPath = mkOption {
|
settingsPath = mkOption {
|
||||||
type = path;
|
type = path;
|
||||||
|
|
@ -116,48 +126,51 @@ in {
|
||||||
cfg.settings
|
cfg.settings
|
||||||
cfg.extraSettings
|
cfg.extraSettings
|
||||||
];
|
];
|
||||||
settingsPath = if cfg.enableSettingsSecrets
|
settingsPath =
|
||||||
|
if cfg.enableSettingsSecrets
|
||||||
then "/run/vouch-proxy/vouch-config.json"
|
then "/run/vouch-proxy/vouch-config.json"
|
||||||
else settingsFormat.generate "vouch-config.json" settings;
|
else settingsFormat.generate "vouch-config.json" settings;
|
||||||
in mkMerge [
|
in
|
||||||
{
|
mkMerge [
|
||||||
services.vouch-proxy = {
|
{
|
||||||
settingsPath = mkOptionDefault settingsPath;
|
services.vouch-proxy = {
|
||||||
};
|
settingsPath = mkOptionDefault settingsPath;
|
||||||
}
|
};
|
||||||
(mkIf cfg.enable {
|
}
|
||||||
systemd.services.vouch-proxy = {
|
(mkIf cfg.enable {
|
||||||
description = "Vouch-proxy";
|
systemd.services.vouch-proxy = {
|
||||||
after = [ "network.target" ];
|
description = "Vouch-proxy";
|
||||||
wantedBy = [ "multi-user.target" ];
|
after = ["network.target"];
|
||||||
serviceConfig = {
|
wantedBy = ["multi-user.target"];
|
||||||
ExecStartPre = let
|
serviceConfig = {
|
||||||
preprocess = pkgs.writeShellScript "vouch-proxy-prestart" (
|
ExecStartPre = let
|
||||||
utils.genJqSecretsReplacementSnippet settings cfg.settingsPath
|
preprocess = pkgs.writeShellScript "vouch-proxy-prestart" (
|
||||||
);
|
utils.genJqSecretsReplacementSnippet settings cfg.settingsPath
|
||||||
in mkIf cfg.enableSettingsSecrets [
|
);
|
||||||
"${preprocess}"
|
in
|
||||||
];
|
mkIf cfg.enableSettingsSecrets [
|
||||||
ExecStart = [
|
"${preprocess}"
|
||||||
"${getExe pkgs.vouch-proxy} -config ${cfg.settingsPath}"
|
];
|
||||||
];
|
ExecStart = [
|
||||||
Restart = "on-failure";
|
"${getExe pkgs.vouch-proxy} -config ${cfg.settingsPath}"
|
||||||
RestartSec = mkDefault 5;
|
];
|
||||||
WorkingDirectory = "/var/lib/vouch-proxy";
|
Restart = "on-failure";
|
||||||
StateDirectory = "vouch-proxy";
|
RestartSec = mkDefault 5;
|
||||||
RuntimeDirectory = "vouch-proxy";
|
WorkingDirectory = "/var/lib/vouch-proxy";
|
||||||
User = cfg.user;
|
StateDirectory = "vouch-proxy";
|
||||||
Group = cfg.group;
|
RuntimeDirectory = "vouch-proxy";
|
||||||
StartLimitBurst = mkDefault 3;
|
User = cfg.user;
|
||||||
|
Group = cfg.group;
|
||||||
|
StartLimitBurst = mkDefault 3;
|
||||||
|
};
|
||||||
};
|
};
|
||||||
};
|
|
||||||
|
|
||||||
users.users.${cfg.user} = {
|
users.users.${cfg.user} = {
|
||||||
inherit (cfg) group;
|
inherit (cfg) group;
|
||||||
isSystemUser = true;
|
isSystemUser = true;
|
||||||
};
|
};
|
||||||
|
|
||||||
users.groups.${cfg.group} = {};
|
users.groups.${cfg.group} = {};
|
||||||
})
|
})
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -3,8 +3,7 @@
|
||||||
meta,
|
meta,
|
||||||
lib,
|
lib,
|
||||||
...
|
...
|
||||||
}:
|
}: let
|
||||||
let
|
|
||||||
inherit (lib.options) mkOption mkEnableOption;
|
inherit (lib.options) mkOption mkEnableOption;
|
||||||
inherit (lib.modules) mkIf mkMerge mkBefore mkDefault;
|
inherit (lib.modules) mkIf mkMerge mkBefore mkDefault;
|
||||||
inherit (lib.strings) optionalString concatStringsSep;
|
inherit (lib.strings) optionalString concatStringsSep;
|
||||||
|
|
@ -56,18 +55,22 @@ in {
|
||||||
type = str;
|
type = str;
|
||||||
};
|
};
|
||||||
preread = {
|
preread = {
|
||||||
enable = mkEnableOption "ssl preread" // {
|
enable =
|
||||||
default = true;
|
mkEnableOption "ssl preread"
|
||||||
};
|
// {
|
||||||
|
default = true;
|
||||||
|
};
|
||||||
port = mkOption {
|
port = mkOption {
|
||||||
type = port;
|
type = port;
|
||||||
default = 444;
|
default = 444;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
kerberos = {
|
kerberos = {
|
||||||
enable = mkEnableOption "proxy kerberos" // {
|
enable =
|
||||||
default = true;
|
mkEnableOption "proxy kerberos"
|
||||||
};
|
// {
|
||||||
|
default = true;
|
||||||
|
};
|
||||||
ports = {
|
ports = {
|
||||||
ticket = mkOption {
|
ticket = mkOption {
|
||||||
type = port;
|
type = port;
|
||||||
|
|
@ -86,7 +89,10 @@ in {
|
||||||
proxyPass = mkOption {
|
proxyPass = mkOption {
|
||||||
type = str;
|
type = str;
|
||||||
default = let
|
default = let
|
||||||
scheme = if access.port == 443 then "https" else "http";
|
scheme =
|
||||||
|
if access.port == 443
|
||||||
|
then "https"
|
||||||
|
else "http";
|
||||||
in "${scheme}://${access.host}:${toString access.port}";
|
in "${scheme}://${access.host}:${toString access.port}";
|
||||||
};
|
};
|
||||||
domain = mkOption {
|
domain = mkOption {
|
||||||
|
|
@ -130,7 +136,7 @@ in {
|
||||||
port = mkDefault access.ldapPort;
|
port = mkDefault access.ldapPort;
|
||||||
useACMEHost = mkDefault access.useACMEHost;
|
useACMEHost = mkDefault access.useACMEHost;
|
||||||
};
|
};
|
||||||
resolver.addresses = mkIf access.preread.enable [ "[::1]" "127.0.0.1:5353" ];
|
resolver.addresses = mkIf access.preread.enable ["[::1]" "127.0.0.1:5353"];
|
||||||
defaultSSLListenPort = mkIf access.preread.enable access.preread.port;
|
defaultSSLListenPort = mkIf access.preread.enable access.preread.port;
|
||||||
streamConfig = let
|
streamConfig = let
|
||||||
preread = ''
|
preread = ''
|
||||||
|
|
@ -174,10 +180,11 @@ in {
|
||||||
proxy_pass ${access.host}:${toString access.kerberos.ports.kpasswd};
|
proxy_pass ${access.host}:${toString access.kerberos.ports.kpasswd};
|
||||||
}
|
}
|
||||||
'';
|
'';
|
||||||
in mkMerge [
|
in
|
||||||
(mkIf access.preread.enable preread)
|
mkMerge [
|
||||||
(mkIf access.kerberos.enable kerberos)
|
(mkIf access.preread.enable preread)
|
||||||
];
|
(mkIf access.kerberos.enable kerberos)
|
||||||
|
];
|
||||||
virtualHosts = {
|
virtualHosts = {
|
||||||
${access.domain} = {
|
${access.domain} = {
|
||||||
inherit locations extraConfig;
|
inherit locations extraConfig;
|
||||||
|
|
@ -207,7 +214,7 @@ in {
|
||||||
local.enable = true;
|
local.enable = true;
|
||||||
inherit locations;
|
inherit locations;
|
||||||
};
|
};
|
||||||
${ldap.domain} = { config, ... }: {
|
${ldap.domain} = {config, ...}: {
|
||||||
useACMEHost = mkDefault virtualHosts.${access.domain}.useACMEHost;
|
useACMEHost = mkDefault virtualHosts.${access.domain}.useACMEHost;
|
||||||
addSSL = mkDefault (config.useACMEHost != null);
|
addSSL = mkDefault (config.useACMEHost != null);
|
||||||
globalRedirect = access.domain;
|
globalRedirect = access.domain;
|
||||||
|
|
|
||||||
|
|
@ -12,9 +12,11 @@
|
||||||
freepbx = config.lib.access.systemFor "freepbx";
|
freepbx = config.lib.access.systemFor "freepbx";
|
||||||
in {
|
in {
|
||||||
options.services.nginx.access.freepbx = with lib.types; {
|
options.services.nginx.access.freepbx = with lib.types; {
|
||||||
global.enable = mkEnableOption "global access" // {
|
global.enable =
|
||||||
default = access.useACMEHost != null;
|
mkEnableOption "global access"
|
||||||
};
|
// {
|
||||||
|
default = access.useACMEHost != null;
|
||||||
|
};
|
||||||
host = mkOption {
|
host = mkOption {
|
||||||
type = str;
|
type = str;
|
||||||
default = freepbx.access.hostnameForNetwork.local;
|
default = freepbx.access.hostnameForNetwork.local;
|
||||||
|
|
@ -94,17 +96,19 @@ in {
|
||||||
};
|
};
|
||||||
"${access.domain}@ucp" = {
|
"${access.domain}@ucp" = {
|
||||||
serverName = access.domain;
|
serverName = access.domain;
|
||||||
listen = concatMap (addr: [
|
listen =
|
||||||
{
|
concatMap (addr: [
|
||||||
inherit addr;
|
{
|
||||||
port = access.ucpPort;
|
inherit addr;
|
||||||
}
|
port = access.ucpPort;
|
||||||
(mkIf (access.useACMEHost != null) {
|
}
|
||||||
inherit addr;
|
(mkIf (access.useACMEHost != null) {
|
||||||
port = access.ucpSslPort;
|
inherit addr;
|
||||||
ssl = true;
|
port = access.ucpSslPort;
|
||||||
})
|
ssl = true;
|
||||||
]) nginx.defaultListenAddresses;
|
})
|
||||||
|
])
|
||||||
|
nginx.defaultListenAddresses;
|
||||||
proxy.websocket.enable = true;
|
proxy.websocket.enable = true;
|
||||||
local.enable = mkDefault (!access.global.enable);
|
local.enable = mkDefault (!access.global.enable);
|
||||||
addSSL = mkDefault (access.useACMEHost != null);
|
addSSL = mkDefault (access.useACMEHost != null);
|
||||||
|
|
@ -116,27 +120,29 @@ in {
|
||||||
inherit extraConfig;
|
inherit extraConfig;
|
||||||
};
|
};
|
||||||
${access.localDomain} = {
|
${access.localDomain} = {
|
||||||
listen = concatMap (addr: [
|
listen =
|
||||||
{
|
concatMap (addr: [
|
||||||
inherit addr;
|
{
|
||||||
port = nginx.defaultHTTPListenPort;
|
inherit addr;
|
||||||
}
|
port = nginx.defaultHTTPListenPort;
|
||||||
{
|
}
|
||||||
inherit addr;
|
{
|
||||||
port = access.ucpPort;
|
inherit addr;
|
||||||
}
|
port = access.ucpPort;
|
||||||
(mkIf (access.useACMEHost != null) {
|
}
|
||||||
inherit addr;
|
(mkIf (access.useACMEHost != null) {
|
||||||
port = nginx.defaultSSLListenPort;
|
inherit addr;
|
||||||
ssl = true;
|
port = nginx.defaultSSLListenPort;
|
||||||
})
|
ssl = true;
|
||||||
(mkIf (access.useACMEHost != null) {
|
})
|
||||||
inherit addr;
|
(mkIf (access.useACMEHost != null) {
|
||||||
port = access.ucpSslPort;
|
inherit addr;
|
||||||
ssl = true;
|
port = access.ucpSslPort;
|
||||||
})
|
ssl = true;
|
||||||
]) nginx.defaultListenAddresses;
|
})
|
||||||
serverAliases = mkIf tailscale.enable [ access.tailDomain ];
|
])
|
||||||
|
nginx.defaultListenAddresses;
|
||||||
|
serverAliases = mkIf tailscale.enable [access.tailDomain];
|
||||||
useACMEHost = mkDefault access.useACMEHost;
|
useACMEHost = mkDefault access.useACMEHost;
|
||||||
addSSL = mkDefault (access.useACMEHost != null);
|
addSSL = mkDefault (access.useACMEHost != null);
|
||||||
kTLS = mkDefault true;
|
kTLS = mkDefault true;
|
||||||
|
|
@ -146,7 +152,7 @@ in {
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
config.networking.firewall = let
|
config.networking.firewall = let
|
||||||
websocketPorts = [ access.ucpPort ] ++ optional (access.useACMEHost != null) access.ucpSslPort;
|
websocketPorts = [access.ucpPort] ++ optional (access.useACMEHost != null) access.ucpSslPort;
|
||||||
in {
|
in {
|
||||||
interfaces.local.allowedTCPPorts = websocketPorts;
|
interfaces.local.allowedTCPPorts = websocketPorts;
|
||||||
allowedTCPPorts = mkIf access.global.enable websocketPorts;
|
allowedTCPPorts = mkIf access.global.enable websocketPorts;
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,4 @@
|
||||||
{
|
{lib, ...}: let
|
||||||
lib,
|
|
||||||
...
|
|
||||||
}: let
|
|
||||||
inherit (lib.modules) mkDefault;
|
inherit (lib.modules) mkDefault;
|
||||||
in {
|
in {
|
||||||
networking = {
|
networking = {
|
||||||
|
|
|
||||||
|
|
@ -34,12 +34,14 @@ in {
|
||||||
url = mkOptionDefault "http://localhost:${toString cfg.port}";
|
url = mkOptionDefault "http://localhost:${toString cfg.port}";
|
||||||
};
|
};
|
||||||
virtualHosts = let
|
virtualHosts = let
|
||||||
invidiousDomains = [
|
invidiousDomains =
|
||||||
access.domain
|
[
|
||||||
access.localDomain
|
access.domain
|
||||||
] ++ optional tailscale.enable access.tailDomain;
|
access.localDomain
|
||||||
|
]
|
||||||
|
++ optional tailscale.enable access.tailDomain;
|
||||||
contentSecurityPolicy' = "default-src 'self'; script-src 'self'; style-src 'self' 'unsafe-inline'; img-src 'self' data:; font-src 'self' data:; connect-src 'self'; manifest-src 'self'; media-src 'self' blob: https://*.googlevideo.com:443 https://*.youtube.com:443; child-src 'self' blob:; frame-src 'self'; frame-ancestors 'none'";
|
contentSecurityPolicy' = "default-src 'self'; script-src 'self'; style-src 'self' 'unsafe-inline'; img-src 'self' data:; font-src 'self' data:; connect-src 'self'; manifest-src 'self'; media-src 'self' blob: https://*.googlevideo.com:443 https://*.youtube.com:443; child-src 'self' blob:; frame-src 'self'; frame-ancestors 'none'";
|
||||||
contentSecurityPolicy = replaceStrings [ "'self'" ] [ "'self' ${concatStringsSep " " invidiousDomains}" ] contentSecurityPolicy';
|
contentSecurityPolicy = replaceStrings ["'self'"] ["'self' ${concatStringsSep " " invidiousDomains}"] contentSecurityPolicy';
|
||||||
extraConfig = ''
|
extraConfig = ''
|
||||||
# Some players don't reopen a socket and playback stops totally instead of resuming after an extended pause
|
# Some players don't reopen a socket and playback stops totally instead of resuming after an extended pause
|
||||||
send_timeout 100m;
|
send_timeout 100m;
|
||||||
|
|
@ -56,14 +58,14 @@ in {
|
||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
in {
|
in {
|
||||||
${access.domain} = { config, ... }: {
|
${access.domain} = {config, ...}: {
|
||||||
vouch.enable = true;
|
vouch.enable = true;
|
||||||
locations."/" = location;
|
locations."/" = location;
|
||||||
kTLS = mkDefault true;
|
kTLS = mkDefault true;
|
||||||
inherit extraConfig;
|
inherit extraConfig;
|
||||||
};
|
};
|
||||||
${access.localDomain} = { config, ... }: {
|
${access.localDomain} = {config, ...}: {
|
||||||
serverAliases = mkIf tailscale.enable [ access.tailDomain ];
|
serverAliases = mkIf tailscale.enable [access.tailDomain];
|
||||||
local.enable = true;
|
local.enable = true;
|
||||||
locations."/" = mkMerge [
|
locations."/" = mkMerge [
|
||||||
location
|
location
|
||||||
|
|
|
||||||
|
|
@ -3,8 +3,7 @@
|
||||||
meta,
|
meta,
|
||||||
lib,
|
lib,
|
||||||
...
|
...
|
||||||
}:
|
}: let
|
||||||
let
|
|
||||||
inherit (lib.options) mkOption;
|
inherit (lib.options) mkOption;
|
||||||
inherit (lib.modules) mkIf mkMerge mkDefault mkOptionDefault;
|
inherit (lib.modules) mkIf mkMerge mkDefault mkOptionDefault;
|
||||||
inherit (config) networking;
|
inherit (config) networking;
|
||||||
|
|
|
||||||
|
|
@ -64,39 +64,47 @@ in {
|
||||||
inherit extraConfig;
|
inherit extraConfig;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
streamListen = { config, ... }: {
|
streamListen = {config, ...}: {
|
||||||
listen = concatMap (addr: [
|
listen =
|
||||||
(mkIf config.addSSL {
|
concatMap (addr: [
|
||||||
inherit addr;
|
(mkIf config.addSSL {
|
||||||
port = nginx.defaultSSLListenPort;
|
inherit addr;
|
||||||
ssl = true;
|
port = nginx.defaultSSLListenPort;
|
||||||
})
|
ssl = true;
|
||||||
{
|
})
|
||||||
inherit addr;
|
{
|
||||||
port = nginx.defaultHTTPListenPort;
|
inherit addr;
|
||||||
}
|
port = nginx.defaultHTTPListenPort;
|
||||||
{
|
}
|
||||||
inherit addr;
|
{
|
||||||
port = access.streamPort;
|
inherit addr;
|
||||||
}
|
port = access.streamPort;
|
||||||
]) nginx.defaultListenAddresses;
|
}
|
||||||
|
])
|
||||||
|
nginx.defaultListenAddresses;
|
||||||
};
|
};
|
||||||
in {
|
in {
|
||||||
${access.domain} = mkMerge [ {
|
${access.domain} = mkMerge [
|
||||||
vouch.enable = true;
|
{
|
||||||
kTLS = mkDefault true;
|
vouch.enable = true;
|
||||||
inherit (access) useACMEHost;
|
kTLS = mkDefault true;
|
||||||
addSSL = mkDefault (access.useACMEHost != null);
|
inherit (access) useACMEHost;
|
||||||
inherit locations;
|
addSSL = mkDefault (access.useACMEHost != null);
|
||||||
} streamListen ];
|
inherit locations;
|
||||||
${access.localDomain} = mkMerge [ {
|
}
|
||||||
serverAliases = mkIf config.services.tailscale.enable [ access.tailDomain ];
|
streamListen
|
||||||
inherit (virtualHosts.${access.domain}) useACMEHost;
|
];
|
||||||
addSSL = mkDefault addSSL;
|
${access.localDomain} = mkMerge [
|
||||||
kTLS = mkDefault true;
|
{
|
||||||
local.enable = true;
|
serverAliases = mkIf config.services.tailscale.enable [access.tailDomain];
|
||||||
inherit locations;
|
inherit (virtualHosts.${access.domain}) useACMEHost;
|
||||||
} streamListen ];
|
addSSL = mkDefault addSSL;
|
||||||
|
kTLS = mkDefault true;
|
||||||
|
local.enable = true;
|
||||||
|
inherit locations;
|
||||||
|
}
|
||||||
|
streamListen
|
||||||
|
];
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
config.networking.firewall.allowedTCPPorts = [
|
config.networking.firewall.allowedTCPPorts = [
|
||||||
|
|
|
||||||
|
|
@ -2,8 +2,7 @@
|
||||||
config,
|
config,
|
||||||
lib,
|
lib,
|
||||||
...
|
...
|
||||||
}:
|
}: let
|
||||||
let
|
|
||||||
inherit (lib.options) mkOption mkEnableOption;
|
inherit (lib.options) mkOption mkEnableOption;
|
||||||
inherit (lib.modules) mkIf mkMerge;
|
inherit (lib.modules) mkIf mkMerge;
|
||||||
inherit (lib.strings) concatMapStringsSep optionalString;
|
inherit (lib.strings) concatMapStringsSep optionalString;
|
||||||
|
|
@ -18,9 +17,11 @@ let
|
||||||
cidrForNetwork.loopback.all
|
cidrForNetwork.loopback.all
|
||||||
++ cidrForNetwork.local.all
|
++ cidrForNetwork.local.all
|
||||||
++ optionals tailscale.enable cidrForNetwork.tail.all;
|
++ optionals tailscale.enable cidrForNetwork.tail.all;
|
||||||
allows = concatMapStringsSep "\n" mkAllow allowAddresses + optionalString localaddrs.enable ''
|
allows =
|
||||||
include ${localaddrs.stateDir}/*.nginx.conf;
|
concatMapStringsSep "\n" mkAllow allowAddresses
|
||||||
'';
|
+ optionalString localaddrs.enable ''
|
||||||
|
include ${localaddrs.stateDir}/*.nginx.conf;
|
||||||
|
'';
|
||||||
in ''
|
in ''
|
||||||
${allows}
|
${allows}
|
||||||
deny all;
|
deny all;
|
||||||
|
|
@ -61,28 +62,29 @@ in {
|
||||||
proxy_ssl on;
|
proxy_ssl on;
|
||||||
proxy_ssl_verify off;
|
proxy_ssl_verify off;
|
||||||
'';
|
'';
|
||||||
in mkIf access.enable (mkMerge [
|
in
|
||||||
''
|
mkIf access.enable (mkMerge [
|
||||||
server {
|
''
|
||||||
listen 0.0.0.0:389;
|
server {
|
||||||
listen [::]:389;
|
listen 0.0.0.0:389;
|
||||||
${allows}
|
listen [::]:389;
|
||||||
proxy_pass ${proxyPass};
|
${allows}
|
||||||
${proxySsl}
|
proxy_pass ${proxyPass};
|
||||||
}
|
${proxySsl}
|
||||||
''
|
}
|
||||||
(mkIf (access.useACMEHost != null) ''
|
''
|
||||||
server {
|
(mkIf (access.useACMEHost != null) ''
|
||||||
listen 0.0.0.0:636 ssl;
|
server {
|
||||||
listen [::]:636 ssl;
|
listen 0.0.0.0:636 ssl;
|
||||||
ssl_certificate ${cert.directory}/fullchain.pem;
|
listen [::]:636 ssl;
|
||||||
ssl_certificate_key ${cert.directory}/key.pem;
|
ssl_certificate ${cert.directory}/fullchain.pem;
|
||||||
ssl_trusted_certificate ${cert.directory}/chain.pem;
|
ssl_certificate_key ${cert.directory}/key.pem;
|
||||||
proxy_pass ${proxyPass};
|
ssl_trusted_certificate ${cert.directory}/chain.pem;
|
||||||
${proxySsl}
|
proxy_pass ${proxyPass};
|
||||||
}
|
${proxySsl}
|
||||||
'')
|
}
|
||||||
]);
|
'')
|
||||||
|
]);
|
||||||
};
|
};
|
||||||
|
|
||||||
networking.firewall = {
|
networking.firewall = {
|
||||||
|
|
|
||||||
|
|
@ -70,10 +70,12 @@ in {
|
||||||
plex-external = mkIf (access.externalPort != null) {
|
plex-external = mkIf (access.externalPort != null) {
|
||||||
serverName = mkDefault access.domain;
|
serverName = mkDefault access.domain;
|
||||||
default = mkDefault true;
|
default = mkDefault true;
|
||||||
listen = map (addr: {
|
listen =
|
||||||
inherit addr;
|
map (addr: {
|
||||||
port = access.externalPort;
|
inherit addr;
|
||||||
}) nginx.defaultListenAddresses;
|
port = access.externalPort;
|
||||||
|
})
|
||||||
|
nginx.defaultListenAddresses;
|
||||||
locations."/" = location;
|
locations."/" = location;
|
||||||
inherit extraConfig;
|
inherit extraConfig;
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -14,10 +14,11 @@
|
||||||
proxyPass = "https://reisen.local.${config.networking.domain}:8006/";
|
proxyPass = "https://reisen.local.${config.networking.domain}:8006/";
|
||||||
unencrypted = mkSnakeOil {
|
unencrypted = mkSnakeOil {
|
||||||
name = "prox-local-cert";
|
name = "prox-local-cert";
|
||||||
domain = singleton "prox.local.${config.networking.domain}"
|
domain =
|
||||||
|
singleton "prox.local.${config.networking.domain}"
|
||||||
++ optional tailscale.enable "prox.tail.${config.networking.domain}";
|
++ optional tailscale.enable "prox.tail.${config.networking.domain}";
|
||||||
};
|
};
|
||||||
sslHost = { config, ... }: {
|
sslHost = {config, ...}: {
|
||||||
sslCertificate = mkIf (!config.enableACME && config.useACMEHost == null) unencrypted.fullchain;
|
sslCertificate = mkIf (!config.enableACME && config.useACMEHost == null) unencrypted.fullchain;
|
||||||
sslCertificateKey = mkIf (!config.enableACME && config.useACMEHost == null) unencrypted.key;
|
sslCertificateKey = mkIf (!config.enableACME && config.useACMEHost == null) unencrypted.key;
|
||||||
};
|
};
|
||||||
|
|
@ -91,24 +92,30 @@ in {
|
||||||
${access.domain} = {
|
${access.domain} = {
|
||||||
inherit locations extraConfig;
|
inherit locations extraConfig;
|
||||||
};
|
};
|
||||||
${access.localDomain} = mkMerge [ {
|
${access.localDomain} = mkMerge [
|
||||||
inherit (virtualHosts.${access.domain}) useACMEHost;
|
{
|
||||||
local.enable = mkDefault true;
|
inherit (virtualHosts.${access.domain}) useACMEHost;
|
||||||
forceSSL = mkDefault true;
|
local.enable = mkDefault true;
|
||||||
locations."/" = {
|
forceSSL = mkDefault true;
|
||||||
proxy.websocket.enable = true;
|
locations."/" = {
|
||||||
inherit proxyPass extraConfig;
|
proxy.websocket.enable = true;
|
||||||
};
|
inherit proxyPass extraConfig;
|
||||||
} sslHost ];
|
};
|
||||||
${access.tailDomain} = mkIf tailscale.enable (mkMerge [ {
|
}
|
||||||
inherit (virtualHosts.${access.domain}) useACMEHost;
|
sslHost
|
||||||
addSSL = mkDefault true;
|
];
|
||||||
local.enable = mkDefault true;
|
${access.tailDomain} = mkIf tailscale.enable (mkMerge [
|
||||||
locations."/" = {
|
{
|
||||||
proxy.websocket.enable = true;
|
inherit (virtualHosts.${access.domain}) useACMEHost;
|
||||||
inherit proxyPass extraConfig;
|
addSSL = mkDefault true;
|
||||||
};
|
local.enable = mkDefault true;
|
||||||
} sslHost ]);
|
locations."/" = {
|
||||||
|
proxy.websocket.enable = true;
|
||||||
|
inherit proxyPass extraConfig;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
sslHost
|
||||||
|
]);
|
||||||
};
|
};
|
||||||
|
|
||||||
config.sops.secrets.access-proxmox = {
|
config.sops.secrets.access-proxmox = {
|
||||||
|
|
|
||||||
|
|
@ -10,9 +10,11 @@
|
||||||
in {
|
in {
|
||||||
options.services.nginx.access.unifi = with lib.types; {
|
options.services.nginx.access.unifi = with lib.types; {
|
||||||
global = {
|
global = {
|
||||||
enable = mkEnableOption "global access" // {
|
enable =
|
||||||
default = access.useACMEHost != null;
|
mkEnableOption "global access"
|
||||||
};
|
// {
|
||||||
|
default = access.useACMEHost != null;
|
||||||
|
};
|
||||||
management = mkEnableOption "global management port access";
|
management = mkEnableOption "global management port access";
|
||||||
};
|
};
|
||||||
host = mkOption {
|
host = mkOption {
|
||||||
|
|
@ -59,11 +61,13 @@ in {
|
||||||
};
|
};
|
||||||
in {
|
in {
|
||||||
"${access.domain}@management" = mkIf access.global.management {
|
"${access.domain}@management" = mkIf access.global.management {
|
||||||
listen = map (addr: {
|
listen =
|
||||||
inherit addr;
|
map (addr: {
|
||||||
port = access.managementPort;
|
inherit addr;
|
||||||
ssl = true;
|
port = access.managementPort;
|
||||||
}) nginx.defaultListenAddresses;
|
ssl = true;
|
||||||
|
})
|
||||||
|
nginx.defaultListenAddresses;
|
||||||
serverName = access.domain;
|
serverName = access.domain;
|
||||||
default = mkDefault true;
|
default = mkDefault true;
|
||||||
forceSSL = mkDefault true;
|
forceSSL = mkDefault true;
|
||||||
|
|
@ -81,7 +85,7 @@ in {
|
||||||
inherit locations extraConfig;
|
inherit locations extraConfig;
|
||||||
};
|
};
|
||||||
${access.localDomain} = {
|
${access.localDomain} = {
|
||||||
serverAliases = mkIf tailscale.enable [ access.tailDomain ];
|
serverAliases = mkIf tailscale.enable [access.tailDomain];
|
||||||
useACMEHost = mkDefault access.useACMEHost;
|
useACMEHost = mkDefault access.useACMEHost;
|
||||||
addSSL = mkDefault (access.useACMEHost != null);
|
addSSL = mkDefault (access.useACMEHost != null);
|
||||||
kTLS = mkDefault true;
|
kTLS = mkDefault true;
|
||||||
|
|
@ -91,7 +95,7 @@ in {
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
config.networking.firewall = {
|
config.networking.firewall = {
|
||||||
interfaces.local.allowedTCPPorts = [ access.managementPort ];
|
interfaces.local.allowedTCPPorts = [access.managementPort];
|
||||||
allowedTCPPorts = mkIf access.global.management [ access.managementPort ];
|
allowedTCPPorts = mkIf access.global.management [access.managementPort];
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -35,8 +35,12 @@ in {
|
||||||
access.vouch = mkIf cfg.enable {
|
access.vouch = mkIf cfg.enable {
|
||||||
url = let
|
url = let
|
||||||
inherit (cfg.settings.vouch) listen;
|
inherit (cfg.settings.vouch) listen;
|
||||||
host = if listen == "0.0.0.0" || listen == "[::]" then "localhost" else listen;
|
host =
|
||||||
in mkOptionDefault "http://${host}:${toString cfg.port}";
|
if listen == "0.0.0.0" || listen == "[::]"
|
||||||
|
then "localhost"
|
||||||
|
else listen;
|
||||||
|
in
|
||||||
|
mkOptionDefault "http://${host}:${toString cfg.port}";
|
||||||
};
|
};
|
||||||
virtualHosts = let
|
virtualHosts = let
|
||||||
locations = {
|
locations = {
|
||||||
|
|
@ -46,17 +50,20 @@ in {
|
||||||
proxy_redirect default;
|
proxy_redirect default;
|
||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
"/validate" = { config, ... }: {
|
"/validate" = {config, ...}: {
|
||||||
proxyPass = mkDefault (access.url + "/validate");
|
proxyPass = mkDefault (access.url + "/validate");
|
||||||
recommendedProxySettings = mkDefault false;
|
recommendedProxySettings = mkDefault false;
|
||||||
extraConfig = if config.local.trusted then ''
|
extraConfig =
|
||||||
if ($http_x_host = ''') {
|
if config.local.trusted
|
||||||
set $http_x_host $host;
|
then ''
|
||||||
}
|
if ($http_x_host = ''') {
|
||||||
proxy_set_header Host $http_x_host;
|
set $http_x_host $host;
|
||||||
'' else ''
|
}
|
||||||
proxy_set_header Host $host;
|
proxy_set_header Host $http_x_host;
|
||||||
'';
|
''
|
||||||
|
else ''
|
||||||
|
proxy_set_header Host $host;
|
||||||
|
'';
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
localLocations = kanidmDomain: {
|
localLocations = kanidmDomain: {
|
||||||
|
|
|
||||||
|
|
@ -2,8 +2,7 @@
|
||||||
config,
|
config,
|
||||||
lib,
|
lib,
|
||||||
...
|
...
|
||||||
}:
|
}: let
|
||||||
let
|
|
||||||
inherit (lib.options) mkOption;
|
inherit (lib.options) mkOption;
|
||||||
inherit (lib.modules) mkIf mkDefault mkOptionDefault;
|
inherit (lib.modules) mkIf mkDefault mkOptionDefault;
|
||||||
cfg = config.services.zigbee2mqtt;
|
cfg = config.services.zigbee2mqtt;
|
||||||
|
|
@ -46,7 +45,7 @@ in {
|
||||||
locations."/" = location;
|
locations."/" = location;
|
||||||
};
|
};
|
||||||
${access.localDomain} = {
|
${access.localDomain} = {
|
||||||
serverAliases = mkIf config.services.tailscale.enable [ access.tailDomain ];
|
serverAliases = mkIf config.services.tailscale.enable [access.tailDomain];
|
||||||
local.enable = true;
|
local.enable = true;
|
||||||
locations."/" = location;
|
locations."/" = location;
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -8,18 +8,30 @@
|
||||||
inherit (lib.lists) head optional;
|
inherit (lib.lists) head optional;
|
||||||
cfg = config.security.acme;
|
cfg = config.security.acme;
|
||||||
mkHash = with builtins; val: substring 0 20 (hashString "sha256" val);
|
mkHash = with builtins; val: substring 0 20 (hashString "sha256" val);
|
||||||
mkAccountHash = { server ? null, keyType, email }: mkHash "${toString server} ${keyType} ${email}";
|
mkAccountHash = {
|
||||||
|
server ? null,
|
||||||
|
keyType,
|
||||||
|
email,
|
||||||
|
}:
|
||||||
|
mkHash "${toString server} ${keyType} ${email}";
|
||||||
mkHost = server: head (splitString "/" (removePrefix "https://" server));
|
mkHost = server: head (splitString "/" (removePrefix "https://" server));
|
||||||
mkAccountDir = { server ? null, email, keyType }: concatStringsSep "/" ([
|
mkAccountDir = {
|
||||||
accountDirRoot
|
server ? null,
|
||||||
(mkAccountHash { inherit server email keyType; })
|
email,
|
||||||
] ++ optional (server != null) (
|
keyType,
|
||||||
mkHost server
|
}:
|
||||||
) ++ [
|
concatStringsSep "/" ([
|
||||||
cfg.defaults.email
|
accountDirRoot
|
||||||
]);
|
(mkAccountHash {inherit server email keyType;})
|
||||||
|
]
|
||||||
|
++ optional (server != null) (
|
||||||
|
mkHost server
|
||||||
|
)
|
||||||
|
++ [
|
||||||
|
cfg.defaults.email
|
||||||
|
]);
|
||||||
accountDirRoot = "/var/lib/acme/.lego/accounts";
|
accountDirRoot = "/var/lib/acme/.lego/accounts";
|
||||||
addr = concatStringsSep "@" [ "gensokyo" "arcn.mx" ];
|
addr = concatStringsSep "@" ["gensokyo" "arcn.mx"];
|
||||||
in {
|
in {
|
||||||
security.acme = {
|
security.acme = {
|
||||||
acceptTerms = true;
|
acceptTerms = true;
|
||||||
|
|
@ -35,16 +47,19 @@ in {
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
sops.secrets = let
|
sops.secrets = let
|
||||||
accountDir = mkAccountDir { inherit (cfg.defaults) server email keyType; };
|
accountDir = mkAccountDir {inherit (cfg.defaults) server email keyType;};
|
||||||
acmeSecret = {
|
acmeSecret = {
|
||||||
sopsFile = mkDefault ./secrets/acme.yaml;
|
sopsFile = mkDefault ./secrets/acme.yaml;
|
||||||
owner = "acme";
|
owner = "acme";
|
||||||
group = "nginx";
|
group = "nginx";
|
||||||
};
|
};
|
||||||
in {
|
in {
|
||||||
acme_account_key = mkMerge [ acmeSecret {
|
acme_account_key = mkMerge [
|
||||||
path = accountDir + "/keys/${cfg.defaults.email}.key";
|
acmeSecret
|
||||||
} ];
|
{
|
||||||
|
path = accountDir + "/keys/${cfg.defaults.email}.key";
|
||||||
|
}
|
||||||
|
];
|
||||||
acme_cloudflare_email = acmeSecret;
|
acme_cloudflare_email = acmeSecret;
|
||||||
acme_cloudflare_token = acmeSecret;
|
acme_cloudflare_token = acmeSecret;
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -26,7 +26,7 @@ in {
|
||||||
daemon = "avahi-daemon.service";
|
daemon = "avahi-daemon.service";
|
||||||
avahi-daemon-watchdog = pkgs.writeShellScript "avahi-daemon-watchdog" ''
|
avahi-daemon-watchdog = pkgs.writeShellScript "avahi-daemon-watchdog" ''
|
||||||
set -eu
|
set -eu
|
||||||
export PATH="$PATH:${makeBinPath [ config.systemd.package pkgs.coreutils pkgs.gnugrep ]}"
|
export PATH="$PATH:${makeBinPath [config.systemd.package pkgs.coreutils pkgs.gnugrep]}"
|
||||||
while read -r line; do
|
while read -r line; do
|
||||||
if [[ $line = *"Host name conflict"* ]]; then
|
if [[ $line = *"Host name conflict"* ]]; then
|
||||||
if systemctl is-active ${daemon} > /dev/null; then
|
if systemctl is-active ${daemon} > /dev/null; then
|
||||||
|
|
@ -38,22 +38,23 @@ in {
|
||||||
fi
|
fi
|
||||||
done < <(journalctl -o cat -feu ${daemon} | grep -F 'Host name conflict, retrying with ')
|
done < <(journalctl -o cat -feu ${daemon} | grep -F 'Host name conflict, retrying with ')
|
||||||
'';
|
'';
|
||||||
in mkIf (cfg.enable && cfg.publish.enable) {
|
in
|
||||||
avahi-daemon = {
|
mkIf (cfg.enable && cfg.publish.enable) {
|
||||||
serviceConfig = {
|
avahi-daemon = {
|
||||||
inherit RestartSec;
|
serviceConfig = {
|
||||||
|
inherit RestartSec;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
avahi-daemon-watchdog = {
|
||||||
|
wantedBy = [daemon];
|
||||||
|
serviceConfig = {
|
||||||
|
Type = mkOptionDefault "exec";
|
||||||
|
ExecStart = [
|
||||||
|
"${avahi-daemon-watchdog}"
|
||||||
|
];
|
||||||
|
Restart = mkOptionDefault "on-failure";
|
||||||
|
RestartSec = mkOptionDefault RestartSec;
|
||||||
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
avahi-daemon-watchdog = {
|
|
||||||
wantedBy = [ daemon ];
|
|
||||||
serviceConfig = {
|
|
||||||
Type = mkOptionDefault "exec";
|
|
||||||
ExecStart = [
|
|
||||||
"${avahi-daemon-watchdog}"
|
|
||||||
];
|
|
||||||
Restart = mkOptionDefault "on-failure";
|
|
||||||
RestartSec = mkOptionDefault RestartSec;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -28,12 +28,11 @@
|
||||||
|
|
||||||
users.users.root = {
|
users.users.root = {
|
||||||
hashedPassword = "$6$i28yOXoo$/WokLdKds5ZHtJHcuyGrH2WaDQQk/2Pj0xRGLgS8UcmY2oMv3fw2j/85PRpsJJwCB2GBRYRK5LlvdTleHd3mB.";
|
hashedPassword = "$6$i28yOXoo$/WokLdKds5ZHtJHcuyGrH2WaDQQk/2Pj0xRGLgS8UcmY2oMv3fw2j/85PRpsJJwCB2GBRYRK5LlvdTleHd3mB.";
|
||||||
openssh.authorizedKeys.keys = with pkgs.lib;
|
openssh.authorizedKeys.keys = with pkgs.lib; (concatLists (mapAttrsToList
|
||||||
(concatLists (mapAttrsToList
|
(name: user:
|
||||||
(name: user:
|
if elem "wheel" user.extraGroups
|
||||||
if elem "wheel" user.extraGroups
|
then user.openssh.authorizedKeys.keys
|
||||||
then user.openssh.authorizedKeys.keys
|
else [])
|
||||||
else [])
|
config.users.users));
|
||||||
config.users.users));
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,3 @@
|
||||||
{ config, ... }: {
|
{config, ...}: {
|
||||||
documentation.nixos.enable = false;
|
documentation.nixos.enable = false;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,7 @@
|
||||||
{ config, pkgs, ... }:
|
|
||||||
|
|
||||||
{
|
{
|
||||||
environment.systemPackages = [ pkgs.buildPackages.buildPackages.kitty.terminfo ];
|
config,
|
||||||
|
pkgs,
|
||||||
|
...
|
||||||
|
}: {
|
||||||
|
environment.systemPackages = [pkgs.buildPackages.buildPackages.kitty.terminfo];
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,10 @@
|
||||||
{ config, options, lib, inputs, ... }: let
|
{
|
||||||
|
config,
|
||||||
|
options,
|
||||||
|
lib,
|
||||||
|
inputs,
|
||||||
|
...
|
||||||
|
}: let
|
||||||
inherit (lib.modules) mkIf mkDefault;
|
inherit (lib.modules) mkIf mkDefault;
|
||||||
hasSops = options ? sops;
|
hasSops = options ? sops;
|
||||||
in {
|
in {
|
||||||
|
|
@ -25,7 +31,8 @@ in {
|
||||||
experimental-features = lib.optional (lib.versionAtLeast config.nix.package.version "2.4") "nix-command flakes";
|
experimental-features = lib.optional (lib.versionAtLeast config.nix.package.version "2.4") "nix-command flakes";
|
||||||
substituters = [
|
substituters = [
|
||||||
"https://gensokyo-infrastructure.cachix.org"
|
"https://gensokyo-infrastructure.cachix.org"
|
||||||
"https://arc.cachix.org" "https://kittywitch.cachix.org"
|
"https://arc.cachix.org"
|
||||||
|
"https://kittywitch.cachix.org"
|
||||||
"https://nix-community.cachix.org"
|
"https://nix-community.cachix.org"
|
||||||
];
|
];
|
||||||
trusted-public-keys = [
|
trusted-public-keys = [
|
||||||
|
|
@ -36,7 +43,7 @@ in {
|
||||||
"ryantrinkle.com-1:JJiAKaRv9mWgpVAz8dwewnZe0AzzEAzPkagE9SP5NWI="
|
"ryantrinkle.com-1:JJiAKaRv9mWgpVAz8dwewnZe0AzzEAzPkagE9SP5NWI="
|
||||||
];
|
];
|
||||||
auto-optimise-store = true;
|
auto-optimise-store = true;
|
||||||
trusted-users = [ "root" "@wheel" ];
|
trusted-users = ["root" "@wheel"];
|
||||||
};
|
};
|
||||||
extraOptions = mkIf hasSops ''
|
extraOptions = mkIf hasSops ''
|
||||||
!include ${config.sops.secrets.github-access-token-public.path}
|
!include ${config.sops.secrets.github-access-token-public.path}
|
||||||
|
|
@ -47,7 +54,11 @@ in {
|
||||||
options = mkDefault "--delete-older-than 7d";
|
options = mkDefault "--delete-older-than 7d";
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
${if hasSops then "sops" else null}.secrets.github-access-token-public = {
|
${
|
||||||
|
if hasSops
|
||||||
|
then "sops"
|
||||||
|
else null
|
||||||
|
}.secrets.github-access-token-public = {
|
||||||
sopsFile = mkDefault ../secrets/nix.yaml;
|
sopsFile = mkDefault ../secrets/nix.yaml;
|
||||||
group = mkDefault "users";
|
group = mkDefault "users";
|
||||||
mode = mkDefault "0644";
|
mode = mkDefault "0644";
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,4 @@
|
||||||
{
|
{inputs, ...}: {
|
||||||
inputs,
|
|
||||||
...
|
|
||||||
}: {
|
|
||||||
nixpkgs = {
|
nixpkgs = {
|
||||||
overlays = [
|
overlays = [
|
||||||
inputs.arcexprs.overlays.default
|
inputs.arcexprs.overlays.default
|
||||||
|
|
|
||||||
|
|
@ -1,11 +1,16 @@
|
||||||
{ config, lib, pkgs, ... }:
|
|
||||||
|
|
||||||
{
|
{
|
||||||
environment.systemPackages = with pkgs; [
|
config,
|
||||||
neofetch
|
lib,
|
||||||
smartmontools
|
pkgs,
|
||||||
hddtemp
|
...
|
||||||
lm_sensors
|
}: {
|
||||||
gnupg
|
environment.systemPackages = with pkgs;
|
||||||
] ++ (lib.optional config.programs.gnupg.agent.enable pinentry-curses);
|
[
|
||||||
|
neofetch
|
||||||
|
smartmontools
|
||||||
|
hddtemp
|
||||||
|
lm_sensors
|
||||||
|
gnupg
|
||||||
|
]
|
||||||
|
++ (lib.optional config.programs.gnupg.agent.enable pinentry-curses);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,4 @@
|
||||||
{ config, ... }:
|
{config, ...}: {
|
||||||
|
|
||||||
{
|
|
||||||
programs.zsh = {
|
programs.zsh = {
|
||||||
enable = true;
|
enable = true;
|
||||||
enableCompletion = true;
|
enableCompletion = true;
|
||||||
|
|
|
||||||
|
|
@ -29,7 +29,7 @@ in {
|
||||||
};
|
};
|
||||||
networking.firewall = {
|
networking.firewall = {
|
||||||
allowedTCPPorts = [publicPort];
|
allowedTCPPorts = [publicPort];
|
||||||
interfaces.local.allowedTCPPorts = [ 22 ];
|
interfaces.local.allowedTCPPorts = [22];
|
||||||
};
|
};
|
||||||
|
|
||||||
programs.mosh.enable = true;
|
programs.mosh.enable = true;
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,3 @@
|
||||||
{ config, ... }: {
|
{config, ...}: {
|
||||||
services.tzupdate.enable = true;
|
services.tzupdate.enable = true;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,4 @@
|
||||||
{ pkgs, ... }:
|
{pkgs, ...}: {
|
||||||
|
|
||||||
{
|
|
||||||
environment.systemPackages = [
|
environment.systemPackages = [
|
||||||
pkgs.buildPackages.rxvt-unicode-unwrapped.terminfo
|
pkgs.buildPackages.rxvt-unicode-unwrapped.terminfo
|
||||||
];
|
];
|
||||||
|
|
|
||||||
|
|
@ -1,12 +1,9 @@
|
||||||
{
|
{lib, ...}: let
|
||||||
lib,
|
|
||||||
...
|
|
||||||
}: let
|
|
||||||
inherit (lib.modules) mkDefault;
|
inherit (lib.modules) mkDefault;
|
||||||
in {
|
in {
|
||||||
services.bazarr = {
|
services.bazarr = {
|
||||||
enable = mkDefault true;
|
enable = mkDefault true;
|
||||||
listenPort = mkDefault 6767;
|
listenPort = mkDefault 6767;
|
||||||
};
|
};
|
||||||
users.users.bazarr.extraGroups = [ "kyuuto" ];
|
users.users.bazarr.extraGroups = ["kyuuto"];
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -14,26 +14,30 @@ in {
|
||||||
protocol = mkDefault "cloudflare";
|
protocol = mkDefault "cloudflare";
|
||||||
zone = mkDefault config.networking.domain;
|
zone = mkDefault config.networking.domain;
|
||||||
use = "no";
|
use = "no";
|
||||||
domains = [ ];
|
domains = [];
|
||||||
extraConfig = mkMerge [ (mkIf config.networking.enableIPv6 ''
|
extraConfig = mkMerge [
|
||||||
usev6=webv6, webv6=https://ipv6.nsupdate.info/myip
|
(mkIf config.networking.enableIPv6 ''
|
||||||
'') ''
|
usev6=webv6, webv6=https://ipv6.nsupdate.info/myip
|
||||||
usev4=webv4, webv4=https://ipv4.nsupdate.info/myip
|
'')
|
||||||
max-interval=1d
|
''
|
||||||
'' ];
|
usev4=webv4, webv4=https://ipv4.nsupdate.info/myip
|
||||||
|
max-interval=1d
|
||||||
|
''
|
||||||
|
];
|
||||||
passwordFile = config.sops.secrets.dyndns_cloudflare_token.path;
|
passwordFile = config.sops.secrets.dyndns_cloudflare_token.path;
|
||||||
};
|
};
|
||||||
systemd.services.ddclient = mkIf cfg.enable rec {
|
systemd.services.ddclient = mkIf cfg.enable rec {
|
||||||
wants = [ "network-online.target" ];
|
wants = ["network-online.target"];
|
||||||
after = wants;
|
after = wants;
|
||||||
wantedBy = mkForce [ ];
|
wantedBy = mkForce [];
|
||||||
serviceConfig = {
|
serviceConfig = {
|
||||||
ExecStartPre = let
|
ExecStartPre = let
|
||||||
inherit (config.systemd.services.ddclient.serviceConfig) RuntimeDirectory;
|
inherit (config.systemd.services.ddclient.serviceConfig) RuntimeDirectory;
|
||||||
prestart-domains = pkgs.writeShellScript "ddclient-prestart-domains" ''
|
prestart-domains = pkgs.writeShellScript "ddclient-prestart-domains" ''
|
||||||
cat ${config.sops.secrets.dyndns_ddclient_domains.path} >> /run/${RuntimeDirectory}/ddclient.conf
|
cat ${config.sops.secrets.dyndns_ddclient_domains.path} >> /run/${RuntimeDirectory}/ddclient.conf
|
||||||
'';
|
'';
|
||||||
in mkAfter [ "!${prestart-domains}" ];
|
in
|
||||||
|
mkAfter ["!${prestart-domains}"];
|
||||||
TimeoutStartSec = 90;
|
TimeoutStartSec = 90;
|
||||||
LogFilterPatterns = [
|
LogFilterPatterns = [
|
||||||
"~WARNING"
|
"~WARNING"
|
||||||
|
|
|
||||||
|
|
@ -42,28 +42,32 @@ in {
|
||||||
parent = builtins.dirOf downloadDir;
|
parent = builtins.dirOf downloadDir;
|
||||||
hasCompletedSubdir = completedDir != null && hasPrefix parent completedDir;
|
hasCompletedSubdir = completedDir != null && hasPrefix parent completedDir;
|
||||||
completedSubdir = removePrefix parent completedDir;
|
completedSubdir = removePrefix parent completedDir;
|
||||||
download = if hasCompletedSubdir then {
|
download =
|
||||||
path = parent;
|
if hasCompletedSubdir
|
||||||
subdirectories = [
|
then {
|
||||||
(builtins.baseNameOf downloadDir)
|
path = parent;
|
||||||
completedSubdir
|
subdirectories = [
|
||||||
];
|
(builtins.baseNameOf downloadDir)
|
||||||
} else {
|
completedSubdir
|
||||||
path = downloadDir;
|
];
|
||||||
};
|
}
|
||||||
|
else {
|
||||||
|
path = downloadDir;
|
||||||
|
};
|
||||||
completed = {
|
completed = {
|
||||||
path = cfg.config.move_completed_path;
|
path = cfg.config.move_completed_path;
|
||||||
};
|
};
|
||||||
in mkIf cfg.enable (mkAfter [
|
in
|
||||||
download
|
mkIf cfg.enable (mkAfter [
|
||||||
(mkIf (completedDir != null && !hasCompletedSubdir) completed)
|
download
|
||||||
]);
|
(mkIf (completedDir != null && !hasCompletedSubdir) completed)
|
||||||
|
]);
|
||||||
users.users = mkIf cfg.enable (mkMerge [
|
users.users = mkIf cfg.enable (mkMerge [
|
||||||
{
|
{
|
||||||
deluge.extraGroups = [ "kyuuto" ];
|
deluge.extraGroups = ["kyuuto"];
|
||||||
}
|
}
|
||||||
(mkIf mediatomb.enable {
|
(mkIf mediatomb.enable {
|
||||||
${mediatomb.user}.extraGroups = [ cfg.group ];
|
${mediatomb.user}.extraGroups = [cfg.group];
|
||||||
})
|
})
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -14,9 +14,11 @@
|
||||||
genZoneAttrs = prefix: f: listToAttrs (genZone (i: nameValuePair "${prefix}${toString i}" (f i)));
|
genZoneAttrs = prefix: f: listToAttrs (genZone (i: nameValuePair "${prefix}${toString i}" (f i)));
|
||||||
in {
|
in {
|
||||||
options.services.github-runner-zone = with lib.types; {
|
options.services.github-runner-zone = with lib.types; {
|
||||||
enable = mkEnableOption "github-runners.zone" // {
|
enable =
|
||||||
default = true;
|
mkEnableOption "github-runners.zone"
|
||||||
};
|
// {
|
||||||
|
default = true;
|
||||||
|
};
|
||||||
targetName = mkOption {
|
targetName = mkOption {
|
||||||
type = str;
|
type = str;
|
||||||
default = "github-runner-zone";
|
default = "github-runner-zone";
|
||||||
|
|
@ -64,7 +66,7 @@ in {
|
||||||
enable = mkDefault true;
|
enable = mkDefault true;
|
||||||
ephemeral = mkDefault cfg.ephemeral;
|
ephemeral = mkDefault cfg.ephemeral;
|
||||||
replace = mkDefault true;
|
replace = mkDefault true;
|
||||||
extraLabels = [ "ubuntu-latest" ];
|
extraLabels = ["ubuntu-latest"];
|
||||||
tokenFile = mkDefault config.sops.secrets.github-runner-gensokyo-zone-token.path;
|
tokenFile = mkDefault config.sops.secrets.github-runner-gensokyo-zone-token.path;
|
||||||
url = mkDefault "https://github.com/gensokyo-zone";
|
url = mkDefault "https://github.com/gensokyo-zone";
|
||||||
group = mkDefault cfg.group;
|
group = mkDefault cfg.group;
|
||||||
|
|
@ -73,9 +75,9 @@ in {
|
||||||
};
|
};
|
||||||
networkNamespace.name = mkIf (cfg.networkNamespace.name != null) (mkDefault cfg.networkNamespace.name);
|
networkNamespace.name = mkIf (cfg.networkNamespace.name != null) (mkDefault cfg.networkNamespace.name);
|
||||||
serviceSettings = {
|
serviceSettings = {
|
||||||
wantedBy = [ "${cfg.targetName}.target" ];
|
wantedBy = ["${cfg.targetName}.target"];
|
||||||
unitConfig = {
|
unitConfig = {
|
||||||
StopPropagatedFrom = [ "${cfg.targetName}.target" ];
|
StopPropagatedFrom = ["${cfg.targetName}.target"];
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
serviceOverrides = mkIf (!cfg.dynamicUser) {
|
serviceOverrides = mkIf (!cfg.dynamicUser) {
|
||||||
|
|
@ -88,15 +90,16 @@ in {
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
services.github-runners = genZoneAttrs cfg.keyPrefix (i: mkMerge [
|
services.github-runners = genZoneAttrs cfg.keyPrefix (i:
|
||||||
(unmerged.merge cfg.runnerSettings)
|
mkMerge [
|
||||||
{
|
(unmerged.merge cfg.runnerSettings)
|
||||||
name = mkDefault "${cfg.namePrefix}${toString i}";
|
{
|
||||||
user = mkIf (cfg.userPrefix != null) (
|
name = mkDefault "${cfg.namePrefix}${toString i}";
|
||||||
mkDefault "${cfg.userPrefix}${toString i}"
|
user = mkIf (cfg.userPrefix != null) (
|
||||||
);
|
mkDefault "${cfg.userPrefix}${toString i}"
|
||||||
}
|
);
|
||||||
]);
|
}
|
||||||
|
]);
|
||||||
|
|
||||||
systemd = mkIf cfg.enable {
|
systemd = mkIf cfg.enable {
|
||||||
services.nix-daemon = mkIf cfg.enable {
|
services.nix-daemon = mkIf cfg.enable {
|
||||||
|
|
@ -106,13 +109,13 @@ in {
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
targets.${cfg.targetName} = {
|
targets.${cfg.targetName} = {
|
||||||
wantedBy = [ "multi-user.target" ];
|
wantedBy = ["multi-user.target"];
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
users = mkIf cfg.enable {
|
users = mkIf cfg.enable {
|
||||||
groups = mkIf (cfg.group != null) {
|
groups = mkIf (cfg.group != null) {
|
||||||
${toString cfg.group} = { };
|
${toString cfg.group} = {};
|
||||||
};
|
};
|
||||||
users = mkMerge [
|
users = mkMerge [
|
||||||
(mkIf (!cfg.dynamicUser) (genZoneAttrs cfg.userPrefix (i: {
|
(mkIf (!cfg.dynamicUser) (genZoneAttrs cfg.userPrefix (i: {
|
||||||
|
|
|
||||||
|
|
@ -85,17 +85,19 @@ in {
|
||||||
];
|
];
|
||||||
entity_config = {};
|
entity_config = {};
|
||||||
};
|
};
|
||||||
homekit = [ {
|
homekit = [
|
||||||
name = "Tewi";
|
{
|
||||||
port = 21063;
|
name = "Tewi";
|
||||||
filter = let
|
port = 21063;
|
||||||
inherit (cfg.config) google_assistant;
|
filter = let
|
||||||
in {
|
inherit (cfg.config) google_assistant;
|
||||||
include_domains = google_assistant.exposed_domains;
|
in {
|
||||||
include_entities = "!include homekit_include_entities.yaml";
|
include_domains = google_assistant.exposed_domains;
|
||||||
};
|
include_entities = "!include homekit_include_entities.yaml";
|
||||||
entity_config = "!include homekit_entity_config.yaml";
|
};
|
||||||
} ];
|
entity_config = "!include homekit_entity_config.yaml";
|
||||||
|
}
|
||||||
|
];
|
||||||
tts = [
|
tts = [
|
||||||
{
|
{
|
||||||
platform = "google_translate";
|
platform = "google_translate";
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,8 @@
|
||||||
{ config, lib, ... }: let
|
{
|
||||||
|
config,
|
||||||
|
lib,
|
||||||
|
...
|
||||||
|
}: let
|
||||||
inherit (lib.modules) mkIf mkDefault mkForce;
|
inherit (lib.modules) mkIf mkDefault mkForce;
|
||||||
cfg = config.services.invidious;
|
cfg = config.services.invidious;
|
||||||
in {
|
in {
|
||||||
|
|
@ -6,12 +10,13 @@ in {
|
||||||
commonSecret = {
|
commonSecret = {
|
||||||
sopsFile = ./secrets/invidious.yaml;
|
sopsFile = ./secrets/invidious.yaml;
|
||||||
owner = "invidious";
|
owner = "invidious";
|
||||||
}; in {
|
};
|
||||||
|
in {
|
||||||
invidious_db_password = commonSecret;
|
invidious_db_password = commonSecret;
|
||||||
invidious_hmac_key = commonSecret;
|
invidious_hmac_key = commonSecret;
|
||||||
};
|
};
|
||||||
|
|
||||||
networking.firewall.interfaces.local.allowedTCPPorts = [ cfg.port ];
|
networking.firewall.interfaces.local.allowedTCPPorts = [cfg.port];
|
||||||
users.groups.invidious = {};
|
users.groups.invidious = {};
|
||||||
users.users.invidious = {
|
users.users.invidious = {
|
||||||
isSystemUser = true;
|
isSystemUser = true;
|
||||||
|
|
|
||||||
|
|
@ -34,7 +34,7 @@ in {
|
||||||
};
|
};
|
||||||
gameLibraries = mkOption {
|
gameLibraries = mkOption {
|
||||||
type = listOf str;
|
type = listOf str;
|
||||||
default = [ "PC" ];
|
default = ["PC"];
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -42,10 +42,19 @@ in {
|
||||||
kyuuto = {
|
kyuuto = {
|
||||||
gameLibraries = [
|
gameLibraries = [
|
||||||
"PC"
|
"PC"
|
||||||
"Wii" "Gamecube" "N64" "SNES" "NES"
|
"Wii"
|
||||||
"NDS" "GBA" "GBC"
|
"Gamecube"
|
||||||
"PS3" "PS2" "PS1"
|
"N64"
|
||||||
"PSVita" "PSP"
|
"SNES"
|
||||||
|
"NES"
|
||||||
|
"NDS"
|
||||||
|
"GBA"
|
||||||
|
"GBC"
|
||||||
|
"PS3"
|
||||||
|
"PS2"
|
||||||
|
"PS1"
|
||||||
|
"PSVita"
|
||||||
|
"PSP"
|
||||||
"Genesis"
|
"Genesis"
|
||||||
];
|
];
|
||||||
};
|
};
|
||||||
|
|
@ -74,7 +83,7 @@ in {
|
||||||
{
|
{
|
||||||
${cfg.shareDir} = mkMerge [
|
${cfg.shareDir} = mkMerge [
|
||||||
shared
|
shared
|
||||||
{ group = "peeps"; }
|
{group = "peeps";}
|
||||||
];
|
];
|
||||||
${cfg.transferDir} = shared;
|
${cfg.transferDir} = shared;
|
||||||
${cfg.libraryDir} = shared;
|
${cfg.libraryDir} = shared;
|
||||||
|
|
@ -108,28 +117,34 @@ in {
|
||||||
};
|
};
|
||||||
|
|
||||||
users = let
|
users = let
|
||||||
mapId = id: if config.proxmoxLXC.privileged or true then 100000 + id else id;
|
mapId = id:
|
||||||
|
if config.proxmoxLXC.privileged or true
|
||||||
|
then 100000 + id
|
||||||
|
else id;
|
||||||
mkDummyUsers = {
|
mkDummyUsers = {
|
||||||
name,
|
name,
|
||||||
group ? name,
|
group ? name,
|
||||||
enable ? !config.services.${serviceName}.enable, serviceName ? name,
|
enable ? !config.services.${serviceName}.enable,
|
||||||
|
serviceName ? name,
|
||||||
uid ? config.ids.uids.${name},
|
uid ? config.ids.uids.${name},
|
||||||
gid ? config.ids.gids.${group},
|
gid ? config.ids.gids.${group},
|
||||||
}: mkIf enable {
|
}:
|
||||||
users.${name} = {
|
mkIf enable {
|
||||||
group = mkIf (group != null) group;
|
users.${name} = {
|
||||||
uid = mapId uid;
|
group = mkIf (group != null) group;
|
||||||
isSystemUser = true;
|
uid = mapId uid;
|
||||||
|
isSystemUser = true;
|
||||||
|
};
|
||||||
|
groups.${group} = {
|
||||||
|
gid = mapId gid;
|
||||||
|
};
|
||||||
};
|
};
|
||||||
groups.${group} = {
|
in
|
||||||
gid = mapId gid;
|
mkMerge [
|
||||||
};
|
(mkDummyUsers {name = "deluge";})
|
||||||
};
|
(mkDummyUsers {name = "radarr";})
|
||||||
in mkMerge [
|
(mkDummyUsers {name = "sonarr";})
|
||||||
(mkDummyUsers { name = "deluge"; })
|
(mkDummyUsers {name = "lidarr";})
|
||||||
(mkDummyUsers { name = "radarr"; })
|
];
|
||||||
(mkDummyUsers { name = "sonarr"; })
|
|
||||||
(mkDummyUsers { name = "lidarr"; })
|
|
||||||
];
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,3 @@
|
||||||
|
|
||||||
{
|
{
|
||||||
config,
|
config,
|
||||||
lib,
|
lib,
|
||||||
|
|
|
||||||
|
|
@ -10,9 +10,11 @@
|
||||||
cfg = kyuuto.opl;
|
cfg = kyuuto.opl;
|
||||||
in {
|
in {
|
||||||
options.kyuuto.opl = with lib.types; {
|
options.kyuuto.opl = with lib.types; {
|
||||||
enable = mkEnableOption "hosting" // {
|
enable =
|
||||||
default = config.services.samba.enable;
|
mkEnableOption "hosting"
|
||||||
};
|
// {
|
||||||
|
default = config.services.samba.enable;
|
||||||
|
};
|
||||||
user = mkOption {
|
user = mkOption {
|
||||||
type = str;
|
type = str;
|
||||||
default = "opl";
|
default = "opl";
|
||||||
|
|
@ -39,22 +41,25 @@ in {
|
||||||
};
|
};
|
||||||
shares.opl = let
|
shares.opl = let
|
||||||
inherit (config.networking.access) cidrForNetwork;
|
inherit (config.networking.access) cidrForNetwork;
|
||||||
localAddrs = cidrForNetwork.loopback.all ++ cidrForNetwork.local.all
|
localAddrs =
|
||||||
|
cidrForNetwork.loopback.all
|
||||||
|
++ cidrForNetwork.local.all
|
||||||
++ lib.optionals config.services.tailscale.enable cidrForNetwork.tail.all;
|
++ lib.optionals config.services.tailscale.enable cidrForNetwork.tail.all;
|
||||||
in mkIf cfg.enable {
|
in
|
||||||
comment = "Kyuuto Media OPL";
|
mkIf cfg.enable {
|
||||||
path = cfg.rootDir;
|
comment = "Kyuuto Media OPL";
|
||||||
writeable = true;
|
path = cfg.rootDir;
|
||||||
browseable = true;
|
writeable = true;
|
||||||
public = false;
|
browseable = true;
|
||||||
"valid users" = [
|
public = false;
|
||||||
cfg.user
|
"valid users" = [
|
||||||
"@kyuuto-peeps"
|
cfg.user
|
||||||
];
|
"@kyuuto-peeps"
|
||||||
"strict sync" = false;
|
];
|
||||||
"keepalive" = 0;
|
"strict sync" = false;
|
||||||
"hosts allow" = localAddrs;
|
"keepalive" = 0;
|
||||||
};
|
"hosts allow" = localAddrs;
|
||||||
|
};
|
||||||
};
|
};
|
||||||
services.tmpfiles = let
|
services.tmpfiles = let
|
||||||
setupFiles = {
|
setupFiles = {
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,3 @@
|
||||||
|
|
||||||
{
|
{
|
||||||
config,
|
config,
|
||||||
lib,
|
lib,
|
||||||
|
|
@ -9,17 +8,21 @@
|
||||||
inherit (config.networking.access) cidrForNetwork;
|
inherit (config.networking.access) cidrForNetwork;
|
||||||
inherit (config) kyuuto;
|
inherit (config) kyuuto;
|
||||||
cfg = config.services.samba;
|
cfg = config.services.samba;
|
||||||
localAddrs = cidrForNetwork.loopback.all ++ cidrForNetwork.local.all
|
localAddrs =
|
||||||
|
cidrForNetwork.loopback.all
|
||||||
|
++ cidrForNetwork.local.all
|
||||||
++ optionals config.services.tailscale.enable cidrForNetwork.tail.all;
|
++ optionals config.services.tailscale.enable cidrForNetwork.tail.all;
|
||||||
guestUsers = mkIf cfg.guest.enable [ cfg.guest.user ];
|
guestUsers = mkIf cfg.guest.enable [cfg.guest.user];
|
||||||
kyuuto-media = {
|
kyuuto-media = {
|
||||||
"create mask" = "0664";
|
"create mask" = "0664";
|
||||||
"force directory mode" = "3000";
|
"force directory mode" = "3000";
|
||||||
"directory mask" = "7775";
|
"directory mask" = "7775";
|
||||||
};
|
};
|
||||||
kyuuto-library = kyuuto-media // {
|
kyuuto-library =
|
||||||
"acl group control" = true;
|
kyuuto-media
|
||||||
};
|
// {
|
||||||
|
"acl group control" = true;
|
||||||
|
};
|
||||||
in {
|
in {
|
||||||
services.samba = {
|
services.samba = {
|
||||||
usershare = {
|
usershare = {
|
||||||
|
|
@ -35,7 +38,7 @@ in {
|
||||||
public = true;
|
public = true;
|
||||||
"valid users" = mkMerge [
|
"valid users" = mkMerge [
|
||||||
guestUsers
|
guestUsers
|
||||||
[ "@peeps" ]
|
["@peeps"]
|
||||||
];
|
];
|
||||||
#"guest only" = true;
|
#"guest only" = true;
|
||||||
"hosts allow" = localAddrs;
|
"hosts allow" = localAddrs;
|
||||||
|
|
@ -54,10 +57,10 @@ in {
|
||||||
public = true;
|
public = true;
|
||||||
"valid users" = mkMerge [
|
"valid users" = mkMerge [
|
||||||
guestUsers
|
guestUsers
|
||||||
[ "@kyuuto-peeps" ]
|
["@kyuuto-peeps"]
|
||||||
];
|
];
|
||||||
"read list" = guestUsers;
|
"read list" = guestUsers;
|
||||||
"write list" = [ "@kyuuto-peeps" ];
|
"write list" = ["@kyuuto-peeps"];
|
||||||
"hosts allow" = localAddrs;
|
"hosts allow" = localAddrs;
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
|
|
@ -69,7 +72,7 @@ in {
|
||||||
writeable = true;
|
writeable = true;
|
||||||
public = false;
|
public = false;
|
||||||
browseable = false;
|
browseable = false;
|
||||||
"valid users" = [ "@kyuuto-peeps" ];
|
"valid users" = ["@kyuuto-peeps"];
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
kyuuto-media = mkMerge [
|
kyuuto-media = mkMerge [
|
||||||
|
|
@ -80,7 +83,7 @@ in {
|
||||||
writeable = true;
|
writeable = true;
|
||||||
public = false;
|
public = false;
|
||||||
browseable = false;
|
browseable = false;
|
||||||
"valid users" = [ "@kyuuto-peeps" ];
|
"valid users" = ["@kyuuto-peeps"];
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
shared = {
|
shared = {
|
||||||
|
|
@ -89,7 +92,7 @@ in {
|
||||||
writeable = true;
|
writeable = true;
|
||||||
public = false;
|
public = false;
|
||||||
browseable = false;
|
browseable = false;
|
||||||
"valid users" = [ "@peeps" ];
|
"valid users" = ["@peeps"];
|
||||||
"create mask" = "0775";
|
"create mask" = "0775";
|
||||||
"force create mode" = "0010";
|
"force create mode" = "0010";
|
||||||
"force directory mode" = "2000";
|
"force directory mode" = "2000";
|
||||||
|
|
@ -99,7 +102,7 @@ in {
|
||||||
writeable = true;
|
writeable = true;
|
||||||
browseable = true;
|
browseable = true;
|
||||||
public = false;
|
public = false;
|
||||||
"valid users" = [ "@peeps" ];
|
"valid users" = ["@peeps"];
|
||||||
"create mask" = "0664";
|
"create mask" = "0664";
|
||||||
"force directory mode" = "5000";
|
"force directory mode" = "5000";
|
||||||
"directory mask" = "7775";
|
"directory mask" = "7775";
|
||||||
|
|
@ -108,5 +111,5 @@ in {
|
||||||
};
|
};
|
||||||
|
|
||||||
# give guest users proper access to the transfer share
|
# give guest users proper access to the transfer share
|
||||||
users.users.guest.extraGroups = [ "kyuuto" ];
|
users.users.guest.extraGroups = ["kyuuto"];
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -2,5 +2,5 @@ _: {
|
||||||
services.lidarr = {
|
services.lidarr = {
|
||||||
enable = true;
|
enable = true;
|
||||||
};
|
};
|
||||||
users.users.lidarr.extraGroups = [ "kyuuto" ];
|
users.users.lidarr.extraGroups = ["kyuuto"];
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -12,6 +12,6 @@ in {
|
||||||
uuid = mkDefault "082fd344-bf69-5b72-a68f-a5a4d88e76b2";
|
uuid = mkDefault "082fd344-bf69-5b72-a68f-a5a4d88e76b2";
|
||||||
};
|
};
|
||||||
config.users.users = mkIf cfg.enable {
|
config.users.users = mkIf cfg.enable {
|
||||||
${cfg.user}.extraGroups = [ "kyuuto" ];
|
${cfg.user}.extraGroups = ["kyuuto"];
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -29,9 +29,9 @@ in {
|
||||||
idmapd.settings = {
|
idmapd.settings = {
|
||||||
General.Domain = mkDefault config.networking.domain;
|
General.Domain = mkDefault config.networking.domain;
|
||||||
Translation.GSS-Methods = concatStringsSep "," (
|
Translation.GSS-Methods = concatStringsSep "," (
|
||||||
[ "static" ]
|
["static"]
|
||||||
++ optional enableLdap "umich_ldap"
|
++ optional enableLdap "umich_ldap"
|
||||||
++ [ "nsswitch" ]
|
++ ["nsswitch"]
|
||||||
);
|
);
|
||||||
Static = {
|
Static = {
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,4 @@
|
||||||
{
|
{lib, ...}: let
|
||||||
lib,
|
|
||||||
...
|
|
||||||
}: let
|
|
||||||
inherit (lib.modules) mkDefault;
|
inherit (lib.modules) mkDefault;
|
||||||
in {
|
in {
|
||||||
services.ombi = {
|
services.ombi = {
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,9 @@
|
||||||
{config, lib, pkgs, ...}: let
|
{
|
||||||
|
config,
|
||||||
|
lib,
|
||||||
|
pkgs,
|
||||||
|
...
|
||||||
|
}: let
|
||||||
inherit (lib.modules) mkIf mkForce mkDefault;
|
inherit (lib.modules) mkIf mkForce mkDefault;
|
||||||
inherit (lib.strings) escapeShellArg;
|
inherit (lib.strings) escapeShellArg;
|
||||||
cfg = config.services.plex;
|
cfg = config.services.plex;
|
||||||
|
|
@ -21,9 +26,10 @@ in {
|
||||||
fi
|
fi
|
||||||
${pkgs.coreutils}/bin/ln -sfT ../Cache "$PLEX_DATADIR/Plex Media Server/Cache"
|
${pkgs.coreutils}/bin/ln -sfT ../Cache "$PLEX_DATADIR/Plex Media Server/Cache"
|
||||||
'';
|
'';
|
||||||
in mkForce [
|
in
|
||||||
''!${preStartScript}''
|
mkForce [
|
||||||
];
|
''!${preStartScript}''
|
||||||
|
];
|
||||||
# KillMode = "mixed" doesn't behave as expected...
|
# KillMode = "mixed" doesn't behave as expected...
|
||||||
TimeoutStopSec = 5;
|
TimeoutStopSec = 5;
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -8,7 +8,7 @@
|
||||||
in {
|
in {
|
||||||
services.postgresql = {
|
services.postgresql = {
|
||||||
enable = mkDefault true;
|
enable = mkDefault true;
|
||||||
ensureDatabases = ["hass" "invidious" "dex"];
|
ensureDatabases = ["hass" "invidious" "dex" "keycloak"];
|
||||||
ensureUsers = [
|
ensureUsers = [
|
||||||
{
|
{
|
||||||
name = "hass";
|
name = "hass";
|
||||||
|
|
@ -25,6 +25,11 @@ in {
|
||||||
ensureDBOwnership = true;
|
ensureDBOwnership = true;
|
||||||
authentication.local.allow = true;
|
authentication.local.allow = true;
|
||||||
}
|
}
|
||||||
|
{
|
||||||
|
name = "keycloak";
|
||||||
|
ensureDBOwnership = true;
|
||||||
|
authentication.local.allow = true;
|
||||||
|
}
|
||||||
];
|
];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -3,5 +3,5 @@ _: {
|
||||||
enable = true;
|
enable = true;
|
||||||
};
|
};
|
||||||
|
|
||||||
users.users.radarr.extraGroups = [ "kyuuto" ];
|
users.users.radarr.extraGroups = ["kyuuto"];
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -2,5 +2,5 @@ _: {
|
||||||
services.readarr = {
|
services.readarr = {
|
||||||
enable = true;
|
enable = true;
|
||||||
};
|
};
|
||||||
users.users.readarr.extraGroups = [ "kyuuto" ];
|
users.users.readarr.extraGroups = ["kyuuto"];
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,4 @@
|
||||||
{
|
{lib, ...}: let
|
||||||
lib,
|
|
||||||
...
|
|
||||||
}: let
|
|
||||||
inherit (lib) mkDefault;
|
inherit (lib) mkDefault;
|
||||||
in {
|
in {
|
||||||
services.kanidm.serverSettings.db_fs_type = mkDefault "zfs";
|
services.kanidm.serverSettings.db_fs_type = mkDefault "zfs";
|
||||||
|
|
|
||||||
|
|
@ -6,8 +6,8 @@
|
||||||
inherit (lib.modules) mkIf mkDefault;
|
inherit (lib.modules) mkIf mkDefault;
|
||||||
inherit (lib.lists) any;
|
inherit (lib.lists) any;
|
||||||
inherit (lib.strings) hasInfix concatMapStringsSep splitString;
|
inherit (lib.strings) hasInfix concatMapStringsSep splitString;
|
||||||
cfg = config.services.samba;
|
cfg = config.services.samba;
|
||||||
hasIpv4 = any (hasInfix ".") config.systemd.network.networks.eth0.address or [ ];
|
hasIpv4 = any (hasInfix ".") config.systemd.network.networks.eth0.address or [];
|
||||||
in {
|
in {
|
||||||
services.samba = {
|
services.samba = {
|
||||||
enable = mkDefault true;
|
enable = mkDefault true;
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
postgresql-init: ENC[AES256_GCM,data:fW9g0WKVHTO9blqlEXLJejyQUqC3na/Xh6Il2GNfuX6c2LfRjfFSeour4qt2envtPO+WanGl+ueE1AMck5t02TjqrN4a6DsQpAIGFVE7L4ajp/13Gp308pY4Xu7OKHjkGpzVBATKgLDZkoU8yAkqKZCBEU3d4xegp8pgnsLSpb/LndKiITjhTe2IJOSkIJd9twSsra8JQWRYCW8WjZZ9YOe5nqtU+56b/zb0CxVhhln0jU/3e5s7pfblfou2TnvnFezswjNTIGftNU1wOaxSCA==,iv:hjKNZ4EbPpl5YIcaWJYLKJzxuOmMjL4AtfUeL4vm5QA=,tag:mYcu4cRUnZeLgeISfaxXPQ==,type:str]
|
postgresql-init: ENC[AES256_GCM,data:lbkeMv6PZgB7tEl4VbIYX9VUAgJ6Kcj0jLNyyqxJJcVJPjo1lF2d/i5bFnU1/6aJ2T7ftMW4hefYgrnIMdKXxPPfrHftaEMhl9bfJIsuX2I1CXAasZOhpsmg9Wf2cvXuVYIlqTVssg+3EKW0ejCMdX6OfGdAXvBlio1DQs7YrUc+BjDiEuAUAaaYbz67EYY3dpYQixQGl/8G2w7S897uCXpc1oOh6vbGY4Nl+GGQ7B5xrrbYcdATwfGyYlZYSlIv8feDsLv7Rt+w3o4tTAxcz+8qZ7KZ6sIsu/nUoYeqoT9MJ8uRpWccXKcBVAFSEooUIHUEBA/QsGizAXBgzCnyLDvuv3DOquo2xeMg0kWM8zsF1f9YRyUKqQ==,iv:RKIvggRZlPocygabF0iKNBThBRFG5rlzrIvGjjt7s0o=,tag:U/XUDJs5J8lHB9BJ5/0fFA==,type:str]
|
||||||
sops:
|
sops:
|
||||||
shamir_threshold: 1
|
shamir_threshold: 1
|
||||||
kms: []
|
kms: []
|
||||||
|
|
@ -33,8 +33,8 @@ sops:
|
||||||
a3l3bUx5NzdqUGd1TEpGY3UvQWt4TU0KB4MAjvI43FaOiGhWTkwPpeMMiAnX4v3L
|
a3l3bUx5NzdqUGd1TEpGY3UvQWt4TU0KB4MAjvI43FaOiGhWTkwPpeMMiAnX4v3L
|
||||||
rLZDdc/vegF10FKTNJdxdq1E7ccMaV1KwjQkJoOJnWe6teKLjGOFkA==
|
rLZDdc/vegF10FKTNJdxdq1E7ccMaV1KwjQkJoOJnWe6teKLjGOFkA==
|
||||||
-----END AGE ENCRYPTED FILE-----
|
-----END AGE ENCRYPTED FILE-----
|
||||||
lastmodified: "2024-02-19T03:46:45Z"
|
lastmodified: "2024-03-13T21:46:56Z"
|
||||||
mac: ENC[AES256_GCM,data:FMzWnFllHDpgIoDJIKS7aWpUSVNH0+ij0+AIzl3qtjeuzmUUluDtEes6yAR8g/Daq+nxiMRnsse0HfUqZeT0rVVEpqvQB4Wsoq+G9qj8mmEUrHJzjU5rSDWV8uf5F1BsZbvF13VBulh/RWsmWjps+z6vyJ7uM1QjS3hSF2k3hSM=,iv:tpH8XjoTtNzPOOIosObpsvOAzZO7ywK9xjow3xTOJqY=,tag:BTzezbH9zZDZBzy1x+AJ1w==,type:str]
|
mac: ENC[AES256_GCM,data:rEtRHX3PH1B+uoR82lDH3ACKHPbhxy+y7B9YgR6TzPSU4yIaTSqSK51eLJZoUtW6UTl6QDcTrsKDA8lGu9M/Ohfx8ayp6rkX63H/hkl0h6YaQmWDAQoNAAEWqfJ9r8O8tKKpE6qF/rw4c4KpuA5ONufOl9qj1KSgFzz0WHaKtWk=,iv:TUBAe62dmF6FAjZOPaxwzQjWL21TdWQG0YyuXJGgtk8=,tag:dewWivfnZO30Np2gajwLIw==,type:str]
|
||||||
pgp:
|
pgp:
|
||||||
- created_at: "2024-01-19T19:08:55Z"
|
- created_at: "2024-01-19T19:08:55Z"
|
||||||
enc: |-
|
enc: |-
|
||||||
|
|
|
||||||
|
|
@ -2,5 +2,5 @@ _: {
|
||||||
services.sonarr = {
|
services.sonarr = {
|
||||||
enable = true;
|
enable = true;
|
||||||
};
|
};
|
||||||
users.users.sonarr.extraGroups = [ "kyuuto" ];
|
users.users.sonarr.extraGroups = ["kyuuto"];
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,13 @@
|
||||||
{ lib, inputs, ... }: with lib; {
|
{
|
||||||
|
lib,
|
||||||
|
inputs,
|
||||||
|
...
|
||||||
|
}:
|
||||||
|
with lib; {
|
||||||
imports = [
|
imports = [
|
||||||
inputs.sops-nix.nixosModules.sops
|
inputs.sops-nix.nixosModules.sops
|
||||||
];
|
];
|
||||||
sops = {
|
sops = {
|
||||||
age.sshKeyPaths = mkDefault [ "/etc/ssh/ssh_host_ed25519_key" ];
|
age.sshKeyPaths = mkDefault ["/etc/ssh/ssh_host_ed25519_key"];
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,4 @@
|
||||||
{
|
{lib, ...}: let
|
||||||
lib,
|
|
||||||
...
|
|
||||||
}: let
|
|
||||||
inherit (lib.modules) mkDefault;
|
inherit (lib.modules) mkDefault;
|
||||||
in {
|
in {
|
||||||
services.steam.accountSwitch = {
|
services.steam.accountSwitch = {
|
||||||
|
|
|
||||||
|
|
@ -1,15 +1,12 @@
|
||||||
{
|
{lib, ...}: let
|
||||||
lib,
|
|
||||||
...
|
|
||||||
}: let
|
|
||||||
inherit (lib.modules) mkDefault;
|
inherit (lib.modules) mkDefault;
|
||||||
in {
|
in {
|
||||||
services.steam.beatsaber = {
|
services.steam.beatsaber = {
|
||||||
enable = mkDefault true;
|
enable = mkDefault true;
|
||||||
defaultVersion = mkDefault "1.29.0";
|
defaultVersion = mkDefault "1.29.0";
|
||||||
versions = {
|
versions = {
|
||||||
"1.29.0" = { };
|
"1.29.0" = {};
|
||||||
"1.34.2" = { };
|
"1.34.2" = {};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
{ config, ... }: {
|
{config, ...}: {
|
||||||
services.syncthing = {
|
services.syncthing = {
|
||||||
enable = true;
|
enable = true;
|
||||||
relay.enable = true;
|
relay.enable = true;
|
||||||
|
|
|
||||||
|
|
@ -10,7 +10,8 @@ in {
|
||||||
enable = mkDefault true;
|
enable = mkDefault true;
|
||||||
user = mkDefault "root";
|
user = mkDefault "root";
|
||||||
mqtt = {
|
mqtt = {
|
||||||
url = mkDefault (if config.services.mosquitto.enable
|
url = mkDefault (
|
||||||
|
if config.services.mosquitto.enable
|
||||||
then "tcp://localhost:1883"
|
then "tcp://localhost:1883"
|
||||||
else "tcp://mqtt.local.${config.networking.domain}:1883"
|
else "tcp://mqtt.local.${config.networking.domain}:1883"
|
||||||
);
|
);
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,8 @@
|
||||||
{config, lib, ...}: let
|
{
|
||||||
|
config,
|
||||||
|
lib,
|
||||||
|
...
|
||||||
|
}: let
|
||||||
inherit (lib.modules) mkIf mkDefault;
|
inherit (lib.modules) mkIf mkDefault;
|
||||||
cfg = config.services.tautulli;
|
cfg = config.services.tautulli;
|
||||||
in {
|
in {
|
||||||
|
|
|
||||||
|
|
@ -1,22 +1,22 @@
|
||||||
{ config, ... }:
|
{config, ...}: {
|
||||||
|
users.users.arc = {name, ...}: {
|
||||||
{
|
|
||||||
users.users.arc = { name, ... }: {
|
|
||||||
uid = 8001;
|
uid = 8001;
|
||||||
isNormalUser = true;
|
isNormalUser = true;
|
||||||
autoSubUidGidRange = false;
|
autoSubUidGidRange = false;
|
||||||
group = name;
|
group = name;
|
||||||
extraGroups = [
|
extraGroups = [
|
||||||
"users" "peeps"
|
"users"
|
||||||
|
"peeps"
|
||||||
"kyuuto"
|
"kyuuto"
|
||||||
"steamaccount" "beatsaber"
|
"steamaccount"
|
||||||
|
"beatsaber"
|
||||||
"wheel"
|
"wheel"
|
||||||
];
|
];
|
||||||
openssh.authorizedKeys.keys = [
|
openssh.authorizedKeys.keys = [
|
||||||
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIJ8Z6briIboxIdedPGObEWB6QEQkvxKvnMW/UVU9t/ac mew-pgp"
|
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIJ8Z6briIboxIdedPGObEWB6QEQkvxKvnMW/UVU9t/ac mew-pgp"
|
||||||
];
|
];
|
||||||
};
|
};
|
||||||
users.groups.arc = { name, ... }: {
|
users.groups.arc = {name, ...}: {
|
||||||
gid = config.users.users.${name}.uid;
|
gid = config.users.users.${name}.uid;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,17 +1,16 @@
|
||||||
{ config, ... }:
|
{config, ...}: {
|
||||||
|
users.users.connieallure = {name, ...}: {
|
||||||
{
|
|
||||||
users.users.connieallure = { name, ... }: {
|
|
||||||
uid = 8003;
|
uid = 8003;
|
||||||
isNormalUser = true;
|
isNormalUser = true;
|
||||||
autoSubUidGidRange = false;
|
autoSubUidGidRange = false;
|
||||||
group = name;
|
group = name;
|
||||||
extraGroups = [
|
extraGroups = [
|
||||||
"users" "peeps"
|
"users"
|
||||||
|
"peeps"
|
||||||
"kyuuto"
|
"kyuuto"
|
||||||
];
|
];
|
||||||
};
|
};
|
||||||
users.groups.connieallure = { name, ... }: {
|
users.groups.connieallure = {name, ...}: {
|
||||||
gid = config.users.users.${name}.uid;
|
gid = config.users.users.${name}.uid;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,18 +1,18 @@
|
||||||
{ config, ... }:
|
{config, ...}: {
|
||||||
|
users.users.kaosubaloo = {name, ...}: {
|
||||||
{
|
|
||||||
users.users.kaosubaloo = { name, ... }: {
|
|
||||||
uid = 8002;
|
uid = 8002;
|
||||||
isNormalUser = true;
|
isNormalUser = true;
|
||||||
autoSubUidGidRange = false;
|
autoSubUidGidRange = false;
|
||||||
group = name;
|
group = name;
|
||||||
extraGroups = [
|
extraGroups = [
|
||||||
"users" "peeps"
|
"users"
|
||||||
|
"peeps"
|
||||||
"kyuuto"
|
"kyuuto"
|
||||||
"steamaccount" "beatsaber"
|
"steamaccount"
|
||||||
|
"beatsaber"
|
||||||
];
|
];
|
||||||
};
|
};
|
||||||
users.groups.kaosubaloo = { name, ... }: {
|
users.groups.kaosubaloo = {name, ...}: {
|
||||||
gid = config.users.users.${name}.uid;
|
gid = config.users.users.${name}.uid;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,25 +1,25 @@
|
||||||
{ config, ... }:
|
{config, ...}: {
|
||||||
|
users.users.kat = {name, ...}: {
|
||||||
{
|
|
||||||
users.users.kat = { name, ... }: {
|
|
||||||
uid = 8000;
|
uid = 8000;
|
||||||
isNormalUser = true;
|
isNormalUser = true;
|
||||||
autoSubUidGidRange = false;
|
autoSubUidGidRange = false;
|
||||||
group = name;
|
group = name;
|
||||||
extraGroups = [
|
extraGroups = [
|
||||||
"users" "peeps"
|
"users"
|
||||||
|
"peeps"
|
||||||
"kyuuto"
|
"kyuuto"
|
||||||
"steamaccount" "beatsaber"
|
"steamaccount"
|
||||||
|
"beatsaber"
|
||||||
"wheel"
|
"wheel"
|
||||||
];
|
];
|
||||||
openssh.authorizedKeys.keys = [
|
openssh.authorizedKeys.keys = [
|
||||||
"ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQCocjQqiDIvzq+Qu3jkf7FXw5piwtvZ1Mihw9cVjdVcsra3U2c9WYtYrA3rS50N3p00oUqQm9z1KUrvHzdE+03ZCrvaGdrtYVsaeoCuuvw7qxTQRbItTAEsfRcZLQ5c1v/57HNYNEsjVrt8VukMPRXWgl+lmzh37dd9w45cCY1QPi+JXQQ/4i9Vc3aWSe4X6PHOEMSBHxepnxm5VNHm4PObGcVbjBf0OkunMeztd1YYA9sEPyEK3b8IHxDl34e5t6NDLCIDz0N/UgzCxSxoz+YJ0feQuZtud/YLkuQcMxW2dSGvnJ0nYy7SA5DkW1oqcy6CGDndHl5StOlJ1IF9aGh0gGkx5SRrV7HOGvapR60RphKrR5zQbFFka99kvSQgOZqSB3CGDEQGHv8dXKXIFlzX78jjWDOBT67vA/M9BK9FS2iNnBF5x6shJ9SU5IK4ySxq8qvN7Us8emkN3pyO8yqgsSOzzJT1JmWUAx0tZWG/BwKcFBHfceAPQl6pwxx28TM3BTBRYdzPJLTkAy48y6iXW6UYdfAPlShy79IYjQtEThTuIiEzdzgYdros0x3PDniuAP0KOKMgbikr0gRa6zahPjf0qqBnHeLB6nHAfaVzI0aNbhOg2bdOueE1FX0x48sjKqjOpjlIfq4WeZp9REr2YHEsoLFOBfgId5P3BPtpBQ== yubikey5"
|
"ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQCocjQqiDIvzq+Qu3jkf7FXw5piwtvZ1Mihw9cVjdVcsra3U2c9WYtYrA3rS50N3p00oUqQm9z1KUrvHzdE+03ZCrvaGdrtYVsaeoCuuvw7qxTQRbItTAEsfRcZLQ5c1v/57HNYNEsjVrt8VukMPRXWgl+lmzh37dd9w45cCY1QPi+JXQQ/4i9Vc3aWSe4X6PHOEMSBHxepnxm5VNHm4PObGcVbjBf0OkunMeztd1YYA9sEPyEK3b8IHxDl34e5t6NDLCIDz0N/UgzCxSxoz+YJ0feQuZtud/YLkuQcMxW2dSGvnJ0nYy7SA5DkW1oqcy6CGDndHl5StOlJ1IF9aGh0gGkx5SRrV7HOGvapR60RphKrR5zQbFFka99kvSQgOZqSB3CGDEQGHv8dXKXIFlzX78jjWDOBT67vA/M9BK9FS2iNnBF5x6shJ9SU5IK4ySxq8qvN7Us8emkN3pyO8yqgsSOzzJT1JmWUAx0tZWG/BwKcFBHfceAPQl6pwxx28TM3BTBRYdzPJLTkAy48y6iXW6UYdfAPlShy79IYjQtEThTuIiEzdzgYdros0x3PDniuAP0KOKMgbikr0gRa6zahPjf0qqBnHeLB6nHAfaVzI0aNbhOg2bdOueE1FX0x48sjKqjOpjlIfq4WeZp9REr2YHEsoLFOBfgId5P3BPtpBQ== yubikey5"
|
||||||
"ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQDPsu3vNsvBb/G+wALpstD/DnoRZ3fipAs00jtl8rzDuv96RlS7AJr4aNvG6Pt2D9SYn2wVLaiw+76mz2gOycH9/N+VCvL4/0MN9uqj+7XIcxNRo0gHVOblmi2bOXcmGKh3eRwHj1xyDwRxo9WIuBEP2bPpDPz75OXRtEdlTgvky7siSguQxJu03cb0p9hNAYhUoohNXyWW2CjDCLUQVE1+QRVUzsKq3KkPy0cHYgmZC1gRSMQyKpMt72L5tayLz3Tp/zrshucc+QO5IJeZdqMxsNAcvALsysT1J5EqxZoYH9VpWLRhSgVD6Nvn853pycJAlXQxgOCpSD3/v/JbgUe5NE+ci0o7NMy5IiHUv2gQMRIEhwBHlRGwokUPL9upx0lsjaEiPya5xQqqDKRom87xytM778ANS5CuMdQMWg9qVbpHZUHMjA0QmNkjPgq71pUDXHk5L4mZuS8wVjyjnvlw68yIJuHEc8P7QiLcjvRHFS2L9Ck8NRmPDTQXlQi9kk6LmMyu6fdevR/kZL21b+xO1e2DMyxBbNDTot8luppiiL8adgUDMwptpIne7JCWB1o9NFCbXUVgwuCCYBif6pOGSc6bGo1JTAKMflRlcy6Mi3t5H0mR2lj/sCSTWwTlP5FM4aPIq08NvW6PeuK1bFJY9fIgTwVsUnbAKOhmsMt62w== cardno:12 078 454"
|
"ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQDPsu3vNsvBb/G+wALpstD/DnoRZ3fipAs00jtl8rzDuv96RlS7AJr4aNvG6Pt2D9SYn2wVLaiw+76mz2gOycH9/N+VCvL4/0MN9uqj+7XIcxNRo0gHVOblmi2bOXcmGKh3eRwHj1xyDwRxo9WIuBEP2bPpDPz75OXRtEdlTgvky7siSguQxJu03cb0p9hNAYhUoohNXyWW2CjDCLUQVE1+QRVUzsKq3KkPy0cHYgmZC1gRSMQyKpMt72L5tayLz3Tp/zrshucc+QO5IJeZdqMxsNAcvALsysT1J5EqxZoYH9VpWLRhSgVD6Nvn853pycJAlXQxgOCpSD3/v/JbgUe5NE+ci0o7NMy5IiHUv2gQMRIEhwBHlRGwokUPL9upx0lsjaEiPya5xQqqDKRom87xytM778ANS5CuMdQMWg9qVbpHZUHMjA0QmNkjPgq71pUDXHk5L4mZuS8wVjyjnvlw68yIJuHEc8P7QiLcjvRHFS2L9Ck8NRmPDTQXlQi9kk6LmMyu6fdevR/kZL21b+xO1e2DMyxBbNDTot8luppiiL8adgUDMwptpIne7JCWB1o9NFCbXUVgwuCCYBif6pOGSc6bGo1JTAKMflRlcy6Mi3t5H0mR2lj/sCSTWwTlP5FM4aPIq08NvW6PeuK1bFJY9fIgTwVsUnbAKOhmsMt62w== cardno:12 078 454"
|
||||||
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAII74JrgGsDQ6r7tD7+k3ykxXV7DpeeFRscPMxrBsDPhz kat@goliath"
|
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAII74JrgGsDQ6r7tD7+k3ykxXV7DpeeFRscPMxrBsDPhz kat@goliath"
|
||||||
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIDkeBFF4xxZgeURLzNHcvUFxImmkQ3pxXtpj3mtSyHXB kat@koishi"
|
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIDkeBFF4xxZgeURLzNHcvUFxImmkQ3pxXtpj3mtSyHXB kat@koishi"
|
||||||
];
|
];
|
||||||
};
|
};
|
||||||
users.groups.kat = { name, ... }: {
|
users.groups.kat = {name, ...}: {
|
||||||
gid = config.users.users.${name}.uid;
|
gid = config.users.users.${name}.uid;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,17 +1,19 @@
|
||||||
{inputs, system}: {
|
{
|
||||||
|
inputs,
|
||||||
|
system,
|
||||||
|
}: {
|
||||||
pkgs = import inputs.nixpkgs {
|
pkgs = import inputs.nixpkgs {
|
||||||
inherit system;
|
inherit system;
|
||||||
overlays =
|
overlays = [
|
||||||
[
|
inputs.deploy-rs.overlay
|
||||||
inputs.deploy-rs.overlay
|
inputs.arcexprs.overlays.default
|
||||||
inputs.arcexprs.overlays.default
|
(final: prev: {
|
||||||
(final: prev: {
|
jemalloc =
|
||||||
jemalloc =
|
if final.hostPlatform != "aarch64-darwin"
|
||||||
if final.hostPlatform != "aarch64-darwin"
|
then prev.jemalloc
|
||||||
then prev.jemalloc
|
else null;
|
||||||
else null;
|
})
|
||||||
})
|
];
|
||||||
];
|
|
||||||
config = {
|
config = {
|
||||||
allowUnfree = true;
|
allowUnfree = true;
|
||||||
allowBroken = true;
|
allowBroken = true;
|
||||||
|
|
|
||||||
|
|
@ -12,7 +12,7 @@
|
||||||
export NF_CONFIG_ROOT=''${NF_CONFIG_ROOT-${toString ../.}}
|
export NF_CONFIG_ROOT=''${NF_CONFIG_ROOT-${toString ../.}}
|
||||||
'';
|
'';
|
||||||
exportsSsh = ''
|
exportsSsh = ''
|
||||||
export PATH="${makeBinPath [ packages.nf-hostname packages.nf-sshopts ]}:$PATH"
|
export PATH="${makeBinPath [packages.nf-hostname packages.nf-sshopts]}:$PATH"
|
||||||
'';
|
'';
|
||||||
exportsFmtNix = ''
|
exportsFmtNix = ''
|
||||||
NF_NIX_BLACKLIST_DIRS=(${string.concatMapSep " " string.escapeShellArg fmt.nix.blacklistDirs})
|
NF_NIX_BLACKLIST_DIRS=(${string.concatMapSep " " string.escapeShellArg fmt.nix.blacklistDirs})
|
||||||
|
|
@ -20,11 +20,16 @@
|
||||||
NF_NIX_WHITELIST_FILES=(${string.concatMapSep " " string.escapeShellArg fmt.nix.whitelist})
|
NF_NIX_WHITELIST_FILES=(${string.concatMapSep " " string.escapeShellArg fmt.nix.whitelist})
|
||||||
'';
|
'';
|
||||||
output = {
|
output = {
|
||||||
inherit (pkgs.buildPackages)
|
inherit
|
||||||
terraform tflint
|
(pkgs.buildPackages)
|
||||||
alejandra deadnix statix
|
terraform
|
||||||
ssh-to-age jq
|
tflint
|
||||||
;
|
alejandra
|
||||||
|
deadnix
|
||||||
|
statix
|
||||||
|
ssh-to-age
|
||||||
|
jq
|
||||||
|
;
|
||||||
inherit (inputs.deploy-rs.packages.${system}) deploy-rs;
|
inherit (inputs.deploy-rs.packages.${system}) deploy-rs;
|
||||||
nf-deploy = pkgs.writeShellScriptBin "nf-deploy" ''
|
nf-deploy = pkgs.writeShellScriptBin "nf-deploy" ''
|
||||||
${exports}
|
${exports}
|
||||||
|
|
@ -52,26 +57,27 @@
|
||||||
INPUT_INFRA_CT_CONFIG = reisen + "/bin/ct-config.sh";
|
INPUT_INFRA_CT_CONFIG = reisen + "/bin/ct-config.sh";
|
||||||
};
|
};
|
||||||
inputVars = set.mapToValues (key: path: ''${key}="$(base64 -w0 < ${path})"'') inputAttrs;
|
inputVars = set.mapToValues (key: path: ''${key}="$(base64 -w0 < ${path})"'') inputAttrs;
|
||||||
in pkgs.writeShellScriptBin "nf-setup-node" ''
|
in
|
||||||
${exports}
|
pkgs.writeShellScriptBin "nf-setup-node" ''
|
||||||
NF_SETUP_INPUTS=(
|
${exports}
|
||||||
${string.intercalate "\n" inputVars}
|
NF_SETUP_INPUTS=(
|
||||||
)
|
${string.intercalate "\n" inputVars}
|
||||||
source ${../ci/setup.sh}
|
)
|
||||||
'';
|
source ${../ci/setup.sh}
|
||||||
|
'';
|
||||||
nf-hostname = pkgs.writeShellScriptBin "nf-hostname" ''
|
nf-hostname = pkgs.writeShellScriptBin "nf-hostname" ''
|
||||||
${exports}
|
${exports}
|
||||||
source ${../ci/hostname.sh}
|
source ${../ci/hostname.sh}
|
||||||
'';
|
'';
|
||||||
nf-sshopts = pkgs.writeShellScriptBin "nf-sshopts" ''
|
nf-sshopts = pkgs.writeShellScriptBin "nf-sshopts" ''
|
||||||
${exports}
|
${exports}
|
||||||
export PATH="$PATH:${makeBinPath [ pkgs.jq ]}"
|
export PATH="$PATH:${makeBinPath [pkgs.jq]}"
|
||||||
source ${../ci/sshopts.sh}
|
source ${../ci/sshopts.sh}
|
||||||
'';
|
'';
|
||||||
nf-sops-keyscan = pkgs.writeShellScriptBin "nf-sops-keyscan" ''
|
nf-sops-keyscan = pkgs.writeShellScriptBin "nf-sops-keyscan" ''
|
||||||
${exports}
|
${exports}
|
||||||
${exportsSsh}
|
${exportsSsh}
|
||||||
export PATH="$PATH:${makeBinPath [ pkgs.ssh-to-age ]}"
|
export PATH="$PATH:${makeBinPath [pkgs.ssh-to-age]}"
|
||||||
source ${../ci/sops-keyscan.sh}
|
source ${../ci/sops-keyscan.sh}
|
||||||
'';
|
'';
|
||||||
nf-ssh = pkgs.writeShellScriptBin "nf-ssh" ''
|
nf-ssh = pkgs.writeShellScriptBin "nf-ssh" ''
|
||||||
|
|
@ -94,39 +100,39 @@
|
||||||
'';
|
'';
|
||||||
nf-generate = pkgs.writeShellScriptBin "nf-generate" ''
|
nf-generate = pkgs.writeShellScriptBin "nf-generate" ''
|
||||||
${exports}
|
${exports}
|
||||||
export PATH="$PATH:${makeBinPath [ pkgs.jq ]}"
|
export PATH="$PATH:${makeBinPath [pkgs.jq]}"
|
||||||
source ${../ci/generate.sh}
|
source ${../ci/generate.sh}
|
||||||
'';
|
'';
|
||||||
nf-statix = pkgs.writeShellScriptBin "nf-statix" ''
|
nf-statix = pkgs.writeShellScriptBin "nf-statix" ''
|
||||||
${exports}
|
${exports}
|
||||||
export PATH="${makeBinPath [ packages.statix ]}:$PATH"
|
export PATH="${makeBinPath [packages.statix]}:$PATH"
|
||||||
source ${../ci/statix.sh}
|
source ${../ci/statix.sh}
|
||||||
'';
|
'';
|
||||||
nf-deadnix = pkgs.writeShellScriptBin "nf-deadnix" ''
|
nf-deadnix = pkgs.writeShellScriptBin "nf-deadnix" ''
|
||||||
${exports}
|
${exports}
|
||||||
${exportsFmtNix}
|
${exportsFmtNix}
|
||||||
export PATH="${makeBinPath [ packages.deadnix pkgs.findutils ]}:$PATH"
|
export PATH="${makeBinPath [packages.deadnix pkgs.findutils]}:$PATH"
|
||||||
source ${../ci/deadnix.sh}
|
source ${../ci/deadnix.sh}
|
||||||
'';
|
'';
|
||||||
nf-alejandra = pkgs.writeShellScriptBin "nf-alejandra" ''
|
nf-alejandra = pkgs.writeShellScriptBin "nf-alejandra" ''
|
||||||
${exports}
|
${exports}
|
||||||
${exportsFmtNix}
|
${exportsFmtNix}
|
||||||
export PATH="${makeBinPath [ packages.alejandra ]}:$PATH"
|
export PATH="${makeBinPath [packages.alejandra]}:$PATH"
|
||||||
source ${../ci/alejandra.sh}
|
source ${../ci/alejandra.sh}
|
||||||
'';
|
'';
|
||||||
nf-lint-tf = pkgs.writeShellScriptBin "nf-lint-tf" ''
|
nf-lint-tf = pkgs.writeShellScriptBin "nf-lint-tf" ''
|
||||||
${exports}
|
${exports}
|
||||||
export PATH="$PATH:${makeBinPath [ packages.tflint ]}"
|
export PATH="$PATH:${makeBinPath [packages.tflint]}"
|
||||||
source ${../ci/lint-tf.sh}
|
source ${../ci/lint-tf.sh}
|
||||||
'';
|
'';
|
||||||
nf-lint-nix = pkgs.writeShellScriptBin "nf-lint-nix" ''
|
nf-lint-nix = pkgs.writeShellScriptBin "nf-lint-nix" ''
|
||||||
${exports}
|
${exports}
|
||||||
export PATH="${makeBinPath [ packages.nf-statix packages.nf-deadnix ]}:$PATH"
|
export PATH="${makeBinPath [packages.nf-statix packages.nf-deadnix]}:$PATH"
|
||||||
source ${../ci/lint-nix.sh}
|
source ${../ci/lint-nix.sh}
|
||||||
'';
|
'';
|
||||||
nf-fmt-tf = pkgs.writeShellScriptBin "nf-fmt-tf" ''
|
nf-fmt-tf = pkgs.writeShellScriptBin "nf-fmt-tf" ''
|
||||||
${exports}
|
${exports}
|
||||||
export PATH="${makeBinPath [ packages.terraform ]}:$PATH"
|
export PATH="${makeBinPath [packages.terraform]}:$PATH"
|
||||||
source ${../ci/fmt-tf.sh}
|
source ${../ci/fmt-tf.sh}
|
||||||
'';
|
'';
|
||||||
nf-fmt-nix = pkgs.writeShellScriptBin "nf-fmt-nix" ''
|
nf-fmt-nix = pkgs.writeShellScriptBin "nf-fmt-nix" ''
|
||||||
|
|
@ -144,4 +150,5 @@
|
||||||
inherit (inputs) self;
|
inherit (inputs) self;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
in output
|
in
|
||||||
|
output
|
||||||
|
|
|
||||||
|
|
@ -5,26 +5,31 @@
|
||||||
}: let
|
}: let
|
||||||
inherit (lib.strings) concatStringsSep;
|
inherit (lib.strings) concatStringsSep;
|
||||||
inherit (lib.lists) toList head;
|
inherit (lib.lists) toList head;
|
||||||
in { domain, name }: runCommand name {
|
in
|
||||||
domains = concatStringsSep "," (toList domain);
|
{
|
||||||
domain = head (toList domain);
|
domain,
|
||||||
nativeBuildInputs = [ buildPackages.minica ];
|
name,
|
||||||
outputs = [ "out" "key" "cakey" "ca" "cert" "fullchain" ];
|
}:
|
||||||
} ''
|
runCommand name {
|
||||||
install -d $out
|
domains = concatStringsSep "," (toList domain);
|
||||||
minica \
|
domain = head (toList domain);
|
||||||
--ca-key ca.key.pem \
|
nativeBuildInputs = [buildPackages.minica];
|
||||||
--ca-cert ca.pem \
|
outputs = ["out" "key" "cakey" "ca" "cert" "fullchain"];
|
||||||
--domains "$domains"
|
} ''
|
||||||
mv ca.pem $ca
|
install -d $out
|
||||||
mv ca.key.pem $cakey
|
minica \
|
||||||
mv $domain/cert.pem $cert
|
--ca-key ca.key.pem \
|
||||||
mv $domain/key.pem $key
|
--ca-cert ca.pem \
|
||||||
cat $cert $ca > $fullchain
|
--domains "$domains"
|
||||||
|
mv ca.pem $ca
|
||||||
|
mv ca.key.pem $cakey
|
||||||
|
mv $domain/cert.pem $cert
|
||||||
|
mv $domain/key.pem $key
|
||||||
|
cat $cert $ca > $fullchain
|
||||||
|
|
||||||
ln -s $fullchain $out/fullchain.pem
|
ln -s $fullchain $out/fullchain.pem
|
||||||
ln -s $key $out/key.pem
|
ln -s $key $out/key.pem
|
||||||
ln -s $cakey $out/ca.key.pem
|
ln -s $cakey $out/ca.key.pem
|
||||||
ln -s $cert $out/cert.pem
|
ln -s $cert $out/cert.pem
|
||||||
ln -s $ca $out/ca.pem
|
ln -s $ca $out/ca.pem
|
||||||
''
|
''
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue