diff --git a/config/system.nix b/config/system.nix index 90e33a7..7b70273 100644 --- a/config/system.nix +++ b/config/system.nix @@ -1,14 +1,10 @@ -{ - lib, - pkgs, - ... -}: { +{pkgs, ...}: { documentation.nixos.enable = false; # Disable sudo which is entierly unnecessary. security.sudo.enable = false; - time.timeZone = lib.mkDefault "Europe/Berlin"; + time.timeZone = "Europe/Berlin"; i18n.defaultLocale = "C.UTF-8"; console.keyMap = "de-latin1-nodeadkeys"; diff --git a/config/users.nix b/config/users.nix index 8369d27..18be875 100644 --- a/config/users.nix +++ b/config/users.nix @@ -35,5 +35,6 @@ stalwart-mail = uidGid 974; netbird-home = uidGid 973; gamemode = uidGid 972; + plausible = uidGid 971; }; } diff --git a/flake.lock b/flake.lock index 22bedf0..ca56dab 100644 --- a/flake.lock +++ b/flake.lock @@ -51,11 +51,11 @@ "pre-commit-hooks": "pre-commit-hooks" }, "locked": { - "lastModified": 1722597419, - "narHash": "sha256-YbMzll0Dh2ln/TryDP+S3IGm8nRHkzcSQIubI4ZEOAw=", + "lastModified": 1725722682, + "narHash": "sha256-AzBlGNCl20Rb3XQQNcTofntkZnaYolanvMJrADH11vM=", "owner": "oddlama", "repo": "agenix-rekey", - "rev": "126b4a5133eb361cbf5bf90e44c71b6f830845ec", + "rev": "10ea05a0077aefe03b443fdb63b58ab78d0440f3", "type": "github" }, "original": { @@ -459,28 +459,6 @@ "type": "github" } }, - "fenix": { - "inputs": { - "nixpkgs": [ - "microvm", - "nixpkgs" - ], - "rust-analyzer-src": "rust-analyzer-src" - }, - "locked": { - "lastModified": 1722580276, - "narHash": "sha256-VaNcSh7n8OaFW/DJsR6Fm23V+EGpSei0DyF71RKB+90=", - "owner": "nix-community", - "repo": "fenix", - "rev": "286f371b3cfeaa5c856c8e6dfb893018e86cc947", - "type": "github" - }, - "original": { - "owner": "nix-community", - "repo": "fenix", - "type": "github" - } - }, "flake-compat": { "flake": false, "locked": { @@ -1160,11 +1138,11 @@ ] }, "locked": { - "lastModified": 1725180166, - "narHash": "sha256-fzssXuGR/mCeGbzM1ExaTqDz7QDGta3WA4jJsZyRruo=", + "lastModified": 1725893417, + "narHash": "sha256-fj2LxTZAncL/s5NrtXe1nLfO0XDvRixtCu3kmV9jDPw=", "owner": "nix-community", "repo": "home-manager", - "rev": "471e3eb0a114265bcd62d11d58ba8d3421ee68eb", + "rev": "10541f19c584fe9633c921903d8c095d5411e041", "type": "github" }, "original": { @@ -1219,11 +1197,11 @@ }, "impermanence": { "locked": { - "lastModified": 1724489415, - "narHash": "sha256-ey8vhwY/6XCKoh7fyTn3aIQs7WeYSYtLbYEG87VCzX4=", + "lastModified": 1725690722, + "narHash": "sha256-4qWg9sNh5g1qPGO6d/GV2ktY+eDikkBTbWSg5/iD2nY=", "owner": "nix-community", "repo": "impermanence", - "rev": "c7f5b394397398c023000cf843986ee2571a1fd7", + "rev": "63f4d0443e32b0dd7189001ee1894066765d18a5", "type": "github" }, "original": { @@ -1247,7 +1225,6 @@ }, "microvm": { "inputs": { - "fenix": "fenix", "flake-utils": "flake-utils_4", "nixpkgs": [ "nixpkgs" @@ -1255,11 +1232,11 @@ "spectrum": "spectrum" }, "locked": { - "lastModified": 1725388988, - "narHash": "sha256-hjO/ZpmaXUHUzTSefzbj0Bosj6inFHRplbb+YqQQULc=", + "lastModified": 1725664757, + "narHash": "sha256-kUMgeF3hHJM8aBpdazNgtCeeOTrWext6lHfrYmC6otU=", "owner": "astro", "repo": "microvm.nix", - "rev": "d52082cc2668b8cd788e3133526c8693ee71f6a5", + "rev": "caac7808d1e31f8a0fa408338cd3736947cb226d", "type": "github" }, "original": { @@ -1336,11 +1313,11 @@ ] }, "locked": { - "lastModified": 1725161148, - "narHash": "sha256-WfAHq3Ag3vLNFfWxKHjFBFdPI6JIideWFJod9mx1eoo=", + "lastModified": 1725765290, + "narHash": "sha256-hwX53i24KyWzp2nWpQsn8lfGQNCP0JoW/bvQmcR1DPY=", "owner": "Mic92", "repo": "nix-index-database", - "rev": "32058e9138248874773630c846563b1a78ee7a5b", + "rev": "642275444c5a9defce57219c944b3179bf2adaa9", "type": "github" }, "original": { @@ -1374,11 +1351,11 @@ }, "nixlib": { "locked": { - "lastModified": 1725152544, - "narHash": "sha256-Tm344cnFM9f2YZsgWtJduvhIrvLr3Bi8J4Xc+UZDKYE=", + "lastModified": 1725757153, + "narHash": "sha256-c1a6iLmCVPFI9EUVMrBN8xdmFxFXEjcVwiTSVmqajOs=", "owner": "nix-community", "repo": "nixpkgs.lib", - "rev": "7f0b9e4fbd91826cb9ce6babbc11c87903191051", + "rev": "68584f89dd0eb16fea5d80ae127f3f681f6a5df7", "type": "github" }, "original": { @@ -1419,11 +1396,11 @@ ] }, "locked": { - "lastModified": 1725497951, - "narHash": "sha256-fayKyVs/9FQdYH+3SCOkQM1GCsEPPVE+lSiVGlYQ7i0=", + "lastModified": 1725843519, + "narHash": "sha256-Z6DglUwgFDz6fIvQ89wx/uBVWrGvEGECq0Ypyk/eigE=", "owner": "nix-community", "repo": "nixos-generators", - "rev": "15a07ebf4a041bf232026263f1f96f2af390f3bc", + "rev": "214efbd73241d72a8f48b8b9a73bb54895cd51a7", "type": "github" }, "original": { @@ -1434,11 +1411,11 @@ }, "nixos-hardware": { "locked": { - "lastModified": 1725477728, - "narHash": "sha256-ahej1VRqKmWbG7gewty+GlrSBEeGY/J2Zy8Nt8+3fdg=", + "lastModified": 1725885300, + "narHash": "sha256-5RLEnou1/GJQl+Wd+Bxaj7QY7FFQ9wjnFq1VNEaxTmc=", "owner": "NixOS", "repo": "nixos-hardware", - "rev": "880be1ab837e1e9fe0449dae41ac4d034694d4ce", + "rev": "166dee4f88a7e3ba1b7a243edb1aca822f00680e", "type": "github" }, "original": { @@ -1646,11 +1623,11 @@ }, "nixpkgs_2": { "locked": { - "lastModified": 1725432240, - "narHash": "sha256-+yj+xgsfZaErbfYM3T+QvEE2hU7UuE+Jf0fJCJ8uPS0=", + "lastModified": 1725634671, + "narHash": "sha256-v3rIhsJBOMLR8e/RNWxr828tB+WywYIoajrZKFM+0Gg=", "owner": "NixOS", "repo": "nixpkgs", - "rev": "ad416d066ca1222956472ab7d0555a6946746a80", + "rev": "574d1eac1c200690e27b8eb4e24887f8df7ac27c", "type": "github" }, "original": { @@ -1691,11 +1668,11 @@ "treefmt-nix": "treefmt-nix" }, "locked": { - "lastModified": 1725478117, - "narHash": "sha256-Ly0DgmYniwBtQ+3aW4JO9ETJq9nbPemlISxC6MEDyB8=", + "lastModified": 1725921389, + "narHash": "sha256-RBpN0ToD8O3qniBjqUiB1d2/LQJt5kH5P3Gt6dF91L0=", "owner": "nix-community", "repo": "nixvim", - "rev": "2ef974182ef62a6a6992118f0beb54dce812ae9b", + "rev": "facf6b2d0c9e22d858956d1d458eac6baf155a08", "type": "github" }, "original": { @@ -1998,23 +1975,6 @@ "wired-notify": "wired-notify" } }, - "rust-analyzer-src": { - "flake": false, - "locked": { - "lastModified": 1722521768, - "narHash": "sha256-FvJ4FaMy1kJbZ3Iw1RyvuiUAsbHJXoU2HwylzaFzj1o=", - "owner": "rust-lang", - "repo": "rust-analyzer", - "rev": "f149dc5029d8406fae8b2c541603bcac06e30deb", - "type": "github" - }, - "original": { - "owner": "rust-lang", - "ref": "nightly", - "repo": "rust-analyzer", - "type": "github" - } - }, "rust-overlay": { "inputs": { "flake-utils": [ diff --git a/hosts/sentinel/blog.nix b/hosts/sentinel/blog.nix new file mode 100644 index 0000000..be0badf --- /dev/null +++ b/hosts/sentinel/blog.nix @@ -0,0 +1,33 @@ +{ + globals, + pkgs, + ... +}: { + services.nginx.virtualHosts.${globals.domains.me} = { + forceSSL = true; + useACMEWildcardHost = true; + locations."/".root = pkgs.runCommand "index.html" {} '' + mkdir -p $out + cat > $out/index.html < + + + + Not empty soon TM. Until then please go here: oddlama + + EOF + ''; + # Don't use the proxyPass option because we don't want the recommended proxy headers + locations."= /js/script.js".extraConfig = '' + proxy_pass https://${globals.services.plausible.domain}/js/script.js; + proxy_set_header Host ${globals.services.plausible.domain}; + proxy_ssl_server_name on; + ''; + locations."= /api/event".extraConfig = '' + proxy_pass https://${globals.services.plausible.domain}/api/event; + proxy_http_version 1.1; + proxy_set_header Host ${globals.services.plausible.domain}; + proxy_ssl_server_name on; + ''; + }; +} diff --git a/hosts/sentinel/clickhouse-config.xml b/hosts/sentinel/clickhouse-config.xml new file mode 100644 index 0000000..be7fc14 --- /dev/null +++ b/hosts/sentinel/clickhouse-config.xml @@ -0,0 +1,17 @@ + + + + warning + true + + + + + + + + + + + + diff --git a/hosts/sentinel/clickhouse-users.xml b/hosts/sentinel/clickhouse-users.xml new file mode 100644 index 0000000..bd2d217 --- /dev/null +++ b/hosts/sentinel/clickhouse-users.xml @@ -0,0 +1,9 @@ + + + + + 0 + 0 + + + diff --git a/hosts/sentinel/default.nix b/hosts/sentinel/default.nix index 41f9f4c..156a54e 100644 --- a/hosts/sentinel/default.nix +++ b/hosts/sentinel/default.nix @@ -1,7 +1,6 @@ { config, globals, - pkgs, ... }: { imports = [ @@ -11,10 +10,13 @@ ../../config/optional/zfs.nix ./acme.nix + ./blog.nix ./coturn.nix ./fs.nix ./net.nix ./oauth2.nix + ./plausible.nix + ./postgresql.nix ]; nixpkgs.hostPlatform = "x86_64-linux"; @@ -26,19 +28,6 @@ services.nginx.enable = true; services.nginx.recommendedSetup = true; - services.nginx.virtualHosts.${globals.domains.me} = { - forceSSL = true; - useACMEWildcardHost = true; - locations."/".root = pkgs.runCommand "index.html" {} '' - mkdir -p $out - cat > $out/index.html < - Not empty soon TM. Until then please go here: oddlama - - EOF - ''; - }; - meta.promtail = { enable = true; proxy = "sentinel"; diff --git a/hosts/sentinel/plausible.nix b/hosts/sentinel/plausible.nix new file mode 100644 index 0000000..f4ff469 --- /dev/null +++ b/hosts/sentinel/plausible.nix @@ -0,0 +1,120 @@ +{ + config, + lib, + globals, + ... +}: let + plausibleDomain = "analytics.${globals.domains.me}"; +in { + age.secrets.plausible-secret = { + generator.script = args: "${args.pkgs.openssl}/bin/openssl rand -base64 64"; + mode = "440"; + group = "plausible"; + }; + + age.secrets.plausible-admin-pw = { + generator.script = "alnum"; + mode = "440"; + group = "plausible"; + }; + + environment.persistence."/persist".directories = [ + { + directory = "/var/lib/clickhouse"; + mode = "0750"; + user = "clickhouse"; + group = "clickhouse"; + } + { + directory = "/var/lib/plausible"; + mode = "0750"; + user = "plausible"; + group = "plausible"; + } + ]; + + services.clickhouse.enable = true; + environment.etc = { + # With changes from https://theorangeone.net/posts/calming-down-clickhouse/ + "clickhouse-server/config.d/custom.xml".source = lib.mkForce ./clickhouse-config.xml; + "clickhouse-server/users.d/custom.xml".source = lib.mkForce ./clickhouse-users.xml; + }; + + globals.services.plausible.domain = plausibleDomain; + services.plausible = { + enable = true; + + server = { + port = 8545; + baseUrl = "https://${plausibleDomain}"; + disableRegistration = true; + secretKeybaseFile = config.age.secrets.plausible-secret.path; + }; + + adminUser = { + activate = true; + name = "admin"; + email = "plausible@${globals.domains.me}"; + passwordFile = config.age.secrets.plausible-admin-pw.path; + }; + }; + + services.nginx = { + upstreams.plausible = { + servers."127.0.0.1:${toString config.services.plausible.server.port}" = {}; + extraConfig = '' + zone plausible 64k; + keepalive 2; + ''; + monitoring = { + enable = true; + expectedBodyRegex = "Plausible"; + }; + }; + virtualHosts.${plausibleDomain} = { + forceSSL = true; + useACMEWildcardHost = true; + oauth2.enable = true; + oauth2.allowedGroups = ["access_analytics"]; + locations."/".proxyPass = "http://plausible"; + locations."= /js/script.js" = { + proxyPass = "http://plausible"; + extraConfig = '' + auth_request off; + ''; + }; + locations."= /api/event" = { + proxyPass = "http://plausible"; + extraConfig = '' + proxy_http_version 1.1; + auth_request off; + ''; + }; + }; + }; + + services.epmd.enable = lib.mkForce false; + systemd.services.plausible = { + environment = { + STORAGE_DIR = lib.mkForce "/run/plausible/elixir_tzdata"; + RELEASE_TMP = lib.mkForce "/run/plausible/tmp"; + HOME = lib.mkForce "/run/plausible"; + }; + serviceConfig = { + RestartSec = "60"; # Retry every minute + DynamicUser = lib.mkForce false; + User = "plausible"; + Group = "plausible"; + StateDirectory = lib.mkForce "plausible"; + RuntimeDirectory = "plausible"; + WorkingDirectory = lib.mkForce "/run/plausible"; + }; + }; + + users.groups.plausible = {}; + users.users.plausible = { + group = "plausible"; + isSystemUser = true; + home = "/var/lib/plausible"; + }; +} diff --git a/hosts/sentinel/postgresql.nix b/hosts/sentinel/postgresql.nix new file mode 100644 index 0000000..6fabc4d --- /dev/null +++ b/hosts/sentinel/postgresql.nix @@ -0,0 +1,23 @@ +{pkgs, ...}: { + services.postgresql = { + enable = true; + package = pkgs.postgresql_16_jit; + + # Doesn't work with plausible, since it wants to connect as the postgres + # for some (probably unecessary) reason. + # + # authentication = lib.mkForce '' + # #type database DBuser auth-method optional_ident_map + # local sameuser all peer map=superuser_map + # local all postgres peer map=superuser_map + # ''; + # + # identMap = '' + # # ArbitraryMapName systemUser DBUser + # superuser_map root postgres + # superuser_map postgres postgres + # # Let other names login as themselves + # superuser_map /^(.*)$ \1 + # ''; + }; +} diff --git a/hosts/ward/guests/kanidm.nix b/hosts/ward/guests/kanidm.nix index 95a9dde..a91d4fe 100644 --- a/hosts/ward/guests/kanidm.nix +++ b/hosts/ward/guests/kanidm.nix @@ -195,6 +195,7 @@ in { groups."web-sentinel.access" = {}; groups."web-sentinel.adguardhome" = {}; groups."web-sentinel.openwebui" = {}; + groups."web-sentinel.analytics" = {}; systems.oauth2.web-sentinel = { displayName = "Web Sentinel"; originUrl = "https://oauth2.${globals.domains.me}/"; @@ -206,6 +207,7 @@ in { joinType = "array"; valuesByGroup."web-sentinel.adguardhome" = ["access_adguardhome"]; valuesByGroup."web-sentinel.openwebui" = ["access_openwebui"]; + valuesByGroup."web-sentinel.analytics" = ["access_analytics"]; }; }; }; diff --git a/modules/oauth2-proxy.nix b/modules/oauth2-proxy.nix index e5b8206..5c6156d 100644 --- a/modules/oauth2-proxy.nix +++ b/modules/oauth2-proxy.nix @@ -84,7 +84,7 @@ in { ''; locations."@redirectToAuth2ProxyLogin" = { - # FIXME: allow refering to another node for the portaldomain + # FIXME: allow referring to another node for the portaldomain setOauth2Headers = false; return = "307 https://${cfg.portalDomain}/oauth2/start?rd=$scheme://$host$request_uri"; extraConfig = '' diff --git a/secrets/generated/sentinel/plausible-admin-pw.age b/secrets/generated/sentinel/plausible-admin-pw.age new file mode 100644 index 0000000..052250e --- /dev/null +++ b/secrets/generated/sentinel/plausible-admin-pw.age @@ -0,0 +1,9 @@ +age-encryption.org/v1 +-> X25519 fa8woWj8FU9qcLWZ6fOxynA9Vebs4/I8iZJnUl/Xoio +NQC2aFU7ndVhcpKURoxW5pPg7rVHdsg42Ufqmn7IKFo +-> piv-p256 xqSe8Q AutAPD4hFrfIsxyaUWmHmgIK2fyZvz6UeQIA56T+3y8H +HDiljHzGE3SV+zSI940OledXsGHh2cDGHqSTQ0Y3Kb4 +-> 5lL{0#F-grease +FD5Q1N/RDC5c5uRaeQkfHUY +--- f/FxUfcp0gWHkUD8PyxGcchvUXvGdxKzVOw7HFEtnwU +eŘ%aϭ^9UeBc""n !9Nsn'oMEU*Ou޻ZWg|q \ No newline at end of file diff --git a/secrets/generated/sentinel/plausible-secret.age b/secrets/generated/sentinel/plausible-secret.age new file mode 100644 index 0000000..14ac18d --- /dev/null +++ b/secrets/generated/sentinel/plausible-secret.age @@ -0,0 +1,10 @@ +age-encryption.org/v1 +-> X25519 /+jL5B4Efw2mdhpmPM0vDIBm7DE5ZimWQ3SGZRPZ6Hg +HAY0F7TJ+17RDAst0kK1E5E82J/BAw4wk/AtfPxbLyc +-> piv-p256 xqSe8Q As3/Rq//NRBvi71T4QOQCRITy2vKPRYs5O8acBIYQY5f +/X45X2RWRwm7Y9PWfwtYJXdlYGQh4FCyGPrBjPE5Czc +-> _O`KD6-grease '%zS +z0dmCOEdvsnAH4KHoXoZ24uPhXz+C2+0WcOCOk5RXcDpQ2En7VY8IE0YyM/JZg +--- x5AYPyZb8rPuCm1vGzklmNUyX6usj+DOZF2XxSSBKVg +^o;\dD4v+[_7Ahv +q::gA@P^:>z |wPջu/tFxpXmNR xa$m4 \ No newline at end of file diff --git a/secrets/global.nix.age b/secrets/global.nix.age index 7fffe1c..2c67dcb 100644 Binary files a/secrets/global.nix.age and b/secrets/global.nix.age differ diff --git a/secrets/rekeyed/sentinel/717d95da48eecb67e345542aee86292f-plausible-admin-pw.age b/secrets/rekeyed/sentinel/717d95da48eecb67e345542aee86292f-plausible-admin-pw.age new file mode 100644 index 0000000..db34c16 --- /dev/null +++ b/secrets/rekeyed/sentinel/717d95da48eecb67e345542aee86292f-plausible-admin-pw.age @@ -0,0 +1,8 @@ +age-encryption.org/v1 +-> ssh-ed25519 yV7lcA Er1Vw7Jhk/D+GnBuhajXvilOF5KMS9t2jBXA6IpTrCA +1tWBxOOJTmojh0E4EK1mEgPqJQE6F3cG48E/Ak1ruGI +-> ssh-ed25519 yV7lcA XdThz+ciEwv3hWkGzxEo31dbLfrg43M7bEzcgR75eGM +CriS2oYnUXnwNQCppdVB6PB9nDv0w3rwlJeUKFcrLXo +-> ZZ}-grease ^F\gsUsr +ZAqDSq+gPYGV9seqbMgAEmz+F0D44p6zXMjvl+/3ZxhFjUmOSrM6vQKFgPGJkrbR +j4vcsTv5b2onXyHDgwH47yRld3i7JuYiMQbO +--- 0TJbeW9vdtCk/cqRozfqc1du6Xrr268964hWfJ2/xKU +nprB]ֱx, A[0j E kh#xjЊޞtx=i{]pc~kuԛ'}-Dr#xpT6.ͯ'%xZV)W +D' \ No newline at end of file