Compare commits
3 commits
d95717941d
...
038865ba84
Author | SHA1 | Date | |
---|---|---|---|
![]() |
038865ba84 | ||
![]() |
96f4272724 | ||
![]() |
1edeffc961 |
11 changed files with 270 additions and 5 deletions
|
@ -32,6 +32,8 @@
|
|||
./gerd/services/drtvrss.nix
|
||||
./gerd/services/vikunja.nix
|
||||
|
||||
./gerd/services/headscale
|
||||
|
||||
./gerd/services/monitoring
|
||||
];
|
||||
|
||||
|
|
26
machines/gerd/services/headscale/default.nix
Normal file
26
machines/gerd/services/headscale/default.nix
Normal file
|
@ -0,0 +1,26 @@
|
|||
{ config, pkgs, ... }:
|
||||
|
||||
let
|
||||
svc_domain = "headscale.${config.mine.shared.settings.domain}";
|
||||
in {
|
||||
imports = [
|
||||
./headscale.nix
|
||||
./headplane.nix
|
||||
];
|
||||
|
||||
|
||||
mine.shared.meta.headscale = {
|
||||
name = "";
|
||||
description = "";
|
||||
|
||||
package = let
|
||||
pkg = pkgs.headscale;
|
||||
in {
|
||||
name = pkg.pname;
|
||||
version = pkg.version;
|
||||
meta = pkg.meta;
|
||||
};
|
||||
};
|
||||
|
||||
mine.shared.settings.headscale.domain = svc_domain;
|
||||
}
|
126
machines/gerd/services/headscale/headplane.nix
Normal file
126
machines/gerd/services/headscale/headplane.nix
Normal file
|
@ -0,0 +1,126 @@
|
|||
{ config, pkgs, ... }:
|
||||
|
||||
let
|
||||
svc_domain = config.mine.shared.settings.headscale.domain;
|
||||
|
||||
sources = import ./../../../../shared/sources;
|
||||
flake-compat = sources.flake-compat;
|
||||
|
||||
newpkgs = (import (builtins.fetchTarball {
|
||||
url = "https://github.com/NixOS/nixpkgs/archive/c2a03962b8e24e669fb37b7df10e7c79531ff1a4.tar.gz";
|
||||
}) {});
|
||||
|
||||
|
||||
headplanesrc = let
|
||||
tmppkgs = (import (builtins.fetchTarball {
|
||||
url = "https://github.com/NixOS/nixpkgs/archive/ab7b6889ae9d484eed2876868209e33eb262511d.tar.gz";
|
||||
}) {});
|
||||
|
||||
src = builtins.fetchTarball {
|
||||
url = "https://github.com/tale/headplane/archive/2f316176c8c37ad63946d7075c727478f81303b2.tar.gz";
|
||||
};
|
||||
in tmppkgs.applyPatches {
|
||||
src = src;
|
||||
name = "headplane-patched";
|
||||
patches = [
|
||||
(tmppkgs.writeText "headplane-package-pnpm-hash.patch" ''
|
||||
diff --git a/nix/package.nix b/nix/package.nix
|
||||
index bb430d7..11349c4 100644
|
||||
--- a/nix/package.nix
|
||||
+++ b/nix/package.nix
|
||||
@@ -23,7 +23,7 @@ stdenv.mkDerivation (finalAttrs: {
|
||||
|
||||
pnpmDeps = pnpm_10.fetchDeps {
|
||||
inherit (finalAttrs) pname version src;
|
||||
- hash = "sha256-OOWgYaGwa5PtWhFEEkRCojCDmkPIR6tJ5cfFMOLND3I=";
|
||||
+ hash = "sha256-xjjkqbgjYaAGYAmlTFE+Lq3Hp6myZKaW3br0YTDNhQA=";
|
||||
};
|
||||
'')
|
||||
];
|
||||
};
|
||||
|
||||
headplane = import flake-compat { src = headplanesrc; };
|
||||
in {
|
||||
imports = [
|
||||
headplane.defaultNix.nixosModules.headplane
|
||||
];
|
||||
|
||||
services.headplane = {
|
||||
enable = true;
|
||||
agent.enable = false;
|
||||
|
||||
settings = {
|
||||
server = {
|
||||
host = "127.0.0.1";
|
||||
port = 53874;
|
||||
cookie_secret = "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"; # replaced in env
|
||||
cookie_secure = true;
|
||||
};
|
||||
|
||||
headscale = {
|
||||
url = "https://${svc_domain}";
|
||||
config_strict = false;
|
||||
};
|
||||
|
||||
oidc = {
|
||||
issuer = "https://${config.mine.shared.settings.authelia.domain}";
|
||||
client_id = "headplane";
|
||||
client_secret = "<from_env>";
|
||||
redirect_uri = "https://${svc_domain}/admin/oidc/callback";
|
||||
|
||||
# headscale API key for authenticating users
|
||||
headscale_api_key = "<from_env>";
|
||||
|
||||
# default to state directory
|
||||
user_storage_file = "/var/lib/headplane/users.json";
|
||||
|
||||
# set to the default authelia auth method
|
||||
token_endpoint_auth_method = "client_secret_basic";
|
||||
|
||||
# disable authenticating with headscale api key
|
||||
disable_api_key_login = true;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
# headplane module does not allow setting package,
|
||||
# so we have to add headplane to pkgs
|
||||
nixpkgs.overlays = [
|
||||
(self: super: {
|
||||
headplane = headplane.defaultNix.packages.x86_64-linux.headplane;
|
||||
})
|
||||
];
|
||||
|
||||
systemd.services.headplane.serviceConfig = {
|
||||
# setup state directory
|
||||
StateDirectory = "headplane";
|
||||
|
||||
# load configs from env file
|
||||
EnvironmentFile = [ config.age.secrets.headplane-env.path ];
|
||||
};
|
||||
|
||||
# setup for oidc
|
||||
services.authelia.instances.main.settings.identity_providers.oidc.clients = [{
|
||||
client_id = "headplane";
|
||||
client_name = "Headplane";
|
||||
client_secret = "$pbkdf2-sha512$310000$h7Te42JTu4Xsqz/8CGan7Q$qDd183LHmEsgNvVAI8Xf.1DpRMeS8DqNmDpkkjkxgRR/lZYQgAkXYzL2MyvLqNFFSVKAdMTsD/Jxk72g9fxnew";
|
||||
consent_mode = "implicit";
|
||||
redirect_uris = [ "https://${svc_domain}/admin/oidc/callback" ];
|
||||
scopes = [
|
||||
"openid"
|
||||
"profile"
|
||||
"email"
|
||||
];
|
||||
}];
|
||||
|
||||
# nginx
|
||||
services.nginx.virtualHosts."${svc_domain}".locations."/admin" = {
|
||||
proxyPass = "http://127.0.0.1:${builtins.toString config.services.headplane.settings.server.port}";
|
||||
priority = 5;
|
||||
};
|
||||
|
||||
# persistence
|
||||
environment.persistence.root.directories = [
|
||||
"/var/lib/headplane"
|
||||
];
|
||||
}
|
80
machines/gerd/services/headscale/headscale.nix
Normal file
80
machines/gerd/services/headscale/headscale.nix
Normal file
|
@ -0,0 +1,80 @@
|
|||
{ config, pkgs, ... }:
|
||||
|
||||
let
|
||||
svc_domain = config.mine.shared.settings.headscale.domain;
|
||||
svc_domain_dns_magic_domain = "ts.${config.mine.shared.settings.domain}";
|
||||
|
||||
grpc_port = 50443;
|
||||
in {
|
||||
services.headscale = {
|
||||
enable = true;
|
||||
|
||||
settings = {
|
||||
server_url = "https://${svc_domain}";
|
||||
|
||||
# grpc
|
||||
grpc_listen_addr = "127.0.0.1:${builtins.toString grpc_port}";
|
||||
grpc_allow_insecure = true;
|
||||
|
||||
# dns
|
||||
dns.base_domain = svc_domain_dns_magic_domain;
|
||||
dns.nameservers.global = [ "1.1.1.1" ];
|
||||
|
||||
# acl -> save in database
|
||||
policy.mode = "database";
|
||||
|
||||
# auth
|
||||
oidc = {
|
||||
only_start_if_oidc_is_available = true;
|
||||
issuer = "https://${config.mine.shared.settings.authelia.domain}";
|
||||
client_id = "headscale";
|
||||
client_secret_path = "$CREDENTIALS_DIRECTORY/authelia-secret";
|
||||
};
|
||||
|
||||
# debug
|
||||
log.level = "debug";
|
||||
};
|
||||
};
|
||||
systemd.services.headscale.serviceConfig.LoadCredential = [
|
||||
"authelia-secret:${config.age.secrets.headscale-authelia-secret.path}"
|
||||
];
|
||||
|
||||
# setup for oidc
|
||||
services.authelia.instances.main.settings.identity_providers.oidc.clients = [{
|
||||
client_id = "headscale";
|
||||
client_name = "Headscale";
|
||||
client_secret = "$pbkdf2-sha512$310000$/xiUR1oDvUEn4OKEu31COw$Z.IMgW3Qb2.mgCyEq1UUDC0i7cX2GOiywUjY4MsNv4ixQCP1jFO7njctCW2mVCqvkgfylDpsWRM3z.uXTs89IA";
|
||||
consent_mode = "implicit";
|
||||
redirect_uris = [ "https://${svc_domain}/oidc/callback" ];
|
||||
scopes = [
|
||||
"openid"
|
||||
"profile"
|
||||
"email"
|
||||
];
|
||||
}];
|
||||
|
||||
# nginx
|
||||
services.nginx.virtualHosts."${svc_domain}" = {
|
||||
forceSSL = true;
|
||||
enableACME = true;
|
||||
|
||||
# headscale gRPC API
|
||||
locations."/headscale" = {
|
||||
extraConfig = ''
|
||||
grpc_pass 127.0.0.1:${builtins.toString grpc_port};
|
||||
'';
|
||||
priority = 0;
|
||||
};
|
||||
|
||||
# fallback to headscale
|
||||
locations."/" = {
|
||||
proxyPass = "http://127.0.0.1:${builtins.toString config.services.headscale.port}";
|
||||
proxyWebsockets = true;
|
||||
};
|
||||
};
|
||||
|
||||
# persistence
|
||||
environment.persistence.root.directories = [
|
||||
"/var/lib/headscale"
|
||||
];
|
||||
}
|
|
@ -23,7 +23,7 @@ let
|
|||
stalwart_user = config.users.users.stalwart-mail.name;
|
||||
stalwart_group = config.users.groups.stalwart-mail.name;
|
||||
|
||||
certLocation = config.security.acme.certs."${svc_domain}".directory;
|
||||
certLocation = config.security.acme.certs."${svc_domain_mail}".directory;
|
||||
in {
|
||||
services.stalwart-mail = {
|
||||
enable = true;
|
||||
|
@ -78,6 +78,7 @@ in {
|
|||
# we dont have access to this in lldap, and
|
||||
# therefore we use secret-changed instead
|
||||
# secret = lconfig.attr.stalwart_secret;
|
||||
secret = lconfig.attr.creationdate;
|
||||
# TODO(eyJhb): remove once LLDAP gets
|
||||
# plugin support, so we can make a plugin
|
||||
# that updates a attribute on password updates
|
||||
|
@ -161,7 +162,7 @@ in {
|
|||
|
||||
# need to change group to stalwart-mail for cert + add nginx to stalwart-mail group to do HTTP ACME
|
||||
users.users.nginx.extraGroups = [ stalwart_group ];
|
||||
security.acme.certs."${svc_domain}" = {
|
||||
security.acme.certs."${svc_domain_mail}" = {
|
||||
group = stalwart_group;
|
||||
reloadServices = [ config.systemd.services.stalwart-mail.name ];
|
||||
};
|
||||
|
|
|
@ -72,6 +72,10 @@
|
|||
|
||||
# vikunja
|
||||
vikunja-env.file = ./vikunja/env.age;
|
||||
|
||||
# headscale/headplan
|
||||
headscale-authelia-secret.file = ./headscale/headscale-authelia-secret.age;
|
||||
headplane-env.file = ./headscale/headplane-env.age;
|
||||
};
|
||||
|
||||
users.groups.secrets-lldap-bind-user-pass = {};
|
||||
|
|
11
secrets/headscale/headplane-env.age
Normal file
11
secrets/headscale/headplane-env.age
Normal file
|
@ -0,0 +1,11 @@
|
|||
age-encryption.org/v1
|
||||
-> ssh-ed25519 QSDXqg U2hjU5FeVfd+/agny133FUmLJ47zqpww10DgzHbkKW8
|
||||
k6k+WH6fZ1UZjnOwe3LS6cXYVcucE+kBhuPRMcNFabI
|
||||
-> X25519 JfLnC3qBptSdDwBRo1Zj/rDqKqWFvxWqBANIKhCIVlc
|
||||
iuqSt9gdPjQVRuv9+iUub1zkecSUjZD1XKvtvkNAaOE
|
||||
-> ssh-ed25519 n8n9DQ eVkQODcS4wG+5xliWzqfEcRKvkHaHTzz8BWXH/ld/3k
|
||||
9q0TB7ZLluGIQhFjMcXUmXlGiof5/ACrrHQRWEq4jik
|
||||
-> ssh-ed25519 BTp6UA hGuGXru5pgShG15hEH6B8fYF4x1SK6blgP+3NSfvklI
|
||||
UZYG5ZfErwlBtux5fWh3CPrT/9oWoDjGXX1M0ojtY8c
|
||||
--- NlksmWK4pF3hQkpCkZaCBWvEv7I9TB0zgYRiJpuLB18
|
||||
±±-ke(~ñ…"KktWv´&«í´~ÔúšžÝ¶û¿Žè½éHÆ)ûjQÔÅÐtRe/<2F>C_s.“ƒÓéýÚÚà/º~21ŸòÜ«"æ!á²ÎÓ<C38E>7IƒÅüÙìŒCj¥KÝÛ¼H«ˆ³o!È{ÁüÏþYhÉzcÀ¢³¬go?ßåtˆäãÔÃ<C394><sì©`ÌÇñŠMZgôÙ¨R:þñ3-i@dVÕDÂ^¸…'{R6{Œ€ÑóIĹѯ›Ò¬¼`UÜSJ&E¯/WâÏ >¾JS @`Ùm±h|‰ˆ±Áe3é¨U!;sñíãÔ}õ¼©L—í Àb¿ê$<24>·-R8Vq:ÏíÚ£uûÉ&üÊK\¥™ÉÛiªð¸8¬‡TALO•ÍÂùOñõgñ3ÒfˆêàT›½€
|
BIN
secrets/headscale/headscale-authelia-secret.age
Normal file
BIN
secrets/headscale/headscale-authelia-secret.age
Normal file
Binary file not shown.
|
@ -82,4 +82,8 @@ in
|
|||
|
||||
# vikunja
|
||||
"vikunja/env.age".publicKeys = defaultAccess;
|
||||
|
||||
# headscale/headplan
|
||||
"headscale/headscale-authelia-secret.age".publicKeys = defaultAccess;
|
||||
"headscale/headplane-env.age".publicKeys = defaultAccess;
|
||||
}
|
||||
|
|
|
@ -18,6 +18,17 @@ in sources // {
|
|||
url = "https://github.com/NixOS/nixpkgs/pull/412054.patch";
|
||||
sha256 = "sha256-OExslGsrGGPWSJJFPkZgYV8DaPKq9YDlmozPf/bV6dE=";
|
||||
})
|
||||
# headscale: 0.25.1 -> 0.26.0, update nixos module and test accordingly #407644
|
||||
(pkgs.fetchpatch {
|
||||
url = "https://github.com/NixOS/nixpkgs/pull/407644.patch";
|
||||
sha256 = "sha256-0fAB9DJ8KeocS/ZP4CPEt9VHkAu6gt025rSu3Skssqo=";
|
||||
})
|
||||
|
||||
# # Revert "nixos/murmur: Get rid of global lib expansion" #413495
|
||||
# (pkgs.fetchpatch {
|
||||
# url = "https://github.com/NixOS/nixpkgs/pull/413495.patch";
|
||||
# sha256 = "sha256-0QI2qn0vkFruk0sq15xLriz6iqvs2e9DjApVblsSULE=";
|
||||
# })
|
||||
];
|
||||
};
|
||||
|
||||
|
|
|
@ -17,10 +17,10 @@
|
|||
"homepage": "",
|
||||
"owner": "nix-community",
|
||||
"repo": "disko",
|
||||
"rev": "a894f2811e1ee8d10c50560551e50d6ab3c392ba",
|
||||
"sha256": "06gbwfkzm73xrf2brnlvg0g6dbjjry7xqmaar320dqwclq44jf83",
|
||||
"rev": "58d6e5a83fff9982d57e0a0a994d4e5c0af441e4",
|
||||
"sha256": "0h4br7anx158shym8a812wi43qhq5qqsv3xk7vxm6s6dawnp4azw",
|
||||
"type": "tarball",
|
||||
"url": "https://github.com/nix-community/disko/archive/a894f2811e1ee8d10c50560551e50d6ab3c392ba.tar.gz",
|
||||
"url": "https://github.com/nix-community/disko/archive/58d6e5a83fff9982d57e0a0a994d4e5c0af441e4.tar.gz",
|
||||
"url_template": "https://github.com/<owner>/<repo>/archive/<rev>.tar.gz"
|
||||
},
|
||||
"drasl": {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue