415 lines
13 KiB
Nix
Executable File
415 lines
13 KiB
Nix
Executable File
{ config, lib, ... }:
|
|
let
|
|
owner = config.users.users."nix-apps".name;
|
|
inherit (config.users.users."${owner}") group;
|
|
sopsFile = lib.snowfall.fs.get-file "secrets/nas-secrets.yaml";
|
|
|
|
sopsSettings = {
|
|
inherit owner group sopsFile;
|
|
mode = "0600";
|
|
};
|
|
in
|
|
{
|
|
# Permission modes are in octal representation (same as chmod),
|
|
# the digits represent: user|group|others
|
|
# 7 - full (rwx)
|
|
# 6 - read and write (rw-)
|
|
# 5 - read and execute (r-x)
|
|
# 4 - read only (r--)
|
|
# 3 - write and execute (-wx)
|
|
# 2 - write only (-w-)
|
|
# 1 - execute only (--x)
|
|
# 0 - none (---)
|
|
# Either a user id or group name representation of the secret owner
|
|
# It is recommended to get the user name from `config.users.users.<?name>.name` to avoid misconfiguration
|
|
# Either the group id or group name representation of the secret group
|
|
# It is recommended to get the group name from `config.users.users.<?name>.group` to avoid misconfiguration
|
|
sops = {
|
|
age.sshKeyPaths = [ "/etc/ssh/ssh_host_ed25519_key" ];
|
|
|
|
# ------------------------------
|
|
# Secrets
|
|
# ------------------------------
|
|
secrets = {
|
|
"jallen-nas/admin_password" = sopsSettings // {
|
|
neededForUsers = true;
|
|
};
|
|
|
|
"jallen-nas/nas_pool" = sopsSettings;
|
|
|
|
# ------------------------------
|
|
# ups
|
|
# ------------------------------
|
|
|
|
"jallen-nas/ups_password" = {
|
|
inherit sopsFile;
|
|
mode = "0777";
|
|
restartUnits = [
|
|
"upsdrv.service"
|
|
"upsd.service"
|
|
"ups-killpower.service"
|
|
"upsmon.service"
|
|
];
|
|
};
|
|
|
|
# ------------------------------
|
|
# SSH keys
|
|
# ------------------------------
|
|
|
|
"ssh-keys-public/jallen-nas-root" = {
|
|
path = "/root/.ssh/id_ed25519.pub";
|
|
mode = "0640";
|
|
};
|
|
"ssh-keys-private/jallen-nas-root" = {
|
|
path = "/root/.ssh/id_ed25519";
|
|
mode = "0600";
|
|
};
|
|
|
|
# ------------------------------
|
|
# authentik
|
|
# ------------------------------
|
|
|
|
"jallen-nas/authentik-env" = {
|
|
inherit sopsFile;
|
|
restartUnits = [ "authentik.service" ];
|
|
};
|
|
|
|
# ------------------------------
|
|
# attic
|
|
# ------------------------------
|
|
"jallen-nas/attic-key" = {
|
|
inherit sopsFile;
|
|
restartUnits = [ "atticd.service" ];
|
|
};
|
|
|
|
# ------------------------------
|
|
# collabora # TODO
|
|
# ------------------------------
|
|
|
|
"jallen-nas/collabora" = {
|
|
inherit sopsFile;
|
|
restartUnits = [ "coolwsd.service" ];
|
|
};
|
|
|
|
# ------------------------------
|
|
# crowdsec
|
|
# ------------------------------
|
|
|
|
# "jallen-nas/crowdsec-firewall-bouncer-api-key" = {
|
|
# restartUnits = [ "crowdsec-firewall-bouncer.service" ];
|
|
# };
|
|
|
|
# "jallen-nas/crowdsec-capi" = {
|
|
# inherit sopsFile;
|
|
# owner = "crowdsec";
|
|
# group = "crowdsec";
|
|
# restartUnits = [ "crowdsec.service" ];
|
|
# };
|
|
|
|
# ------------------------------
|
|
# mariadb # TODO
|
|
# ------------------------------
|
|
|
|
"jallen-nas/mariadb/db_pass" = {
|
|
inherit sopsFile;
|
|
restartUnits = [ "mysql.service" ];
|
|
};
|
|
"jallen-nas/mariadb/root_pass" = {
|
|
inherit sopsFile;
|
|
restartUnits = [ "mysql.service" ];
|
|
};
|
|
|
|
# ------------------------------
|
|
# nextcloud
|
|
# ------------------------------
|
|
|
|
"jallen-nas/nextcloud/dbpassword" = sopsSettings // {
|
|
mode = "0650";
|
|
restartUnits = [ "nextcloud.service" ];
|
|
};
|
|
"jallen-nas/nextcloud/adminpassword" = sopsSettings // {
|
|
mode = "0440";
|
|
group = "keys";
|
|
restartUnits = [
|
|
"nextcloud.service"
|
|
"prometheus-nextcloud-exporter.service" # actual systemd unit name
|
|
];
|
|
};
|
|
"jallen-nas/nextcloud/smtp_settings" = sopsSettings // {
|
|
mode = "0650";
|
|
restartUnits = [ "nextcloud.service" ];
|
|
};
|
|
|
|
# ------------------------------
|
|
# onlyoffice
|
|
# ------------------------------
|
|
|
|
"jallen-nas/onlyoffice-key" = sopsSettings // {
|
|
mode = "0655";
|
|
restartUnits = [ "nextcloud.service" ];
|
|
};
|
|
|
|
# ------------------------------
|
|
# manyfold
|
|
# ------------------------------
|
|
|
|
"jallen-nas/manyfold/secretkeybase" = {
|
|
inherit sopsFile;
|
|
restartUnits = [ "podman-manyfold.service" ];
|
|
};
|
|
|
|
# ------------------------------
|
|
# immich
|
|
# ------------------------------
|
|
|
|
"jallen-nas/immich/db-password" = {
|
|
inherit sopsFile;
|
|
mode = "0440";
|
|
group = "keys";
|
|
restartUnits = [ "immich.service" ];
|
|
};
|
|
|
|
# ------------------------------
|
|
# open-webui
|
|
# ------------------------------
|
|
|
|
"jallen-nas/open-webui" = {
|
|
inherit sopsFile;
|
|
restartUnits = [ "open-webui.service" ];
|
|
};
|
|
|
|
# ------------------------------
|
|
# paperless
|
|
# ------------------------------
|
|
|
|
"jallen-nas/paperless/secret" = {
|
|
inherit sopsFile;
|
|
restartUnits = [ "paperless.service" ];
|
|
};
|
|
"jallen-nas/paperless/authentik-client-id" = {
|
|
inherit sopsFile;
|
|
restartUnits = [ "paperless.service" ];
|
|
};
|
|
"jallen-nas/paperless/authentik-client-secret" = {
|
|
inherit sopsFile;
|
|
restartUnits = [ "paperless.service" ];
|
|
};
|
|
|
|
# ------------------------------
|
|
# Gitea
|
|
# ------------------------------
|
|
|
|
"jallen-nas/gitea/mail-key" = {
|
|
inherit sopsFile;
|
|
owner = "root";
|
|
group = "keys";
|
|
mode = "0440";
|
|
restartUnits = [ "gitea.service" ];
|
|
};
|
|
"jallen-nas/gitea/metrics-key" = {
|
|
inherit sopsFile;
|
|
owner = "root";
|
|
group = "keys";
|
|
mode = "0440";
|
|
restartUnits = [ "gitea.service" ];
|
|
};
|
|
|
|
# ------------------------------
|
|
# free-games-claimer
|
|
# ------------------------------
|
|
"jallen-nas/free-games/eg-email" = {
|
|
inherit sopsFile;
|
|
};
|
|
"jallen-nas/free-games/eg-pass" = {
|
|
inherit sopsFile;
|
|
};
|
|
"jallen-nas/free-games/eg-otp" = {
|
|
inherit sopsFile;
|
|
};
|
|
"jallen-nas/free-games/pg-email" = {
|
|
inherit sopsFile;
|
|
};
|
|
"jallen-nas/free-games/pg-pass" = {
|
|
inherit sopsFile;
|
|
};
|
|
"jallen-nas/free-games/gog-email" = {
|
|
inherit sopsFile;
|
|
};
|
|
"jallen-nas/free-games/gog-pass" = {
|
|
inherit sopsFile;
|
|
};
|
|
|
|
# ------------------------------
|
|
# ntfy
|
|
# ------------------------------
|
|
"jallen-nas/ntfy/auth-users" = {
|
|
inherit sopsFile;
|
|
};
|
|
|
|
"jallen-nas/ntfy/user" = {
|
|
inherit sopsFile;
|
|
mode = "0440";
|
|
group = "keys";
|
|
restartUnits = [
|
|
"grafana.service"
|
|
"crowdsec.service"
|
|
"upsmon.service"
|
|
];
|
|
};
|
|
"jallen-nas/ntfy/password" = {
|
|
inherit sopsFile;
|
|
mode = "0440";
|
|
group = "keys";
|
|
restartUnits = [
|
|
"grafana.service"
|
|
"crowdsec.service"
|
|
"upsmon.service"
|
|
];
|
|
};
|
|
|
|
# ------------------------------
|
|
# sparky-fitness
|
|
# ------------------------------
|
|
"jallen-nas/sparky-fitness/db-password" = {
|
|
inherit sopsFile;
|
|
restartUnits = [ "podman-sparky-fitness-server.service" ];
|
|
};
|
|
"jallen-nas/sparky-fitness/api-encryption-key" = {
|
|
inherit sopsFile;
|
|
restartUnits = [ "podman-sparky-fitness-server.service" ];
|
|
};
|
|
"jallen-nas/sparky-fitness/auth-secret" = {
|
|
inherit sopsFile;
|
|
restartUnits = [ "podman-sparky-fitness-server.service" ];
|
|
};
|
|
|
|
# ------------------------------
|
|
# authentik-rac
|
|
# NOTE: add to nas-secrets.yaml via `sops secrets/nas-secrets.yaml`:
|
|
# jallen-nas/authentik-rac/token: <authentik RAC outpost token>
|
|
# ------------------------------
|
|
"jallen-nas/authentik-rac/token" = {
|
|
inherit sopsFile;
|
|
restartUnits = [ "podman-authenticRac.service" ];
|
|
};
|
|
|
|
# ------------------------------
|
|
# Grafana
|
|
# ------------------------------
|
|
# secret_key was previously the upstream default "SW2YcwTIb9zpOOhoPsMm".
|
|
# It is stored here so Grafana can read it via the file provider without
|
|
# embedding it in the world-readable Nix store.
|
|
# To rotate: use https://github.com/erooke/grafana-secretkey-rotation-tool
|
|
"jallen-nas/grafana/secret-key" = {
|
|
inherit sopsFile;
|
|
owner = "grafana";
|
|
group = "grafana";
|
|
mode = "0400";
|
|
restartUnits = [ "grafana.service" ];
|
|
};
|
|
};
|
|
|
|
# ------------------------------
|
|
# Templates
|
|
# ------------------------------
|
|
templates = {
|
|
"fgc.env" = {
|
|
inherit owner group;
|
|
content = ''
|
|
EG_EMAIL = ${config.sops.placeholder."jallen-nas/free-games/eg-email"}
|
|
EG_PASSWORD = ${config.sops.placeholder."jallen-nas/free-games/eg-pass"}
|
|
EG_OTPKEY = ${config.sops.placeholder."jallen-nas/free-games/eg-otp"}
|
|
PG_EMAIL = ${config.sops.placeholder."jallen-nas/free-games/pg-email"}
|
|
PG_PASSWORD = ${config.sops.placeholder."jallen-nas/free-games/pg-pass"}
|
|
GOG_EMAIL = ${config.sops.placeholder."jallen-nas/free-games/gog-email"}
|
|
GOG_PASSWORD = ${config.sops.placeholder."jallen-nas/free-games/gog-pass"}
|
|
'';
|
|
mode = "0650";
|
|
restartUnits = [ "podman-free-games-claimer.service" ];
|
|
};
|
|
|
|
"authentik-rac.env" = {
|
|
content = ''
|
|
AUTHENTIK_TOKEN=${config.sops.placeholder."jallen-nas/authentik-rac/token"}
|
|
'';
|
|
mode = "0600";
|
|
restartUnits = [ "podman-authenticRac.service" ];
|
|
};
|
|
|
|
"ntfy.env" = {
|
|
content = ''
|
|
NTFY_USER=${config.sops.placeholder."jallen-nas/ntfy/user"}
|
|
NTFY_PASSWORD=${config.sops.placeholder."jallen-nas/ntfy/password"}
|
|
'';
|
|
mode = "0640";
|
|
group = "keys";
|
|
restartUnits = [
|
|
"crowdsec.service"
|
|
"upsmon.service"
|
|
"nix-rebuild-cache.service"
|
|
"update-qwen-model.service"
|
|
];
|
|
};
|
|
|
|
# Grafana reads ntfy credentials via systemd EnvironmentFile so the
|
|
# $__env{} provider works in alerting provisioning YAML. The file
|
|
# provider ($__file{}) only works in grafana.ini, not in provisioning.
|
|
"grafana.env" = {
|
|
content = ''
|
|
GRAFANA_NTFY_USER=${config.sops.placeholder."jallen-nas/ntfy/user"}
|
|
GRAFANA_NTFY_PASSWORD=${config.sops.placeholder."jallen-nas/ntfy/password"}
|
|
'';
|
|
mode = "0400";
|
|
owner = "grafana";
|
|
restartUnits = [ "grafana.service" ];
|
|
};
|
|
|
|
# CrowdSec HTTP notification plugin config with credentials baked in.
|
|
# The plugin process spawned by crowdsec/cscli reads this file directly.
|
|
# Credentials are embedded in the URL using HTTP basic auth so no
|
|
# base64 encoding or env var injection is needed.
|
|
"crowdsec/notifications/ntfy.yaml" = {
|
|
content = ''
|
|
type: http
|
|
name: ntfy_plugin
|
|
log_level: info
|
|
format: "{{range . -}}CrowdSec blocked: {{.Scenario}}\nSource IP: {{.Source.Value}}\nCountry: {{.Source.Cn}}\nDecisions: {{.Decisions | len}}{{range .Decisions}}\nAction: {{.Type}} for {{.Duration}}{{end}}\n{{end}}"
|
|
url: https://${config.sops.placeholder."jallen-nas/ntfy/user"}:${
|
|
config.sops.placeholder."jallen-nas/ntfy/password"
|
|
}@ntfy.mjallen.dev/crowdsec
|
|
method: POST
|
|
headers:
|
|
Title: "CrowdSec: {{(index . 0).Scenario}}"
|
|
Priority: "high"
|
|
Tags: "rotating_light,shield"
|
|
skip_tls_verify: false
|
|
timeout: 10s
|
|
'';
|
|
mode = "0440";
|
|
owner = "crowdsec";
|
|
group = "crowdsec";
|
|
restartUnits = [ "crowdsec.service" ];
|
|
};
|
|
|
|
"paperless.env" = {
|
|
inherit owner group;
|
|
content = ''
|
|
PAPERLESS_ADMIN_USER = "mjallen"
|
|
PAPERLESS_ADMIN_PASSWORD = ${config.sops.placeholder."matt_password"}
|
|
PAPERLESS_URL = "https://paperless.jallen.dev"
|
|
PAPERLESS_SECRET = ${config.sops.placeholder."jallen-nas/paperless/secret"}
|
|
PAPERLESS_ENABLE_ALLAUTH = true
|
|
PAPERLESS_APPS = "allauth.socialaccount.providers.openid_connect"
|
|
PAPERLESS_SOCIALACCOUNT_PROVIDERS = {"openid_connect":{"OAUTH_PKCE_ENABLED":true,"APPS":[{"provider_id":"authentik","name":"authentik","client_id":"${
|
|
config.sops.placeholder."jallen-nas/paperless/authentik-client-id"
|
|
}","secret":"${
|
|
config.sops.placeholder."jallen-nas/paperless/authentik-client-secret"
|
|
}","settings":{"server_url":"https://authentik.mjallen.dev/application/o/paperless/.well-known/openid-configuration"}}]}}
|
|
'';
|
|
mode = "0650";
|
|
restartUnits = [ "paperless-web.service" ];
|
|
};
|
|
};
|
|
};
|
|
}
|