treewide: fmt

This commit is contained in:
Felix Buehler 2024-07-28 21:08:02 +02:00
parent 330abe53d2
commit ea37c7b836
95 changed files with 1162 additions and 779 deletions

View file

@ -14,11 +14,7 @@
receivers = [
{
name = "default";
email_configs = [
{
to = "server@buehler.rocks";
}
];
email_configs = [ { to = "server@buehler.rocks"; } ];
webhook_configs = [
{
url = "http://localhost:4050/services/hooks/YWxlcnRtYW5hZ2VyX3NlcnZpY2U";

View file

@ -1,5 +1,10 @@
# monitoring system services
{ config, lib, pkgs, ... }:
{
config,
lib,
pkgs,
...
}:
let
cfg = config.my.services.alertmanager;
inherit (config.networking) domain;
@ -37,24 +42,18 @@ in
extraFlags = [ "--cluster.advertise-address 127.0.0.1:${toString cfg.port}" ];
};
alertmanagers = [
{
static_configs = [
{
targets = [ "localhost:${toString cfg.port}" ];
}
];
}
];
alertmanagers = [ { static_configs = [ { targets = [ "localhost:${toString cfg.port}" ]; } ]; } ];
scrapeConfigs = [
{
job_name = "alertmanager";
static_configs = [{
targets = [ "127.0.0.1:${toString cfg.port}" ];
labels = {
instance = config.networking.hostName;
};
}];
static_configs = [
{
targets = [ "127.0.0.1:${toString cfg.port}" ];
labels = {
instance = config.networking.hostName;
};
}
];
}
];
};

View file

@ -1,5 +1,10 @@
# to download things
{ config, lib, pkgs, ... }:
{
config,
lib,
pkgs,
...
}:
let
cfg = config.my.services.aria2;
inherit (config.networking) domain;

View file

@ -1,4 +1,9 @@
{ config, lib, pkgs, ... }:
{
config,
lib,
pkgs,
...
}:
let
cfg = config.my.services.backup;
in
@ -52,9 +57,7 @@ in
type = with types; listOf str;
description = lib.mdDoc "additional path(s) to back up";
default = [ "/" ];
example = [
"/home/user"
];
example = [ "/home/user" ];
};
exclude = mkOption {
type = with types; listOf str;
@ -100,8 +103,8 @@ in
# other-os
"**/.Trash" # apple
"**/.DS_Store" # apple
"**/$RECYCLE.BIN" #windows
"**/System Volume Information" #windows
"**/$RECYCLE.BIN" # windows
"**/System Volume Information" # windows
# var data
"/var/cache"
@ -138,27 +141,31 @@ in
inherit (cfg) doInit;
compression = "auto,zstd";
postHook = ''
if (( $exitStatus > 1 )); then
'' + lib.optionalString cfg.OnFailureNotification ''
# iterate over all logged in users
for user in $(users); do
sway_pid=$(${pkgs.procps}/bin/pgrep -x "sway" -u "$user")
if [ -n "$sway_pid" ]; then
# set environment variables
export $(cat /proc/$sway_pid/environ | grep -z '^DBUS_SESSION_BUS_ADDRESS=' | tr -d '\0')
export DISPLAY=:0
# send notification via dbus: https://wiki.archlinux.org/title/Desktop_notifications#Bash
${pkgs.sudo}/bin/sudo --preserve-env=DBUS_SESSION_BUS_ADDRESS,DISPLAY -u $user ${pkgs.libnotify}/bin/notify-send -u critical "BorgBackup Failed!" "Run journalctl -u borgbackup-job* for more details."
echo "sent notification"
postHook =
''
if (( $exitStatus > 1 )); then
''
+ lib.optionalString cfg.OnFailureNotification ''
# iterate over all logged in users
for user in $(users); do
sway_pid=$(${pkgs.procps}/bin/pgrep -x "sway" -u "$user")
if [ -n "$sway_pid" ]; then
# set environment variables
export $(cat /proc/$sway_pid/environ | grep -z '^DBUS_SESSION_BUS_ADDRESS=' | tr -d '\0')
export DISPLAY=:0
# send notification via dbus: https://wiki.archlinux.org/title/Desktop_notifications#Bash
${pkgs.sudo}/bin/sudo --preserve-env=DBUS_SESSION_BUS_ADDRESS,DISPLAY -u $user ${pkgs.libnotify}/bin/notify-send -u critical "BorgBackup Failed!" "Run journalctl -u borgbackup-job* for more details."
echo "sent notification"
fi
done
''
+ lib.optionalString (cfg.OnFailureMail != null) ''
journalctl -u borgbackup-job-hetzner.service | ${pkgs.mailutils}/bin/mail -r "Administrator<root@buehler.rocks>" -s "Backup Error" server@buehler.rocks
echo "sent mail"
''
+ ''
fi
done
'' + lib.optionalString (cfg.OnFailureMail != null) ''
journalctl -u borgbackup-job-hetzner.service | ${pkgs.mailutils}/bin/mail -r "Administrator<root@buehler.rocks>" -s "Backup Error" server@buehler.rocks
echo "sent mail"
'' + ''
fi
'';
'';
# for mail sending
readWritePaths = lib.optional (cfg.OnFailureMail != null) "/var/lib/postfix/queue/maildrop/";

View file

@ -31,12 +31,14 @@ in
prometheus.scrapeConfigs = [
{
job_name = "bazarr";
static_configs = [{
targets = [ "127.0.0.1:${toString port + 1}" ];
labels = {
instance = config.networking.hostName;
};
}];
static_configs = [
{
targets = [ "127.0.0.1:${toString port + 1}" ];
labels = {
instance = config.networking.hostName;
};
}
];
}
];
};

View file

@ -1,5 +1,10 @@
# monitor urls
{ config, lib, pkgs, ... }:
{
config,
lib,
pkgs,
...
}:
let
cfg = config.my.services.blackbox;
blackBoxConfig = {
@ -11,12 +16,8 @@ let
ssh_banner = {
prober = "tcp";
tcp.query_response = [
{
send = "SSH-2.0-blackbox-ssh-check";
}
{
expect = "^SSH-2.0-";
}
{ send = "SSH-2.0-blackbox-ssh-check"; }
{ expect = "^SSH-2.0-"; }
];
};
};

View file

@ -1,5 +1,10 @@
# Fast and lightweight DNS proxy as ad-blocker for local network
{ config, lib, pkgs, ... }:
{
config,
lib,
pkgs,
...
}:
let
cfg = config.my.services.blocky;
in

View file

@ -1,5 +1,10 @@
# RSS aggregator and reader
{ config, lib, pkgs, ... }:
{
config,
lib,
pkgs,
...
}:
let
cfg = config.my.services.freshrss;
inherit (config.networking) domain;

View file

@ -1,5 +1,10 @@
# self-hosted git service
{ config, lib, pkgs, ... }:
{
config,
lib,
pkgs,
...
}:
let
cfg = config.my.services.gitea;
inherit (config.networking) domain;

View file

@ -1,5 +1,10 @@
# visualize monitoring services
{ config, lib, pkgs, ... }:
{
config,
lib,
pkgs,
...
}:
let
cfg = config.my.services.grafana;
inherit (config.networking) domain;

View file

@ -1,5 +1,10 @@
# HedgeDoc is an open-source, web-based, self-hosted, collaborative markdown editor.
{ config, lib, pkgs, ... }:
{
config,
lib,
pkgs,
...
}:
let
cfg = config.my.services.hedgedoc;
inherit (config.networking) domain;

View file

@ -1,5 +1,10 @@
# home automation
{ config, lib, pkgs, ... }:
{
config,
lib,
pkgs,
...
}:
let
cfg = config.my.services.home-automation;
inherit (config.networking) domain;

View file

@ -1,5 +1,10 @@
# My own personal homepage
{ config, lib, inputs, ... }:
{
config,
lib,
inputs,
...
}:
let
cfg = config.my.services.homepage;
inherit (config.networking) domain;

View file

@ -3,24 +3,26 @@
{
options.webapps = {
dashboardCategories = lib.mkOption {
type = lib.types.listOf (lib.types.submodule {
options = {
name = lib.mkOption {
type = lib.types.str;
description = ''
Category name.
'';
example = "Applications";
type = lib.types.listOf (
lib.types.submodule {
options = {
name = lib.mkOption {
type = lib.types.str;
description = ''
Category name.
'';
example = "Applications";
};
tag = lib.mkOption {
type = lib.types.str;
description = ''
Category tag.
'';
example = "app";
};
};
tag = lib.mkOption {
type = lib.types.str;
description = ''
Category tag.
'';
example = "app";
};
};
});
}
);
description = ''
App categories to display on the dashboard.
'';
@ -34,8 +36,8 @@
};
apps = lib.mkOption {
type = lib.types.attrsOf
(lib.types.submodule {
type = lib.types.attrsOf (
lib.types.submodule {
options = {
dashboard = {
url = lib.mkOption {
@ -79,7 +81,10 @@
default = "Ping";
};
method = lib.mkOption {
type = lib.types.enum [ "get" "head" ];
type = lib.types.enum [
"get"
"head"
];
description = ''
method of request used
'';
@ -88,7 +93,8 @@
};
};
};
});
}
);
description = ''
Defines a web application.
'';
@ -105,24 +111,33 @@
let
apps = builtins.filter (a: a.dashboard.name != null) (lib.attrValues cfg.apps);
in
lib.forEach cfg.dashboardCategories (cat:
lib.forEach cfg.dashboardCategories (
cat:
let
catApps = lib.sort (a: b: a.dashboard.name < b.dashboard.name) (
builtins.filter
(a:
a.dashboard.category != null && a.dashboard.category == cat.tag ||
a.dashboard.category == null && cat.tag == "misc")
apps);
builtins.filter (
a:
a.dashboard.category != null && a.dashboard.category == cat.tag
|| a.dashboard.category == null && cat.tag == "misc"
) apps
);
in
{
inherit (cat) name;
items = lib.forEach catApps (a: {
inherit (a.dashboard) method name type url;
inherit (a.dashboard)
method
name
type
url
;
icon = lib.optionalString (a.dashboard.icon != null) "fas fa-${a.dashboard.icon}";
target = "_blank";
});
}
);
my.services.blackbox.http_endpoints = lib.mapAttrsToList (_key: value: value.dashboard.url) config.webapps.apps ++ [ "https://${config.networking.domain}/" ];
my.services.blackbox.http_endpoints =
lib.mapAttrsToList (_key: value: value.dashboard.url) config.webapps.apps
++ [ "https://${config.networking.domain}/" ];
};
}

View file

@ -1,5 +1,10 @@
# Dashboard site
{ config, lib, pkgs, ... }:
{
config,
lib,
pkgs,
...
}:
let
cfg = config.my.services.homer;
inherit (config.networking) domain;
@ -14,9 +19,7 @@ let
};
in
{
imports = [
./config.nix
];
imports = [ ./config.nix ];
options.my.services.homer = with lib; {
enable = mkEnableOption "Homer Dashboard";
@ -44,10 +47,22 @@ in
webapps = {
dashboardCategories = [
{ name = "Applications"; tag = "app"; }
{ name = "Media"; tag = "media"; }
{ name = "Infrastructure"; tag = "infra"; }
{ name = "Others"; tag = "other"; }
{
name = "Applications";
tag = "app";
}
{
name = "Media";
tag = "media";
}
{
name = "Infrastructure";
tag = "infra";
}
{
name = "Others";
tag = "other";
}
];
};
};

View file

@ -15,9 +15,7 @@ in
ssh = {
enable = true;
port = 2222;
hostKeys = [
"/etc/secrets/initrd/ssh_host_ed25519_key"
];
hostKeys = [ "/etc/secrets/initrd/ssh_host_ed25519_key" ];
authorizedKeys = [
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIOFx6OLwL9MbkD3mnMsv+xrzZHN/rwCTgVs758SCLG0h felix@thinkman"
];

View file

@ -1,5 +1,10 @@
# The Free Software Media System
{ config, lib, pkgs, ... }:
{
config,
lib,
pkgs,
...
}:
let
cfg = config.my.services.jellyfin;
inherit (config.networking) domain;
@ -8,10 +13,7 @@ let
jellyfin-with-metrics = pkgs.jellyfin.overrideAttrs (attrs: {
patches =
let
existingPatches =
if attrs ? patches && builtins.isList attrs.patches
then attrs.patches
else [ ];
existingPatches = if attrs ? patches && builtins.isList attrs.patches then attrs.patches else [ ];
in
# with this patch the default setting for metrics is changed
existingPatches ++ [ ./enable-metrics.patch ];

View file

@ -1,5 +1,10 @@
# log monitoring
{ config, lib, pkgs, ... }:
{
config,
lib,
pkgs,
...
}:
let
cfg = config.my.services.loki;
in
@ -15,8 +20,8 @@ in
};
rules = mkOption {
type = types.attrsOf
(types.submodule {
type = types.attrsOf (
types.submodule {
options = {
condition = mkOption {
type = types.str;
@ -53,7 +58,8 @@ in
default = "2m";
};
};
});
}
);
description = ''
Defines the loki rules.
'';
@ -67,14 +73,12 @@ in
groups = [
{
name = "alerting-rules";
rules = lib.mapAttrsToList
(name: opts: {
alert = name;
inherit (opts) condition labels;
for = opts.time;
annotations.description = opts.description;
})
cfg.rules;
rules = lib.mapAttrsToList (name: opts: {
alert = name;
inherit (opts) condition labels;
for = opts.time;
annotations.description = opts.description;
}) cfg.rules;
}
];
};
@ -114,16 +118,18 @@ in
};
schema_config = {
configs = [{
from = "2020-11-08";
store = "tsdb";
object_store = "filesystem";
schema = "v13";
index = {
prefix = "index_";
period = "24h";
};
}];
configs = [
{
from = "2020-11-08";
store = "tsdb";
object_store = "filesystem";
schema = "v13";
index = {
prefix = "index_";
period = "24h";
};
}
];
};
limits_config = {

View file

@ -1,5 +1,10 @@
# sandbox video game
{ config, lib, pkgs, ... }:
{
config,
lib,
pkgs,
...
}:
let
cfg = config.my.services.minecraft-server;
in

View file

@ -1,5 +1,10 @@
# Have a good quality voice chat
{ config, lib, pkgs, ... }:
{
config,
lib,
pkgs,
...
}:
let
cfg = config.my.services.mumble-server;
domain = "voice.${config.networking.domain}";
@ -28,7 +33,10 @@ in
'';
};
users.groups."voice-buehler-rocks".members = [ "murmur" "nginx" ];
users.groups."voice-buehler-rocks".members = [
"murmur"
"nginx"
];
my.services.prometheus.rules = {
mumble_not_running = {

View file

@ -1,5 +1,10 @@
# A FLOSS self-hosted, subsonic compatible music server
{ config, lib, pkgs, ... }:
{
config,
lib,
pkgs,
...
}:
let
cfg = config.my.services.navidrome;
inherit (config.networking) domain;

View file

@ -1,5 +1,10 @@
# self-hosted cloud
{ config, lib, pkgs, ... }:
{
config,
lib,
pkgs,
...
}:
let
cfg = config.my.services.nextcloud;
inherit (config.networking) domain;
@ -71,7 +76,12 @@ in
};
extraApps = with pkgs.nextcloud29Packages.apps; {
inherit calendar contacts tasks deck;
inherit
calendar
contacts
tasks
deck
;
};
extraAppsEnable = true;
};

View file

@ -1,60 +1,65 @@
# A simple abstraction layer for almost all of my services' needs
{ config, lib, pkgs, ... }:
{
config,
lib,
pkgs,
...
}:
let
cfg = config.my.services.nginx;
virtualHostOption = with lib; types.submodule {
options = {
subdomain = mkOption {
type = types.str;
example = "dev";
description = ''
Which subdomain, under config.networking.domain, to use
for this virtual host.
'';
};
port = mkOption {
type = with types; nullOr port;
default = null;
example = 8080;
description = ''
Which port to proxy to, through 127.0.0.1, for this virtual host.
This option is incompatible with `root`.
'';
};
root = mkOption {
type = with types; nullOr path;
default = null;
example = "/var/www/blog";
description = ''
The root folder for this virtual host. This option is incompatible
with `port`.
'';
};
sso = {
enable = mkEnableOption "SSO authentication";
};
extraConfig = mkOption {
type = types.attrs; # FIXME: forward type of virtualHosts
example = literalExpression ''
{
locations."/socket" = {
proxyPass = "http://127.0.0.1:8096/";
proxyWebsockets = true;
};
}
'';
default = { };
description = ''
Any extra configuration that should be applied to this virtual host.
'';
virtualHostOption =
with lib;
types.submodule {
options = {
subdomain = mkOption {
type = types.str;
example = "dev";
description = ''
Which subdomain, under config.networking.domain, to use
for this virtual host.
'';
};
port = mkOption {
type = with types; nullOr port;
default = null;
example = 8080;
description = ''
Which port to proxy to, through 127.0.0.1, for this virtual host.
This option is incompatible with `root`.
'';
};
root = mkOption {
type = with types; nullOr path;
default = null;
example = "/var/www/blog";
description = ''
The root folder for this virtual host. This option is incompatible
with `port`.
'';
};
sso = {
enable = mkEnableOption "SSO authentication";
};
extraConfig = mkOption {
type = types.attrs; # FIXME: forward type of virtualHosts
example = literalExpression ''
{
locations."/socket" = {
proxyPass = "http://127.0.0.1:8096/";
proxyWebsockets = true;
};
}
'';
default = { };
description = ''
Any extra configuration that should be applied to this virtual host.
'';
};
};
};
};
in
{
imports = [
./sso
];
imports = [ ./sso ];
options.my.services.nginx = with lib; {
enable = mkEnableOption "Nginx";
acme = {
@ -116,20 +121,22 @@ in
description = "Port to use for internal webui.";
};
users = mkOption {
type = types.attrsOf (types.submodule {
options = {
passwordHashFile = mkOption {
type = types.str;
example = "/var/lib/nginx-sso/alice/password-hash.txt";
description = "Path to file containing the user's password hash.";
type = types.attrsOf (
types.submodule {
options = {
passwordHashFile = mkOption {
type = types.str;
example = "/var/lib/nginx-sso/alice/password-hash.txt";
description = "Path to file containing the user's password hash.";
};
totpSecretFile = mkOption {
type = types.str;
example = "/var/lib/nginx-sso/alice/totp-secret.txt";
description = "Path to file containing the user's TOTP secret.";
};
};
totpSecretFile = mkOption {
type = types.str;
example = "/var/lib/nginx-sso/alice/totp-secret.txt";
description = "Path to file containing the user's TOTP secret.";
};
};
});
}
);
example = literalExpression ''
{
alice = {
@ -153,9 +160,13 @@ in
};
};
config = lib.mkIf cfg.enable {
assertions = lib.flip builtins.map cfg.virtualHosts ({ subdomain, ... } @ args:
assertions = lib.flip builtins.map cfg.virtualHosts (
{ subdomain, ... }@args:
let
conflicts = [ "port" "root" ];
conflicts = [
"port"
"root"
];
optionsNotNull = builtins.map (v: args.${v} != null) conflicts;
optionsSet = lib.filter lib.id optionsNotNull;
in
@ -166,39 +177,40 @@ in
lib.concatStringsSep ", " (builtins.map (v: "'${v}'") conflicts)
} configured.
'';
})
# ++ (
# let
# ports = lib.my.mapFilter
# (v: v != null)
# ({ port, ... }: port)
# cfg.virtualHosts;
# lib.unique ports;
# lib.compareLists ports
# portCounts = lib.my.countValues ports;
# nonUniquesCounts = lib.filterAttrs (_: v: v != 1) portCounts;
# nonUniques = builtins.attrNames nonUniquesCounts;
# mkAssertion = port: {
# assertion = false;
# message = "Port ${port} cannot appear in multiple virtual hosts.";
# };
# in
# map mkAssertion nonUniques
# ) ++ (
# let
# subs = map ({ subdomain, ... }: subdomain) cfg.virtualHosts;
# subsCounts = lib.my.countValues subs;
# nonUniquesCounts = lib.filterAttrs (_: v: v != 1) subsCounts;
# nonUniques = builtins.attrNames nonUniquesCounts;
# mkAssertion = v: {
# assertion = false;
# message = ''
# Subdomain '${v}' cannot appear in multiple virtual hosts.
# '';
# };
# in
# map mkAssertion nonUniques
# )
}
)
# ++ (
# let
# ports = lib.my.mapFilter
# (v: v != null)
# ({ port, ... }: port)
# cfg.virtualHosts;
# lib.unique ports;
# lib.compareLists ports
# portCounts = lib.my.countValues ports;
# nonUniquesCounts = lib.filterAttrs (_: v: v != 1) portCounts;
# nonUniques = builtins.attrNames nonUniquesCounts;
# mkAssertion = port: {
# assertion = false;
# message = "Port ${port} cannot appear in multiple virtual hosts.";
# };
# in
# map mkAssertion nonUniques
# ) ++ (
# let
# subs = map ({ subdomain, ... }: subdomain) cfg.virtualHosts;
# subsCounts = lib.my.countValues subs;
# nonUniquesCounts = lib.filterAttrs (_: v: v != 1) subsCounts;
# nonUniques = builtins.attrNames nonUniquesCounts;
# mkAssertion = v: {
# assertion = false;
# message = ''
# Subdomain '${v}' cannot appear in multiple virtual hosts.
# '';
# };
# in
# map mkAssertion nonUniques
# )
;
services = {
nginx = {
@ -251,67 +263,68 @@ in
let
genAttrs' = values: f: lib.listToAttrs (map f values);
inherit (config.networking) domain;
mkVHost = { subdomain, ... } @ args: lib.nameValuePair
"${subdomain}.${domain}"
(lib.foldl lib.recursiveUpdate { } [
# Base configuration
{
forceSSL = true;
useACMEHost = domain;
}
# Proxy to port
(lib.optionalAttrs (args.port != null) {
locations."/".proxyPass =
"http://127.0.0.1:${toString args.port}";
# TODO make ipv6 possible
# http://[::1]:${toString args.port};
})
# Serve filesystem content
(lib.optionalAttrs (args.root != null) {
inherit (args) root;
})
# VHost specific configuration
args.extraConfig
# SSO configuration
(lib.optionalAttrs args.sso.enable {
extraConfig = (args.extraConfig.extraConfig or "") + ''
error_page 401 = @error401;
'';
locations = {
"@error401".return = ''
302 https://${cfg.sso.subdomain}.${config.networking.domain}/login?go=$scheme://$http_host$request_uri
'';
"/" = {
extraConfig =
(args.extraConfig.locations."/".extraConfig or "") + ''
# Use SSO
auth_request /sso-auth;
# Set username through header
auth_request_set $username $upstream_http_x_username;
proxy_set_header X-User $username;
# Renew SSO cookie on request
auth_request_set $cookie $upstream_http_set_cookie;
add_header Set-Cookie $cookie;
'';
};
"/sso-auth" = {
proxyPass = "http://localhost:${toString cfg.sso.port}/auth";
extraConfig = ''
# Do not allow requests from outside
internal;
# Do not forward the request body
proxy_pass_request_body off;
proxy_set_header Content-Length "";
# Set X-Application according to subdomain for matching
proxy_set_header X-Application "${subdomain}";
# Set origin URI for matching
proxy_set_header X-Origin-URI $request_uri;
mkVHost =
{ subdomain, ... }@args:
lib.nameValuePair "${subdomain}.${domain}" (
lib.foldl lib.recursiveUpdate { } [
# Base configuration
{
forceSSL = true;
useACMEHost = domain;
}
# Proxy to port
(lib.optionalAttrs (args.port != null) {
locations."/".proxyPass = "http://127.0.0.1:${toString args.port}";
# TODO make ipv6 possible
# http://[::1]:${toString args.port};
})
# Serve filesystem content
(lib.optionalAttrs (args.root != null) { inherit (args) root; })
# VHost specific configuration
args.extraConfig
# SSO configuration
(lib.optionalAttrs args.sso.enable {
extraConfig =
(args.extraConfig.extraConfig or "")
+ ''
error_page 401 = @error401;
'';
locations = {
"@error401".return = ''
302 https://${cfg.sso.subdomain}.${config.networking.domain}/login?go=$scheme://$http_host$request_uri
'';
"/" = {
extraConfig =
(args.extraConfig.locations."/".extraConfig or "")
+ ''
# Use SSO
auth_request /sso-auth;
# Set username through header
auth_request_set $username $upstream_http_x_username;
proxy_set_header X-User $username;
# Renew SSO cookie on request
auth_request_set $cookie $upstream_http_set_cookie;
add_header Set-Cookie $cookie;
'';
};
"/sso-auth" = {
proxyPass = "http://localhost:${toString cfg.sso.port}/auth";
extraConfig = ''
# Do not allow requests from outside
internal;
# Do not forward the request body
proxy_pass_request_body off;
proxy_set_header Content-Length "";
# Set X-Application according to subdomain for matching
proxy_set_header X-Application "${subdomain}";
# Set origin URI for matching
proxy_set_header X-Origin-URI $request_uri;
'';
};
};
};
})
])
;
})
]
);
in
genAttrs' cfg.virtualHosts mkVHost;
sso = {
@ -322,9 +335,7 @@ in
inherit (cfg.sso) port;
};
audit_log = {
target = [
"fd://stdout"
];
target = [ "fd://stdout" ];
events = [
"access_denied"
"login_success"
@ -359,21 +370,30 @@ in
in
{
users = applyUsers (_: v: { _secret = v.passwordHashFile; });
mfa = applyUsers (_: v: [{
provider = "totp";
attributes = {
secret = {
_secret = v.totpSecretFile;
};
};
}]);
mfa = applyUsers (
_: v: [
{
provider = "totp";
attributes = {
secret = {
_secret = v.totpSecretFile;
};
};
}
]
);
inherit (cfg.sso) groups;
};
};
acl = {
rule_sets = [
{
rules = [{ field = "x-application"; present = true; }];
rules = [
{
field = "x-application";
present = true;
}
];
allow = [ "@root" ];
}
];
@ -426,7 +446,10 @@ in
];
};
networking.firewall.allowedTCPPorts = [ 80 443 ];
networking.firewall.allowedTCPPorts = [
80
443
];
# Nginx needs to be able to read the certificates
users.users.nginx.extraGroups = [ "acme" ];
security.acme = {

View file

@ -1,5 +1,11 @@
# I must override the module to allow having runtime secrets
{ config, lib, pkgs, utils, ... }:
{
config,
lib,
pkgs,
utils,
...
}:
let
cfg = config.services.nginx.sso;
pkg = lib.getBin cfg.package;
@ -8,7 +14,6 @@ in
{
disabledModules = [ "services/security/nginx-sso.nix" ];
options.services.nginx.sso = with lib; {
enable = mkEnableOption "nginx-sso service";
@ -67,8 +72,7 @@ in
# Fix permissions
chown nginx-sso:nginx-sso ${confPath}
chmod 0600 ${confPath}
''
}'';
''}'';
ExecStart = lib.mkForce ''
${pkg}/bin/nginx-sso \
--config ${confPath} \

View file

@ -1,5 +1,11 @@
# monitoring system services
{ config, lib, pkgs, inputs, ... }:
{
config,
lib,
pkgs,
inputs,
...
}:
let
cfg = config.my.services.node-exporter;
in
@ -17,9 +23,7 @@ in
"systemd"
"textfile"
];
extraFlags = [
"--collector.textfile.directory=/etc/prometheus-node-exporter-text-files"
];
extraFlags = [ "--collector.textfile.directory=/etc/prometheus-node-exporter-text-files" ];
port = 9100;
listenAddress = "127.0.0.1";
};
@ -32,21 +36,25 @@ in
scrapeConfigs = [
{
job_name = "node";
static_configs = [{
targets = [ "127.0.0.1:${toString config.services.prometheus.exporters.node.port}" ];
labels = {
instance = config.networking.hostName;
};
}];
static_configs = [
{
targets = [ "127.0.0.1:${toString config.services.prometheus.exporters.node.port}" ];
labels = {
instance = config.networking.hostName;
};
}
];
}
{
job_name = "systemd";
static_configs = [{
targets = [ "127.0.0.1:${toString config.services.prometheus.exporters.systemd.port}" ];
labels = {
instance = config.networking.hostName;
};
}];
static_configs = [
{
targets = [ "127.0.0.1:${toString config.services.prometheus.exporters.systemd.port}" ];
labels = {
instance = config.networking.hostName;
};
}
];
}
];
};
@ -55,10 +63,14 @@ in
environment.etc =
let
inputsWithDate = lib.filterAttrs (_: input: input ? lastModified) inputs;
flakeAttrs = input: (lib.mapAttrsToList (n: v: ''${n}="${v}"'')
(lib.filterAttrs (_n: v: (builtins.typeOf v) == "string") input));
lastModified = name: input: ''
flake_input_last_modified{input="${name}",${lib.concatStringsSep "," (flakeAttrs input)}} ${toString input.lastModified}'';
flakeAttrs =
input:
(lib.mapAttrsToList (n: v: ''${n}="${v}"'') (
lib.filterAttrs (_n: v: (builtins.typeOf v) == "string") input
));
lastModified =
name: input:
''flake_input_last_modified{input="${name}",${lib.concatStringsSep "," (flakeAttrs input)}} ${toString input.lastModified}'';
in
{
"prometheus-node-exporter-text-files/flake-inputs.prom" = {

View file

@ -19,14 +19,18 @@ in
config = lib.mkIf cfg.enable {
services.octoprint = {
enable = true;
plugins = plugins: with plugins; [
costestimation
displayprogress
m86motorsoff
stlviewer
telegram
titlestatus
] ++ cfg.plugins;
plugins =
plugins:
with plugins;
[
costestimation
displayprogress
m86motorsoff
stlviewer
telegram
titlestatus
]
++ cfg.plugins;
};
networking.firewall.allowedTCPPorts = [ 5000 ];
};

View file

@ -49,7 +49,12 @@ in
config = lib.mkIf cfg.enable {
services.photoprism = {
enable = true;
inherit (cfg) passwordFile port originalsPath settings;
inherit (cfg)
passwordFile
port
originalsPath
settings
;
};
my.services.nginx.virtualHosts = [

View file

@ -1,5 +1,10 @@
# monitoring system services
{ config, lib, pkgs, ... }:
{
config,
lib,
pkgs,
...
}:
let
cfg = config.my.services.prometheus;
inherit (config.networking) domain;
@ -31,8 +36,8 @@ in
# a good collections for allerts can be found here: https://samber.github.io/awesome-prometheus-alerts/rules#blackbox
rules = mkOption {
type = types.attrsOf
(types.submodule {
type = types.attrsOf (
types.submodule {
options = {
condition = mkOption {
type = types.str;
@ -69,7 +74,8 @@ in
default = "2m";
};
};
});
}
);
description = ''
Defines the prometheus rules.
'';
@ -92,12 +98,12 @@ in
};
ruleFiles = [
(pkgs.writeText "prometheus-rules.yml" (builtins.toJSON {
groups = [
{
name = "alerting-rules";
rules = lib.mapAttrsToList
(name: opts: {
(pkgs.writeText "prometheus-rules.yml" (
builtins.toJSON {
groups = [
{
name = "alerting-rules";
rules = lib.mapAttrsToList (name: opts: {
alert = name;
expr = opts.condition;
for = opts.time;
@ -106,22 +112,24 @@ in
inherit (opts) description;
grafana = lib.optionalString config.services.grafana.enable "https://visualization.${domain}";
};
})
cfg.rules;
}
];
}))
}) cfg.rules;
}
];
}
))
];
scrapeConfigs = [
{
job_name = "prometheus";
static_configs = [{
targets = [ "127.0.0.1:${toString cfg.port}" ];
labels = {
instance = config.networking.hostName;
};
}];
static_configs = [
{
targets = [ "127.0.0.1:${toString cfg.port}" ];
labels = {
instance = config.networking.hostName;
};
}
];
}
];
};

View file

@ -28,9 +28,11 @@ in
positions = {
filename = "/tmp/positions.yaml";
};
clients = [{
url = "http://127.0.0.1:${toString config.services.loki.configuration.server.http_listen_port}/loki/api/v1/push";
}];
clients = [
{
url = "http://127.0.0.1:${toString config.services.loki.configuration.server.http_listen_port}/loki/api/v1/push";
}
];
scrape_configs = [
{
job_name = "journal";
@ -41,18 +43,18 @@ in
host = config.networking.hostName;
};
};
relabel_configs = [{
source_labels = [ "__journal__systemd_unit" ];
target_label = "unit";
}];
relabel_configs = [
{
source_labels = [ "__journal__systemd_unit" ];
target_label = "unit";
}
];
}
{
job_name = "nginx";
static_configs = [
{
targets = [
"localhost"
];
targets = [ "localhost" ];
labels = {
job = "nginx";
__path__ = "/var/log/nginx/*.log";

View file

@ -31,12 +31,14 @@ in
prometheus.scrapeConfigs = [
{
job_name = "prowlarr";
static_configs = [{
targets = [ "127.0.0.1:${toString port + 1}" ];
labels = {
instance = config.networking.hostName;
};
}];
static_configs = [
{
targets = [ "127.0.0.1:${toString port + 1}" ];
labels = {
instance = config.networking.hostName;
};
}
];
}
];
};

View file

@ -31,12 +31,14 @@ in
prometheus.scrapeConfigs = [
{
job_name = "radarr";
static_configs = [{
targets = [ "127.0.0.1:${toString port + 1}" ];
labels = {
instance = config.networking.hostName;
};
}];
static_configs = [
{
targets = [ "127.0.0.1:${toString port + 1}" ];
labels = {
instance = config.networking.hostName;
};
}
];
}
];
};

View file

@ -1,5 +1,10 @@
# manages remote builds
{ config, lib, pkgs, ... }:
{
config,
lib,
pkgs,
...
}:
let
cfg = config.my.services.remote-build;
in
@ -15,7 +20,9 @@ in
isSystemUser = true;
group = "nixremote";
shell = pkgs.bashInteractive;
openssh.authorizedKeys.keys = [ "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIGYSzDdxqaNHmaaLqEvOK/vB65zvqoCebI3Nxzgg5smq root@thinkman" ];
openssh.authorizedKeys.keys = [
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIGYSzDdxqaNHmaaLqEvOK/vB65zvqoCebI3Nxzgg5smq root@thinkman"
];
};
nix.settings.trusted-users = [ "nixremote" ];
};

View file

@ -31,12 +31,14 @@ in
prometheus.scrapeConfigs = [
{
job_name = "sonarr";
static_configs = [{
targets = [ "127.0.0.1:${toString port + 1}" ];
labels = {
instance = config.networking.hostName;
};
}];
static_configs = [
{
targets = [ "127.0.0.1:${toString port + 1}" ];
labels = {
instance = config.networking.hostName;
};
}
];
}
];
};