diff --git a/flake.lock b/flake.lock index d530407..ce68c1d 100644 --- a/flake.lock +++ b/flake.lock @@ -96,6 +96,21 @@ "type": "github" } }, + "impermanence": { + "locked": { + "lastModified": 1708968331, + "narHash": "sha256-VUXLaPusCBvwM3zhGbRIJVeYluh2uWuqtj4WirQ1L9Y=", + "owner": "nix-community", + "repo": "impermanence", + "rev": "a33ef102a02ce77d3e39c25197664b7a636f9c30", + "type": "github" + }, + "original": { + "owner": "nix-community", + "repo": "impermanence", + "type": "github" + } + }, "mk-naked-shell": { "flake": false, "locked": { @@ -383,6 +398,7 @@ "root": { "inputs": { "home-manager": "home-manager", + "impermanence": "impermanence", "nix-index-database": "nix-index-database", "nix-inspect": "nix-inspect", "nix-vscode-extensions": "nix-vscode-extensions", diff --git a/flake.nix b/flake.nix index 27ab6df..130f274 100644 --- a/flake.nix +++ b/flake.nix @@ -6,6 +6,10 @@ nixpkgs.url = "github:nixos/nixpkgs/nixos-23.11"; nixpkgs-unstable.url = "github:nixos/nixpkgs/nixos-unstable"; + # impermanence + # https://github.com/nix-community/impermanence + impermanence.url = "github:nix-community/impermanence"; + # nur nur.url = "github:nix-community/NUR"; @@ -50,6 +54,7 @@ , sops-nix , home-manager , nix-vscode-extensions + , impermanence , ... } @ inputs: @@ -97,6 +102,7 @@ , baseModules ? [ sops-nix.nixosModules.sops home-manager.nixosModules.home-manager + impermanence.nixosModules.impermanence ./nixos/profiles/global.nix # all machines get a global profile ./nixos/modules/nixos # all machines get nixos modules ./nixos/hosts/${hostname} # load this host's config folder for machine-specific config diff --git a/nixos/hosts/daedalus/default.nix b/nixos/hosts/daedalus/default.nix index 3470d5e..d58004a 100644 --- a/nixos/hosts/daedalus/default.nix +++ b/nixos/hosts/daedalus/default.nix @@ -86,6 +86,7 @@ { device = "rpool/safe/persist"; fsType = "zfs"; + # neededForBoot = true; # for impermanence }; swapDevices = diff --git a/nixos/hosts/durandal/default.nix b/nixos/hosts/durandal/default.nix index 646cd72..881eee6 100644 --- a/nixos/hosts/durandal/default.nix +++ b/nixos/hosts/durandal/default.nix @@ -11,6 +11,7 @@ openssh.enable = true; podman.enable = true; traefik.enable = true; + postgresql.enable = true; diff --git a/nixos/hosts/shodan/default.nix b/nixos/hosts/shodan/default.nix index dafc17f..a036173 100644 --- a/nixos/hosts/shodan/default.nix +++ b/nixos/hosts/shodan/default.nix @@ -26,6 +26,9 @@ mosquitto.enable = true; zigbee2mqtt.enable = true; + node-red.enable = true; + home-assistant.enable = true; + openvscode-server.enable = true; }; @@ -78,6 +81,7 @@ { device = "rpool/safe/persist"; fsType = "zfs"; + # neededForBoot = true; # for impermanence }; fileSystems."/boot" = diff --git a/nixos/lib/default.nix b/nixos/lib/default.nix index fcdbf6e..bcbc606 100644 --- a/nixos/lib/default.nix +++ b/nixos/lib/default.nix @@ -23,12 +23,15 @@ rec { let user = existsOrDefault "user" options "568"; group = existsOrDefault "group" options "568"; - envFiles = existsOrDefault "envFiles" options [ ]; - addTraefikLabels = if (builtins.hasAttr "container" options) && (builtins.hasAttr "addTraefikLabels" options.container) then options.container.addTraefikLabels else false; + + addTraefikLabels = if (builtins.hasAttr "container" options) && (builtins.hasAttr "addTraefikLabels" options.container) then options.container.addTraefikLabels else true; + addToHomepage = lib.attrsets.attrByPath [ "homepage" "enable" ] true options; homepageIcon = if (builtins.hasAttr "homepage" options) && (builtins.hasAttr "icon" options.homepage) then options.homepage.icon else "${options.app}.svg"; + subdomain = existsOrDefault "subdomainOverride" options options.app; + host = existsOrDefault "host" options "${subdomain}.${options.domain}"; - host = existsOrDefault "host" options "${options.app}.${options.domain}"; - + enableBackups = (lib.attrsets.hasAttrByPath [ "persistence" "folder" ] options) + && (lib.attrsets.attrByPath [ "persistence" "enable" ] true options); # nix doesnt have an exhausive list of options for oci # so here i try to get a robust list of security options for containers # because everyone needs more tinfoild hat right? RIGHT? @@ -44,19 +47,23 @@ rec { in { - virtualisation.oci-containers.containers.${options.app} = { - image = "${options.image}"; + virtualisation.oci-containers.containers.${options.app} = mkIf options.container.enable { + image = "${options.container.image}"; user = "${user}:${group}"; environment = { TZ = options.timeZone; } // options.container.env; - environmentFiles = [ ] ++ envFiles; - volumes = [ - "/etc/localtime:/etc/localtime:ro" - ]; + environmentFiles = [ ] + ++ lib.attrsets.attrByPath [ "container" "envFiles" ] [ ] options; + volumes = [ "/etc/localtime:/etc/localtime:ro" ] + ++ lib.optionals (lib.attrsets.hasAttrByPath [ "container" "persistentFolderMount" ] options) [ + "${options.persistence.folder}:${options.container.persistentFolderMount}:rw" + ] + ++ lib.attrsets.attrByPath [ "container" "volumes" ] [ ] options; + labels = mkIf addTraefikLabels (mkTraefikLabels { - name = options.app; + name = subdomain; port = options.port; domain = options.domain; url = host; @@ -65,16 +72,22 @@ rec { extraOptions = containerExtraOptions; }; - mySystem.services.homepage.${options.homepage.category} = mkIf options.addToHomepage [ + systemd.tmpfiles.rules = [ ] + ++ lib.optionals (lib.attrsets.hasAttrByPath [ "persistence" "folder" ] options) [ "d ${options.persistence.folder} 0755 ${user} ${group} -" ] + ; + + # built a entry for homepage + mySystem.services.homepage.${options.homepage.category} = mkIf addToHomepage [ { ${options.app} = { icon = homepageIcon; - href = "https://${host}"; + href = "https://${ host }"; host = host; description = options.description; }; } ]; + } @@ -107,5 +120,4 @@ rec { } ); - } diff --git a/nixos/modules/nixos/containers/default.nix b/nixos/modules/nixos/containers/default.nix index 4ebb92b..c4773be 100644 --- a/nixos/modules/nixos/containers/default.nix +++ b/nixos/modules/nixos/containers/default.nix @@ -12,5 +12,7 @@ ./factorio ./whoogle ./redlib + ./home-assistant + ./node-red ]; } diff --git a/nixos/modules/nixos/containers/home-assistant/default-old.nix b/nixos/modules/nixos/containers/home-assistant/default-old.nix new file mode 100644 index 0000000..f44251e --- /dev/null +++ b/nixos/modules/nixos/containers/home-assistant/default-old.nix @@ -0,0 +1,67 @@ +{ lib +, config +, pkgs +, ... +}: +with lib; +let + cfg = config.mySystem.services.home-assistant; + app = "Home-assistant"; + user = "kah"; + group = "kah"; + appFolder = "home-assistant"; + persistentFolder = "${config.mySystem.persistentFolder}/containers/${appFolder}"; + +in +{ + options.mySystem.services.home-assistant.enable = mkEnableOption "home-assistant"; + + # running in a container vs nix module mainly + # as I know the container is solid. Bit iffy + # over the packaging of HA in nix & arguments + # from HA dev on nix packaging + config = mkIf cfg.enable + (lib.recursiveUpdate + { + sops.secrets."services/${app}/env" = { + sopsFile = ./secrets.sops.yaml; + owner = user; + group = group; + restartUnits = [ "podman-${app}.service" ]; + }; + } + + (myLib.mkService + { + inherit app user group; + description = "Home Automation"; + port = 8123; + timeZone = config.time.timeZone; + # subdomainOverride = "hass"; + domain = config.networking.domain; + persistence = { + folder = persistentFolder; + backup = true; + }; + homepage = { + icon = "home-assistant.svg"; + category = "home"; + }; + container = { + enable = true; + image = "ghcr.io/onedr0p/home-assistant:2024.1.5@sha256:64bb3ffa532c3c52563f0e4a4de8d50c889f42a1b0826b35ee1ac728652fb107"; + env = { + HASS_IP = "10.8.20.42"; + }; + envFiles = [ config.sops.secrets."services/${app}/env".path ]; + persistentFolderMount = "/config"; + addTraefikLabels = true; + caps = { + # readOnly = true; + noNewPrivileges = true; + # dropAll = true; + }; + }; + }) + ); +} diff --git a/nixos/modules/nixos/containers/home-assistant/default.nix b/nixos/modules/nixos/containers/home-assistant/default.nix new file mode 100644 index 0000000..4f18dc1 --- /dev/null +++ b/nixos/modules/nixos/containers/home-assistant/default.nix @@ -0,0 +1,89 @@ +{ lib +, config +, pkgs +, ... +}: +with lib; +let + app = "home-assistant"; + image = "ghcr.io/onedr0p/home-assistant:2024.1.5@sha256:64bb3ffa532c3c52563f0e4a4de8d50c889f42a1b0826b35ee1ac728652fb107"; + user = "568"; #string + group = "568"; #string + port = 8123; #int + cfg = config.mySystem.services.${app}; + appFolder = "containers/${app}"; + persistentFolder = "${config.mySystem.persistentFolder}/${appFolder}"; +in +{ + options.mySystem.services.${app} = + { + enable = mkEnableOption "${app}"; + addToHomepage = mkEnableOption "Add ${app} to homepage" // { default = true; }; + }; + + config = mkIf cfg.enable { + # ensure folder exist and has correct owner/group + systemd.tmpfiles.rules = [ + "d ${persistentFolder} 0755 ${user} ${group} -" #The - disables automatic cleanup, so the file wont be removed after a period + ]; + + sops.secrets."services/${app}/env" = { + + # configure secret for forwarding rules + sopsFile = ./secrets.sops.yaml; + owner = config.users.users.kah.name; + inherit (config.users.users.kah) group; + restartUnits = [ "podman-${app}.service" ]; + }; + + virtualisation.oci-containers.containers.${app} = { + image = "${image}"; + user = "${user}:${group}"; + environment = { + HASS_IP = "10.8.20.42"; + }; + environmentFiles = [ config.sops.secrets."services/${app}/env".path ]; + volumes = [ + "${persistentFolder}:/config:rw" + "/etc/localtime:/etc/localtime:ro" + ]; + labels = lib.myLib.mkTraefikLabels { + name = app; + domain = config.networking.domain; + + inherit port; + }; + }; + + + mySystem.services.homepage.media = mkIf cfg.addToHomepage [ + { + Lidarr = { + icon = "${app}.svg"; + href = "https://${app}.${config.mySystem.domain}"; + + description = "Home automation"; + container = "${app}"; + }; + } + ]; + + mySystem.services.gatus.monitors = [{ + + name = app; + group = "media"; + url = "https://${app}.${config.mySystem.domain}"; + interval = "1m"; + conditions = [ "[CONNECTED] == true" "[STATUS] == 200" "[RESPONSE_TIME] < 50" ]; + }]; + + services.restic.backups = config.lib.mySystem.mkRestic + { + inherit app; + user = builtins.toString user; + excludePaths = [ "Backups" ]; + paths = [ appFolder ]; + inherit appFolder; + }; + }; +} diff --git a/nixos/modules/nixos/containers/home-assistant/secrets.sops.yaml b/nixos/modules/nixos/containers/home-assistant/secrets.sops.yaml new file mode 100644 index 0000000..5d65549 --- /dev/null +++ b/nixos/modules/nixos/containers/home-assistant/secrets.sops.yaml @@ -0,0 +1,77 @@ +services: + home-assistant: + env: ENC[AES256_GCM,data:SzSN0Gu1RhTL4VDyX5nOPFadNZ4s0grYnQKzZhHb3MwPkYtrinnFKARahZ0dkvnKjOjCxxP6uaYHF/9rBxyRRuxjoOk7Qj4xF9Rr9v5e/YSyJHhIOcX4KTaagLW55t7IK0dmHPX2eimWdUcTh1MKjWKgG6CtRGLYMN4fPTxzTjoLjtGiHD3tLhrDc+vMS4GYDWocBx3FXp8vICbKaLpVsUHT3JUWstQhnadtmCvywgrXid5UoJnWxtpQxR2vf7m7SYjcIRX1iA6/PHAhgZftsMt8Aw4tw8+gR5jJivmkBm3HE2iJwtDJnowvdVeAaLMdpdzDW45a7P++F5Cwr5yQLuKfkPeCkgiD1EzDKjQs4Rnq19+7ZDZT8WCA5wtzwP8+yzjLO0wZfJ4Bda0jd1tR+FeID3NSsU1il8S3bXLegLxmCLnYvzKRdxHrUUFu85xTfe8GYMtllUv8c10zAL9nRmRUPXh7JpXntKEidEy6w0F1iOWsR67yp1qOzlGOu7k0wMAS7QZ5/Op/nBjuugh+mOyABO5CpjnPqIXc19oerkNCHZJOmmHdT7wf3n90yn4j09XyIYDI6e7G+FXa/QwBqO5r0z+ulqHcpyhkklB425Zz5G2QUCBCz3mqJ/RhiWk+g4WwNEEecy31hNIaVl4zwwTlk/iFXdZ938NWp3jZp2zOzhGLlRcFbcuUzvqXqL1tFmIokIE/4AQll1zkmgUFFc/76ppTc4qylNy9z7NxM5/SJoONKW2jx4Tf2sEBIK/LICHgGu2VzBhCSOW+EyWr4vziRT9Kq4TVHLf56k+Sh2SKGFZg4FKkIVl7ZbiQyRp88Jqlna4sZwlA+4bcPMi8BMFj3yREv6t1uSaiUO+OtMpCrREuU9afp4OsQs1QyoED24Zh1TKkpZ7vJ6rYCT/j0EEEsSMEcV/dmIoyawGyM8KB5ZjZIR8LWaLffHARWBcholKANWv9a3kFp0qsqvqVxxNxH3GEqZlFz83igwWOeILeSdZ2BEVKZBP4tmQu8HvUEPHtucRUIbsPSMgRXHJPbmia4w7053OrmATEKNYKVXCspoA0gsPF9AqsH/I67NbpamJ0F1/sc+d0Zw8oJKHexes9WAa3S3bCVwdtPI2cIMNLTA4T7fA5d4yZ6joe+CnHZnprbd7LlQIoK/MEM8bftvGz3Jnk/3fqTOlW8yC4tknsnO44m3LJmQ2rDbWlswO3rQTP/SCpkHcXTgbT5A==,iv:q4C1fJqWWH5RIn42p7VWwonpMaOeahyp2jzb+1pNPr0=,tag:gDytkHSuISDbNqIbfvDnwQ==,type:str] +sops: + kms: [] + gcp_kms: [] + azure_kv: [] + hc_vault: [] + age: + - recipient: age1lj5vmr02qkudvv2xedfj5tq8x93gllgpr6tzylwdlt7lud4tfv5qfqsd5u + enc: | + -----BEGIN AGE ENCRYPTED FILE----- + YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBNQzA1VlEzeVVwcDN6ZHpm + bDhYNlU4VWI5Z2FwUmVNZUJETUhKSkVCcm1vClI0ZmlyekRicUR4Z2lhMVdpUjE2 + VXdrRDhuQWZ1K2Frb1dsWWFvdDBNQWsKLS0tIDgvcTBncUpYcHE4cXJzeUl6K2lY + VEJPencraktjeTFMeTJxWUowbUcyeFUKWRIPe0rrbHRpE4d4saqS9xMRzcy2huwg + kDXek89pTY+2kYcPiKIQ4FPdOO2abGkRZeNWUZ/Nc/MvUqBhtQoUQA== + -----END AGE ENCRYPTED FILE----- + - recipient: age17edew3aahg3t5nte5g0a505sn96vnj8g8gqse8q06ccrrn2n3uysyshu2c + enc: | + -----BEGIN AGE ENCRYPTED FILE----- + YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSB3ZnRncGo4VzFieTJIQXFn + VzFVQVhVSkVyeTFGaEtuYXBnQU5mZDhrS0FFCnZPanhkL2pCTzBEc1IrMGMwTDh6 + eklPS0dOb0dJZEtEMU9YTHNQSURFNmcKLS0tIGRNTUU0MS9HMXdHQ0xXekNwNXMz + OUwrYnRXQkEvNXFRTkl2VVFoKy85NVkKvw3PHp1TwvCmXGKCv4mxvJQYhKommZg0 + e0OAmzasx8ek7HDySvfTuYjQKVSCB46wtojuAMUkPScI/yqJLHJ4rQ== + -----END AGE ENCRYPTED FILE----- + - recipient: age1u4tht685sqg6dkmjyer96r93pl425u6353md6fphpd84jh3jwcusvm7mgk + enc: | + -----BEGIN AGE ENCRYPTED FILE----- + YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSB2N1I4QXczQUZqb1NGdXdk + VWRmTExoeDhXaVJPOWJYMW9IU2NseGxKY0ZzClhMRWJUSldDTzRvQkpBWldXVGVm + VXBmRFJDMkpaeXNDWE9lQ1Q5OWF6QUkKLS0tIGJ0VUd3OVZJVmRFMS9KdlFhSFdT + aU9rQU5mT3NNVjdvbUlaZ1hvbUErenMKyu1/RxivA+uaIjg+NbZUYSvMACyT5Jkq + Qu6Gq+hzh5++pi+dBn/OHqwn0hCszBYT5MBu3PueZoLAyqLwsuQ9eQ== + -----END AGE ENCRYPTED FILE----- + - recipient: age1cp6vegrmqfkuj8nmt2u3z0sur7n0f7e9x9zmdv4zygp8j2pnucpsdkgagc + enc: | + -----BEGIN AGE ENCRYPTED FILE----- + YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBXZEp2SFVDcnMvNmxmUERQ + RG9FRnFuWmhCUnE2aktyWEFodExPWGo0OWxFCm5UbU91b1pVbkt3ZnIyNmlvbGxn + NFI4R2N2a1hJc2lhNEZiRzRCMFpWYUkKLS0tIHJkY1NnNjJwMmxTUDJRK2dIbzcv + TWMxL0FndGFqRlVyNFgxUjdIVVVRTUkKqtG3A2QgQtII1F3AhOBVggdtG8V8QezT + CTvO9LcCrb4cy2kC/7hC1HoUFVz3CJGlubS0QA9nfB4o3s5qdZ5XvA== + -----END AGE ENCRYPTED FILE----- + - recipient: age1ekt5xz7u2xgdzgsrffhd9x22n80cn4thxd8zxjy2ey5vq3ca7gnqz25g5r + enc: | + -----BEGIN AGE ENCRYPTED FILE----- + YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBjUGdYb3BFWUJTekdzdHdo + N0JIblVRSldRTmFPMC9ReHJOVm04ditlSjJVCkpabGRldkVOTTA0RnF1cDZkZ2Ji + UlhuU1NWTFBOSnc2TUI5amNXWUJDNWcKLS0tIG45Q2ZlbzdiZFlvODgrN1JtaTQy + RG00dTI4RVNPL2lqbDVJTzMrODlsS0kKVj9SIj0j+dXB1yDAsshcumTTxx/IaGo9 + FJ+Lhcb6w8C+e6MFLHFl45ifYcyRV7vqzzdPUzemjyJWm0FqbSeu+Q== + -----END AGE ENCRYPTED FILE----- + - recipient: age1jpeh4s553taxkyxhzlshzqjfrtvmmp5lw0hmpgn3mdnmgzku332qe082dl + enc: | + -----BEGIN AGE ENCRYPTED FILE----- + YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBVU3FsMUxGTC9XUTJ4Tys1 + YXgxamo2d3IyTDQyS1orb1ZNbGJaaklGZnlFCmlnUjk1cysySlNHNmpQdERVSTRa + cFhIV1N1bUs0enJzMVkxYVBnNVdralkKLS0tIEFEak04NENELy9mNk4wVm4wWlVQ + TmsxQitKMkpNNzlQaTVVWnIzSHE3YUUK6d+F8J//NhP9/R8S9fm8JBI9N76bzD6o + tLuj1N6MG+R2xONW1C4Eu39K+I5ynNyMPFCo7ACKb1TF91i28V7wtQ== + -----END AGE ENCRYPTED FILE----- + - recipient: age1j2r8mypw44uvqhfs53424h6fu2rkr5m7asl7rl3zn3xzva9m3dcqpa97gw + enc: | + -----BEGIN AGE ENCRYPTED FILE----- + YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBUVHFaR3BOaE1LSzFQSnB0 + NnZsMnZud0xzcmV2S3JQUkpkaXlYTFFsa21BCjNYRFhJQ2VITGRRdzYycGFJVDFr + TFZ1ZFhjOW5MYThiUlloQW1Wa3lBMFEKLS0tIERrU3R1d2JWM2p6ZktxZ2JoamNq + WTJJdkNXTy8yYUNQS0RzRHZpQlZjV2sKmLACWwksFbii3K5E9sfTSJq2Z3HMaj/F + hsHcpeNPdKtQlWw7ILa6Dl0/0sVAXssRFamb6teEVchipF9KJVATLQ== + -----END AGE ENCRYPTED FILE----- + lastmodified: "2024-04-29T08:40:40Z" + mac: ENC[AES256_GCM,data:4S2pnHbrARApO/hRWn0ZlgWNNgdzzd2T/fx3LJ8M8n1cE5Us5Tj0yFxJPoiT/1Y+n3aZ/9hKD7AyIXhhrXA9gXk2MLHI1XjYVYkAtlW7264SIt9ZCEuJk4KN7LJnlFvxjF18yjKMBmjl34FCDaD8C+Pv+L3L1wOw/CMHHJ3Ayik=,iv:zT/TS+EDnq9s8mZiGR3rE2EDXwtPV3XUWE3xN2sHPQ4=,tag:Kh+PD7Hg5veeZvTb7Ta8rQ==,type:str] + pgp: [] + unencrypted_suffix: _unencrypted + version: 3.8.1 diff --git a/nixos/modules/nixos/containers/node-red/default.nix b/nixos/modules/nixos/containers/node-red/default.nix new file mode 100644 index 0000000..f550b5d --- /dev/null +++ b/nixos/modules/nixos/containers/node-red/default.nix @@ -0,0 +1,92 @@ +{ lib +, config +, pkgs +, ... +}: +with lib; +let + cfg = config.mySystem.services.node-red; + app = "node-red"; + persistentFolder = "${config.mySystem.persistentFolder}/${appFolder}"; + appFolder = "apps/${app}"; + user = config.services.node-red.user; + group = config.services.node-red.group; + url = "code-${config.networking.hostName}.${config.networking.domain}"; + +in +{ + options.mySystem.services.node-red = + { + enable = mkEnableOption "node-red"; + addToHomepage = mkEnableOption "Add ${app} to homepage" // { default = true; }; + }; + + config = mkIf cfg.enable { + + # ensure folder exist and has correct owner/group + systemd.tmpfiles.rules = [ + "d ${persistentFolder} 0755 ${user} ${group} -" #The - disables automatic cleanup, so the file wont be removed after a period + ]; + + services.node-red = { + enable = true; + userDir = persistentFolder; + }; + + mySystem.services.traefik.routers = [{ + http.routers.${app} = { + rule = "Host(`${app}.${config.mySystem.domain}`)"; + entrypoints = "websecure"; + middlewares = "local-ip-only@file"; + service = "${app}"; + }; + http.services.${app} = { + loadBalancer = { + servers = [{ + url = "http://localhost:1880"; + }]; + }; + }; + + }]; + + mySystem.services.homepage.media = mkIf cfg.addToHomepage [ + { + code-shodan = { + icon = "${app}.svg"; + href = "https://${url}"; + + description = "Music management"; + container = "${app}"; + widget = { + type = "${app}"; + url = "https://${url}"; + key = "{{HOMEPAGE_VAR_LIDARR__API_KEY}}"; + }; + }; + } + ]; + + mySystem.services.gatus.monitors = [{ + + name = app; + group = "media"; + url = "https://${url}"; + interval = "1m"; + conditions = [ "[CONNECTED] == true" "[STATUS] == 200" "[RESPONSE_TIME] < 50" ]; + }]; + + services.restic.backups = config.lib.mySystem.mkRestic + { + inherit app; + user = builtins.toString user; + excludePaths = [ "Backups" ]; + paths = [ appFolder ]; + inherit appFolder; + }; + + + + + }; +} diff --git a/nixos/modules/nixos/containers/redlib/default.nix b/nixos/modules/nixos/containers/redlib/default.nix index 197508f..5ca56e6 100644 --- a/nixos/modules/nixos/containers/redlib/default.nix +++ b/nixos/modules/nixos/containers/redlib/default.nix @@ -17,16 +17,18 @@ in { app = "Redlib"; description = "Reddit alternate frontend"; - image = "quay.io/redlib/redlib@sha256:7fa92bb9b5a281123ee86a0b77a443939c2ccdabba1c12595dcd671a84cd5a64"; port = 8080; user = "nobody"; group = "nobody"; timeZone = config.time.timeZone; domain = config.networking.domain; - addToHomepage = true; - homepage.icon = "libreddit.svg"; - homepage.category = "home"; + homepage = { + icon = "libreddit.svg"; + category = "home"; + }; container = { + enable = true; + image = "quay.io/redlib/redlib@sha256:7fa92bb9b5a281123ee86a0b77a443939c2ccdabba1c12595dcd671a84cd5a64"; env = { REDLIB_DEFAULT_SHOW_NSFW = "on"; REDLIB_DEFAULT_USE_HLS = "on"; diff --git a/nixos/modules/nixos/containers/whoogle/default.nix b/nixos/modules/nixos/containers/whoogle/default.nix index c03ed72..4f8538f 100644 --- a/nixos/modules/nixos/containers/whoogle/default.nix +++ b/nixos/modules/nixos/containers/whoogle/default.nix @@ -71,7 +71,7 @@ in mySystem.services.gatus.monitors = [{ name = app; - group = "media"; + group = "services"; url = "https://${app}.${config.mySystem.domain}"; interval = "1m"; conditions = [ "[CONNECTED] == true" "[STATUS] == 200" "[RESPONSE_TIME] < 50" ]; diff --git a/nixos/modules/nixos/lib.nix b/nixos/modules/nixos/lib.nix index 9603c23..6f5be9e 100644 --- a/nixos/modules/nixos/lib.nix +++ b/nixos/modules/nixos/lib.nix @@ -19,7 +19,7 @@ with lib; ]; initialize = true; backupPrepareCommand = '' - # remove stale locks - this avoids some annoyance + # remove stale locks - this avoids some occasional annoyance # ${pkgs.restic}/bin/restic unlock --remove-all || true ''; diff --git a/nixos/modules/nixos/services/adguardhome/default.nix b/nixos/modules/nixos/services/adguardhome/default.nix index 1a67417..7a5fc95 100644 --- a/nixos/modules/nixos/services/adguardhome/default.nix +++ b/nixos/modules/nixos/services/adguardhome/default.nix @@ -75,7 +75,6 @@ in upstream_dns = [ # split brain dns - forward to local powerdns "[/trux.dev/]127.0.0.1:5353" - "[/natallan.com/]127.0.0.1:5353" # resolve fqdn for local ip's "[/l.voltaicforge.com/]10.8.10.1" @@ -111,47 +110,29 @@ in theme = "auto"; }; + filters = + let + urls = [ + { name = "AdGuard DNS filter"; url = "https://adguardteam.github.io/AdGuardSDNSFilter/Filters/filter.txt"; } + { name = "AdAway Default Blocklist"; url = "https://adaway.org/hosts.txt"; } + { name = "Big OSID"; url = "https://big.oisd.nl"; } + { name = "1Hosts Lite"; url = "https://o0.pages.dev/Lite/adblock.txt"; } + { name = "hagezi multi pro"; url = "https://cdn.jsdelivr.net/gh/hagezi/dns-blocklists@latest/adblock/pro.txt"; } + { name = "osint"; url = "https://osint.digitalside.it/Threat-Intel/lists/latestdomains.txt"; } + { name = "phishing army"; url = "https://phishing.army/download/phishing_army_blocklist_extended.txt"; } + { name = "notrack malware"; url = "https://gitlab.com/quidsup/notrack-blocklists/raw/master/notrack-malware.txt"; } + { name = "EasyPrivacy"; url = "https://v.firebog.net/hosts/Easyprivacy.txt"; } + ]; - filters = [ - { - # AdGuard Base filter, Social media filter, Spyware filter, Mobile ads filter, EasyList and EasyPrivacy - enabled = true; - id = 1; - name = "AdGuard DNS filter"; - url = "https://adguardteam.github.io/AdGuardSDNSFilter/Filters/filter.txt"; - } - { - # AdAway default blocklist - enabled = true; - id = 2; - name = "AdAway Default Blocklist"; - url = "https://adaway.org/hosts.txt"; - } - { - # Big OSID - enabled = true; - id = 3; - name = "Big OSID"; - url = "https://big.oisd.nl"; - } - { - # 1Hosts Lite - enabled = true; - id = 4; - name = "1Hosts Lite"; - url = "https://o0.pages.dev/Lite/adblock.txt"; - } - { - # HAGEZI Multi Pro - enabled = true; - id = 5; - name = "hagezi multi pro"; - url = "https://cdn.jsdelivr.net/gh/hagezi/dns-blocklists@latest/adblock/pro.txt"; - } + buildList = id: url: { + enabled = true; + id = id; + name = url.name; + url = url.url; + }; + in - - - ]; + (lib.imap1 buildList urls); }; }; diff --git a/nixos/modules/nixos/services/blocky/default.nix b/nixos/modules/nixos/services/blocky/default.nix new file mode 100644 index 0000000..9d736e9 --- /dev/null +++ b/nixos/modules/nixos/services/blocky/default.nix @@ -0,0 +1,221 @@ +{ lib +, config +, pkgs +, ... +}: +with lib; +let + cfg = config.mySystem.services.blocky; +in +{ + options.mySystem.services.blocky.enable = mkEnableOption "blocky"; + + config = mkIf cfg.enable { + + services.blocky = { + enable = true; + settings = { + + # optional: use black and white lists to block queries (for example ads, trackers, adult pages etc.) + blocking = { + # definition of blacklist groups. Can be external link (http/https) or local file + blackLists = { + ads = [ + + + "https://blocklistproject.github.io/Lists/ads.txt" + + ]; + malicious = [ + "https://blocklistproject.github.io/Lists/adguard/malware-ags.txt" + + ]; + adult = [ + "https://blocklistproject.github.io/Lists/adguard/porn-ags.txt" + ]; + + void = [ ]; + }; + # definition of whitelist groups. Attention: if the same group has black and whitelists, whitelists will be used to disable particular blacklist entries. If a group has only whitelist entries -> this means only domains from this list are allowed, all other domains will be blocked + whiteLists.ads = [ ]; + # definition: which groups should be applied for which client + clientGroupsBlock = { + # default will be used, if no special definition for a client name exists + default = [ "ads" "malicious" ]; + # use client name (with wildcard support: * - sequence of any characters, [0-9] - range) + # or single ip address / client subnet as CIDR notation + # "foo*" = [ "ads" ]; + "10.8.10.40/24" = [ "ads" "malicioous" "adult" ]; + }; + + # which response will be sent, if query is blocked: + # zeroIp: 0.0.0.0 will be returned (default) + # nxDomain: return NXDOMAIN as return code + # comma separated list of destination IP addresses (for example: 192.100.100.15, 2001:0db8:85a3:08d3:1319:8a2e:0370:7344). Should contain ipv4 and ipv6 to cover all query types. Useful with running web server on this address to display the "blocked" page. + blockType = "zeroIp"; + # optional: TTL for answers to blocked domains + # default: 6h + blockTTL = "6h"; + + loading = { + # optional: automatically list refresh period (in duration format). Default: 4h. + # Negative value -> deactivate automatically refresh. + # 0 value -> use default + refreshPeriod = "4h"; + + # optional: if failOnError, application startup will fail if at least one list can't be downloaded / opened. Default: blocking + strategy = "fast"; + + downloads = { + # optional: timeout for list download (each url). Default: 60s. Use large values for big lists or slow internet connections + timeout = "60s"; + # optional: Number of download attempts. + attempts = 5; + # optional: Time between the download attempts. Default: 1s + cooldown = "1s"; + }; + }; + }; + + # optional: use these DNS servers to resolve blacklist urls and upstream DNS servers. It is useful if no system DNS resolver is configured, and/or to encrypt the bootstrap queries. + bootstrapDns = [ + { + upstream = "https://one.one.one.one/dns-query"; + ips = [ "1.1.1.1" "1.0.0.1" ]; + } + { + upstream = "https://dns.quad9.net/dns-query"; + ips = [ "9.9.9.9" "149.112.112.112" ]; + } + ]; + # optional: configuration for caching of DNS responses + caching = { + # duration how long a response must be cached (min value). + # If <=0, use response's TTL, if >0 use this value, if TTL is smaller + # Default: 0 + minTime = "0m"; + # duration how long a response must be cached (max value). + # If <0, do not cache responses + # If 0, use TTL + # If > 0, use this value, if TTL is greater + # Default: 0 + maxTime = "0m"; + # Max number of cache entries (responses) to be kept in cache (soft limit). Useful on systems with limited amount of RAM. + # Default (0): unlimited + maxItemsCount = 0; + # if true, will preload DNS results for often used queries (default: names queried more than 5 times in a 2-hour time window) + # this improves the response time for often used queries, but significantly increases external traffic + # default: false + prefetching = true; + # prefetch track time window (in duration format) + # default: 120 + prefetchExpires = "2h"; + # name queries threshold for prefetch + # default: 5 + prefetchThreshold = 5; + # Max number of domains to be kept in cache for prefetching (soft limit). Useful on systems with limited amount of RAM. + # Default (0): unlimited + prefetchMaxItemsCount = 0; + # Time how long negative results (NXDOMAIN response or empty result) are cached. A value of -1 will disable caching for negative results. + # Default: 30m + cacheTimeNegative = "90m"; + }; + + # optional: Determines how blocky will create outgoing connections. This impacts both upstreams, and lists. + # accepted: dual, v4, v6 + # default: dual + connectIPVersion = "v4"; + + # optional: custom IP address(es) for domain name (with all sub-domains). Multiple addresses must be separated by a comma + # example: query "printer.local" or "my.printer.local" will return 192.168.178.3 + customDNS = { + customTTL = "1h"; + # optional: if true (default), return empty result for unmapped query types (for example TXT, MX or AAAA if only IPv4 address is defined). + # if false, queries with unmapped types will be forwarded to the upstream resolver + filterUnmappedTypes = false; + # optional: replace domain in the query with other domain before resolver lookup in the mapping + # mapping = [ ]; + }; + # conditional = { + # fallbackUpstream = false; + # mapping = { + # "trux.dev" = "127.0.0.1:5353"; + + # # resolve fqdn for local ip's + # "l.voltaicforge.com" = "10.8.10.1"; + + # # reverse dns setup + # "in-addr.arpa" = "10.8.10.1"; # reverse dns lookup to UDMP + # "ip6.arpa" = "10.8.10.1"; # reverse dns lookup to UDMP + # }; + # }; + # optional: drop all queries with following query types. Default: empty + filtering.queryTypes = [ "AAAA" ]; + + # optional: logging configuration + log = { + # optional: Log level (one from debug, info, warn, error). Default: info + level = "info"; + # optional: Log format (text or json). Default: text + format = "text"; + # optional: log timestamps. Default: true + timestamp = true; + # optional: obfuscate log output (replace all alphanumeric characters with *) for user sensitive data like request domains or responses to increase privacy. Default: false + privacy = false; + }; + + # optional: Minimal TLS version that the DoH and DoT server will use + minTlsServeVersion = "1.2"; + # if https port > 0: path to cert and key file for SSL encryption. if not set, self-signed certificate will be generated + #certFile: server.crt + #keyFile: server.key + + # optional: ports configuration + ports = { + # optional: DNS listener port(s) and bind ip address(es), default 53 (UDP and TCP). Example: 53, :53, "127.0.0.1:5353,[::1]:5353" + dns = 53; + # optional: Port(s) and bind ip address(es) for DoT (DNS-over-TLS) listener. Example: 853, 127.0.0.1:853 + tls = 853; + # optional: Port(s) and optional bind ip address(es) to serve HTTPS used for prometheus metrics, pprof, REST API, DoH... If you wish to specify a specific IP, you can do so such as 192.168.0.1:443. Example: 443, :443, 127.0.0.1:443,[::1]:443 + https = 8443; + # optional: Port(s) and optional bind ip address(es) to serve HTTP used for prometheus metrics, pprof, REST API, DoH... If you wish to specify a specific IP, you can do so such as 192.168.0.1:4000. Example: 4000, :4000, 127.0.0.1:4000,[::1]:4000 + http = 4000; + }; + + # optional: configuration for prometheus metrics endpoint + prometheus = { + # enabled if true + enable = true; + # url path, optional (default '/metrics') + path = "/metrics"; + }; + + # optional: If true, blocky will fail to start unless at least one upstream server per group is reachable. Default: false + startVerifyUpstream = true; + + upstreams = { + groups = { + # these external DNS resolvers will be used. Blocky picks 2 random resolvers from the list for each query + # format for resolver: [net:]host:[port][/path]. net could be empty (default, shortcut for tcp+udp), tcp+udp, tcp, udp, tcp-tls or https (DoH). If port is empty, default port will be used (53 for udp and tcp, 853 for tcp-tls, 443 for https (Doh)) + # this configuration is mandatory, please define at least one external DNS resolver + default = [ + "https://dns10.quad9.net/dns-query" + "https://dns.cloudflare.com/dns-query" + "https://doh.mullvad.net/dns-query" + ]; + + # optional: use client name (with wildcard support: * - sequence of any characters, [0-9] - range) + # or single ip address / client subnet as CIDR notation + "10.8.50.1/24" = [ "https://cloudflare-dns.com/dns-query" ]; + }; + # Blocky supports different upstream strategies (default parallel_best) that determine how and to which upstream DNS servers requests are forwarded. + strategy = "parallel_best"; + + # optional: timeout to query the upstream resolver. Default: 2s + timeout = "2s"; + }; + }; + }; + + }; +} diff --git a/nixos/modules/nixos/services/cockpit/default.nix b/nixos/modules/nixos/services/cockpit/default.nix index 2307432..07e4b5f 100644 --- a/nixos/modules/nixos/services/cockpit/default.nix +++ b/nixos/modules/nixos/services/cockpit/default.nix @@ -29,7 +29,7 @@ in config.environment = mkIf cfg.enable { systemPackages = with pkgs; [ - (mkIf config.virtualisation.podman.enable nur.repos.procyon.cockpit-podman) # only if server runs pods + # (mkIf config.virtualisation.podman.enable nur.repos.procyon.cockpit-podman) # TODO replace only if server runs pods # nur.repos.dukzcry.cockpit-machines # TODO enable with virtualisation on server # nur.repos.dukzcry.libvirt-dbus # TODO enable with virtualisation on server diff --git a/nixos/modules/nixos/services/default.nix b/nixos/modules/nixos/services/default.nix index 2213008..9da7545 100644 --- a/nixos/modules/nixos/services/default.nix +++ b/nixos/modules/nixos/services/default.nix @@ -17,5 +17,8 @@ ./adguardhome ./mosquitto ./zigbee2mqtt + ./postgresql + ./blocky + ./openvscode-server ]; } diff --git a/nixos/modules/nixos/services/mosquitto/secrets.sops.yaml b/nixos/modules/nixos/services/mosquitto/secrets.sops.yaml index fa37de9..24f07ce 100644 --- a/nixos/modules/nixos/services/mosquitto/secrets.sops.yaml +++ b/nixos/modules/nixos/services/mosquitto/secrets.sops.yaml @@ -1,8 +1,8 @@ services: mosquitto: mq: - hashedPassword: ENC[AES256_GCM,data:FI2KLDYBW+HCXbOfmdyRYEwI8IeEX2iNWAiyGyn6FE2kkP1K1GETLbissBds+6DAPgbBULhxh8PZ9nkOCtR9QGKLkImxgMU1o8Zmwc6UxfkmFWvEDyt0/3g5gEVoO2rsLx4GMp4qO6Wbz0QCxJWJwQ==,iv:Pt9g/c3A1aChcgxQMSa76f1/c7uq8ctf9CDTFKNSvcs=,tag:zSS9heWyjvwFwKoEmYo+GA==,type:str] - plainPassword.yaml: ENC[AES256_GCM,data:z+/SQE+PfsIoDekjf5D6f6nkxsfiNmcym4YSVdIl,iv:heh5N8HazUUP251llJLVGdka+65Ofjm4by1kug5uKYI=,tag:NS5K47rZRLH6OzyQopB3+A==,type:str] + hashedPassword: ENC[AES256_GCM,data:rQYF6iIShg6CourZ6OzxKuAaXvIjDNThFm0g2foz05579PIPda/rAq7AgpKsiE0D5sCWhdJMfTYh58f8jTPN6ogzP1vb4tLHwzAI/w9DrDpoOH7dzkqcCXfkY0gVKdnKxXnzxnEefysaC9ReAq9IBw==,iv:ZHa+ihzRyCmAbvo1oZbtoqszKwyzoDTcdc5Ye6D7CMw=,tag:eQMR2NQzyYCkhEzX7dhaDQ==,type:str] + plainPassword.yaml: ENC[AES256_GCM,data:lbEC1tPTJiuNE0SluO4kYgQgCvOAXlJBZeTpBvRy,iv:N2HAZs/+6faMa/Ujo70ETHTPz/imi5pfqN9AZMFtR6g=,tag:sgFpjbnopM4KHgKGTw4nxw==,type:str] sops: kms: [] gcp_kms: [] @@ -12,68 +12,68 @@ sops: - recipient: age1lj5vmr02qkudvv2xedfj5tq8x93gllgpr6tzylwdlt7lud4tfv5qfqsd5u enc: | -----BEGIN AGE ENCRYPTED FILE----- - YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBjNmJPbGFaRXkrYnh6RHR4 - dHBWNWs0RDB1UnFycXdoWmFFYkNGcHh4YUZjCm9LYnZIU1dvNzVTNHp0NjBEMTE2 - MHpOdVh5aVR3c2o5V21LU1ZDWnpXdFEKLS0tIDB4emRQRGVVYzFYQ2JsakVIeFhn - QlFEYjBSVjVKUFVEV3gwK2NZaW1XSGMKHBPiLSd7Ixs68xMcpOJzw2Vu4GbKAglY - 1yAcQgIRvFxCV/uz4BwAFvyCtYYsUD4GhEAFp/wwq6W1hTEAseV0RA== + YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBzd01kUitkWFYraHNRWVNa + S0pWSFJONWtMWkFIZlp5RkVFVktRQ2pNZmtFClBrQzIrT2JrWGNpaElaNytsSGRz + Yk9OVXNnWmlraXgwb005R3BvTHlocWMKLS0tIGx1bUE5SnFBMnNIMG4zRTF4SE4v + T3IwT3c1bHZTMUN5K01iOHFiYTVHeE0KNOeRo78A13VYg0IrwmqBYYi+SSRurTc8 + Xbdl2CFMR+i+2gL1dRx7clFX5bXvft0g3Ma2eMJaAg/lCUo5CDr/tw== -----END AGE ENCRYPTED FILE----- - recipient: age17edew3aahg3t5nte5g0a505sn96vnj8g8gqse8q06ccrrn2n3uysyshu2c enc: | -----BEGIN AGE ENCRYPTED FILE----- - YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBGRGE0OWZaR0ZhY2piMkxY - cG1HRFIrWjJFeG8vbzhPWW51cWVvN2FXV2hvCjhLNmVwRkRWQm54N3FPczFudGVB - N096dmFaUktqMDBIRWxlTnVaa2VOcVkKLS0tIEFZSmYweDRqVlpOdUhESXFjbnR0 - RXpBU2t0bFlJQW1RSXZ0dzZFT3RXT0UKraC9wurjhf+SiKPewE5L3auOI59kaj/h - 7nUUnWUQfkebO5wxtmbbmenXK//oY1tRbC/Dp2JPUTQo2wwrXMF/JQ== + YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBidStyMXBRNkt5dDh2cnZx + bXZqdm45WktRN3NUL3RyVHd1THhWVFF0V0F3CllHMXg2TGxKY0Vhdjc1MythMHJJ + N1NmeTBRYWxSeUNucWl5Z0hwTVQ0S3cKLS0tIDRFVGVDTURtSVp1QTFxazZPMnM5 + THUzOFNDZ0dYNGtOY3dPOFA4aGxFSkEKJc6Q5goFoZ6qhVUlxUw1S/NzwPbL9kWs + 11jAiUxoUXySI3nCfg4TVNzxUPwn0ecnDH6Q/Q4Xa+ZU+zfCZI5UVw== -----END AGE ENCRYPTED FILE----- - recipient: age1u4tht685sqg6dkmjyer96r93pl425u6353md6fphpd84jh3jwcusvm7mgk enc: | -----BEGIN AGE ENCRYPTED FILE----- - YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBEVjdTRkdDMElXV0pLL3Fv - MFpxaStjaHNPSmY1RnFUbUhVS09hUEZYYVFVCk4yUEsxV2FvYm5ybVdGS0pmVW5m - b1FYb3RxYXFhVVhjNms1bjBtVEYyMm8KLS0tIDk2Uy9xT3VZdGdSY1Rjc3l5OGE4 - ZzJvWTdDRlFNMmliUGZZbnRCc0UwRHcKdJllfqPlYBNf/nWkT5E1Is1moIFvN6lc - XVGQ9tzH1tpZC9PwmC1nL08fmuzwI5k9zqL2D+eG+vH7yjBLRFzxVg== + YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBUZWJkWjkyS0g1MlBGeTRQ + ejJPMUV3cmdqUU83c2xtZHJyZEkvbFYyaTB3Ck5yZnFXTmpZeTYwU2txc1Q1NktZ + cVhDS0FwWDIwZG82Y3VGVmpUQXlXbzAKLS0tIFBwcjdSTU9Vblk5djdhWG93NHBN + NERNbWtmVXlxMThFdDNPdTBvcHR4cDgKXSZczDzQ0dhOTa3gQd0T/jvqnVt3fq/t + sj2ZXRvfFBsRhhmvKXWODRzq2EFBBSTmsa0vXPrAIKKrXjHsYdyYsA== -----END AGE ENCRYPTED FILE----- - recipient: age1cp6vegrmqfkuj8nmt2u3z0sur7n0f7e9x9zmdv4zygp8j2pnucpsdkgagc enc: | -----BEGIN AGE ENCRYPTED FILE----- - YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSAzOUJOTFJFSHp1QTdKVmZk - UVZhVEpqQzVTOTZHOXBYbDJUVjBpL2ErV2tJCm1jOUVmVE8wc3ZLSDZJRVkxQkNU - eEw2RVNpVzJFcTlPbnF1Q2g0RVo5OUEKLS0tIFpvcU11RGVNR0dNQWc1aGJFd1lm - Ym1kellUNjRsTTdQZTViZnBkRllqbWsKWFwR8WeIxJunlgzT3GpYkIdFRLJZlhm4 - Vr4N5CMnNXJYWRiNJDrHDKvVw6EeUUhyJ+7aJ9UAfR0YfX47yIlW5A== + YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBZcm9sRFpTZE51SVd2YTJr + amlzRjB2emszSmR5S2w0V09DUm8rbndtaVJrCmJOKzNjUC9PNjJsYXF5cGJXdTYx + bHZ0VjJrZUF0d2diOU9qVGQ3QUFqdW8KLS0tIExxUld4aWVpVWZ5SVphQkhnSDdS + ZzZoRjJpN1FzM1pZQjNBaFNyS0RsODgKwMsYtYN+fepfQX8aS0scDdgloT6Qx+xq + u3Gu3CF9uCifK0I/kr+4DzPpV/vJBR0Ash0NqSO69ljhYW2cc+NgnA== -----END AGE ENCRYPTED FILE----- - recipient: age1ekt5xz7u2xgdzgsrffhd9x22n80cn4thxd8zxjy2ey5vq3ca7gnqz25g5r enc: | -----BEGIN AGE ENCRYPTED FILE----- - YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBnWUpaOUVnRS9Va211UXl0 - dUFmOVlmR2d1REVNRXJKMFV1OTVsSDZGRldvCk5CcGpWZHFBYmtsbVRjWW1QejNJ - Y0FPSVJ1UlhhcVhRaTVXMERyRURIRjAKLS0tIDloZ2J0anNqSEZmUXg4eDFyTVZ0 - WXAvTmRpUjRKMnJlZmV0SEEwZndtNkEK99oVyOIlfKP6zHnuS1LKGORuOLfX3vAU - Gw7IHXRUSpZhElOSK0jc9F2O6IEGYpfu5PYC4m8uojhRXsG6W/XTXA== + YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSA1bi9EZDZKVVMrRGZaZ1lV + a0pRY254YzNMVWdRdGtMbnhGbU1nY2NQN1RnCm5rVHNoMFg2SEE5TElqeE9LRGNP + Ykk0c2RrZWRZT2xBeHhrRVI2dlJKVDgKLS0tIGlZY2tUTkVWOWluU0RReC81bS9N + aFpyZS8zQ3YzNkMwV2lNYmFXNEt5TWMKSivmE6kEm9lEfEdJmn9gorprZGz59blJ + xQaFGuqYQBiVj1SQA/NCcVqBnoFBwC+WuCkGIuezzsQGEFp4FxmSwQ== -----END AGE ENCRYPTED FILE----- - recipient: age1jpeh4s553taxkyxhzlshzqjfrtvmmp5lw0hmpgn3mdnmgzku332qe082dl enc: | -----BEGIN AGE ENCRYPTED FILE----- - YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSArUVZScTVpWjZvUzlFeDVQ - RjRreTBPTEF3bXZ1Sk5sWmgzUURxcU5talFzClFRSjFFUEtQMis4dkNLRFFaaHlq - QXdhQWxEMXdHSGgzSXlqZm4xbEFVaGMKLS0tIG9OOHUwZWI3SXJ2SWZvdS9EVzV5 - aVpWNmk5b1owbjJHSWtnOHRJWmhEbGMKT4VdLG/8qX+KWO6vQ2TsrT1+w4XgDani - KOAS/DimV22EjmHljs9ByWdqkVw0KIBfp2oXo9m0Jqn0H1M2yEMozg== + YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSA0Z0ZlZHg4QjJ2bzlFY3pt + VE1oZ2QySDFnejlvUDFpdlBhN1hMVnBDNkVnCkF1UnpsaHZBRTJKRFpBcFB2eDBU + ZU4xSGc3YXVJbkxvSG04MjBVb3I4bFUKLS0tIHFWTFVBbWRSazNMc053S1QvVDhJ + cmRidFd6TWV0RXFOd2FBWkZCaE9RZncKdm5y1iSNtp9G7TO0P37P+txz25kwYLuU + 0IOBAf5JzqmiVV3cOPumhnXxESo2AG8404U1FV/7BsyCtDLWy/Sm4Q== -----END AGE ENCRYPTED FILE----- - recipient: age1j2r8mypw44uvqhfs53424h6fu2rkr5m7asl7rl3zn3xzva9m3dcqpa97gw enc: | -----BEGIN AGE ENCRYPTED FILE----- - YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBWNzZiS1pVTXMxQW9UUldr - dFNHUDhxV1lnOFNaK2J6SEY3WUtId0FLSTNjCkJhUm1sVnlJMFk5Wm9lNGdMYnZv - eVR6MGNVYjBSNENqU1BJWituMnJJeFUKLS0tIEk0ZUVETHRmSmJjT2NDMGNrajlZ - NUMxdEhvQnRES2hwck5jeEw3bnprZ00KUnkLNK+hmCihLwPiWt3NHjASuQwgBOlf - AsW8BkUjjQY/ABR3X6sNSI8uXQt+8BHP14U4cO8jwggcyE2W1Pq03A== + YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBEOUlsT2hiVlV4c2JtN2dJ + dC8yb3N0L0xxczAyVWpJdHhTNzNBZFhwK1ZNCkt6VWloUDJzNDVJajN5OHJzcXQy + SEdCbVdMd0lTZmU2aTZhUGdVYWhDbkUKLS0tIGc2K3VFeWVUUjFwRGk4eXNCRFFV + RlFqRytvRWFoY1hjRHg0SS9SZWloWFUKhdVdRHgnJ6n0UMLlhspqtBmvgO7TkZXb + fNhTuhmCi5THYE/I1/8Q9dMHwBPIRVM+1N2ZLrobd5GuS4ZY4AUXFQ== -----END AGE ENCRYPTED FILE----- - lastmodified: "2024-04-25T05:21:30Z" - mac: ENC[AES256_GCM,data:aN2YsPhDMl8vvLgi98iRCl5f7llJ8VTt7y1vh7liBAwG6hW1vZeetqSxvWiVDugozjsbK6n44AUDjhnfwo8EXp8iWQmJDXuS1PoEph4C18oo4Eu8n9ZpLQFGSKRMYXuetwrzOkn42tMYadYbwLPIandKqaTGUD4FcoqZtGxaH3c=,iv:Wfb1r8JNO74KjBWTIGwW2bXTVv3AIpj5KW9FXYrDm7c=,tag:FEnXv1S0J3XaxZ6TQz0bhQ==,type:str] + lastmodified: "2024-04-29T06:34:35Z" + mac: ENC[AES256_GCM,data:yaPeSkjnA2rQhUVbJd7JIgwbQe2xFl/GFZb+nPZUSZ+SrTnJd90X4NWxnyREkv7kvYzrmMF0XqMhZFHkQf6iGXwRlN53Bz4DjsGrHKDoxjYznOY8U2/UNgghqmZRjhrMBJecxjBjXpxb6myoi6MlRB6T/BC01DGy91s/T8lpqtM=,iv:7Dd6PiMObDY6MJ6G/Xz9sC6//qImtW+ErPtc1kbf33A=,tag:hLc+AtDVLHW4wHHZOrYQ7Q==,type:str] pgp: [] unencrypted_suffix: _unencrypted version: 3.8.1 diff --git a/nixos/modules/nixos/services/openvscode-server/default.nix b/nixos/modules/nixos/services/openvscode-server/default.nix new file mode 100644 index 0000000..158578d --- /dev/null +++ b/nixos/modules/nixos/services/openvscode-server/default.nix @@ -0,0 +1,72 @@ +{ lib +, config +, pkgs +, ... +}: +with lib; +let + cfg = config.mySystem.services.openvscode-server; + app = "openvscode-server"; + url = "code-${config.networking.hostName}.${config.networking.domain}"; +in +{ + options.mySystem.services.openvscode-server = + { + enable = mkEnableOption "openvscode-server"; + addToHomepage = mkEnableOption "Add ${app} to homepage" // { default = true; }; + }; + + config = mkIf cfg.enable { + + services.openvscode-server = { + enable = true; + telemetryLevel = "off"; + package = pkgs.unstable.openvscode-server; # TODO move to stable in 24.05? + # serverDataDir + user = "truxnell"; + host = "0.0.0.0"; + extraPackages = with pkgs;[ fish tmux ]; + withoutConnectionToken = true; + }; + + mySystem.services.traefik.routers = [{ + http.routers.${app} = { + rule = "Host(`${url}`)"; + entrypoints = "websecure"; + middlewares = "local-ip-only@file"; + service = "${app}"; + }; + http.services.${app} = { + loadBalancer = { + servers = [{ + url = "http://localhost:${builtins.toString config.services.openvscode-server.port}"; + }]; + }; + }; + + }]; + + mySystem.services.homepage.media = mkIf cfg.addToHomepage [ + { + code-shodan = { + icon = "vscode.svg"; + href = "https://${url}"; + + description = "Code editor"; + container = "${app}"; + }; + } + ]; + + mySystem.services.gatus.monitors = [{ + + name = app; + group = "services"; + url = "https://${url}"; + interval = "1m"; + conditions = [ "[CONNECTED] == true" "[STATUS] == 200" "[RESPONSE_TIME] < 50" ]; + }]; + + + }; +} diff --git a/nixos/modules/nixos/services/postgresql/default.nix b/nixos/modules/nixos/services/postgresql/default.nix new file mode 100644 index 0000000..f787ad3 --- /dev/null +++ b/nixos/modules/nixos/services/postgresql/default.nix @@ -0,0 +1,30 @@ +{ lib +, config +, pkgs +, ... +}: +with lib; +let + cfg = config.mySystem.services.postgresql; +in +{ + options.mySystem.services.postgresql.enable = mkEnableOption "postgresql"; + + config = mkIf cfg.enable { + + services.postgresql = { + enable = true; + authentication = '' + local homeassistant homeassistant ident map=ha + ''; + identMap = '' + ha root homeassistant + ''; + ensureDatabases = [ "homeassistant" ]; + ensureUsers = [ + { name = "homeassistant"; ensureDBOwnership = true; } + ]; + }; + + }; +} diff --git a/nixos/modules/nixos/services/traefik/default.nix b/nixos/modules/nixos/services/traefik/default.nix index a6d0a58..a350b74 100644 --- a/nixos/modules/nixos/services/traefik/default.nix +++ b/nixos/modules/nixos/services/traefik/default.nix @@ -105,6 +105,11 @@ in config = mkIf cfg.enable { + # ensure folder exist and has correct owner/group + systemd.tmpfiles.rules = [ + "f ${config.services.traefik.dataDir}/acme.json 0600 traefik ${config.services.traefik.group} -" #The - disables automatic cleanup, so the file wont be removed after a period + ]; + # put the dynamic configs in a file # i put this in a file instead of piping directly into # the traefik module, so that if i update the file diff --git a/nixos/modules/nixos/services/zigbee2mqtt/default.nix b/nixos/modules/nixos/services/zigbee2mqtt/default.nix index 7fec079..cc05a21 100644 --- a/nixos/modules/nixos/services/zigbee2mqtt/default.nix +++ b/nixos/modules/nixos/services/zigbee2mqtt/default.nix @@ -37,7 +37,7 @@ in enable = true; dataDir = persistentFolder; settings = { - advanced.log_level = "warn"; + advanced.log_level = "debug"; homeassistant = true; permit_join = false; include_device_information = true; @@ -79,7 +79,7 @@ in }]; - mySystem.services.homepage.media = mkIf cfg.addToHomepage [ + mySystem.services.homepage.infrastructure = mkIf cfg.addToHomepage [ { ${app} = { icon = "${app}.svg"; diff --git a/nixos/profiles/impermanence.nix b/nixos/profiles/impermanence.nix index 6640486..79b3e48 100644 --- a/nixos/profiles/impermanence.nix +++ b/nixos/profiles/impermanence.nix @@ -34,7 +34,13 @@ with lib; zfs rollback -r ${cfg.rootPoolName}@${cfg.rootBlankSnapshotName} ''; - + # environment.persistence."${cfg.persistPath}/nixos" = { + # hideMounts = true; + # directories = + # [ + # "/var/log" + # ]; + # }; # move ssh keys to persist folder services.openssh.hostKeys = mkIf config.services.openssh.enable [