Compare commits
11 Commits
60d0753c11
...
9523a36795
Author | SHA1 | Date | |
---|---|---|---|
9523a36795 | |||
3371942b33 | |||
2e5c13d8be | |||
f2f49f1819 | |||
02f9916be6 | |||
4fa2ec5f78 | |||
9b670ac6de | |||
c07ccfa42b | |||
c129c6adfb | |||
035cf0e555 | |||
a9f77a1b2b |
3
.gitignore
vendored
3
.gitignore
vendored
@ -4,4 +4,5 @@ result*
|
|||||||
*.bak
|
*.bak
|
||||||
*.qcow2
|
*.qcow2
|
||||||
*.raw
|
*.raw
|
||||||
*.img
|
*.img
|
||||||
|
*.log
|
713
flake.lock
generated
713
flake.lock
generated
File diff suppressed because it is too large
Load Diff
30
flake.nix
30
flake.nix
@ -4,8 +4,6 @@
|
|||||||
inputs = {
|
inputs = {
|
||||||
flake-utils-plus.url = "github:gytis-ivaskevicius/flake-utils-plus/v1.4.0";
|
flake-utils-plus.url = "github:gytis-ivaskevicius/flake-utils-plus/v1.4.0";
|
||||||
nixpkgs.url = "github:nixos/nixpkgs/nixos-unstable";
|
nixpkgs.url = "github:nixos/nixpkgs/nixos-unstable";
|
||||||
# 6.1.55 kernel breaks podman. wait for fix
|
|
||||||
nixpkgs-pinned.url = "github:nixos/nixpkgs/9eebdbb7182caf58dbbc11a4c221c23e867cca08";
|
|
||||||
nixpkgs-master.url = "github:nixos/nixpkgs/master";
|
nixpkgs-master.url = "github:nixos/nixpkgs/master";
|
||||||
nixpkgs-stable.url = "github:nixos/nixpkgs/nixos-23.11";
|
nixpkgs-stable.url = "github:nixos/nixpkgs/nixos-23.11";
|
||||||
flake-registry = {
|
flake-registry = {
|
||||||
@ -17,11 +15,15 @@
|
|||||||
inputs.nixpkgs.follows = "nixpkgs";
|
inputs.nixpkgs.follows = "nixpkgs";
|
||||||
};
|
};
|
||||||
impermanence.url = "github:nix-community/impermanence";
|
impermanence.url = "github:nix-community/impermanence";
|
||||||
aagl.url = "github:ezKEa/aagl-gtk-on-nix";
|
aagl = {
|
||||||
|
url = "github:ezKEa/aagl-gtk-on-nix";
|
||||||
|
inputs.nixpkgs.follows = "nixpkgs";
|
||||||
|
};
|
||||||
arkenfox-userjs = {
|
arkenfox-userjs = {
|
||||||
url = "github:arkenfox/user.js";
|
url = "github:arkenfox/user.js";
|
||||||
flake = false;
|
flake = false;
|
||||||
};
|
};
|
||||||
|
ataraxiasjel-nur.url = "github:AtaraxiaSjel/nur";
|
||||||
attic.url = "github:zhaofengli/attic";
|
attic.url = "github:zhaofengli/attic";
|
||||||
base16.url = "github:AtaraxiaSjel/base16-nix";
|
base16.url = "github:AtaraxiaSjel/base16-nix";
|
||||||
base16-tokyonight-scheme = {
|
base16-tokyonight-scheme = {
|
||||||
@ -33,7 +35,6 @@
|
|||||||
inputs.nixpkgs.follows = "nixpkgs";
|
inputs.nixpkgs.follows = "nixpkgs";
|
||||||
};
|
};
|
||||||
deploy-rs.url = "github:serokell/deploy-rs";
|
deploy-rs.url = "github:serokell/deploy-rs";
|
||||||
devenv.url = "github:cachix/devenv";
|
|
||||||
disko = {
|
disko = {
|
||||||
url = "github:nix-community/disko";
|
url = "github:nix-community/disko";
|
||||||
inputs.nixpkgs.follows = "nixpkgs";
|
inputs.nixpkgs.follows = "nixpkgs";
|
||||||
@ -43,9 +44,7 @@
|
|||||||
inputs.nixpkgs.follows = "nixpkgs"; # MESA/OpenGL HW workaround
|
inputs.nixpkgs.follows = "nixpkgs"; # MESA/OpenGL HW workaround
|
||||||
};
|
};
|
||||||
hyprpaper = {
|
hyprpaper = {
|
||||||
# TODO: return to upstream after fix merge
|
url = "github:hyprwm/hyprpaper";
|
||||||
url = "github:AtaraxiaSjel/hyprpaper/fix-nix";
|
|
||||||
# url = "github:hyprwm/hyprpaper";
|
|
||||||
inputs.nixpkgs.follows = "nixpkgs";
|
inputs.nixpkgs.follows = "nixpkgs";
|
||||||
};
|
};
|
||||||
mms.url = "github:mkaito/nixos-modded-minecraft-servers";
|
mms.url = "github:mkaito/nixos-modded-minecraft-servers";
|
||||||
@ -66,20 +65,12 @@
|
|||||||
url = "github:nix-community/nixos-generators";
|
url = "github:nix-community/nixos-generators";
|
||||||
inputs.nixpkgs.follows = "nixpkgs";
|
inputs.nixpkgs.follows = "nixpkgs";
|
||||||
};
|
};
|
||||||
nur.url = "github:nix-community/NUR";
|
# nur.url = "github:nix-community/NUR";
|
||||||
prismlauncher.url = "github:AtaraxiaSjel/PrismLauncher/develop";
|
prismlauncher.url = "github:AtaraxiaSjel/PrismLauncher/develop";
|
||||||
rnix-lsp = {
|
|
||||||
url = "github:nix-community/rnix-lsp";
|
|
||||||
inputs.nixpkgs.follows = "nixpkgs";
|
|
||||||
};
|
|
||||||
rycee = {
|
rycee = {
|
||||||
url = "gitlab:rycee/nur-expressions";
|
url = "gitlab:rycee/nur-expressions";
|
||||||
flake = false;
|
flake = false;
|
||||||
};
|
};
|
||||||
simple-nixos-mailserver = {
|
|
||||||
url = "gitlab:simple-nixos-mailserver/nixos-mailserver";
|
|
||||||
inputs.nixpkgs.follows = "nixpkgs";
|
|
||||||
};
|
|
||||||
sops-nix = {
|
sops-nix = {
|
||||||
url = "github:Mic92/sops-nix";
|
url = "github:Mic92/sops-nix";
|
||||||
inputs.nixpkgs.follows = "nixpkgs";
|
inputs.nixpkgs.follows = "nixpkgs";
|
||||||
@ -127,7 +118,10 @@
|
|||||||
"webhooks.patch"
|
"webhooks.patch"
|
||||||
];
|
];
|
||||||
sharedOverlays = [ flake-utils-plus.overlay inputs.sops-nix.overlays.default ];
|
sharedOverlays = [ flake-utils-plus.overlay inputs.sops-nix.overlays.default ];
|
||||||
channelsConfig = { allowUnfree = true; android_sdk.accept_license = true; };
|
channelsConfig = {
|
||||||
|
allowUnfree = true; android_sdk.accept_license = true;
|
||||||
|
permittedInsecurePackages = [ "electron-25.9.0" ];
|
||||||
|
};
|
||||||
channels.unstable.input = nixpkgs;
|
channels.unstable.input = nixpkgs;
|
||||||
channels.unstable.patches = patchesPath [ "zen-kernels.patch" "ydotoold.patch" ] ++ sharedPatches;
|
channels.unstable.patches = patchesPath [ "zen-kernels.patch" "ydotoold.patch" ] ++ sharedPatches;
|
||||||
channels.stable.input = inputs.nixpkgs-stable;
|
channels.stable.input = inputs.nixpkgs-stable;
|
||||||
@ -211,7 +205,7 @@
|
|||||||
name = "aliases";
|
name = "aliases";
|
||||||
packages = with pkgs; [
|
packages = with pkgs; [
|
||||||
rebuild update-vscode upgrade upgrade-hyprland
|
rebuild update-vscode upgrade upgrade-hyprland
|
||||||
nixfmt nixpkgs-fmt statix vulnix deadnix git deploy-rs
|
nixfmt-rfc-style nixpkgs-fmt statix vulnix deadnix git deploy-rs
|
||||||
fup-repl ssh-to-pgp sops
|
fup-repl ssh-to-pgp sops
|
||||||
];
|
];
|
||||||
};
|
};
|
||||||
|
@ -1,4 +1,6 @@
|
|||||||
{ config, inputs, ... }: {
|
{ config, inputs, ... }: {
|
||||||
|
imports = [ inputs.ataraxiasjel-nur.nixosModules.rustic ];
|
||||||
|
|
||||||
sops.secrets.rustic-nas-pass.sopsFile = inputs.self.secretsDir + /rustic.yaml;
|
sops.secrets.rustic-nas-pass.sopsFile = inputs.self.secretsDir + /rustic.yaml;
|
||||||
sops.secrets.rclone-rustic-backups.sopsFile = inputs.self.secretsDir + /rustic.yaml;
|
sops.secrets.rclone-rustic-backups.sopsFile = inputs.self.secretsDir + /rustic.yaml;
|
||||||
services.rustic.backups = rec {
|
services.rustic.backups = rec {
|
||||||
|
@ -21,7 +21,7 @@ in {
|
|||||||
customProfiles.hoyolab
|
customProfiles.hoyolab
|
||||||
customProfiles.inpx-web
|
customProfiles.inpx-web
|
||||||
customProfiles.it-tools
|
customProfiles.it-tools
|
||||||
customProfiles.joplin-server
|
# customProfiles.joplin-server
|
||||||
customProfiles.media-stack
|
customProfiles.media-stack
|
||||||
customProfiles.minio
|
customProfiles.minio
|
||||||
customProfiles.nginx
|
customProfiles.nginx
|
||||||
|
@ -1,4 +1,6 @@
|
|||||||
{ config, inputs, ... }: {
|
{ config, inputs, ... }: {
|
||||||
|
imports = [ inputs.ataraxiasjel-nur.nixosModules.rustic ];
|
||||||
|
|
||||||
sops.secrets.rustic-vps-pass.sopsFile = inputs.self.secretsDir + /rustic.yaml;
|
sops.secrets.rustic-vps-pass.sopsFile = inputs.self.secretsDir + /rustic.yaml;
|
||||||
sops.secrets.rclone-rustic-backups.sopsFile = inputs.self.secretsDir + /rustic.yaml;
|
sops.secrets.rclone-rustic-backups.sopsFile = inputs.self.secretsDir + /rustic.yaml;
|
||||||
services.rustic.backups = rec {
|
services.rustic.backups = rec {
|
||||||
@ -31,7 +33,7 @@
|
|||||||
ignore-devid = true;
|
ignore-devid = true;
|
||||||
group-by = "label";
|
group-by = "label";
|
||||||
sources = [{
|
sources = [{
|
||||||
source = "/srv/marzban /srv/nextcloud/config /srv/nextcloud/data";
|
source = "/srv/marzban";
|
||||||
}];
|
}];
|
||||||
};
|
};
|
||||||
forget = {
|
forget = {
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
{ config, pkgs, lib, inputs, ... }:
|
{ config, pkgs, inputs, ... }:
|
||||||
let
|
let
|
||||||
|
inherit (pkgs.hostPlatform) system;
|
||||||
cert-key = config.sops.secrets."cert.key".path;
|
cert-key = config.sops.secrets."cert.key".path;
|
||||||
cert-pem = config.sops.secrets."cert.pem".path;
|
cert-pem = config.sops.secrets."cert.pem".path;
|
||||||
nginx-conf = config.sops.secrets."nginx.conf".path;
|
nginx-conf = config.sops.secrets."nginx.conf".path;
|
||||||
@ -25,16 +26,6 @@ in {
|
|||||||
};
|
};
|
||||||
|
|
||||||
virtualisation.oci-containers.containers = {
|
virtualisation.oci-containers.containers = {
|
||||||
nextcloud = {
|
|
||||||
autoStart = true;
|
|
||||||
image = "docker.io/nextcloud:stable";
|
|
||||||
ports = [ "9765:80" ];
|
|
||||||
volumes = [
|
|
||||||
"/srv/nextcloud/html:/var/www/html"
|
|
||||||
"/srv/nextcloud/config:/var/www/html/config"
|
|
||||||
"/srv/nextcloud/data:/var/www/html/data"
|
|
||||||
];
|
|
||||||
};
|
|
||||||
marzban = {
|
marzban = {
|
||||||
autoStart = true;
|
autoStart = true;
|
||||||
image = "ghcr.io/gozargah/marzban:v0.4.1";
|
image = "ghcr.io/gozargah/marzban:v0.4.1";
|
||||||
@ -57,10 +48,20 @@ in {
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
services.ocis = {
|
||||||
|
enable = true;
|
||||||
|
package = inputs.ataraxiasjel-nur.packages.${system}.ocis-bin;
|
||||||
|
configDir = "/srv/ocis/config";
|
||||||
|
baseDataPath = "/srv/ocis/data";
|
||||||
|
environment = {
|
||||||
|
OCIS_INSECURE = "false";
|
||||||
|
OCIS_URL = "https://cloud.ataraxiadev.com";
|
||||||
|
PROXY_HTTP_ADDR = "127.0.0.1:9200";
|
||||||
|
PROXY_TLS = "false";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
systemd.tmpfiles.rules = [
|
systemd.tmpfiles.rules = [
|
||||||
"d /srv/marzban 0755 root root -"
|
"d /srv/marzban 0755 root root -"
|
||||||
"d /srv/nextcloud/html 0755 33 33 -"
|
|
||||||
"d /srv/nextcloud/config 0755 33 33 -"
|
|
||||||
"d /srv/nextcloud/data 0755 33 33 -"
|
|
||||||
];
|
];
|
||||||
}
|
}
|
@ -1,320 +0,0 @@
|
|||||||
# Thanks for original module, anpin! https://gist.github.com/anpin/ecbdb6625400908856ef9482eca3380c
|
|
||||||
{ config, pkgs, lib, ... }:
|
|
||||||
let
|
|
||||||
cfg = config.services.authentik;
|
|
||||||
databaseActuallyCreateLocally = cfg.database.createLocally
|
|
||||||
&& cfg.database.host == "/run/postgresql";
|
|
||||||
|
|
||||||
inherit (lib)
|
|
||||||
mkIf mkEnableOption mkOption types mdDoc literalExpression optional attrsets;
|
|
||||||
inherit (attrsets) optionalAttrs;
|
|
||||||
inherit (types) str bool port submodule package nullOr path enum;
|
|
||||||
|
|
||||||
hostWithPort = h: p: "${h}:${toString p}";
|
|
||||||
|
|
||||||
authentikBaseService = {
|
|
||||||
after = [ "network.target" ]
|
|
||||||
++ optional databaseActuallyCreateLocally "postgresql.service";
|
|
||||||
wantedBy = [ "multi-user.target" ];
|
|
||||||
path = [ cfg.package ];
|
|
||||||
environment = let
|
|
||||||
listenAddress = hostWithPort cfg.listen.address;
|
|
||||||
in {
|
|
||||||
AUTHENTIK_REDIS__HOST = cfg.redis.host;
|
|
||||||
AUTHENTIK_REDIS__PORT = toString cfg.redis.port;
|
|
||||||
|
|
||||||
AUTHENTIK_POSTGRESQL__HOST = cfg.database.host;
|
|
||||||
AUTHENTIK_POSTGRESQL__PORT = mkIf (cfg.database.port != null) "${toString cfg.database.port}";
|
|
||||||
AUTHENTIK_POSTGRESQL__USER = cfg.database.user;
|
|
||||||
AUTHENTIK_POSTGRESQL__NAME = cfg.database.name;
|
|
||||||
|
|
||||||
AUTHENTIK_LISTEN__HTTP = listenAddress cfg.listen.http;
|
|
||||||
AUTHENTIK_LISTEN__HTTPS = listenAddress cfg.listen.https;
|
|
||||||
|
|
||||||
# initial password for admin user
|
|
||||||
AUTHENTIK_BOOTSTRAP_PASSWORD = cfg.defaultPassword;
|
|
||||||
|
|
||||||
# disable outbound connections
|
|
||||||
AUTHENTIK_DISABLE_UPDATE_CHECK = "true";
|
|
||||||
AUTHENTIK_ERROR_REPORTING__ENABLED = "false";
|
|
||||||
AUTHENTIK_DISABLE_STARTUP_ANALYTICS = "true";
|
|
||||||
AUTHENTIK_AVATARS = "initials";
|
|
||||||
|
|
||||||
AUTHENTIK_LOG_LEVEL = cfg.logLevel;
|
|
||||||
};
|
|
||||||
serviceConfig = {
|
|
||||||
User = "authentik";
|
|
||||||
Group = "authentik";
|
|
||||||
EnvironmentFile = cfg.environmentFile;
|
|
||||||
WorkingDirectory = cfg.package;
|
|
||||||
DynamicUser = true;
|
|
||||||
RuntimeDirectory = "authentik";
|
|
||||||
NoNewPrivileges = true;
|
|
||||||
PrivateTmp = true;
|
|
||||||
ProtectHome = true;
|
|
||||||
ProtectSystem = "strict";
|
|
||||||
ProtectKernelTunables = true;
|
|
||||||
ProtectKernelModules = true;
|
|
||||||
ProtectControlGroups = true;
|
|
||||||
SystemCallFilter= "~@cpu-emulation @keyring @module @obsolete @raw-io @reboot @swap @sync";
|
|
||||||
ConfigurationDirectory = "authentik";
|
|
||||||
StateDirectoryMode = "0750";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
in {
|
|
||||||
options.services.authentik = {
|
|
||||||
enable = mkEnableOption "Enables Authentik service";
|
|
||||||
|
|
||||||
package = mkOption {
|
|
||||||
type = package;
|
|
||||||
default = pkgs.authentik;
|
|
||||||
defaultText = literalExpression "pkgs.authentik";
|
|
||||||
description = mdDoc "Authentik package to use.";
|
|
||||||
};
|
|
||||||
|
|
||||||
defaultPassword = mkOption {
|
|
||||||
description = mdDoc "Default admin password. Only read on first startup.";
|
|
||||||
type = str;
|
|
||||||
default = "change-me";
|
|
||||||
};
|
|
||||||
|
|
||||||
logLevel = mkOption {
|
|
||||||
description = mdDoc
|
|
||||||
"Log level for the server and worker containers. Setting the log level to trace will include sensitive details in logs, so it shouldn't be used in most cases.";
|
|
||||||
type = enum [ "trace" "debug" "info" "warning" "error" ];
|
|
||||||
default = "info";
|
|
||||||
};
|
|
||||||
|
|
||||||
listen = mkOption {
|
|
||||||
description = mdDoc "Listen ports";
|
|
||||||
default = { };
|
|
||||||
type = submodule {
|
|
||||||
options = {
|
|
||||||
http = mkOption {
|
|
||||||
description = mdDoc "HTTP port.";
|
|
||||||
type = port;
|
|
||||||
default = 9000;
|
|
||||||
};
|
|
||||||
https = mkOption {
|
|
||||||
description = mdDoc "HTTPS port.";
|
|
||||||
type = port;
|
|
||||||
default = 9443;
|
|
||||||
};
|
|
||||||
address = mkOption {
|
|
||||||
description = mdDoc "Address to listen on.";
|
|
||||||
type = str;
|
|
||||||
default = "0.0.0.0";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
redis = {
|
|
||||||
createLocally = mkOption {
|
|
||||||
description = mdDoc "Configure local Redis server for Authentik.";
|
|
||||||
type = bool;
|
|
||||||
default = true;
|
|
||||||
};
|
|
||||||
|
|
||||||
host = mkOption {
|
|
||||||
description = mdDoc "Redis host.";
|
|
||||||
type = str;
|
|
||||||
default = "127.0.0.1";
|
|
||||||
};
|
|
||||||
|
|
||||||
port = mkOption {
|
|
||||||
description = mdDoc "Redis port.";
|
|
||||||
type = port;
|
|
||||||
default = 31637;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
ssl = {
|
|
||||||
cert = mkOption {
|
|
||||||
type = nullOr path;
|
|
||||||
default = null;
|
|
||||||
};
|
|
||||||
|
|
||||||
key = mkOption {
|
|
||||||
type = nullOr path;
|
|
||||||
default = null;
|
|
||||||
};
|
|
||||||
|
|
||||||
name = mkOption {
|
|
||||||
type = str;
|
|
||||||
default = "SSL from NIXOS";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
environmentFile = mkOption {
|
|
||||||
type = nullOr path;
|
|
||||||
default = null;
|
|
||||||
example = "/var/lib/authentik/secrets/db-password";
|
|
||||||
description = mdDoc ''
|
|
||||||
Environment variables including :
|
|
||||||
- Secret key used for cookie signing and unique user IDs, don't change this after the first install.
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
|
|
||||||
database = {
|
|
||||||
createLocally = mkOption {
|
|
||||||
description =
|
|
||||||
mdDoc "Configure local PostgreSQL database server for authentik.";
|
|
||||||
type = bool;
|
|
||||||
default = true;
|
|
||||||
};
|
|
||||||
|
|
||||||
host = mkOption {
|
|
||||||
type = str;
|
|
||||||
default = "/run/postgresql";
|
|
||||||
example = "192.168.23.42";
|
|
||||||
description = mdDoc "Database host address or unix socket.";
|
|
||||||
};
|
|
||||||
|
|
||||||
port = mkOption {
|
|
||||||
type = nullOr port;
|
|
||||||
default = if cfg.database.createLocally then null else 5432;
|
|
||||||
defaultText = literalExpression ''
|
|
||||||
if config.database.createLocally then null else 5432
|
|
||||||
'';
|
|
||||||
description = mdDoc "Database host port.";
|
|
||||||
};
|
|
||||||
|
|
||||||
name = mkOption {
|
|
||||||
type = str;
|
|
||||||
default = "authentik";
|
|
||||||
description = mdDoc "Database name.";
|
|
||||||
};
|
|
||||||
|
|
||||||
user = mkOption {
|
|
||||||
type = str;
|
|
||||||
default = "authentik";
|
|
||||||
description = mdDoc "Database user.";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
outposts = mkOption {
|
|
||||||
type = submodule {
|
|
||||||
options = {
|
|
||||||
ldap = mkOption {
|
|
||||||
type = submodule {
|
|
||||||
options = {
|
|
||||||
enable =
|
|
||||||
mkEnableOption (lib.mdDoc "the authentik ldap outpost");
|
|
||||||
package = mkOption {
|
|
||||||
type = path;
|
|
||||||
default = pkgs.authentik-outposts.ldap;
|
|
||||||
};
|
|
||||||
host = mkOption {
|
|
||||||
type = str;
|
|
||||||
default = if cfg.outposts.ldap.insecure then
|
|
||||||
"http://127.0.0.1:${toString cfg.listen.http}"
|
|
||||||
else
|
|
||||||
"https://127.0.0.1:${toString cfg.listen.https}";
|
|
||||||
};
|
|
||||||
insecure = mkOption {
|
|
||||||
type = bool;
|
|
||||||
default = false;
|
|
||||||
};
|
|
||||||
environmentFile = mkOption {
|
|
||||||
type = nullOr path;
|
|
||||||
default = null;
|
|
||||||
example = "/var/lib/authentik-ldap/secrets/env";
|
|
||||||
description = mdDoc ''
|
|
||||||
Environment variables including :
|
|
||||||
- API TOKEN
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
listen = mkOption {
|
|
||||||
description = mdDoc "Listen ports";
|
|
||||||
default = { };
|
|
||||||
type = submodule {
|
|
||||||
options = {
|
|
||||||
ldap = mkOption {
|
|
||||||
description = mdDoc "LDAP port.";
|
|
||||||
type = port;
|
|
||||||
default = 3389;
|
|
||||||
};
|
|
||||||
ldaps = mkOption {
|
|
||||||
description = mdDoc "LDAPS port.";
|
|
||||||
type = port;
|
|
||||||
default = 6636;
|
|
||||||
};
|
|
||||||
address = mkOption {
|
|
||||||
description = mdDoc "Address to listen on.";
|
|
||||||
type = str;
|
|
||||||
default = "0.0.0.0";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
default = { ldap = { enable = false; }; };
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
config = mkIf cfg.enable {
|
|
||||||
users.users.authentik = {
|
|
||||||
isSystemUser = true;
|
|
||||||
home = cfg.package;
|
|
||||||
group = "authentik";
|
|
||||||
};
|
|
||||||
users.groups.authentik = { };
|
|
||||||
|
|
||||||
services.postgresql = mkIf databaseActuallyCreateLocally {
|
|
||||||
enable = true;
|
|
||||||
ensureUsers = [{
|
|
||||||
name = cfg.database.name;
|
|
||||||
ensureDBOwnership = true;
|
|
||||||
}];
|
|
||||||
ensureDatabases = [ cfg.database.name ];
|
|
||||||
};
|
|
||||||
|
|
||||||
services.redis.servers.authentik =
|
|
||||||
mkIf (cfg.redis.createLocally && cfg.redis.host == "127.0.0.1") {
|
|
||||||
enable = true;
|
|
||||||
port = cfg.redis.port;
|
|
||||||
bind = "127.0.0.1";
|
|
||||||
};
|
|
||||||
|
|
||||||
systemd.services.authentik-server = authentikBaseService // {
|
|
||||||
serviceConfig = authentikBaseService.serviceConfig // {
|
|
||||||
ExecStart = "${cfg.package}/bin/ak server";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
systemd.services.authentik-worker = authentikBaseService // {
|
|
||||||
serviceConfig = authentikBaseService.serviceConfig // {
|
|
||||||
ExecStart = "${cfg.package}/bin/ak worker";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
# systemd.services.authentik-ssl-import = authentikBaseService // {
|
|
||||||
# before = [ "authentik-server.service" ];
|
|
||||||
# serviceConfig = authentikBaseService.serviceConfig // {
|
|
||||||
# Type = "oneshot";
|
|
||||||
# RemainAfterExit = true;
|
|
||||||
# ExecStart = ''
|
|
||||||
# ${cfg.package}/bin/ak import_certificate --name "${cfg.ssl.name}" --certificate "${cfg.ssl.cert}" --private-key "${cfg.ssl.key}"'';
|
|
||||||
# };
|
|
||||||
# };
|
|
||||||
|
|
||||||
systemd.services.authentik-ldap-outpost = let
|
|
||||||
ldapCfg = cfg.outposts.ldap;
|
|
||||||
in mkIf ldapCfg.enable (authentikBaseService // {
|
|
||||||
description = "authentik ldap outpost";
|
|
||||||
environment = let listenAddress = hostWithPort ldapCfg.listen.address;
|
|
||||||
in {
|
|
||||||
AUTHENTIK_HOST = ldapCfg.host;
|
|
||||||
AUTHENTIK_LISTEN__LDAP = listenAddress ldapCfg.listen.ldap;
|
|
||||||
AUTHENTIK_LISTEN__LDAPS = listenAddress ldapCfg.listen.ldaps;
|
|
||||||
} // optionalAttrs ldapCfg.insecure { AUTHENTIK_INSECURE = "true"; };
|
|
||||||
serviceConfig = authentikBaseService.serviceConfig // {
|
|
||||||
ExecStart = "${cfg.outposts.ldap.package}/bin/ldap";
|
|
||||||
EnvironmentFile = ldapCfg.environmentFile;
|
|
||||||
};
|
|
||||||
});
|
|
||||||
};
|
|
||||||
}
|
|
@ -58,13 +58,13 @@ with lib;
|
|||||||
HEADSCALE_CLI_ADDRESS = "wg.ataraxiadev.com:443";
|
HEADSCALE_CLI_ADDRESS = "wg.ataraxiadev.com:443";
|
||||||
};
|
};
|
||||||
script = ''
|
script = ''
|
||||||
auth_key=$(headscale preauthkeys create -e ${cfg.expire} -u ${cfg.user} -o json ${optionalString cfg.ephemeral "--ephemeral"} | jq -r .key)
|
while true; do
|
||||||
if [ "$auth_key" = "null" ]; then
|
auth_key=$(headscale preauthkeys create -e ${cfg.expire} -u ${cfg.user} -o json ${optionalString cfg.ephemeral "--ephemeral"} | jq -r .key)
|
||||||
echo "Cannot retrieve auth key." >&2
|
[[ "$auth_key" = "null" ]] || break
|
||||||
exit 1
|
echo "Cannot retrieve auth key. Will try again after 5 seconds." >&2
|
||||||
else
|
sleep 5
|
||||||
echo $auth_key > "${cfg.outPath}"
|
done
|
||||||
fi
|
echo $auth_key > "${cfg.outPath}"
|
||||||
'';
|
'';
|
||||||
serviceConfig = {
|
serviceConfig = {
|
||||||
EnvironmentFile = config.sops.secrets.headscale-api-env.path;
|
EnvironmentFile = config.sops.secrets.headscale-api-env.path;
|
||||||
|
@ -1,80 +0,0 @@
|
|||||||
{ config, lib, pkgs, ... }:
|
|
||||||
with lib;
|
|
||||||
let
|
|
||||||
cfg = config.services.kes;
|
|
||||||
format = pkgs.formats.yaml { };
|
|
||||||
configFile = format.generate "config.yaml" cfg.settings;
|
|
||||||
port = strings.toInt (lists.last (strings.splitString ":" cfg.settings.address));
|
|
||||||
in
|
|
||||||
{
|
|
||||||
options.services.kes = {
|
|
||||||
enable = mkEnableOption (mdDoc "Minio's Key Managament Server");
|
|
||||||
package = mkOption {
|
|
||||||
type = types.package;
|
|
||||||
description = mdDoc "Which package to use for the kes instance.";
|
|
||||||
default = pkgs.minio-kes;
|
|
||||||
};
|
|
||||||
environmentFile = mkOption {
|
|
||||||
type = with types; nullOr str;
|
|
||||||
default = null;
|
|
||||||
description = lib.mdDoc ''
|
|
||||||
File in the format of an EnvironmentFile as described by systemd.exec(5).
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
settings = mkOption {
|
|
||||||
type = format.type;
|
|
||||||
default = { address = "0.0.0.0:7373"; };
|
|
||||||
example = literalExpression ''
|
|
||||||
{
|
|
||||||
address = "0.0.0.0:7373";
|
|
||||||
cache = {
|
|
||||||
expiry = {
|
|
||||||
any = "5m0s";
|
|
||||||
unused = "20s";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
}
|
|
||||||
'';
|
|
||||||
description = mdDoc ''
|
|
||||||
KES Configuration.
|
|
||||||
Refer to <https://github.com/minio/kes/blob/master/server-config.yaml>
|
|
||||||
for details on supported values.
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
};
|
|
||||||
config = mkIf cfg.enable {
|
|
||||||
systemd.services.kes = {
|
|
||||||
description = "KES";
|
|
||||||
wantedBy = [ "multi-user.target" ];
|
|
||||||
wants = [ "network-online.target" ];
|
|
||||||
after = [ "network-online.target" ];
|
|
||||||
path = [ cfg.package ];
|
|
||||||
serviceConfig = {
|
|
||||||
Type = "simple";
|
|
||||||
Restart = "always";
|
|
||||||
ExecStart = "${cfg.package}/bin/kes server --config ${configFile}";
|
|
||||||
User = "kes";
|
|
||||||
Group = "kes";
|
|
||||||
# WorkingDirectory = "/etc/kes";
|
|
||||||
|
|
||||||
AmbientCapabilities = mkIf (port < 1024) ["CAP_NET_BIND_SERVICE"];
|
|
||||||
LimitNOFILE = 65536;
|
|
||||||
ProtectProc = "invisible";
|
|
||||||
SendSIGKILL = "no";
|
|
||||||
TasksMax = "infinity";
|
|
||||||
TimeoutStopSec = "infinity";
|
|
||||||
} // optionalAttrs (cfg.environmentFile != null) {
|
|
||||||
EnvironmentFile = cfg.environmentFile;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
environment.systemPackages = [ cfg.package ];
|
|
||||||
|
|
||||||
users.groups.kes = { };
|
|
||||||
users.users.kes = {
|
|
||||||
description = "KES user";
|
|
||||||
group = "kes";
|
|
||||||
isSystemUser = true;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
}
|
|
159
modules/ocis.nix
159
modules/ocis.nix
@ -1,159 +0,0 @@
|
|||||||
{ config, lib, pkgs, ... }:
|
|
||||||
with lib;
|
|
||||||
let
|
|
||||||
cfg = config.services.ocis;
|
|
||||||
format = pkgs.formats.yaml { };
|
|
||||||
|
|
||||||
linkConfigs = confDir: lib.pipe cfg.settings [
|
|
||||||
(lib.attrsets.mapAttrs (n: v: format.generate "${n}.yaml" v))
|
|
||||||
(lib.mapAttrsToList (n: v: "ln -sf ${v} ${confDir}/${n}.yaml"))
|
|
||||||
(lib.concatStringsSep "\n")
|
|
||||||
];
|
|
||||||
|
|
||||||
mkExport = { arg, value }: "export ${arg}=${value}";
|
|
||||||
adminpass = {
|
|
||||||
arg = "ADMIN_PASSWORD";
|
|
||||||
value = ''"$(<"${toString cfg.adminpassFile}")"'';
|
|
||||||
};
|
|
||||||
in
|
|
||||||
{
|
|
||||||
options.services.ocis = {
|
|
||||||
enable = mkEnableOption (lib.mdDoc "ownCloud Infinite Scale Stack");
|
|
||||||
package = mkOption {
|
|
||||||
type = types.package;
|
|
||||||
description = lib.mdDoc "Which package to use for the ocis instance.";
|
|
||||||
default = pkgs.ocis-bin;
|
|
||||||
};
|
|
||||||
configDir = mkOption {
|
|
||||||
default = "/var/lib/ocis/.config";
|
|
||||||
type = types.path;
|
|
||||||
description = lib.mdDoc "The config directory. Set OCIS_CONFIG_DIR env variable.";
|
|
||||||
};
|
|
||||||
baseDataPath = mkOption {
|
|
||||||
default = "/var/lib/ocis";
|
|
||||||
type = types.path;
|
|
||||||
description = lib.mdDoc "The base data directory. Set OCIS_BASE_DATA_PATH env variable.";
|
|
||||||
};
|
|
||||||
environment = lib.mkOption {
|
|
||||||
type = lib.types.attrsOf lib.types.str;
|
|
||||||
default = { };
|
|
||||||
example = lib.literalExpression ''
|
|
||||||
{
|
|
||||||
OCIS_URL = "https://localhost:9200";
|
|
||||||
}
|
|
||||||
'';
|
|
||||||
description = lib.mdDoc "Environment variables to pass to ocis instance.";
|
|
||||||
};
|
|
||||||
environmentFile = mkOption {
|
|
||||||
type = with types; nullOr str;
|
|
||||||
default = null;
|
|
||||||
description = lib.mdDoc ''
|
|
||||||
File in the format of an EnvironmentFile as described by systemd.exec(5).
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
adminpassFile = mkOption {
|
|
||||||
type = with types; nullOr str;
|
|
||||||
default = null;
|
|
||||||
description = lib.mdDoc ''
|
|
||||||
The full path to a file that contains the admin's password. Must be
|
|
||||||
readable by user `ocis`. The password is set only in the initial
|
|
||||||
setup of Ocis by the systemd service `ocis-init.service`.
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
settings = mkOption {
|
|
||||||
type = with types; attrsOf format.type;
|
|
||||||
default = { };
|
|
||||||
example = lib.literalExpression ''
|
|
||||||
{
|
|
||||||
auth-bearer = {
|
|
||||||
tracing = {
|
|
||||||
enabled = true;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
proxy = {
|
|
||||||
user_oidc_claim = "preferred_username";
|
|
||||||
user_cs3_claim = "username";
|
|
||||||
};
|
|
||||||
}
|
|
||||||
'';
|
|
||||||
description = lib.mdDoc ''
|
|
||||||
OCIS configuration. Refer to
|
|
||||||
<https://doc.owncloud.com/ocis/next/deployment/services/services.html>
|
|
||||||
for details on supported values.
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
};
|
|
||||||
config = mkIf cfg.enable {
|
|
||||||
systemd.tmpfiles.rules = [
|
|
||||||
"d '${cfg.configDir}' - ocis ocis - -"
|
|
||||||
"d '${cfg.baseDataPath}' - ocis ocis - -"
|
|
||||||
];
|
|
||||||
systemd.services.ocis-init = rec {
|
|
||||||
before = [ "ocis-server.service" ];
|
|
||||||
requiredBy = [ "ocis-server.service" ];
|
|
||||||
path = [ cfg.package ];
|
|
||||||
environment = {
|
|
||||||
OCIS_CONFIG_DIR = cfg.configDir;
|
|
||||||
OCIS_BASE_DATA_PATH = cfg.baseDataPath;
|
|
||||||
} // cfg.environment;
|
|
||||||
script = ''
|
|
||||||
${lib.optionalString (cfg.settings != { }) "${linkConfigs environment.OCIS_CONFIG_DIR}"}
|
|
||||||
if [ ! -f "$OCIS_CONFIG_DIR/ocis.yaml" ]; then
|
|
||||||
${
|
|
||||||
lib.optionalString (cfg.adminpassFile != null) ''
|
|
||||||
if [ ! -r "${cfg.adminpassFile}" ]; then
|
|
||||||
echo "adminpassFile ${cfg.adminpassFile} is not readable by ocis:ocis! Aborting..."
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
if [ -z "$(<${cfg.adminpassFile})" ]; then
|
|
||||||
echo "adminpassFile ${cfg.adminpassFile} is empty!"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
${mkExport adminpass}
|
|
||||||
''
|
|
||||||
}
|
|
||||||
ocis init
|
|
||||||
fi
|
|
||||||
'';
|
|
||||||
serviceConfig = {
|
|
||||||
Type = "simple";
|
|
||||||
StateDirectory = "ocis";
|
|
||||||
User = "ocis";
|
|
||||||
Group = "ocis";
|
|
||||||
} // optionalAttrs (cfg.environmentFile != null) {
|
|
||||||
EnvironmentFile = cfg.environmentFile;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
systemd.services.ocis-server = {
|
|
||||||
description = "ownCloud Infinite Scale Stack";
|
|
||||||
wantedBy = [ "multi-user.target" ];
|
|
||||||
path = [ cfg.package ];
|
|
||||||
environment = {
|
|
||||||
OCIS_CONFIG_DIR = cfg.configDir;
|
|
||||||
OCIS_BASE_DATA_PATH = cfg.baseDataPath;
|
|
||||||
OCIS_URL = "https://localhost:9200";
|
|
||||||
PROXY_HTTP_ADDR = "127.0.0.1:9200";
|
|
||||||
} // cfg.environment;
|
|
||||||
serviceConfig = {
|
|
||||||
Type = "simple";
|
|
||||||
Restart = "always";
|
|
||||||
ExecStart = "${cfg.package}/bin/ocis server";
|
|
||||||
User = "ocis";
|
|
||||||
Group = "ocis";
|
|
||||||
LimitNOFILE = 65536;
|
|
||||||
} // optionalAttrs (cfg.environmentFile != null) {
|
|
||||||
EnvironmentFile = cfg.environmentFile;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
environment.systemPackages = [ cfg.package ];
|
|
||||||
|
|
||||||
users.groups.ocis = { };
|
|
||||||
users.users.ocis = {
|
|
||||||
description = "Ocis Daemon User";
|
|
||||||
group = "ocis";
|
|
||||||
isSystemUser = true;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
}
|
|
@ -19,6 +19,7 @@ with lib;
|
|||||||
}));
|
}));
|
||||||
default = { };
|
default = { };
|
||||||
};
|
};
|
||||||
|
imports = [ inputs.ataraxiasjel-nur.nixosModules.rustic ];
|
||||||
config = mkIf (config.backups.postgresql != { }) {
|
config = mkIf (config.backups.postgresql != { }) {
|
||||||
sops.secrets.rclone-postgresql-backups.sopsFile = inputs.self.secretsDir + /rustic.yaml;
|
sops.secrets.rclone-postgresql-backups.sopsFile = inputs.self.secretsDir + /rustic.yaml;
|
||||||
sops.secrets.rustic-postgresql-pass.sopsFile = inputs.self.secretsDir + /rustic.yaml;
|
sops.secrets.rustic-postgresql-pass.sopsFile = inputs.self.secretsDir + /rustic.yaml;
|
||||||
|
@ -1,324 +0,0 @@
|
|||||||
{ config, lib, pkgs, utils, ... }:
|
|
||||||
|
|
||||||
with lib;
|
|
||||||
|
|
||||||
let
|
|
||||||
# Type for a valid systemd unit option. Needed for correctly passing "timerConfig" to "systemd.timers"
|
|
||||||
inherit (utils.systemdUtils.unitOptions) unitOption;
|
|
||||||
settingsFormat = pkgs.formats.toml {};
|
|
||||||
in
|
|
||||||
{
|
|
||||||
options.services.rustic.backups = mkOption {
|
|
||||||
description = lib.mdDoc ''
|
|
||||||
Periodic backups to create with Rustic.
|
|
||||||
'';
|
|
||||||
type = types.attrsOf (types.submodule ({ config, name, ... }: {
|
|
||||||
options = {
|
|
||||||
settings = mkOption {
|
|
||||||
type = settingsFormat.type;
|
|
||||||
default = {};
|
|
||||||
description = lib.mdDoc ''
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
|
|
||||||
environmentFile = mkOption {
|
|
||||||
type = with types; nullOr str;
|
|
||||||
default = null;
|
|
||||||
description = lib.mdDoc ''
|
|
||||||
file containing the credentials to access the repository, in the
|
|
||||||
format of an EnvironmentFile as described by systemd.exec(5)
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
|
|
||||||
extraEnvironment = lib.mkOption {
|
|
||||||
type = lib.types.attrsOf lib.types.str;
|
|
||||||
default = { };
|
|
||||||
example = lib.literalExpression ''
|
|
||||||
{
|
|
||||||
http_proxy = "http://server:12345";
|
|
||||||
}
|
|
||||||
'';
|
|
||||||
description = lib.mdDoc "Environment variables to pass to rustic.";
|
|
||||||
};
|
|
||||||
|
|
||||||
rcloneOptions = mkOption {
|
|
||||||
type = with types; nullOr (attrsOf (oneOf [ str bool ]));
|
|
||||||
default = null;
|
|
||||||
description = lib.mdDoc ''
|
|
||||||
Options to pass to rclone to control its behavior.
|
|
||||||
See <https://rclone.org/docs/#options> for
|
|
||||||
available options. When specifying option names, strip the
|
|
||||||
leading `--`. To set a flag such as
|
|
||||||
`--drive-use-trash`, which does not take a value,
|
|
||||||
set the value to the Boolean `true`.
|
|
||||||
'';
|
|
||||||
example = {
|
|
||||||
bwlimit = "10M";
|
|
||||||
drive-use-trash = "true";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
rcloneConfigFile = mkOption {
|
|
||||||
type = with types; nullOr path;
|
|
||||||
default = null;
|
|
||||||
description = lib.mdDoc ''
|
|
||||||
Path to the file containing rclone configuration. This file
|
|
||||||
must contain configuration for the remote specified in this backup
|
|
||||||
set and also must be readable by root. Options set in
|
|
||||||
`rcloneConfig` will override those set in this
|
|
||||||
file.
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
|
|
||||||
timerConfig = mkOption {
|
|
||||||
type = types.attrsOf unitOption;
|
|
||||||
default = {
|
|
||||||
OnCalendar = "daily";
|
|
||||||
Persistent = true;
|
|
||||||
};
|
|
||||||
description = lib.mdDoc ''
|
|
||||||
When to run the backup. See {manpage}`systemd.timer(5)` for details.
|
|
||||||
'';
|
|
||||||
example = {
|
|
||||||
OnCalendar = "00:05";
|
|
||||||
RandomizedDelaySec = "5h";
|
|
||||||
Persistent = true;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
user = mkOption {
|
|
||||||
type = types.str;
|
|
||||||
default = "root";
|
|
||||||
description = lib.mdDoc ''
|
|
||||||
As which user the backup should run.
|
|
||||||
'';
|
|
||||||
example = "postgresql";
|
|
||||||
};
|
|
||||||
|
|
||||||
extraBackupArgs = mkOption {
|
|
||||||
type = types.listOf types.str;
|
|
||||||
default = [ ];
|
|
||||||
description = lib.mdDoc ''
|
|
||||||
Extra arguments passed to rustic backup.
|
|
||||||
'';
|
|
||||||
example = [
|
|
||||||
"--exclude-file=/etc/nixos/rustic-ignore"
|
|
||||||
];
|
|
||||||
};
|
|
||||||
|
|
||||||
extraOptions = mkOption {
|
|
||||||
type = types.listOf types.str;
|
|
||||||
default = [ ];
|
|
||||||
description = lib.mdDoc ''
|
|
||||||
Extra extended options to be passed to the rustic --option flag.
|
|
||||||
'';
|
|
||||||
example = [
|
|
||||||
"sftp.command='ssh backup@192.168.1.100 -i /home/user/.ssh/id_rsa -s sftp'"
|
|
||||||
];
|
|
||||||
};
|
|
||||||
|
|
||||||
backup = mkOption {
|
|
||||||
type = types.bool;
|
|
||||||
default = true;
|
|
||||||
description = lib.mdDoc ''
|
|
||||||
Start backup.
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
|
|
||||||
prune = mkOption {
|
|
||||||
type = types.bool;
|
|
||||||
default = true;
|
|
||||||
description = lib.mdDoc ''
|
|
||||||
Start prune.
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
|
|
||||||
initialize = mkOption {
|
|
||||||
type = types.bool;
|
|
||||||
default = false;
|
|
||||||
description = lib.mdDoc ''
|
|
||||||
Create the repository if it doesn't exist.
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
|
|
||||||
initializeOpts = mkOption {
|
|
||||||
type = types.listOf types.str;
|
|
||||||
default = [ ];
|
|
||||||
description = lib.mdDoc ''
|
|
||||||
A list of options for 'rustic init'.
|
|
||||||
'';
|
|
||||||
example = [
|
|
||||||
"--set-version 2"
|
|
||||||
];
|
|
||||||
};
|
|
||||||
|
|
||||||
checkOpts = mkOption {
|
|
||||||
type = types.listOf types.str;
|
|
||||||
default = [ ];
|
|
||||||
description = lib.mdDoc ''
|
|
||||||
A list of options for 'rustic check', which is run after
|
|
||||||
pruning.
|
|
||||||
'';
|
|
||||||
example = [
|
|
||||||
"--with-cache"
|
|
||||||
];
|
|
||||||
};
|
|
||||||
|
|
||||||
pruneOpts = mkOption {
|
|
||||||
type = types.listOf types.str;
|
|
||||||
default = [ ];
|
|
||||||
description = lib.mdDoc ''
|
|
||||||
A list of options for 'rustic prune', which is run before
|
|
||||||
pruning.
|
|
||||||
'';
|
|
||||||
example = [
|
|
||||||
"--repack-cacheable-only=false"
|
|
||||||
];
|
|
||||||
};
|
|
||||||
|
|
||||||
backupCommandPrefix = mkOption {
|
|
||||||
type = types.str;
|
|
||||||
default = "";
|
|
||||||
description = lib.mdDoc ''
|
|
||||||
Prefix for backup command.
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
|
|
||||||
backupCommandSuffix = mkOption {
|
|
||||||
type = types.str;
|
|
||||||
default = "";
|
|
||||||
description = lib.mdDoc ''
|
|
||||||
Suffix for backup command.
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
|
|
||||||
backupPrepareCommand = mkOption {
|
|
||||||
type = with types; nullOr str;
|
|
||||||
default = null;
|
|
||||||
description = lib.mdDoc ''
|
|
||||||
A script that must run before starting the backup process.
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
|
|
||||||
backupCleanupCommand = mkOption {
|
|
||||||
type = with types; nullOr str;
|
|
||||||
default = null;
|
|
||||||
description = lib.mdDoc ''
|
|
||||||
A script that must run after finishing the backup process.
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
|
|
||||||
package = mkOption {
|
|
||||||
type = types.package;
|
|
||||||
default = pkgs.rustic-rs;
|
|
||||||
defaultText = literalExpression "pkgs.rustic-rs";
|
|
||||||
description = lib.mdDoc ''
|
|
||||||
Rustic package to use.
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
|
|
||||||
createWrapper = lib.mkOption {
|
|
||||||
type = lib.types.bool;
|
|
||||||
default = true;
|
|
||||||
description = ''
|
|
||||||
Whether to generate and add a script to the system path, that has the same environment variables set
|
|
||||||
as the systemd service. This can be used to e.g. mount snapshots or perform other opterations, without
|
|
||||||
having to manually specify most options.
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
};
|
|
||||||
}));
|
|
||||||
default = { };
|
|
||||||
};
|
|
||||||
|
|
||||||
config = {
|
|
||||||
systemd.services =
|
|
||||||
mapAttrs'
|
|
||||||
(name: backup:
|
|
||||||
let
|
|
||||||
profile = settingsFormat.generate "${name}.toml" backup.settings;
|
|
||||||
extraOptions = concatMapStrings (arg: " -o ${arg}") backup.extraOptions;
|
|
||||||
rusticCmd = "${backup.package}/bin/rustic -P ${lib.strings.removeSuffix ".toml" profile}${extraOptions}";
|
|
||||||
# Helper functions for rclone remotes
|
|
||||||
rcloneAttrToOpt = v: "RCLONE_" + toUpper (builtins.replaceStrings [ "-" ] [ "_" ] v);
|
|
||||||
toRcloneVal = v: if lib.isBool v then lib.boolToString v else v;
|
|
||||||
in
|
|
||||||
nameValuePair "rustic-backups-${name}" ({
|
|
||||||
environment = backup.extraEnvironment // {
|
|
||||||
# not %C, because that wouldn't work in the wrapper script
|
|
||||||
RUSTIC_CACHE_DIR = "/var/cache/rustic-backups-${name}";
|
|
||||||
} // optionalAttrs (backup.rcloneConfigFile != null) {
|
|
||||||
RCLONE_CONFIG = backup.rcloneConfigFile;
|
|
||||||
} // optionalAttrs (backup.rcloneOptions != null) (mapAttrs'
|
|
||||||
(name: value:
|
|
||||||
nameValuePair (rcloneAttrToOpt name) (toRcloneVal value)
|
|
||||||
)
|
|
||||||
backup.rcloneOptions);
|
|
||||||
path = [ config.programs.ssh.package pkgs.rclone ];
|
|
||||||
restartIfChanged = false;
|
|
||||||
wants = [ "network-online.target" ];
|
|
||||||
after = [ "network-online.target" ];
|
|
||||||
script = ''
|
|
||||||
${optionalString (backup.backup) ''
|
|
||||||
${backup.backupCommandPrefix} ${rusticCmd} backup ${concatStringsSep " " backup.extraBackupArgs} ${backup.backupCommandSuffix}
|
|
||||||
''}
|
|
||||||
${optionalString (backup.prune) ''
|
|
||||||
${rusticCmd} forget --prune ${concatStringsSep " " backup.pruneOpts}
|
|
||||||
${rusticCmd} check ${concatStringsSep " " backup.checkOpts}
|
|
||||||
''}
|
|
||||||
'';
|
|
||||||
serviceConfig = {
|
|
||||||
Type = "oneshot";
|
|
||||||
User = backup.user;
|
|
||||||
RuntimeDirectory = "rustic-backups-${name}";
|
|
||||||
CacheDirectory = "rustic-backups-${name}";
|
|
||||||
CacheDirectoryMode = "0700";
|
|
||||||
PrivateTmp = true;
|
|
||||||
} // optionalAttrs (backup.environmentFile != null) {
|
|
||||||
EnvironmentFile = backup.environmentFile;
|
|
||||||
};
|
|
||||||
} // optionalAttrs (backup.initialize || backup.backupPrepareCommand != null) {
|
|
||||||
preStart = ''
|
|
||||||
${optionalString (backup.backupPrepareCommand != null) ''
|
|
||||||
${pkgs.writeScript "backupPrepareCommand" backup.backupPrepareCommand}
|
|
||||||
''}
|
|
||||||
${optionalString (backup.initialize) ''
|
|
||||||
${rusticCmd} init ${concatStringsSep " " backup.initializeOpts} || true
|
|
||||||
''}
|
|
||||||
'';
|
|
||||||
} // optionalAttrs (backup.backupCleanupCommand != null) {
|
|
||||||
postStop = ''
|
|
||||||
${optionalString (backup.backupCleanupCommand != null) ''
|
|
||||||
${pkgs.writeScript "backupCleanupCommand" backup.backupCleanupCommand}
|
|
||||||
''}
|
|
||||||
'';
|
|
||||||
})
|
|
||||||
)
|
|
||||||
config.services.rustic.backups;
|
|
||||||
systemd.timers =
|
|
||||||
mapAttrs'
|
|
||||||
(name: backup: nameValuePair "rustic-backups-${name}" {
|
|
||||||
wantedBy = [ "timers.target" ];
|
|
||||||
timerConfig = backup.timerConfig;
|
|
||||||
})
|
|
||||||
config.services.rustic.backups;
|
|
||||||
|
|
||||||
# generate wrapper scripts, as described in the createWrapper option
|
|
||||||
environment.systemPackages = lib.mapAttrsToList (name: backup: let
|
|
||||||
profile = settingsFormat.generate "${name}.toml" backup.settings;
|
|
||||||
extraOptions = concatMapStrings (arg: " -o ${arg}") backup.extraOptions;
|
|
||||||
rusticCmd = "${backup.package}/bin/rustic -P ${lib.strings.removeSuffix ".toml" profile}${extraOptions}";
|
|
||||||
in pkgs.writeShellScriptBin "rustic-${name}" ''
|
|
||||||
set -a # automatically export variables
|
|
||||||
${lib.optionalString (backup.environmentFile != null) "source ${backup.environmentFile}"}
|
|
||||||
# set same environment variables as the systemd service
|
|
||||||
${lib.pipe config.systemd.services."rustic-backups-${name}".environment [
|
|
||||||
(lib.filterAttrs (_: v: v != null))
|
|
||||||
(lib.mapAttrsToList (n: v: "${n}=${v}"))
|
|
||||||
(lib.concatStringsSep "\n")
|
|
||||||
]}
|
|
||||||
|
|
||||||
exec ${rusticCmd} $@
|
|
||||||
'') (lib.filterAttrs (_: v: v.createWrapper) config.services.rustic.backups);
|
|
||||||
};
|
|
||||||
}
|
|
@ -62,6 +62,7 @@ with config.deviceSpecific; {
|
|||||||
# libreoffice
|
# libreoffice
|
||||||
obs-studio
|
obs-studio
|
||||||
obs-studio-plugins.obs-vkcapture
|
obs-studio-plugins.obs-vkcapture
|
||||||
|
obsidian
|
||||||
pinta
|
pinta
|
||||||
qbittorrent
|
qbittorrent
|
||||||
sonixd
|
sonixd
|
||||||
@ -92,6 +93,7 @@ with config.deviceSpecific; {
|
|||||||
".config/kdeconnect"
|
".config/kdeconnect"
|
||||||
".config/libreoffice"
|
".config/libreoffice"
|
||||||
".config/obs-studio"
|
".config/obs-studio"
|
||||||
|
".config/obsidian"
|
||||||
".config/pcmanfm"
|
".config/pcmanfm"
|
||||||
# ".config/Pinta"
|
# ".config/Pinta"
|
||||||
".config/qBittorrent"
|
".config/qBittorrent"
|
||||||
|
@ -123,12 +123,12 @@ in
|
|||||||
"license.extension" = ".md";
|
"license.extension" = ".md";
|
||||||
"license.year" = "auto";
|
"license.year" = "auto";
|
||||||
"nix.enableLanguageServer" = true;
|
"nix.enableLanguageServer" = true;
|
||||||
"nix.formatterPath" = "${pkgs.nixfmt}/bin/nixfmt";
|
"nix.formatterPath" = "${pkgs.nixfmt-rfc-style}/bin/nixfmt";
|
||||||
"nix.serverPath" = "${pkgs.nil}/bin/nil";
|
"nix.serverPath" = "${pkgs.nil}/bin/nil";
|
||||||
"nix.serverSettings" = {
|
"nix.serverSettings" = {
|
||||||
"nil" = {
|
"nil" = {
|
||||||
"formatting" = {
|
"formatting" = {
|
||||||
"command" = ["${pkgs.nixfmt}/bin/nixfmt"];
|
"command" = ["${pkgs.nixfmt-rfc-style}/bin/nixfmt"];
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
@ -9,16 +9,16 @@ let
|
|||||||
config = config.nixpkgs.config;
|
config = config.nixpkgs.config;
|
||||||
localSystem = { inherit system; };
|
localSystem = { inherit system; };
|
||||||
};
|
};
|
||||||
nur = import inputs.nur {
|
# nur = import inputs.nur {
|
||||||
nurpkgs = import inputs.nixpkgs {
|
# nurpkgs = import inputs.nixpkgs {
|
||||||
system = "x86_64-linux";
|
# system = "x86_64-linux";
|
||||||
};
|
# };
|
||||||
};
|
# };
|
||||||
in
|
in
|
||||||
with lib; {
|
with lib; {
|
||||||
nixpkgs.overlays = [
|
nixpkgs.overlays = [
|
||||||
nur.repos.ataraxiasjel.overlays.default
|
inputs.ataraxiasjel-nur.overlays.default
|
||||||
nur.repos.ataraxiasjel.overlays.grub2-argon2
|
inputs.ataraxiasjel-nur.overlays.grub2-argon2
|
||||||
inputs.deploy-rs.overlay
|
inputs.deploy-rs.overlay
|
||||||
inputs.hyprland.overlays.default
|
inputs.hyprland.overlays.default
|
||||||
(final: prev:
|
(final: prev:
|
||||||
|
@ -1,4 +1,6 @@
|
|||||||
{ config, inputs, ... }: {
|
{ config, inputs, ... }: {
|
||||||
|
imports = [ inputs.ataraxiasjel-nur.nixosModules.authentik ];
|
||||||
|
|
||||||
sops.secrets.authentik-env.sopsFile = inputs.self.secretsDir + /home-hypervisor/authentik.yaml;
|
sops.secrets.authentik-env.sopsFile = inputs.self.secretsDir + /home-hypervisor/authentik.yaml;
|
||||||
sops.secrets.authentik-ldap.sopsFile = inputs.self.secretsDir + /home-hypervisor/authentik.yaml;
|
sops.secrets.authentik-ldap.sopsFile = inputs.self.secretsDir + /home-hypervisor/authentik.yaml;
|
||||||
sops.secrets.authentik-env.restartUnits = [ "authentik-server.service" "authentik-worker.service" ];
|
sops.secrets.authentik-env.restartUnits = [ "authentik-server.service" "authentik-worker.service" ];
|
||||||
|
@ -40,11 +40,14 @@ in {
|
|||||||
owner = "headscale";
|
owner = "headscale";
|
||||||
restartUnits = [ "headscale.service" ];
|
restartUnits = [ "headscale.service" ];
|
||||||
};
|
};
|
||||||
systemd.services.headscale.after = lib.mkIf config.services.authentik.enable [
|
systemd.services.headscale = {
|
||||||
"authentik-server.service"
|
serviceConfig.TimeoutStopSec = 10;
|
||||||
"authentik-worker.service"
|
after = lib.mkIf config.services.authentik.enable [
|
||||||
"nginx.service"
|
"authentik-server.service"
|
||||||
];
|
"authentik-worker.service"
|
||||||
|
"nginx.service"
|
||||||
|
];
|
||||||
|
};
|
||||||
|
|
||||||
persist.state.directories = [ "/var/lib/headscale" ];
|
persist.state.directories = [ "/var/lib/headscale" ];
|
||||||
}
|
}
|
@ -1,72 +1,30 @@
|
|||||||
{ config, lib, pkgs, ... }:
|
{ config, inputs, ... }: {
|
||||||
let
|
imports = [ inputs.ataraxiasjel-nur.nixosModules.homepage ];
|
||||||
backend = config.virtualisation.oci-containers.backend;
|
|
||||||
nas-path = "/media/nas/containers";
|
services.homepage-dashboard = {
|
||||||
pod-name = "homepage-pod";
|
enable = true;
|
||||||
pod-dns = "192.168.0.1";
|
listenPort = 3000;
|
||||||
open-ports = [
|
dataDir = "/srv/homepage";
|
||||||
"127.0.0.1:3000:3000/tcp"
|
|
||||||
];
|
|
||||||
in {
|
|
||||||
virtualisation.oci-containers.containers = {
|
|
||||||
homepage = {
|
|
||||||
autoStart = true;
|
|
||||||
image = "ghcr.io/gethomepage/homepage:v0.8.0";
|
|
||||||
environment = {
|
|
||||||
PUID = "1000";
|
|
||||||
PGID = "100";
|
|
||||||
};
|
|
||||||
extraOptions = [ "--pod=${pod-name}" ];
|
|
||||||
volumes = [
|
|
||||||
"${nas-path}/homepage/config:/app/config"
|
|
||||||
"${nas-path}/homepage/icons:/app/public/icons"
|
|
||||||
"${nas-path}/homepage/images:/app/public/images"
|
|
||||||
];
|
|
||||||
};
|
|
||||||
docker-proxy = {
|
|
||||||
autoStart = true;
|
|
||||||
image = "ghcr.io/tecnativa/docker-socket-proxy:0.1.1";
|
|
||||||
environment = {
|
|
||||||
CONTAINERS = "1";
|
|
||||||
SERVICES = "0";
|
|
||||||
TASKS = "0";
|
|
||||||
POST = "0";
|
|
||||||
};
|
|
||||||
extraOptions = [ "--pod=${pod-name}" ];
|
|
||||||
volumes = [
|
|
||||||
"${nas-path}/homepage/config:/app/config"
|
|
||||||
"${nas-path}/homepage/icons:/app/public/icons"
|
|
||||||
"${nas-path}/homepage/images:/app/public/images"
|
|
||||||
"/var/run/docker.sock:/var/run/docker.sock:ro"
|
|
||||||
];
|
|
||||||
};
|
|
||||||
};
|
};
|
||||||
|
|
||||||
systemd.tmpfiles.rules = [
|
systemd.tmpfiles.rules = let
|
||||||
"d ${nas-path}/homepage/config 0755 1000 100 -"
|
cfg = config.services.homepage-dashboard;
|
||||||
"d ${nas-path}/homepage/icons 0755 1000 100 -"
|
in [
|
||||||
"d ${nas-path}/homepage/images 0755 1000 100 -"
|
"d ${cfg.dataDir} 0755 ${cfg.user} ${cfg.group} -"
|
||||||
];
|
];
|
||||||
|
|
||||||
systemd.services."podman-create-${pod-name}" = let
|
virtualisation.oci-containers.containers.docker-proxy = {
|
||||||
portsMapping = lib.concatMapStrings (port: " -p " + port) open-ports;
|
autoStart = true;
|
||||||
start = pkgs.writeShellScript "create-pod-${pod-name}" ''
|
image = "ghcr.io/tecnativa/docker-socket-proxy:0.1.1";
|
||||||
podman pod exists ${pod-name} || podman pod create -n ${pod-name} ${portsMapping} --dns ${pod-dns}
|
environment = {
|
||||||
'';
|
CONTAINERS = "1";
|
||||||
stop = "podman pod rm -i -f ${pod-name}";
|
SERVICES = "0";
|
||||||
in rec {
|
TASKS = "0";
|
||||||
path = [ pkgs.coreutils config.virtualisation.podman.package ];
|
POST = "0";
|
||||||
before = [
|
|
||||||
"${backend}-homepage.service"
|
|
||||||
"${backend}-docker-proxy.service"
|
|
||||||
];
|
|
||||||
requiredBy = before;
|
|
||||||
partOf = before;
|
|
||||||
serviceConfig = {
|
|
||||||
Type = "oneshot";
|
|
||||||
RemainAfterExit = "yes";
|
|
||||||
ExecStart = start;
|
|
||||||
ExecStop = stop;
|
|
||||||
};
|
};
|
||||||
|
ports = [ "127.0.0.1:2375:2375/tcp" ];
|
||||||
|
volumes = [
|
||||||
|
"/var/run/docker.sock:/var/run/docker.sock:ro"
|
||||||
|
];
|
||||||
};
|
};
|
||||||
}
|
}
|
@ -13,6 +13,8 @@ let
|
|||||||
restartUnits = [ "kes.service" ];
|
restartUnits = [ "kes.service" ];
|
||||||
};
|
};
|
||||||
in {
|
in {
|
||||||
|
imports = [ inputs.ataraxiasjel-nur.nixosModules.kes ];
|
||||||
|
|
||||||
sops.secrets.minio-credentials = minio-secret;
|
sops.secrets.minio-credentials = minio-secret;
|
||||||
sops.secrets.kes-vault-env = kes-secret;
|
sops.secrets.kes-vault-env = kes-secret;
|
||||||
sops.secrets.kes-key = kes-secret;
|
sops.secrets.kes-key = kes-secret;
|
||||||
|
@ -5,6 +5,8 @@
|
|||||||
sopsFile = inputs.self.secretsDir + /home-hypervisor/ocis.yaml;
|
sopsFile = inputs.self.secretsDir + /home-hypervisor/ocis.yaml;
|
||||||
restartUnits = [ "ocis-server.service" ];
|
restartUnits = [ "ocis-server.service" ];
|
||||||
};
|
};
|
||||||
|
imports = [ inputs.ataraxiasjel-nur.nixosModules.ocis ];
|
||||||
|
|
||||||
services.ocis = {
|
services.ocis = {
|
||||||
enable = true;
|
enable = true;
|
||||||
configDir = "/var/lib/ocis";
|
configDir = "/var/lib/ocis";
|
||||||
|
@ -24,10 +24,16 @@ in {
|
|||||||
wantedBy = [ "multi-user.target" ];
|
wantedBy = [ "multi-user.target" ];
|
||||||
partOf = [ "vault.service" ];
|
partOf = [ "vault.service" ];
|
||||||
after = [ "vault.service" ];
|
after = [ "vault.service" ];
|
||||||
path = [ pkgs.curl ];
|
path = [ pkgs.curl pkgs.jq ];
|
||||||
script = ''
|
script = ''
|
||||||
set -aeuo pipefail
|
set -a
|
||||||
source ${config.sops.secrets.vault-keys-env.path}
|
source ${config.sops.secrets.vault-keys-env.path}
|
||||||
|
while true; do
|
||||||
|
initialized=$(curl -s ${api-addr}/v1/sys/health | jq -r '.initialized')
|
||||||
|
[[ "$initialized" = "true" ]] && break
|
||||||
|
echo "Vault has not been initialized yet. Will try again after 5 seconds." >&2
|
||||||
|
sleep 5
|
||||||
|
done
|
||||||
curl -H "Content-Type: application/json" --data "{\"key\":\"$VAULT_KEY1\"}" ${api-addr}/v1/sys/unseal >/dev/null 2>&1
|
curl -H "Content-Type: application/json" --data "{\"key\":\"$VAULT_KEY1\"}" ${api-addr}/v1/sys/unseal >/dev/null 2>&1
|
||||||
curl -H "Content-Type: application/json" --data "{\"key\":\"$VAULT_KEY2\"}" ${api-addr}/v1/sys/unseal >/dev/null 2>&1
|
curl -H "Content-Type: application/json" --data "{\"key\":\"$VAULT_KEY2\"}" ${api-addr}/v1/sys/unseal >/dev/null 2>&1
|
||||||
curl -H "Content-Type: application/json" --data "{\"key\":\"$VAULT_KEY3\"}" ${api-addr}/v1/sys/unseal >/dev/null 2>&1
|
curl -H "Content-Type: application/json" --data "{\"key\":\"$VAULT_KEY3\"}" ${api-addr}/v1/sys/unseal >/dev/null 2>&1
|
||||||
|
File diff suppressed because one or more lines are too long
Loading…
x
Reference in New Issue
Block a user