mirror of
https://github.com/Swarsel/.dotfiles.git
synced 2025-12-06 09:07:21 +01:00
feat: network overhaul
This commit is contained in:
parent
22fe55c284
commit
ed15ef02bb
34 changed files with 1704 additions and 1037 deletions
|
|
@ -5,4 +5,8 @@
|
|||
type = lib.types.path;
|
||||
default = ./.;
|
||||
};
|
||||
options.node.name = lib.mkOption {
|
||||
description = "Node Name.";
|
||||
type = lib.types.str;
|
||||
};
|
||||
}
|
||||
|
|
|
|||
78
modules/nixos/common/nodes.nix
Normal file
78
modules/nixos/common/nodes.nix
Normal file
|
|
@ -0,0 +1,78 @@
|
|||
{ config, lib, outputs, ... }:
|
||||
let
|
||||
inherit (lib)
|
||||
attrNames
|
||||
concatMap
|
||||
concatStringsSep
|
||||
foldl'
|
||||
getAttrFromPath
|
||||
mkMerge
|
||||
mkOption
|
||||
mkOptionType
|
||||
optionals
|
||||
recursiveUpdate
|
||||
setAttrByPath
|
||||
types
|
||||
;
|
||||
|
||||
nodeName = config.node.name;
|
||||
mkForwardedOption =
|
||||
path:
|
||||
mkOption {
|
||||
type = mkOptionType {
|
||||
name = "Same type that the receiving option `${concatStringsSep "." path}` normally accepts.";
|
||||
merge =
|
||||
_loc: defs:
|
||||
builtins.filter (x: builtins.isAttrs x -> ((x._type or "") != "__distributed_config_empty")) (
|
||||
map (x: x.value) defs
|
||||
);
|
||||
};
|
||||
default = {
|
||||
_type = "__distributed_config_empty";
|
||||
};
|
||||
description = ''
|
||||
Anything specified here will be forwarded to `${concatStringsSep "." path}`
|
||||
on the given node. Forwarding happens as-is to the raw values,
|
||||
so validity can only be checked on the receiving node.
|
||||
'';
|
||||
};
|
||||
|
||||
forwardedOptions = [
|
||||
[
|
||||
"services"
|
||||
"nginx"
|
||||
"upstreams"
|
||||
]
|
||||
[
|
||||
"services"
|
||||
"nginx"
|
||||
"virtualHosts"
|
||||
]
|
||||
];
|
||||
|
||||
attrsForEachOption =
|
||||
f: foldl' (acc: path: recursiveUpdate acc (setAttrByPath path (f path))) { } forwardedOptions;
|
||||
in
|
||||
{
|
||||
options.nodes = mkOption {
|
||||
description = "Options forwarded to the given node.";
|
||||
default = { };
|
||||
type = types.attrsOf (
|
||||
types.submodule {
|
||||
options = attrsForEachOption mkForwardedOption;
|
||||
}
|
||||
);
|
||||
};
|
||||
|
||||
config =
|
||||
let
|
||||
getConfig =
|
||||
path: otherNode:
|
||||
let
|
||||
cfg = outputs.nixosConfigurations.${otherNode}.config.nodes.${nodeName} or null;
|
||||
in
|
||||
optionals (cfg != null) (getAttrFromPath path cfg);
|
||||
mergeConfigFromOthers = path: mkMerge (concatMap (getConfig path) (attrNames outputs.nixosConfigurations));
|
||||
in
|
||||
attrsForEachOption mergeConfigFromOthers;
|
||||
}
|
||||
|
|
@ -23,7 +23,7 @@ in
|
|||
id = "O7RWDMD-AEAHPP7-7TAVLKZ-BSWNBTU-2VA44MS-EYGUNBB-SLHKB3C-ZSLMOAA";
|
||||
};
|
||||
"moonside (@oracle)" = {
|
||||
id = "YJLYL4Z-JIYHFKX-554ZR7B-YAF3PNH-CX7JF53-NYUMVGL-4EWWASH-GDAMBQA";
|
||||
id = "VPCDZB6-MGVGQZD-Q6DIZW3-IZJRJTO-TCC3QUQ-2BNTL7P-AKE7FBO-N55UNQE";
|
||||
};
|
||||
};
|
||||
folders = {
|
||||
|
|
|
|||
|
|
@ -1,8 +1,11 @@
|
|||
{ pkgs, config, lib, ... }:
|
||||
{ self, pkgs, config, lib, ... }:
|
||||
let
|
||||
sopsFile = self + /secrets/general/secrets.yaml;
|
||||
in
|
||||
{
|
||||
options.swarselsystems.modules.users = lib.mkEnableOption "user config";
|
||||
config = lib.mkIf config.swarselsystems.modules.users {
|
||||
sops.secrets.swarseluser = lib.mkIf (!config.swarselsystems.isPublic) { neededForUsers = true; };
|
||||
sops.secrets.swarseluser = lib.mkIf (!config.swarselsystems.isPublic) { inherit sopsFile; neededForUsers = true; };
|
||||
|
||||
users = {
|
||||
mutableUsers = lib.mkIf (!config.swarselsystems.initialSetup) false;
|
||||
|
|
|
|||
|
|
@ -175,7 +175,7 @@ in
|
|||
id = "O7RWDMD-AEAHPP7-7TAVLKZ-BSWNBTU-2VA44MS-EYGUNBB-SLHKB3C-ZSLMOAA";
|
||||
};
|
||||
"moonside (@oracle)" = {
|
||||
id = "YJLYL4Z-JIYHFKX-554ZR7B-YAF3PNH-CX7JF53-NYUMVGL-4EWWASH-GDAMBQA";
|
||||
id = "VPCDZB6-MGVGQZD-Q6DIZW3-IZJRJTO-TCC3QUQ-2BNTL7P-AKE7FBO-N55UNQE";
|
||||
};
|
||||
folders = {
|
||||
"Documents" = {
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@ let
|
|||
cfg = config.services.firefly-iii;
|
||||
fireflyDomain = "stonks.swarsel.win";
|
||||
fireflyUser = "firefly-iii";
|
||||
serviceName = "firefly";
|
||||
in
|
||||
{
|
||||
options.swarselsystems.modules.server.firefly = lib.mkEnableOption "enable firefly-iii on server";
|
||||
|
|
@ -31,6 +32,7 @@ in
|
|||
APP_KEY_FILE = config.sops.secrets.firefly-iii-app-key.path;
|
||||
APP_ENV = "local";
|
||||
DB_CONNECTION = "sqlite";
|
||||
TRUSTED_PROXIES = "**";
|
||||
# AUTHENTICATION_GUARD = "remote_user_guard";
|
||||
# AUTHENTICATION_GUARD_HEADER = "X-User";
|
||||
# AUTHENTICATION_GUARD_EMAIL = "X-Email";
|
||||
|
|
@ -42,52 +44,7 @@ in
|
|||
nginx = {
|
||||
virtualHosts = {
|
||||
"${fireflyDomain}" = {
|
||||
enableACME = true;
|
||||
forceSSL = true;
|
||||
acmeRoot = null;
|
||||
# main config is automatically added by nixos firefly config.
|
||||
# hence, only provide certificate
|
||||
locations = {
|
||||
"/" = {
|
||||
extraConfig = ''
|
||||
auth_request /oauth2/auth;
|
||||
error_page 401 = /oauth2/sign_in;
|
||||
|
||||
# pass information via X-User and X-Email headers to backend,
|
||||
# requires running with --set-xauthrequest flag (done by NixOS)
|
||||
auth_request_set $user $upstream_http_x_auth_request_user;
|
||||
auth_request_set $email $upstream_http_x_auth_request_email;
|
||||
proxy_set_header X-User $user;
|
||||
proxy_set_header X-Email $email;
|
||||
|
||||
# if you enabled --pass-access-token, this will pass the token to the backend
|
||||
auth_request_set $token $upstream_http_x_auth_request_access_token;
|
||||
proxy_set_header X-Access-Token $token;
|
||||
|
||||
# if you enabled --cookie-refresh, this is needed for it to work with auth_request
|
||||
auth_request_set $auth_cookie $upstream_http_set_cookie;
|
||||
add_header Set-Cookie $auth_cookie;
|
||||
'';
|
||||
};
|
||||
"/oauth2/" = {
|
||||
proxyPass = "http://oauth2-proxy";
|
||||
extraConfig = ''
|
||||
|
||||
proxy_set_header X-Scheme $scheme;
|
||||
proxy_set_header X-Auth-Request-Redirect $scheme://$host$request_uri;
|
||||
'';
|
||||
};
|
||||
"= /oauth2/auth" = {
|
||||
proxyPass = "http://oauth2-proxy/oauth2/auth";
|
||||
extraConfig = ''
|
||||
internal;
|
||||
|
||||
proxy_set_header X-Scheme $scheme;
|
||||
# nginx auth_request includes headers but not body
|
||||
proxy_set_header Content-Length "";
|
||||
proxy_pass_request_body off;
|
||||
'';
|
||||
};
|
||||
"/api" = {
|
||||
extraConfig = ''
|
||||
index index.php;
|
||||
|
|
@ -102,5 +59,70 @@ in
|
|||
};
|
||||
};
|
||||
};
|
||||
|
||||
nodes.moonside.services.nginx = {
|
||||
upstreams = {
|
||||
"${serviceName}" = {
|
||||
servers = {
|
||||
"192.168.1.2:80" = { };
|
||||
};
|
||||
};
|
||||
};
|
||||
virtualHosts = {
|
||||
"${fireflyDomain}" = {
|
||||
enableACME = true;
|
||||
forceSSL = true;
|
||||
acmeRoot = null;
|
||||
# main config is automatically added by nixos firefly config.
|
||||
# hence, only provide certificate
|
||||
locations = {
|
||||
"/" = {
|
||||
proxyPass = "http://${serviceName}";
|
||||
extraConfig = ''
|
||||
auth_request /oauth2/auth;
|
||||
error_page 401 = /oauth2/sign_in;
|
||||
|
||||
# pass information via X-User and X-Email headers to backend,
|
||||
# requires running with --set-xauthrequest flag (done by NixOS)
|
||||
auth_request_set $user $upstream_http_x_auth_request_user;
|
||||
auth_request_set $email $upstream_http_x_auth_request_email;
|
||||
proxy_set_header X-User $user;
|
||||
proxy_set_header X-Email $email;
|
||||
|
||||
# if you enabled --pass-access-token, this will pass the token to the backend
|
||||
auth_request_set $token $upstream_http_x_auth_request_access_token;
|
||||
proxy_set_header X-Access-Token $token;
|
||||
|
||||
# if you enabled --cookie-refresh, this is needed for it to work with auth_request
|
||||
auth_request_set $auth_cookie $upstream_http_set_cookie;
|
||||
add_header Set-Cookie $auth_cookie;
|
||||
'';
|
||||
};
|
||||
"/oauth2/" = {
|
||||
proxyPass = "http://oauth2-proxy";
|
||||
extraConfig = ''
|
||||
|
||||
proxy_set_header X-Scheme $scheme;
|
||||
proxy_set_header X-Auth-Request-Redirect $scheme://$host$request_uri;
|
||||
'';
|
||||
};
|
||||
"= /oauth2/auth" = {
|
||||
proxyPass = "http://oauth2-proxy/oauth2/auth";
|
||||
extraConfig = ''
|
||||
internal;
|
||||
|
||||
proxy_set_header X-Scheme $scheme;
|
||||
# nginx auth_request includes headers but not body
|
||||
proxy_set_header Content-Length "";
|
||||
proxy_pass_request_body off;
|
||||
'';
|
||||
};
|
||||
"/api" = {
|
||||
proxyPass = "http://${serviceName}";
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,7 @@
|
|||
{ lib, config, ... }:
|
||||
let
|
||||
serviceName = "freshrss";
|
||||
in
|
||||
{
|
||||
options.swarselsystems.modules.server.freshrss = lib.mkEnableOption "enable freshrss on server";
|
||||
config = lib.mkIf config.swarselsystems.modules.server.freshrss {
|
||||
|
|
@ -52,7 +55,14 @@
|
|||
# config.sops.templates.freshrss-env.path
|
||||
# ];
|
||||
|
||||
services.nginx = {
|
||||
nodes.moonside.services.nginx = {
|
||||
upstreams = {
|
||||
"${serviceName}" = {
|
||||
servers = {
|
||||
"192.168.1.2:80" = { };
|
||||
};
|
||||
};
|
||||
};
|
||||
virtualHosts = {
|
||||
"signpost.swarsel.win" = {
|
||||
enableACME = true;
|
||||
|
|
@ -60,6 +70,7 @@
|
|||
acmeRoot = null;
|
||||
locations = {
|
||||
"/" = {
|
||||
proxyPass = "http://${serviceName}";
|
||||
extraConfig = ''
|
||||
auth_request /oauth2/auth;
|
||||
error_page 401 = /oauth2/sign_in;
|
||||
|
|
|
|||
|
|
@ -1,17 +1,22 @@
|
|||
{ lib, config, ... }:
|
||||
let
|
||||
serviceDomain = "shots.swarsel.win";
|
||||
servicePort = 3001;
|
||||
serviceUser = "immich";
|
||||
serviceName = "immich";
|
||||
in
|
||||
{
|
||||
options.swarselsystems.modules.server.immich = lib.mkEnableOption "enable immich on server";
|
||||
config = lib.mkIf config.swarselsystems.modules.server.immich {
|
||||
options.swarselsystems.modules.server."${serviceName}" = lib.mkEnableOption "enable ${serviceName} on server";
|
||||
config = lib.mkIf config.swarselsystems.modules.server."${serviceName}" {
|
||||
|
||||
users.users.immich = {
|
||||
users.users."${serviceUser}" = {
|
||||
extraGroups = [ "video" "render" "users" ];
|
||||
};
|
||||
|
||||
# sops.secrets.nextcloudadminpass = { owner = "nextcloud"; };
|
||||
|
||||
services.immich = {
|
||||
enable = true;
|
||||
port = 3001;
|
||||
host = "0.0.0.0";
|
||||
port = servicePort;
|
||||
openFirewall = true;
|
||||
mediaLocation = "/Vault/Eternor/Immich";
|
||||
environment = {
|
||||
|
|
@ -19,16 +24,24 @@
|
|||
};
|
||||
};
|
||||
|
||||
networking.firewall.allowedTCPPorts = [ 3001 ];
|
||||
|
||||
services.nginx = {
|
||||
nodes.moonside.services.nginx = {
|
||||
upstreams = {
|
||||
"${serviceName}" = {
|
||||
servers = {
|
||||
"192.168.1.2:${builtins.toString servicePort}" = { };
|
||||
};
|
||||
};
|
||||
};
|
||||
virtualHosts = {
|
||||
"shots.swarsel.win" = {
|
||||
"${serviceDomain}" = {
|
||||
enableACME = true;
|
||||
forceSSL = true;
|
||||
acmeRoot = null;
|
||||
locations = {
|
||||
"/" = {
|
||||
proxyPass = "http://localhost:3001";
|
||||
proxyPass = "http://${serviceName}";
|
||||
extraConfig = ''
|
||||
client_max_body_size 0;
|
||||
|
||||
|
|
|
|||
|
|
@ -1,8 +1,14 @@
|
|||
{ pkgs, lib, config, ... }:
|
||||
let
|
||||
serviceDomain = "screen.swarsel.win";
|
||||
servicePort = 8096;
|
||||
serviceName = "jellyfin";
|
||||
serviceUser = "jellyfin";
|
||||
in
|
||||
{
|
||||
options.swarselsystems.modules.server.jellyfin = lib.mkEnableOption "enable jellyfin on server";
|
||||
config = lib.mkIf config.swarselsystems.modules.server.jellyfin {
|
||||
users.users.jellyfin = {
|
||||
options.swarselsystems.modules.server."${serviceName}" = lib.mkEnableOption "enable ${serviceName} on server";
|
||||
config = lib.mkIf config.swarselsystems.modules.server."${serviceName}" {
|
||||
users.users."${serviceUser}" = {
|
||||
extraGroups = [ "video" "render" "users" ];
|
||||
};
|
||||
nixpkgs.config.packageOverrides = pkgs: {
|
||||
|
|
@ -19,19 +25,26 @@
|
|||
};
|
||||
services.jellyfin = {
|
||||
enable = true;
|
||||
user = "jellyfin";
|
||||
user = serviceUser;
|
||||
openFirewall = true; # this works only for the default ports
|
||||
};
|
||||
|
||||
services.nginx = {
|
||||
nodes.moonside.services.nginx = {
|
||||
upstreams = {
|
||||
"${serviceName}" = {
|
||||
servers = {
|
||||
"192.168.1.2:${builtins.toString servicePort}" = { };
|
||||
};
|
||||
};
|
||||
};
|
||||
virtualHosts = {
|
||||
"screen.swarsel.win" = {
|
||||
"${serviceDomain}" = {
|
||||
enableACME = true;
|
||||
forceSSL = true;
|
||||
acmeRoot = null;
|
||||
locations = {
|
||||
"/" = {
|
||||
proxyPass = "http://localhost:8096";
|
||||
proxyPass = "http://${serviceName}";
|
||||
extraConfig = ''
|
||||
client_max_body_size 0;
|
||||
'';
|
||||
|
|
|
|||
|
|
@ -1,62 +1,52 @@
|
|||
{ self, lib, pkgs, config, ... }:
|
||||
let
|
||||
certsSopsFile = self + /secrets/certs/secrets.yaml;
|
||||
kanidmDomain = "sso.swarsel.win";
|
||||
serviceDomain = "sso.swarsel.win";
|
||||
servicePort = 8300;
|
||||
serviceUser = "kanidm";
|
||||
serviceGroup = serviceUser;
|
||||
serviceName = "kanidm";
|
||||
oauth2ProxyDomain = "soauth.swarsel.win";
|
||||
kanidmPort = 8300;
|
||||
oauth2ProxyPort = 3004;
|
||||
in
|
||||
{
|
||||
options.swarselsystems.modules.server.kanidm = lib.mkEnableOption "enable kanidm on server";
|
||||
config = lib.mkIf config.swarselsystems.modules.server.kanidm {
|
||||
options.swarselsystems.modules.server."${serviceName}" = lib.mkEnableOption "enable ${serviceName} on server";
|
||||
config = lib.mkIf config.swarselsystems.modules.server."${serviceName}" {
|
||||
|
||||
users.users.kanidm = {
|
||||
group = "kanidm";
|
||||
users.users."${serviceUser}" = {
|
||||
group = serviceGroup;
|
||||
isSystemUser = true;
|
||||
};
|
||||
|
||||
users.groups.kanidm = { };
|
||||
users.groups."${serviceGroup}" = { };
|
||||
|
||||
sops = {
|
||||
secrets = {
|
||||
"oauth2-cookie-secret" = { owner = "oauth2-proxy"; group = "oauth2-proxy"; mode = "0440"; };
|
||||
"kanidm-self-signed-crt" = { sopsFile = certsSopsFile; owner = "kanidm"; group = "kanidm"; mode = "0440"; };
|
||||
"kanidm-self-signed-key" = { sopsFile = certsSopsFile; owner = "kanidm"; group = "kanidm"; mode = "0440"; };
|
||||
"kanidm-admin-pw" = { owner = "kanidm"; group = "kanidm"; mode = "0440"; };
|
||||
"kanidm-idm-admin-pw" = { owner = "kanidm"; group = "kanidm"; mode = "0440"; };
|
||||
"kanidm-immich" = { owner = "kanidm"; group = "kanidm"; mode = "0440"; };
|
||||
"kanidm-paperless" = { owner = "kanidm"; group = "kanidm"; mode = "0440"; };
|
||||
"kanidm-forgejo" = { owner = "kanidm"; group = "kanidm"; mode = "0440"; };
|
||||
"kanidm-grafana" = { owner = "kanidm"; group = "kanidm"; mode = "0440"; };
|
||||
"kanidm-nextcloud" = { owner = "kanidm"; group = "kanidm"; mode = "0440"; };
|
||||
"kanidm-freshrss" = { owner = "kanidm"; group = "kanidm"; mode = "0440"; };
|
||||
"kanidm-oauth2-proxy" = { owner = "kanidm"; group = "kanidm"; mode = "0440"; };
|
||||
"kanidm-oauth2-proxy-client" = { owner = "oauth2-proxy"; group = "oauth2-proxy"; mode = "0440"; };
|
||||
};
|
||||
|
||||
templates = {
|
||||
"kanidm-oauth2-proxy-client-env" = {
|
||||
content = ''
|
||||
OAUTH2_PROXY_CLIENT_SECRET="${config.sops.placeholder.kanidm-oauth2-proxy-client}"
|
||||
OAUTH2_PROXY_COOKIE_SECRET=${config.sops.placeholder.oauth2-cookie-secret}
|
||||
'';
|
||||
owner = "oauth2-proxy";
|
||||
group = "oauth2-proxy";
|
||||
mode = "0440";
|
||||
};
|
||||
"kanidm-self-signed-crt" = { sopsFile = certsSopsFile; owner = serviceUser; group = serviceGroup; mode = "0440"; };
|
||||
"kanidm-self-signed-key" = { sopsFile = certsSopsFile; owner = serviceUser; group = serviceGroup; mode = "0440"; };
|
||||
"kanidm-admin-pw" = { owner = serviceUser; group = serviceGroup; mode = "0440"; };
|
||||
"kanidm-idm-admin-pw" = { owner = serviceUser; group = serviceGroup; mode = "0440"; };
|
||||
"kanidm-immich" = { owner = serviceUser; group = serviceGroup; mode = "0440"; };
|
||||
"kanidm-paperless" = { owner = serviceUser; group = serviceGroup; mode = "0440"; };
|
||||
"kanidm-forgejo" = { owner = serviceUser; group = serviceGroup; mode = "0440"; };
|
||||
"kanidm-grafana" = { owner = serviceUser; group = serviceGroup; mode = "0440"; };
|
||||
"kanidm-nextcloud" = { owner = serviceUser; group = serviceGroup; mode = "0440"; };
|
||||
"kanidm-freshrss" = { owner = serviceUser; group = serviceGroup; mode = "0440"; };
|
||||
"kanidm-oauth2-proxy" = { owner = serviceUser; group = serviceGroup; mode = "0440"; };
|
||||
};
|
||||
};
|
||||
|
||||
networking.firewall.allowedTCPPorts = [ servicePort ];
|
||||
|
||||
services = {
|
||||
kanidm = {
|
||||
package = pkgs.kanidmWithSecretProvisioning;
|
||||
enableServer = true;
|
||||
serverSettings = {
|
||||
domain = kanidmDomain;
|
||||
origin = "https://${kanidmDomain}";
|
||||
domain = serviceDomain;
|
||||
origin = "https://${serviceDomain}";
|
||||
tls_chain = config.sops.secrets.kanidm-self-signed-crt.path;
|
||||
tls_key = config.sops.secrets.kanidm-self-signed-key.path;
|
||||
bindaddress = "0.0.0.0:${toString kanidmPort}";
|
||||
bindaddress = "0.0.0.0:${toString servicePort}";
|
||||
trust_x_forward_for = true;
|
||||
};
|
||||
enableClient = true;
|
||||
|
|
@ -177,19 +167,6 @@ in
|
|||
};
|
||||
};
|
||||
};
|
||||
# freshrss = {
|
||||
# displayName = "FreshRSS";
|
||||
# originUrl = "https://signpost.swarsel.win/apps/sociallogin/custom_oidc/kanidm";
|
||||
# originLanding = "https://signpost.swarsel.win/";
|
||||
# basicSecretFile = config.sops.secrets.kanidm-freshrss.path;
|
||||
# allowInsecureClientDisablePkce = true;
|
||||
# scopeMaps."freshrss.access" = [
|
||||
# "openid"
|
||||
# "email"
|
||||
# "profile"
|
||||
# ];
|
||||
# preferShortUsername = true;
|
||||
# };
|
||||
oauth2-proxy = {
|
||||
displayName = "Oauth2-Proxy";
|
||||
originUrl = "https://${oauth2ProxyDomain}/oauth2/callback";
|
||||
|
|
@ -226,96 +203,34 @@ in
|
|||
};
|
||||
};
|
||||
};
|
||||
oauth2-proxy = {
|
||||
enable = true;
|
||||
cookie = {
|
||||
domain = ".swarsel.win";
|
||||
secure = true;
|
||||
expire = "900m";
|
||||
secret = null; # set by service EnvironmentFile
|
||||
};
|
||||
clientSecret = null; # set by service EnvironmentFile
|
||||
reverseProxy = true;
|
||||
httpAddress = "0.0.0.0:${builtins.toString oauth2ProxyPort}";
|
||||
redirectURL = "https://${oauth2ProxyDomain}/oauth2/callback";
|
||||
setXauthrequest = true;
|
||||
extraConfig = {
|
||||
code-challenge-method = "S256";
|
||||
whitelist-domain = ".swarsel.win";
|
||||
set-authorization-header = true;
|
||||
pass-access-token = true;
|
||||
skip-jwt-bearer-tokens = true;
|
||||
upstream = "static://202";
|
||||
oidc-issuer-url = "https://${kanidmDomain}/oauth2/openid/oauth2-proxy";
|
||||
provider-display-name = "Kanidm";
|
||||
};
|
||||
provider = "oidc";
|
||||
scope = "openid email";
|
||||
loginURL = "https://${kanidmDomain}/ui/oauth2";
|
||||
redeemURL = "https://${kanidmDomain}/oauth2/token";
|
||||
validateURL = "https://${kanidmDomain}/oauth2/openid/oauth2-proxy/userinfo";
|
||||
clientID = "oauth2-proxy";
|
||||
email.domains = [ "*" ];
|
||||
};
|
||||
};
|
||||
|
||||
systemd.services = {
|
||||
kanidm.serviceConfig.RestartSec = "30";
|
||||
oauth2-proxy = {
|
||||
after = [ "kanidm.service" ];
|
||||
serviceConfig = {
|
||||
RuntimeDirectory = "oauth2-proxy";
|
||||
RuntimeDirectoryMode = "0750";
|
||||
UMask = "007"; # TODO remove once https://github.com/oauth2-proxy/oauth2-proxy/issues/2141 is fixed
|
||||
RestartSec = "60"; # Retry every minute
|
||||
EnvironmentFile = [
|
||||
config.sops.templates.kanidm-oauth2-proxy-client-env.path
|
||||
];
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
services.nginx = {
|
||||
nodes.moonside.services.nginx = {
|
||||
upstreams = {
|
||||
kanidm = {
|
||||
"${serviceName}" = {
|
||||
servers = {
|
||||
"192.168.1.2:${builtins.toString kanidmPort}" = { };
|
||||
};
|
||||
};
|
||||
oauth2-proxy = {
|
||||
servers = {
|
||||
"192.168.1.2:${builtins.toString oauth2ProxyPort}" = { };
|
||||
"192.168.1.2:${builtins.toString servicePort}" = { };
|
||||
};
|
||||
};
|
||||
};
|
||||
virtualHosts = {
|
||||
"${kanidmDomain}" = {
|
||||
"${serviceDomain}" = {
|
||||
enableACME = true;
|
||||
forceSSL = true;
|
||||
acmeRoot = null;
|
||||
locations = {
|
||||
"/" = {
|
||||
proxyPass = "https://kanidm";
|
||||
proxyPass = "https://${serviceName}";
|
||||
};
|
||||
};
|
||||
extraConfig = ''
|
||||
proxy_ssl_verify off;
|
||||
'';
|
||||
};
|
||||
"${oauth2ProxyDomain}" = {
|
||||
enableACME = true;
|
||||
forceSSL = true;
|
||||
acmeRoot = null;
|
||||
locations = {
|
||||
"/" = {
|
||||
proxyPass = "http://oauth2-proxy";
|
||||
};
|
||||
};
|
||||
extraConfig = ''
|
||||
proxy_set_header X-Scheme $scheme;
|
||||
proxy_set_header X-Auth-Request-Redirect $scheme://$host$request_uri;
|
||||
'';
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
|
|
|||
|
|
@ -1,36 +1,48 @@
|
|||
{ pkgs, lib, config, ... }:
|
||||
let
|
||||
serviceName = "kavita";
|
||||
serviceUser = "kavita";
|
||||
serviceDomain = "scroll.swarsel.win";
|
||||
servicePort = 8080;
|
||||
in
|
||||
{
|
||||
options.swarselsystems.modules.server.kavita = lib.mkEnableOption "enable kavita on server";
|
||||
config = lib.mkIf config.swarselsystems.modules.server.kavita {
|
||||
options.swarselsystems.modules.server."${serviceName}" = lib.mkEnableOption "enable ${serviceName} on server";
|
||||
config = lib.mkIf config.swarselsystems.modules.server."${serviceName}" {
|
||||
environment.systemPackages = with pkgs; [
|
||||
calibre
|
||||
];
|
||||
|
||||
|
||||
users.users.kavita = {
|
||||
users.users."${serviceUser}" = {
|
||||
extraGroups = [ "users" ];
|
||||
};
|
||||
|
||||
sops.secrets.kavita = { owner = "kavita"; };
|
||||
sops.secrets.kavita = { owner = serviceUser; };
|
||||
|
||||
networking.firewall.allowedTCPPorts = [ 8080 ];
|
||||
|
||||
services.kavita = {
|
||||
enable = true;
|
||||
user = "kavita";
|
||||
settings.Port = 8080;
|
||||
user = serviceUser;
|
||||
settings.Port = servicePort;
|
||||
tokenKeyFile = config.sops.secrets.kavita.path;
|
||||
};
|
||||
|
||||
services.nginx = {
|
||||
nodes.moonside.services.nginx = {
|
||||
upstreams = {
|
||||
"${serviceName}" = {
|
||||
servers = {
|
||||
"192.168.1.2:${builtins.toString servicePort}" = { };
|
||||
};
|
||||
};
|
||||
};
|
||||
virtualHosts = {
|
||||
"scroll.swarsel.win" = {
|
||||
"${serviceDomain}" = {
|
||||
enableACME = true;
|
||||
forceSSL = true;
|
||||
acmeRoot = null;
|
||||
locations = {
|
||||
"/" = {
|
||||
proxyPass = "http://localhost:8080";
|
||||
proxyPass = "http://${serviceName}";
|
||||
extraConfig = ''
|
||||
client_max_body_size 0;
|
||||
'';
|
||||
|
|
|
|||
|
|
@ -55,7 +55,7 @@ in
|
|||
};
|
||||
};
|
||||
|
||||
networking.firewall.allowedTCPPorts = [ postgresPort ];
|
||||
networking.firewall.allowedTCPPorts = [ servicePort postgresPort ];
|
||||
|
||||
systemd.services.postgresql.postStart =
|
||||
let
|
||||
|
|
@ -86,17 +86,24 @@ in
|
|||
host ${serviceDB} ${serviceDB} 10.88.0.0/16 scram-sha-256
|
||||
'';
|
||||
};
|
||||
};
|
||||
|
||||
nginx = {
|
||||
virtualHosts = {
|
||||
"${serviceDomain}" = {
|
||||
enableACME = true;
|
||||
forceSSL = true;
|
||||
acmeRoot = null;
|
||||
locations = {
|
||||
"/" = {
|
||||
proxyPass = "http://localhost:${toString servicePort}";
|
||||
};
|
||||
nodes.moonside.services.nginx = {
|
||||
upstreams = {
|
||||
"${serviceName}" = {
|
||||
servers = {
|
||||
"192.168.1.2:${builtins.toString servicePort}" = { };
|
||||
};
|
||||
};
|
||||
};
|
||||
virtualHosts = {
|
||||
"${serviceDomain}" = {
|
||||
enableACME = true;
|
||||
forceSSL = true;
|
||||
acmeRoot = null;
|
||||
locations = {
|
||||
"/" = {
|
||||
proxyPass = "http://${serviceName}";
|
||||
};
|
||||
};
|
||||
};
|
||||
|
|
|
|||
|
|
@ -1,6 +1,13 @@
|
|||
{ config, lib, pkgs, sops, ... }:
|
||||
let
|
||||
matrixDomain = "swatrix.swarsel.win";
|
||||
serviceName = "matrix";
|
||||
synapsePort = 8008;
|
||||
synapseUser = "matrix-synapse";
|
||||
whatsappPort = 29318;
|
||||
telegramPort = 29317;
|
||||
signalPort = 29328;
|
||||
|
||||
baseUrl = "https://${matrixDomain}";
|
||||
clientConfig."m.homeserver".base_url = baseUrl;
|
||||
serverConfig."m.server" = "${matrixDomain}:443";
|
||||
|
|
@ -11,8 +18,8 @@ let
|
|||
'';
|
||||
in
|
||||
{
|
||||
options.swarselsystems.modules.server.matrix = lib.mkEnableOption "enable matrix on server";
|
||||
config = lib.mkIf config.swarselsystems.modules.server.matrix {
|
||||
options.swarselsystems.modules.server."${serviceName}" = lib.mkEnableOption "enable ${serviceName} on server";
|
||||
config = lib.mkIf config.swarselsystems.modules.server."${serviceName}" {
|
||||
environment.systemPackages = with pkgs; [
|
||||
matrix-synapse
|
||||
lottieconverter
|
||||
|
|
@ -21,24 +28,24 @@ in
|
|||
|
||||
sops = {
|
||||
secrets = {
|
||||
matrixsharedsecret = { owner = "matrix-synapse"; };
|
||||
mautrixtelegram_as = { owner = "matrix-synapse"; };
|
||||
mautrixtelegram_hs = { owner = "matrix-synapse"; };
|
||||
mautrixtelegram_api_id = { owner = "matrix-synapse"; };
|
||||
mautrixtelegram_api_hash = { owner = "matrix-synapse"; };
|
||||
matrixsharedsecret = { owner = synapseUser; };
|
||||
mautrixtelegram_as = { owner = synapseUser; };
|
||||
mautrixtelegram_hs = { owner = synapseUser; };
|
||||
mautrixtelegram_api_id = { owner = synapseUser; };
|
||||
mautrixtelegram_api_hash = { owner = synapseUser; };
|
||||
};
|
||||
templates = {
|
||||
"matrix_user_register.sh".content = ''
|
||||
register_new_matrix_user -k ${config.sops.placeholder.matrixsharedsecret} http://localhost:8008
|
||||
register_new_matrix_user -k ${config.sops.placeholder.matrixsharedsecret} http://localhost:${builtins.toString synapsePort}
|
||||
'';
|
||||
matrixshared = {
|
||||
owner = "matrix-synapse";
|
||||
owner = synapseUser;
|
||||
content = ''
|
||||
registration_shared_secret: ${config.sops.placeholder.matrixsharedsecret}
|
||||
'';
|
||||
};
|
||||
mautrixtelegram = {
|
||||
owner = "matrix-synapse";
|
||||
owner = synapseUser;
|
||||
content = ''
|
||||
MAUTRIX_TELEGRAM_APPSERVICE_AS_TOKEN=${config.sops.placeholder.mautrixtelegram_as}
|
||||
MAUTRIX_TELEGRAM_APPSERVICE_HS_TOKEN=${config.sops.placeholder.mautrixtelegram_hs}
|
||||
|
|
@ -49,6 +56,8 @@ in
|
|||
};
|
||||
};
|
||||
|
||||
networking.firewall.allowedTCPPorts = [ 8008 8448 ];
|
||||
|
||||
systemd = {
|
||||
timers."restart-bridges" = {
|
||||
wantedBy = [ "timers.target" ];
|
||||
|
|
@ -118,9 +127,9 @@ in
|
|||
public_baseurl = "https://${matrixDomain}";
|
||||
listeners = [
|
||||
{
|
||||
port = 8008;
|
||||
port = synapsePort;
|
||||
bind_addresses = [
|
||||
"127.0.0.1"
|
||||
"0.0.0.0"
|
||||
# "::1"
|
||||
];
|
||||
type = "http";
|
||||
|
|
@ -146,13 +155,13 @@ in
|
|||
registerToSynapse = false;
|
||||
settings = {
|
||||
homeserver = {
|
||||
address = "http://localhost:8008";
|
||||
address = "http://localhost:${builtins.toString synapsePort}";
|
||||
domain = matrixDomain;
|
||||
};
|
||||
appservice = {
|
||||
address = "http://localhost:29317";
|
||||
hostname = "localhost";
|
||||
port = "29317";
|
||||
address = "http://localhost:${builtins.toString telegramPort}";
|
||||
hostname = "0.0.0.0";
|
||||
port = telegramPort;
|
||||
provisioning.enabled = true;
|
||||
id = "telegram";
|
||||
# ephemeral_events = true; # not needed due to double puppeting
|
||||
|
|
@ -192,13 +201,13 @@ in
|
|||
registerToSynapse = false;
|
||||
settings = {
|
||||
homeserver = {
|
||||
address = "http://localhost:8008";
|
||||
address = "http://localhost:${builtins.toString synapsePort}";
|
||||
domain = matrixDomain;
|
||||
};
|
||||
appservice = {
|
||||
address = "http://localhost:29318";
|
||||
hostname = "127.0.0.1";
|
||||
port = 29318;
|
||||
address = "http://localhost:${builtins.toString whatsappPort}";
|
||||
hostname = "0.0.0.0";
|
||||
port = whatsappPort;
|
||||
database = {
|
||||
type = "postgres";
|
||||
uri = "postgresql:///mautrix-whatsapp?host=/run/postgresql";
|
||||
|
|
@ -239,14 +248,13 @@ in
|
|||
registerToSynapse = false;
|
||||
settings = {
|
||||
homeserver = {
|
||||
address = "http://localhost:8008";
|
||||
address = "http://localhost:${builtins.toString synapsePort}";
|
||||
domain = matrixDomain;
|
||||
};
|
||||
appservice = {
|
||||
|
||||
address = "http://localhost:29328";
|
||||
hostname = "127.0.0.1";
|
||||
port = 29328;
|
||||
address = "http://localhost:${builtins.toString signalPort}";
|
||||
hostname = "0.0.0.0";
|
||||
port = signalPort;
|
||||
database = {
|
||||
type = "postgres";
|
||||
uri = "postgresql:///mautrix-signal?host=/run/postgresql";
|
||||
|
|
@ -265,61 +273,65 @@ in
|
|||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
# restart the bridges daily. this is done for the signal bridge mainly which stops carrying
|
||||
# messages out after a while.
|
||||
# restart the bridges daily. this is done for the signal bridge mainly which stops carrying
|
||||
# messages out after a while.
|
||||
|
||||
|
||||
nginx = {
|
||||
virtualHosts = {
|
||||
"swatrix.swarsel.win" = {
|
||||
enableACME = true;
|
||||
forceSSL = true;
|
||||
acmeRoot = null;
|
||||
listen = [
|
||||
{
|
||||
addr = "0.0.0.0";
|
||||
port = 8448;
|
||||
ssl = true;
|
||||
extraParameters = [
|
||||
"default_server"
|
||||
];
|
||||
}
|
||||
{
|
||||
addr = "[::0]";
|
||||
port = 8448;
|
||||
ssl = true;
|
||||
extraParameters = [
|
||||
"default_server"
|
||||
];
|
||||
}
|
||||
{
|
||||
addr = "0.0.0.0";
|
||||
port = 443;
|
||||
ssl = true;
|
||||
}
|
||||
{
|
||||
addr = "[::0]";
|
||||
port = 443;
|
||||
ssl = true;
|
||||
}
|
||||
];
|
||||
locations = {
|
||||
"~ ^(/_matrix|/_synapse/client)" = {
|
||||
# proxyPass = "http://localhost:8008";
|
||||
proxyPass = "http://localhost:8008";
|
||||
extraConfig = ''
|
||||
client_max_body_size 0;
|
||||
'';
|
||||
};
|
||||
"= /.well-known/matrix/server".extraConfig = mkWellKnown serverConfig;
|
||||
"= /.well-known/matrix/client".extraConfig = mkWellKnown clientConfig;
|
||||
nodes.moonside.services.nginx = {
|
||||
upstreams = {
|
||||
"${serviceName}" = {
|
||||
servers = {
|
||||
"192.168.1.2:${builtins.toString synapsePort}" = { };
|
||||
};
|
||||
};
|
||||
};
|
||||
virtualHosts = {
|
||||
"${matrixDomain}" = {
|
||||
enableACME = true;
|
||||
forceSSL = true;
|
||||
acmeRoot = null;
|
||||
listen = [
|
||||
{
|
||||
addr = "0.0.0.0";
|
||||
port = 8448;
|
||||
ssl = true;
|
||||
extraParameters = [
|
||||
"default_server"
|
||||
];
|
||||
}
|
||||
{
|
||||
addr = "[::0]";
|
||||
port = 8448;
|
||||
ssl = true;
|
||||
extraParameters = [
|
||||
"default_server"
|
||||
];
|
||||
}
|
||||
{
|
||||
addr = "0.0.0.0";
|
||||
port = 443;
|
||||
ssl = true;
|
||||
}
|
||||
{
|
||||
addr = "[::0]";
|
||||
port = 443;
|
||||
ssl = true;
|
||||
}
|
||||
];
|
||||
locations = {
|
||||
"~ ^(/_matrix|/_synapse/client)" = {
|
||||
proxyPass = "http://${serviceName}";
|
||||
extraConfig = ''
|
||||
client_max_body_size 0;
|
||||
'';
|
||||
};
|
||||
"= /.well-known/matrix/server".extraConfig = mkWellKnown serverConfig;
|
||||
"= /.well-known/matrix/client".extraConfig = mkWellKnown clientConfig;
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,23 +1,23 @@
|
|||
{ self, lib, config, ... }:
|
||||
let
|
||||
grafanaDomain = "status.swarsel.win";
|
||||
serviceDomain = "status.swarsel.win";
|
||||
servicePort = 3000;
|
||||
serviceUser = "grafana";
|
||||
serviceGroup = serviceUser;
|
||||
moduleName = "monitoring";
|
||||
grafanaUpstream = "grafana";
|
||||
prometheusUpstream = "prometheus";
|
||||
prometheusPort = 9090;
|
||||
prometheusWebRoot = "prometheus";
|
||||
in
|
||||
{
|
||||
options.swarselsystems.modules.server.monitoring = lib.mkEnableOption "enable monitoring on server";
|
||||
config = lib.mkIf config.swarselsystems.modules.server.monitoring {
|
||||
options.swarselsystems.modules.server."${moduleName}" = lib.mkEnableOption "enable ${moduleName} on server";
|
||||
config = lib.mkIf config.swarselsystems.modules.server."${moduleName}" {
|
||||
|
||||
sops.secrets = {
|
||||
grafanaadminpass = {
|
||||
owner = "grafana";
|
||||
};
|
||||
prometheusadminpass = {
|
||||
owner = "grafana";
|
||||
};
|
||||
kanidm-grafana-client = {
|
||||
owner = "grafana";
|
||||
group = "grafana";
|
||||
mode = "0440";
|
||||
};
|
||||
grafanaadminpass = { owner = serviceUser; group = serviceGroup; mode = "0440"; };
|
||||
prometheusadminpass = { owner = serviceUser; group = serviceGroup; mode = "0440"; };
|
||||
kanidm-grafana-client = { owner = serviceUser; group = serviceGroup; mode = "0440"; };
|
||||
};
|
||||
|
||||
users = {
|
||||
|
|
@ -26,12 +26,14 @@ in
|
|||
extraGroups = [ "nextcloud" ];
|
||||
};
|
||||
|
||||
grafana = {
|
||||
"${serviceUser}" = {
|
||||
extraGroups = [ "users" ];
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
networking.firewall.allowedTCPPorts = [ servicePort prometheusPort ];
|
||||
|
||||
services = {
|
||||
grafana = {
|
||||
enable = true;
|
||||
|
|
@ -43,7 +45,7 @@ in
|
|||
{
|
||||
name = "prometheus";
|
||||
type = "prometheus";
|
||||
url = "https://${grafanaDomain}/prometheus";
|
||||
url = "https://${serviceDomain}/prometheus";
|
||||
editable = false;
|
||||
access = "proxy";
|
||||
basicAuth = true;
|
||||
|
|
@ -66,13 +68,21 @@ in
|
|||
};
|
||||
|
||||
settings = {
|
||||
security.admin_password = "$__file{/run/secrets/grafanaadminpass}";
|
||||
analytics.reporting_enabled = false;
|
||||
users.allow_sign_up = false;
|
||||
security = {
|
||||
admin_password = "$__file{/run/secrets/grafanaadminpass}";
|
||||
cookie_secure = true;
|
||||
disable_gravatar = true;
|
||||
};
|
||||
server = {
|
||||
domain = grafanaDomain;
|
||||
root_url = "https://${grafanaDomain}";
|
||||
http_port = 3000;
|
||||
domain = serviceDomain;
|
||||
root_url = "https://${serviceDomain}";
|
||||
http_port = servicePort;
|
||||
http_addr = "0.0.0.0";
|
||||
protocol = "http";
|
||||
enforce_domain = true;
|
||||
enable_gzip = true;
|
||||
};
|
||||
"auth.generic_oauth" = {
|
||||
enabled = true;
|
||||
|
|
@ -98,9 +108,9 @@ in
|
|||
|
||||
prometheus = {
|
||||
enable = true;
|
||||
webExternalUrl = "https://status.swarsel.win/prometheus";
|
||||
port = 9090;
|
||||
listenAddress = "127.0.0.1";
|
||||
webExternalUrl = "https://status.swarsel.win/${prometheusWebRoot}";
|
||||
port = prometheusPort;
|
||||
listenAddress = "0.0.0.0";
|
||||
globalConfig = {
|
||||
scrape_interval = "10s";
|
||||
};
|
||||
|
|
@ -164,33 +174,44 @@ in
|
|||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
nginx = {
|
||||
virtualHosts = {
|
||||
"${grafanaDomain}" = {
|
||||
enableACME = true;
|
||||
forceSSL = true;
|
||||
acmeRoot = null;
|
||||
locations = {
|
||||
"/" = {
|
||||
proxyPass = "http://localhost:3000";
|
||||
proxyWebsockets = true;
|
||||
extraConfig = ''
|
||||
client_max_body_size 0;
|
||||
'';
|
||||
};
|
||||
"/prometheus" = {
|
||||
proxyPass = "http://localhost:9090";
|
||||
extraConfig = ''
|
||||
client_max_body_size 0;
|
||||
'';
|
||||
};
|
||||
nodes.moonside.services.nginx = {
|
||||
upstreams = {
|
||||
"${grafanaUpstream}" = {
|
||||
servers = {
|
||||
"192.168.1.2:${builtins.toString servicePort}" = { };
|
||||
};
|
||||
};
|
||||
"${prometheusUpstream}" = {
|
||||
servers = {
|
||||
"192.168.1.2:${builtins.toString prometheusPort}" = { };
|
||||
};
|
||||
};
|
||||
};
|
||||
virtualHosts = {
|
||||
"${serviceDomain}" = {
|
||||
enableACME = true;
|
||||
forceSSL = true;
|
||||
acmeRoot = null;
|
||||
locations = {
|
||||
"/" = {
|
||||
proxyPass = "http://${grafanaUpstream}";
|
||||
proxyWebsockets = true;
|
||||
extraConfig = ''
|
||||
client_max_body_size 0;
|
||||
'';
|
||||
};
|
||||
"/${prometheusWebRoot}" = {
|
||||
proxyPass = "http://${prometheusUpstream}";
|
||||
extraConfig = ''
|
||||
client_max_body_size 0;
|
||||
'';
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,7 +1,14 @@
|
|||
{ pkgs, config, lib, ... }:
|
||||
let
|
||||
serviceDomain = "sound.swarsel.win";
|
||||
servicePort = 4040;
|
||||
serviceName = "navidrome";
|
||||
serviceUser = "navidrome";
|
||||
serviceGroup = serviceUser;
|
||||
in
|
||||
{
|
||||
options.swarselsystems.modules.server.navidrome = lib.mkEnableOption "enable navidrome on server";
|
||||
config = lib.mkIf config.swarselsystems.modules.server.navidrome {
|
||||
options.swarselsystems.modules.server."${serviceName}" = lib.mkEnableOption "enable ${serviceName} on server";
|
||||
config = lib.mkIf config.swarselsystems.modules.server."${serviceName}" {
|
||||
environment.systemPackages = with pkgs; [
|
||||
pciutils
|
||||
alsa-utils
|
||||
|
|
@ -10,16 +17,16 @@
|
|||
|
||||
users = {
|
||||
groups = {
|
||||
navidrome = {
|
||||
"$(serviceGroup}" = {
|
||||
gid = 61593;
|
||||
};
|
||||
};
|
||||
|
||||
users = {
|
||||
navidrome = {
|
||||
"${serviceUser}" = {
|
||||
isSystemUser = true;
|
||||
uid = 61593;
|
||||
group = "navidrome";
|
||||
group = serviceGroup;
|
||||
extraGroups = [ "audio" "utmp" "users" "pipewire" ];
|
||||
};
|
||||
};
|
||||
|
|
@ -37,8 +44,8 @@
|
|||
openFirewall = true;
|
||||
settings = {
|
||||
LogLevel = "debug";
|
||||
Address = "127.0.0.1";
|
||||
Port = 4040;
|
||||
Address = "0.0.0.0";
|
||||
Port = servicePort;
|
||||
MusicFolder = "/Vault/Eternor/Music";
|
||||
PlaylistsPath = "./Playlists";
|
||||
EnableSharing = true;
|
||||
|
|
@ -70,15 +77,22 @@
|
|||
};
|
||||
};
|
||||
|
||||
services.nginx = {
|
||||
nodes.moonside.services.nginx = {
|
||||
upstreams = {
|
||||
"${serviceName}" = {
|
||||
servers = {
|
||||
"192.168.1.2:${builtins.toString servicePort}" = { };
|
||||
};
|
||||
};
|
||||
};
|
||||
virtualHosts = {
|
||||
"sound.swarsel.win" = {
|
||||
"${serviceDomain}" = {
|
||||
enableACME = true;
|
||||
forceSSL = true;
|
||||
acmeRoot = null;
|
||||
locations = {
|
||||
"/" = {
|
||||
proxyPass = "http://localhost:4040";
|
||||
proxyPass = "http://navidrome";
|
||||
proxyWebsockets = true;
|
||||
extraConfig = ''
|
||||
auth_request /oauth2/auth;
|
||||
|
|
@ -125,7 +139,7 @@
|
|||
'';
|
||||
};
|
||||
"/share" = {
|
||||
proxyPass = "http://localhost:4040";
|
||||
proxyPass = "http://navidrome";
|
||||
proxyWebsockets = true;
|
||||
extraConfig = ''
|
||||
proxy_redirect http:// https://;
|
||||
|
|
@ -139,7 +153,7 @@
|
|||
'';
|
||||
};
|
||||
"/rest" = {
|
||||
proxyPass = "http://localhost:4040";
|
||||
proxyPass = "http://navidrome";
|
||||
proxyWebsockets = true;
|
||||
extraConfig = ''
|
||||
proxy_redirect http:// https://;
|
||||
|
|
|
|||
|
|
@ -1,20 +1,23 @@
|
|||
{ pkgs, lib, config, ... }:
|
||||
let
|
||||
nextcloudDomain = "stash.swarsel.win";
|
||||
serviceDomain = "stash.swarsel.win";
|
||||
serviceUser = "nextcloud";
|
||||
serviceGroup = serviceUser;
|
||||
serviceName = "nextcloud";
|
||||
in
|
||||
{
|
||||
options.swarselsystems.modules.server.nextcloud = lib.mkEnableOption "enable nextcloud on server";
|
||||
config = lib.mkIf config.swarselsystems.modules.server.nextcloud {
|
||||
options.swarselsystems.modules.server."${serviceName}" = lib.mkEnableOption "enable ${serviceName} on server";
|
||||
config = lib.mkIf config.swarselsystems.modules.server."${serviceName}" {
|
||||
|
||||
sops.secrets = {
|
||||
nextcloudadminpass = {
|
||||
owner = "nextcloud";
|
||||
group = "nextcloud";
|
||||
owner = serviceUser;
|
||||
group = serviceGroup;
|
||||
mode = "0440";
|
||||
};
|
||||
kanidm-nextcloud-client = {
|
||||
owner = "nextcloud";
|
||||
group = "nextcloud";
|
||||
owner = serviceUser;
|
||||
group = serviceGroup;
|
||||
mode = "0440";
|
||||
};
|
||||
};
|
||||
|
|
@ -22,8 +25,12 @@ in
|
|||
services = {
|
||||
nextcloud = {
|
||||
enable = true;
|
||||
settings = {
|
||||
trusted_proxies = [ "0.0.0.0" ];
|
||||
overwriteprotocol = "https";
|
||||
};
|
||||
package = pkgs.nextcloud31;
|
||||
hostName = nextcloudDomain;
|
||||
hostName = serviceDomain;
|
||||
home = "/Vault/apps/nextcloud";
|
||||
datadir = "/Vault/data/nextcloud";
|
||||
https = true;
|
||||
|
|
@ -39,19 +46,28 @@ in
|
|||
dbtype = "sqlite";
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
nginx = {
|
||||
virtualHosts = {
|
||||
"${nextcloudDomain}" = {
|
||||
enableACME = true;
|
||||
forceSSL = true;
|
||||
acmeRoot = null;
|
||||
# config is automatically added by nixos nextcloud config.
|
||||
# hence, only provide certificate
|
||||
nodes.moonside.services.nginx = {
|
||||
upstreams = {
|
||||
"${serviceName}" = {
|
||||
servers = {
|
||||
"192.168.1.2:80" = { };
|
||||
};
|
||||
};
|
||||
};
|
||||
virtualHosts = {
|
||||
"${serviceDomain}" = {
|
||||
enableACME = true;
|
||||
forceSSL = true;
|
||||
acmeRoot = null;
|
||||
locations = {
|
||||
"/" = {
|
||||
proxyPass = "http://${serviceName}";
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
|||
107
modules/nixos/server/oauth2-proxy.nix
Normal file
107
modules/nixos/server/oauth2-proxy.nix
Normal file
|
|
@ -0,0 +1,107 @@
|
|||
{ lib, config, ... }:
|
||||
let
|
||||
kanidmDomain = "sso.swarsel.win";
|
||||
oauth2ProxyDomain = "soauth.swarsel.win";
|
||||
oauth2ProxyPort = 3004;
|
||||
in
|
||||
{
|
||||
options.swarselsystems.modules.server.oauth2Proxy = lib.mkEnableOption "enable oauth2-proxy on server";
|
||||
config = lib.mkIf config.swarselsystems.modules.server.oauth2Proxy {
|
||||
|
||||
sops = {
|
||||
secrets = {
|
||||
"oauth2-cookie-secret" = { owner = "oauth2-proxy"; group = "oauth2-proxy"; mode = "0440"; };
|
||||
"kanidm-oauth2-proxy-client" = { owner = "oauth2-proxy"; group = "oauth2-proxy"; mode = "0440"; };
|
||||
};
|
||||
|
||||
templates = {
|
||||
"kanidm-oauth2-proxy-client-env" = {
|
||||
content = ''
|
||||
OAUTH2_PROXY_CLIENT_SECRET="${config.sops.placeholder.kanidm-oauth2-proxy-client}"
|
||||
OAUTH2_PROXY_COOKIE_SECRET=${config.sops.placeholder.oauth2-cookie-secret}
|
||||
'';
|
||||
owner = "oauth2-proxy";
|
||||
group = "oauth2-proxy";
|
||||
mode = "0440";
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
networking.firewall.allowedTCPPorts = [ oauth2ProxyPort ];
|
||||
|
||||
services = {
|
||||
oauth2-proxy = {
|
||||
enable = true;
|
||||
cookie = {
|
||||
domain = ".swarsel.win";
|
||||
secure = true;
|
||||
expire = "900m";
|
||||
secret = null; # set by service EnvironmentFile
|
||||
};
|
||||
clientSecret = null; # set by service EnvironmentFile
|
||||
reverseProxy = true;
|
||||
httpAddress = "0.0.0.0:${builtins.toString oauth2ProxyPort}";
|
||||
redirectURL = "https://${oauth2ProxyDomain}/oauth2/callback";
|
||||
setXauthrequest = true;
|
||||
extraConfig = {
|
||||
code-challenge-method = "S256";
|
||||
whitelist-domain = ".swarsel.win";
|
||||
set-authorization-header = true;
|
||||
pass-access-token = true;
|
||||
skip-jwt-bearer-tokens = true;
|
||||
upstream = "static://202";
|
||||
oidc-issuer-url = "https://${kanidmDomain}/oauth2/openid/oauth2-proxy";
|
||||
provider-display-name = "Kanidm";
|
||||
};
|
||||
provider = "oidc";
|
||||
scope = "openid email";
|
||||
loginURL = "https://${kanidmDomain}/ui/oauth2";
|
||||
redeemURL = "https://${kanidmDomain}/oauth2/token";
|
||||
validateURL = "https://${kanidmDomain}/oauth2/openid/oauth2-proxy/userinfo";
|
||||
clientID = "oauth2-proxy";
|
||||
email.domains = [ "*" ];
|
||||
};
|
||||
};
|
||||
|
||||
systemd.services = {
|
||||
oauth2-proxy = {
|
||||
# after = [ "kanidm.service" ];
|
||||
serviceConfig = {
|
||||
RuntimeDirectory = "oauth2-proxy";
|
||||
RuntimeDirectoryMode = "0750";
|
||||
UMask = "007"; # TODO remove once https://github.com/oauth2-proxy/oauth2-proxy/issues/2141 is fixed
|
||||
RestartSec = "60"; # Retry every minute
|
||||
EnvironmentFile = [
|
||||
config.sops.templates.kanidm-oauth2-proxy-client-env.path
|
||||
];
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
services.nginx = {
|
||||
upstreams = {
|
||||
oauth2-proxy = {
|
||||
servers = {
|
||||
"localhost:${builtins.toString oauth2ProxyPort}" = { };
|
||||
};
|
||||
};
|
||||
};
|
||||
virtualHosts = {
|
||||
"${oauth2ProxyDomain}" = {
|
||||
enableACME = true;
|
||||
forceSSL = true;
|
||||
acmeRoot = null;
|
||||
locations = {
|
||||
"/" = {
|
||||
proxyPass = "http://oauth2-proxy";
|
||||
};
|
||||
};
|
||||
extraConfig = ''
|
||||
proxy_set_header X-Scheme $scheme;
|
||||
proxy_set_header X-Auth-Request-Redirect $scheme://$host$request_uri;
|
||||
'';
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
||||
|
|
@ -1,30 +1,39 @@
|
|||
{ lib, pkgs, config, ... }:
|
||||
let
|
||||
serviceDomain = "scan.swarsel.win";
|
||||
servicePort = 28981;
|
||||
serviceUser = "paperless";
|
||||
serviceGroup = serviceUser;
|
||||
serviceName = "paperless";
|
||||
in
|
||||
{
|
||||
options.swarselsystems.modules.server.paperless = lib.mkEnableOption "enable paperless on server";
|
||||
config = lib.mkIf config.swarselsystems.modules.server.paperless {
|
||||
options.swarselsystems.modules.server."${serviceName}" = lib.mkEnableOption "enable ${serviceName} on server";
|
||||
config = lib.mkIf config.swarselsystems.modules.server."${serviceName}" {
|
||||
|
||||
users.users.paperless = {
|
||||
users.users."${serviceUser}" = {
|
||||
extraGroups = [ "users" ];
|
||||
};
|
||||
|
||||
sops.secrets = {
|
||||
paperless_admin = { owner = "paperless"; };
|
||||
paperless_admin = { owner = serviceUser; };
|
||||
kanidm-paperless-client = {
|
||||
owner = "paperless";
|
||||
group = "paperless";
|
||||
owner = serviceUser;
|
||||
group = serviceGroup;
|
||||
mode = "0440";
|
||||
};
|
||||
};
|
||||
|
||||
networking.firewall.allowedTCPPorts = [ servicePort ];
|
||||
|
||||
services = {
|
||||
paperless = {
|
||||
enable = true;
|
||||
mediaDir = "/Vault/Eternor/Paperless";
|
||||
dataDir = "/Vault/data/paperless";
|
||||
user = "paperless";
|
||||
port = 28981;
|
||||
user = serviceUser;
|
||||
port = servicePort;
|
||||
passwordFile = config.sops.secrets.paperless_admin.path;
|
||||
address = "127.0.0.1";
|
||||
address = "0.0.0.0";
|
||||
settings = {
|
||||
PAPERLESS_OCR_LANGUAGE = "deu+eng";
|
||||
PAPERLESS_URL = "https://scan.swarsel.win";
|
||||
|
|
@ -84,15 +93,22 @@
|
|||
)
|
||||
'';
|
||||
|
||||
services.nginx = {
|
||||
nodes.moonside.services.nginx = {
|
||||
upstreams = {
|
||||
"${serviceName}" = {
|
||||
servers = {
|
||||
"192.168.1.2:${builtins.toString servicePort}" = { };
|
||||
};
|
||||
};
|
||||
};
|
||||
virtualHosts = {
|
||||
"scan.swarsel.win" = {
|
||||
"${serviceDomain}" = {
|
||||
enableACME = true;
|
||||
forceSSL = true;
|
||||
acmeRoot = null;
|
||||
locations = {
|
||||
"/" = {
|
||||
proxyPass = "http://localhost:28981";
|
||||
proxyPass = "http://${serviceName}";
|
||||
extraConfig = ''
|
||||
client_max_body_size 0;
|
||||
proxy_connect_timeout 300;
|
||||
|
|
|
|||
|
|
@ -1,26 +1,34 @@
|
|||
{ lib, config, ... }:
|
||||
let
|
||||
inherit (config.repo.secrets.common) workHostName;
|
||||
serviceDomain = "storync.swarsel.win";
|
||||
servicePort = 8384;
|
||||
serviceUser = "syncthing";
|
||||
serviceGroup = serviceUser;
|
||||
serviceName = "syncthing";
|
||||
in
|
||||
{
|
||||
options.swarselsystems.modules.server.syncthing = lib.mkEnableOption "enable syncthing on server";
|
||||
config = lib.mkIf config.swarselsystems.modules.server.syncthing {
|
||||
options.swarselsystems.modules.server."${serviceName}" = lib.mkEnableOption "enable ${serviceName} on server";
|
||||
config = lib.mkIf config.swarselsystems.modules.server."${serviceName}" {
|
||||
|
||||
users.users.syncthing = {
|
||||
users.users."${serviceUser}" = {
|
||||
extraGroups = [ "users" ];
|
||||
group = "syncthing";
|
||||
group = serviceGroup;
|
||||
isSystemUser = true;
|
||||
};
|
||||
|
||||
users.groups.syncthing = { };
|
||||
users.groups."${serviceGroup}" = { };
|
||||
|
||||
networking.firewall.allowedTCPPorts = [ servicePort ];
|
||||
|
||||
services.syncthing = {
|
||||
enable = true;
|
||||
user = "swarsel";
|
||||
user = serviceUser;
|
||||
group = serviceGroup;
|
||||
dataDir = "/Vault/data/syncthing";
|
||||
configDir = "/Vault/apps/syncthing";
|
||||
guiAddress = "0.0.0.0:8384";
|
||||
openDefaultPorts = true;
|
||||
guiAddress = "0.0.0.0:${builtins.toString servicePort}";
|
||||
openDefaultPorts = true; # opens ports TCP/UDP 22000 and UDP 21027 for discovery
|
||||
relay.enable = false;
|
||||
settings = {
|
||||
urAccepted = -1;
|
||||
|
|
@ -34,13 +42,16 @@ in
|
|||
"${workHostName}" = {
|
||||
id = "YAPV4BV-I26WPTN-SIP32MV-SQP5TBZ-3CHMTCI-Z3D6EP2-MNDQGLP-53FT3AB";
|
||||
};
|
||||
"moonside (@oracle)" = {
|
||||
id = "VPCDZB6-MGVGQZD-Q6DIZW3-IZJRJTO-TCC3QUQ-2BNTL7P-AKE7FBO-N55UNQE";
|
||||
};
|
||||
};
|
||||
folders = {
|
||||
"Default Folder" = lib.mkForce {
|
||||
path = "/Vault/data/syncthing/Sync";
|
||||
type = "receiveonly";
|
||||
versioning = null;
|
||||
devices = [ "sync (@oracle)" "magicant" "${workHostName}" ];
|
||||
devices = [ "sync (@oracle)" "magicant" "${workHostName}" "moonside (@oracle)" ];
|
||||
id = "default";
|
||||
};
|
||||
"Obsidian" = {
|
||||
|
|
@ -50,7 +61,7 @@ in
|
|||
type = "simple";
|
||||
params.keep = "5";
|
||||
};
|
||||
devices = [ "sync (@oracle)" "magicant" "${workHostName}" ];
|
||||
devices = [ "sync (@oracle)" "magicant" "${workHostName}" "moonside (@oracle)" ];
|
||||
id = "yjvni-9eaa7";
|
||||
};
|
||||
"Org" = {
|
||||
|
|
@ -60,7 +71,7 @@ in
|
|||
type = "simple";
|
||||
params.keep = "5";
|
||||
};
|
||||
devices = [ "sync (@oracle)" "magicant" "${workHostName}" ];
|
||||
devices = [ "sync (@oracle)" "magicant" "${workHostName}" "moonside (@oracle)" ];
|
||||
id = "a7xnl-zjj3d";
|
||||
};
|
||||
"Vpn" = {
|
||||
|
|
@ -70,7 +81,7 @@ in
|
|||
type = "simple";
|
||||
params.keep = "5";
|
||||
};
|
||||
devices = [ "sync (@oracle)" "magicant" "${workHostName}" ];
|
||||
devices = [ "sync (@oracle)" "magicant" "${workHostName}" "moonside (@oracle)" ];
|
||||
id = "hgp9s-fyq3p";
|
||||
};
|
||||
"Documents" = {
|
||||
|
|
@ -80,27 +91,29 @@ in
|
|||
type = "simple";
|
||||
params.keep = "5";
|
||||
};
|
||||
devices = [ "magicant" "${workHostName}" ];
|
||||
devices = [ "magicant" "${workHostName}" "moonside (@oracle)" ];
|
||||
id = "hgr3d-pfu3w";
|
||||
};
|
||||
# ".elfeed" = {
|
||||
# path = "/Vault/data/syncthing/.elfeed";
|
||||
# devices = [ "sync (@oracle)" "magicant" "${workHostName}" ];
|
||||
# id = "h7xbs-fs9v1";
|
||||
# };
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
services.nginx = {
|
||||
nodes.moonside.services.nginx = {
|
||||
upstreams = {
|
||||
"${serviceName}" = {
|
||||
servers = {
|
||||
"192.168.1.2:${builtins.toString servicePort}" = { };
|
||||
};
|
||||
};
|
||||
};
|
||||
virtualHosts = {
|
||||
"storync.swarsel.win" = {
|
||||
"${serviceDomain}" = {
|
||||
enableACME = true;
|
||||
forceSSL = true;
|
||||
acmeRoot = null;
|
||||
locations = {
|
||||
"/" = {
|
||||
proxyPass = "http://localhost:8384";
|
||||
proxyPass = "http://${serviceName}";
|
||||
extraConfig = ''
|
||||
client_max_body_size 0;
|
||||
'';
|
||||
|
|
@ -110,5 +123,4 @@ in
|
|||
};
|
||||
};
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue