commit 79aceaa6489e547f23bef48fe0e48d248486b05f Author: Lu Wang Date: Thu Nov 28 01:14:34 2024 +0800 treewide: init flakes diff --git a/.envrc b/.envrc new file mode 100644 index 0000000..7b8e847 --- /dev/null +++ b/.envrc @@ -0,0 +1,4 @@ +use flake +if has sops; then + export TF_ENCRYPTION=$(sops --extract '["tofu"]' -d infra/secrets.yaml) +fi diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..8c8d374 --- /dev/null +++ b/.gitignore @@ -0,0 +1,3 @@ +result* +.direnv +.pre-commit-config.yaml diff --git a/.sops.yaml b/.sops.yaml new file mode 100644 index 0000000..02d589d --- /dev/null +++ b/.sops.yaml @@ -0,0 +1,29 @@ +keys: + age: + - &marisa age1sfnct03u4cvfj98x4yjrcrrnu5gg8qgxrwk4uqq8w4e6wveeaedq97rn44 + - &flandre age166kxtrcx99fxlgtvz5mvyt5ctvk3dt09f42gvm94ngnkyztmmelsyzdn77 + - &reisen age1uf2h3hlv373ppdstjlngyuu7q5mee3u3ww3674lsj9rlt9ax7vqsv7wpe8 +creation_rules: + - path_regex: infra/.* + key_groups: + - age: + - *marisa + - path_regex: secrets/local.* + key_groups: + - age: + - *marisa + - *flandre + - path_regex: secrets/hosts/(opentofu/)?marisa-.* + key_groups: + - age: + - *marisa + - path_regex: secrets/hosts/(opentofu/)?flandre-.* + key_groups: + - age: + - *marisa + - *flandre + - path_regex: secrets/hosts/(opentofu/)?reisen-.* + key_groups: + - age: + - *marisa + - *reisen diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..b559963 --- /dev/null +++ b/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2024 rebmit + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/flake.lock b/flake.lock new file mode 100644 index 0000000..10e64d0 --- /dev/null +++ b/flake.lock @@ -0,0 +1,552 @@ +{ + "nodes": { + "crane": { + "inputs": { + "nixpkgs": [ + "lanzaboote", + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1717535930, + "narHash": "sha256-1hZ/txnbd/RmiBPNUs7i8UQw2N89uAK3UzrGAWdnFfU=", + "owner": "ipetkov", + "repo": "crane", + "rev": "55e7754ec31dac78980c8be45f8a28e80e370946", + "type": "github" + }, + "original": { + "owner": "ipetkov", + "repo": "crane", + "type": "github" + } + }, + "devshell": { + "inputs": { + "nixpkgs": [ + "rebmit", + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1728330715, + "narHash": "sha256-xRJ2nPOXb//u1jaBnDP56M7v5ldavjbtR6lfGqSvcKg=", + "owner": "numtide", + "repo": "devshell", + "rev": "dd6b80932022cea34a019e2bb32f6fa9e494dfef", + "type": "github" + }, + "original": { + "owner": "numtide", + "repo": "devshell", + "type": "github" + } + }, + "disko": { + "inputs": { + "nixpkgs": [ + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1730135292, + "narHash": "sha256-CI27qHAbc3/tIe8sb37kiHNaeCqGxNimckCMj0lW5kg=", + "owner": "nix-community", + "repo": "disko", + "rev": "ab58501b2341bc5e0fc88f2f5983a679b075ddf5", + "type": "github" + }, + "original": { + "owner": "nix-community", + "ref": "v1.9.0", + "repo": "disko", + "type": "github" + } + }, + "flake-compat": { + "flake": false, + "locked": { + "lastModified": 1696426674, + "narHash": "sha256-kvjfFW7WAETZlt09AgDn1MrtKzP7t90Vf7vypd3OL1U=", + "owner": "edolstra", + "repo": "flake-compat", + "rev": "0f9255e01c2351cc7d116c072cb317785dd33b33", + "type": "github" + }, + "original": { + "owner": "edolstra", + "repo": "flake-compat", + "type": "github" + } + }, + "flake-parts": { + "inputs": { + "nixpkgs-lib": [ + "rebmit", + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1730504689, + "narHash": "sha256-hgmguH29K2fvs9szpq2r3pz2/8cJd2LPS+b4tfNFCwE=", + "owner": "hercules-ci", + "repo": "flake-parts", + "rev": "506278e768c2a08bec68eb62932193e341f55c90", + "type": "github" + }, + "original": { + "owner": "hercules-ci", + "repo": "flake-parts", + "type": "github" + } + }, + "flake-utils": { + "inputs": { + "systems": "systems" + }, + "locked": { + "lastModified": 1731533236, + "narHash": "sha256-l0KFg5HjrsfsO/JpG+r7fRrqm12kzFHyUHqHCVpMMbI=", + "owner": "numtide", + "repo": "flake-utils", + "rev": "11707dc2f618dd54ca8739b309ec4fc024de578b", + "type": "github" + }, + "original": { + "owner": "numtide", + "repo": "flake-utils", + "type": "github" + } + }, + "git-hooks-nix": { + "inputs": { + "flake-compat": [ + "rebmit", + "flake-compat" + ], + "gitignore": [ + "rebmit", + "gitignore-nix" + ], + "nixpkgs": [ + "rebmit", + "nixpkgs" + ], + "nixpkgs-stable": [ + "rebmit", + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1731363552, + "narHash": "sha256-vFta1uHnD29VUY4HJOO/D6p6rxyObnf+InnSMT4jlMU=", + "owner": "cachix", + "repo": "git-hooks.nix", + "rev": "cd1af27aa85026ac759d5d3fccf650abe7e1bbf0", + "type": "github" + }, + "original": { + "owner": "cachix", + "repo": "git-hooks.nix", + "type": "github" + } + }, + "gitignore-nix": { + "inputs": { + "nixpkgs": [ + "rebmit", + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1709087332, + "narHash": "sha256-HG2cCnktfHsKV0s4XW83gU3F57gaTljL9KNSuG6bnQs=", + "owner": "hercules-ci", + "repo": "gitignore.nix", + "rev": "637db329424fd7e46cf4185293b9cc8c88c95394", + "type": "github" + }, + "original": { + "owner": "hercules-ci", + "repo": "gitignore.nix", + "type": "github" + } + }, + "haumea": { + "inputs": { + "nixpkgs": [ + "rebmit", + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1708375098, + "narHash": "sha256-DaFJp3wDHgOqx98U0SF57bXaH2Orp106c+jSdPCVu1E=", + "owner": "nix-community", + "repo": "haumea", + "rev": "ec6350fd9353e7f27ce0e85d31f82e3ed73e4d70", + "type": "github" + }, + "original": { + "owner": "nix-community", + "repo": "haumea", + "type": "github" + } + }, + "home-manager": { + "inputs": { + "nixpkgs": [ + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1732303962, + "narHash": "sha256-5Umjb5AdtxV5jSJd5jxoCckh5mlg+FBQDsyAilu637g=", + "owner": "nix-community", + "repo": "home-manager", + "rev": "8cf9cb2ee78aa129e5b8220135a511a2be254c0c", + "type": "github" + }, + "original": { + "owner": "nix-community", + "repo": "home-manager", + "type": "github" + } + }, + "impermanence": { + "locked": { + "lastModified": 1731242966, + "narHash": "sha256-B3C3JLbGw0FtLSWCjBxU961gLNv+BOOBC6WvstKLYMw=", + "owner": "nix-community", + "repo": "impermanence", + "rev": "3ed3f0eaae9fcc0a8331e77e9319c8a4abd8a71a", + "type": "github" + }, + "original": { + "owner": "nix-community", + "repo": "impermanence", + "type": "github" + } + }, + "lanzaboote": { + "inputs": { + "crane": "crane", + "flake-compat": [ + "flake-compat" + ], + "flake-parts": [ + "flake-parts" + ], + "flake-utils": [ + "flake-utils" + ], + "nixpkgs": [ + "nixpkgs" + ], + "pre-commit-hooks-nix": [ + "git-hooks-nix" + ], + "rust-overlay": "rust-overlay" + }, + "locked": { + "lastModified": 1718178907, + "narHash": "sha256-eSZyrQ9uoPB9iPQ8Y5H7gAmAgAvCw3InStmU3oEjqsE=", + "owner": "nix-community", + "repo": "lanzaboote", + "rev": "b627ccd97d0159214cee5c7db1412b75e4be6086", + "type": "github" + }, + "original": { + "owner": "nix-community", + "ref": "v0.4.1", + "repo": "lanzaboote", + "type": "github" + } + }, + "niri-flake": { + "inputs": { + "niri-stable": "niri-stable", + "niri-unstable": "niri-unstable", + "nixpkgs": [ + "nixpkgs" + ], + "nixpkgs-stable": [ + "nixpkgs" + ], + "xwayland-satellite-stable": "xwayland-satellite-stable", + "xwayland-satellite-unstable": "xwayland-satellite-unstable" + }, + "locked": { + "lastModified": 1732261496, + "narHash": "sha256-GLPyY+OMmiTMPXUwwdFiM4GVwouOSh/hLoPg5D6X2bc=", + "owner": "sodiboo", + "repo": "niri-flake", + "rev": "d4b0bc42a58a4cee1deb19d7d8350384e9aa4240", + "type": "github" + }, + "original": { + "owner": "sodiboo", + "repo": "niri-flake", + "type": "github" + } + }, + "niri-stable": { + "flake": false, + "locked": { + "lastModified": 1731483594, + "narHash": "sha256-Qjf7alRbPPERfiZsM9EMKX+HwjESky1tieh5PJIkLwE=", + "owner": "YaLTeR", + "repo": "niri", + "rev": "75c79116a7e40cbc0e110ce0cdd500e896458679", + "type": "github" + }, + "original": { + "owner": "YaLTeR", + "ref": "v0.1.10.1", + "repo": "niri", + "type": "github" + } + }, + "niri-unstable": { + "flake": false, + "locked": { + "lastModified": 1732257446, + "narHash": "sha256-xTqbonT9ZJ1PkgDvftoyMYuDul8J4VJccOtsOeRorZM=", + "owner": "YaLTeR", + "repo": "niri", + "rev": "c239937fac836f308311eff5f5d5fc5262c6eb55", + "type": "github" + }, + "original": { + "owner": "YaLTeR", + "repo": "niri", + "type": "github" + } + }, + "nixpkgs-unstable": { + "locked": { + "lastModified": 1731676054, + "narHash": "sha256-OZiZ3m8SCMfh3B6bfGC/Bm4x3qc1m2SVEAlkV6iY7Yg=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "5e4fbfb6b3de1aa2872b76d49fafc942626e2add", + "type": "github" + }, + "original": { + "owner": "NixOS", + "ref": "nixos-unstable", + "repo": "nixpkgs", + "type": "github" + } + }, + "ranet": { + "inputs": { + "flake-utils": [ + "flake-utils" + ], + "nixpkgs": [ + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1728965628, + "narHash": "sha256-GB8FXnHzaM06MivfpYEFFIp4q0WfH3a7+jmoC3Tpwbs=", + "owner": "NickCao", + "repo": "ranet", + "rev": "964565690eddec2a660a887aea924c36f358f2a0", + "type": "github" + }, + "original": { + "owner": "NickCao", + "repo": "ranet", + "type": "github" + } + }, + "rebmit": { + "inputs": { + "devshell": "devshell", + "flake-compat": "flake-compat", + "flake-parts": "flake-parts", + "git-hooks-nix": "git-hooks-nix", + "gitignore-nix": "gitignore-nix", + "haumea": "haumea", + "nixpkgs": [ + "rebmit", + "nixpkgs-unstable" + ], + "nixpkgs-unstable": "nixpkgs-unstable", + "treefmt-nix": "treefmt-nix" + }, + "locked": { + "lastModified": 1732721386, + "narHash": "sha256-UPjh8eXgssjDH7XjMtO9Q9ysWEo9rnwJiX2Gpmt4aJY=", + "owner": "rebmit", + "repo": "nix-exprs", + "rev": "a5973d50b8660c3a87224a58ffd38bedff9559bb", + "type": "github" + }, + "original": { + "owner": "rebmit", + "repo": "nix-exprs", + "type": "github" + } + }, + "root": { + "inputs": { + "devshell": [ + "rebmit", + "devshell" + ], + "disko": "disko", + "flake-compat": [ + "rebmit", + "flake-compat" + ], + "flake-parts": [ + "rebmit", + "flake-parts" + ], + "flake-utils": "flake-utils", + "git-hooks-nix": [ + "rebmit", + "git-hooks-nix" + ], + "home-manager": "home-manager", + "impermanence": "impermanence", + "lanzaboote": "lanzaboote", + "niri-flake": "niri-flake", + "nixpkgs": [ + "rebmit", + "nixpkgs" + ], + "nixpkgs-unstable": [ + "rebmit", + "nixpkgs-unstable" + ], + "ranet": "ranet", + "rebmit": "rebmit", + "sops-nix": "sops-nix", + "treefmt-nix": [ + "rebmit", + "treefmt-nix" + ] + } + }, + "rust-overlay": { + "inputs": { + "flake-utils": [ + "lanzaboote", + "flake-utils" + ], + "nixpkgs": [ + "lanzaboote", + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1717813066, + "narHash": "sha256-wqbRwq3i7g5EHIui0bIi84mdqZ/It1AXBSLJ5tafD28=", + "owner": "oxalica", + "repo": "rust-overlay", + "rev": "6dc3e45fe4aee36efeed24d64fc68b1f989d5465", + "type": "github" + }, + "original": { + "owner": "oxalica", + "repo": "rust-overlay", + "type": "github" + } + }, + "sops-nix": { + "inputs": { + "nixpkgs": [ + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1732186149, + "narHash": "sha256-N9JGWe/T8BC0Tss2Cv30plvZUYoiRmykP7ZdY2on2b0=", + "owner": "Mic92", + "repo": "sops-nix", + "rev": "53c853fb1a7e4f25f68805ee25c83d5de18dc699", + "type": "github" + }, + "original": { + "owner": "Mic92", + "repo": "sops-nix", + "type": "github" + } + }, + "systems": { + "locked": { + "lastModified": 1681028828, + "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=", + "owner": "nix-systems", + "repo": "default", + "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e", + "type": "github" + }, + "original": { + "owner": "nix-systems", + "repo": "default", + "type": "github" + } + }, + "treefmt-nix": { + "inputs": { + "nixpkgs": [ + "rebmit", + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1730321837, + "narHash": "sha256-vK+a09qq19QNu2MlLcvN4qcRctJbqWkX7ahgPZ/+maI=", + "owner": "numtide", + "repo": "treefmt-nix", + "rev": "746901bb8dba96d154b66492a29f5db0693dbfcc", + "type": "github" + }, + "original": { + "owner": "numtide", + "repo": "treefmt-nix", + "type": "github" + } + }, + "xwayland-satellite-stable": { + "flake": false, + "locked": { + "lastModified": 1730166465, + "narHash": "sha256-nq7bouXQXaaPPo/E+Jbq+wNHnatD4dY8OxSrRqzvy6s=", + "owner": "Supreeeme", + "repo": "xwayland-satellite", + "rev": "a713cf46cb7db84a0d1b57c3a397c610cad3cf98", + "type": "github" + }, + "original": { + "owner": "Supreeeme", + "ref": "v0.5", + "repo": "xwayland-satellite", + "type": "github" + } + }, + "xwayland-satellite-unstable": { + "flake": false, + "locked": { + "lastModified": 1732233710, + "narHash": "sha256-gWf9dX6DVx0ssK2G3yrFG9yMT9UU0mDwyD51z/Q6FTA=", + "owner": "Supreeeme", + "repo": "xwayland-satellite", + "rev": "02f30546264ff8407cbb39528b3a3cc3045e53c1", + "type": "github" + }, + "original": { + "owner": "Supreeeme", + "repo": "xwayland-satellite", + "type": "github" + } + } + }, + "root": "root", + "version": 7 +} diff --git a/flake.nix b/flake.nix new file mode 100644 index 0000000..958f8b0 --- /dev/null +++ b/flake.nix @@ -0,0 +1,78 @@ +{ + description = "a nixos configuration collection by rebmit"; + + outputs = + inputs@{ flake-parts, rebmit, ... }: + flake-parts.lib.mkFlake { inherit inputs; } { + inherit (rebmit.lib) systems; + imports = [ + inputs.devshell.flakeModule + inputs.git-hooks-nix.flakeModule + inputs.treefmt-nix.flakeModule + inputs.rebmit.flakeModule + ] ++ rebmit.lib.path.buildModuleList ./flake; + }; + + inputs = { + # flake-parts + + flake-parts.follows = "rebmit/flake-parts"; + + # nixpkgs + + nixpkgs.follows = "rebmit/nixpkgs"; + nixpkgs-unstable.follows = "rebmit/nixpkgs-unstable"; + + # flake modules + + devshell.follows = "rebmit/devshell"; + git-hooks-nix.follows = "rebmit/git-hooks-nix"; + treefmt-nix.follows = "rebmit/treefmt-nix"; + + # nixos modules + + impermanence.url = "github:nix-community/impermanence"; + home-manager = { + url = "github:nix-community/home-manager"; + inputs.nixpkgs.follows = "nixpkgs"; + }; + sops-nix = { + url = "github:Mic92/sops-nix"; + inputs.nixpkgs.follows = "nixpkgs"; + }; + disko = { + url = "github:nix-community/disko/v1.9.0"; + inputs.nixpkgs.follows = "nixpkgs"; + }; + lanzaboote = { + url = "github:nix-community/lanzaboote/v0.4.1"; + inputs.nixpkgs.follows = "nixpkgs"; + inputs.flake-parts.follows = "flake-parts"; + inputs.flake-utils.follows = "flake-utils"; + inputs.flake-compat.follows = "flake-compat"; + inputs.pre-commit-hooks-nix.follows = "git-hooks-nix"; + }; + + # programs + + niri-flake = { + url = "github:sodiboo/niri-flake"; + inputs.nixpkgs.follows = "nixpkgs"; + inputs.nixpkgs-stable.follows = "nixpkgs"; + }; + ranet = { + url = "github:NickCao/ranet"; + inputs.nixpkgs.follows = "nixpkgs"; + inputs.flake-utils.follows = "flake-utils"; + }; + + # libraries + + rebmit.url = "github:rebmit/nix-exprs"; + flake-utils.url = "github:numtide/flake-utils"; + + # misc + + flake-compat.follows = "rebmit/flake-compat"; + }; +} diff --git a/flake/devshell.nix b/flake/devshell.nix new file mode 100644 index 0000000..37a502c --- /dev/null +++ b/flake/devshell.nix @@ -0,0 +1,30 @@ +{ + perSystem = + { + config, + pkgs, + lib, + ... + }: + { + devshells.default = { + packages = with pkgs; [ + just + sops + rage + (opentofu.withPlugins ( + ps: with ps; [ + sops + tls + ] + )) + ]; + env = [ + (lib.nameValuePair "DEVSHELL_NO_MOTD" 1) + # https://github.com/opentofu/opentofu/issues/1478 + (lib.nameValuePair "OPENTOFU_STATEFILE_PROVIDER_ADDRESS_TRANSLATION" 0) + ]; + devshell.startup.pre-commit-hook.text = config.pre-commit.installationScript; + }; + }; +} diff --git a/flake/home-manager.nix b/flake/home-manager.nix new file mode 100644 index 0000000..9f66c55 --- /dev/null +++ b/flake/home-manager.nix @@ -0,0 +1,73 @@ +# Portions of this file are sourced from +# https://github.com/linyinfeng/dotfiles/blob/b618b0fd16fb9c79ab7199ed51c4c0f98a392cea/flake/hosts.nix +{ + inputs, + lib, + ... +}: +let + inherit (inputs.rebmit.lib.path) buildModuleList rakeLeaves; + buildSuites = profiles: f: lib.mapAttrs (_: lib.flatten) (lib.fix (f profiles)); + + homeModules = buildModuleList ../home-manager/modules; + homeProfiles = rakeLeaves ../home-manager/profiles; + homeSuites = buildSuites homeProfiles ( + profiles: suites: { + baseline = with profiles; [ + # keep-sorted start + applications.base + fish + helix + tmux + yazi + # keep-sorted end + ]; + + development = with profiles; [ + # keep-sorted start + development + direnv + git + # keep-sorted end + ]; + + workstation = suites.baseline ++ suites.development; + + desktop-baseline = + suites.baseline + ++ (with profiles; [ + # keep-sorted start + applications.desktop + darkman + fcitx5 + firefox + fontconfig + gtk + kitty + qt + theme.catppuccin + xdg-user-dirs + # keep-sorted end + ]); + + desktop-niri = with profiles; [ + # keep-sorted start + cliphist + fuzzel + mako + niri + swaylock + swww + waybar.niri + # keep-sorted end + ]; + + desktop-workstation = suites.workstation ++ suites.desktop-baseline ++ suites.desktop-niri; + } + ); +in +{ + passthru = { + inherit homeModules homeProfiles homeSuites; + }; +} diff --git a/flake/hosts.nix b/flake/hosts.nix new file mode 100644 index 0000000..4ca9f51 --- /dev/null +++ b/flake/hosts.nix @@ -0,0 +1,152 @@ +# Portions of this file are sourced from +# https://github.com/linyinfeng/dotfiles/blob/b618b0fd16fb9c79ab7199ed51c4c0f98a392cea/flake/hosts.nix +{ + config, + inputs, + self, + lib, + getSystem, + ... +}: +let + inherit (config.passthru) + nixosModules + nixosProfiles + nixosSuites + homeModules + homeProfiles + homeSuites + ; + + data = builtins.fromJSON (builtins.readFile ../zones/data.json); + mylib = inputs.rebmit.lib; + + nixosSpecialArgs = name: { + inherit + inputs + self + data + mylib + ; + profiles = nixosProfiles; + suites = nixosSuites; + hostData = data.hosts."${name}"; + }; + + homeSpecialArgs = name: { + inherit + inputs + self + data + mylib + ; + profiles = homeProfiles; + suites = homeSuites; + hostData = data.hosts."${name}"; + }; + + commonNixosModules = + name: + nixosModules + ++ [ + inputs.impermanence.nixosModules.impermanence + inputs.home-manager.nixosModules.home-manager + inputs.sops-nix.nixosModules.sops + inputs.disko.nixosModules.disko + inputs.lanzaboote.nixosModules.lanzaboote + + ( + { ... }: + { + home-manager = { + useGlobalPkgs = true; + useUserPackages = true; + sharedModules = commonHomeModules name; + extraSpecialArgs = homeSpecialArgs name; + }; + } + ) + ]; + + commonHomeModules = + _name: + homeModules + ++ [ + inputs.niri-flake.homeModules.niri + + ( + { osConfig, ... }: + { + home.stateVersion = osConfig.system.stateVersion; + } + ) + ]; + + mkHost = + { + name, + configurationName ? name, + nixpkgs ? inputs.nixpkgs, + system, + forceFlakeNixpkgs ? true, + }: + { + ${name} = nixpkgs.lib.nixosSystem { + specialArgs = nixosSpecialArgs name; + modules = + (commonNixosModules name) + ++ lib.optional (configurationName != null) ../nixos/hosts/${configurationName} + ++ [ + ( + { lib, ... }: + { + networking.hostName = lib.mkDefault name; + } + ) + ( + if forceFlakeNixpkgs then + { + imports = [ nixpkgs.nixosModules.readOnlyPkgs ]; + nixpkgs = { + inherit ((getSystem system).allModuleArgs) pkgs; + }; + } + else + { + nixpkgs = { + inherit ((getSystem system).nixpkgs) config overlays; + }; + } + ) + ]; + }; + }; +in +{ + flake.nixosConfigurations = lib.mkMerge [ + (mkHost { + name = "marisa-7d76"; + system = "x86_64-linux"; + }) + + (mkHost { + name = "marisa-a7s"; + system = "x86_64-linux"; + }) + + (mkHost { + name = "flandre-m5p"; + system = "x86_64-linux"; + }) + + (mkHost { + name = "reisen-sin0"; + system = "x86_64-linux"; + }) + + (mkHost { + name = "reisen-lax0"; + system = "x86_64-linux"; + }) + ]; +} diff --git a/flake/nixos.nix b/flake/nixos.nix new file mode 100644 index 0000000..d49cc91 --- /dev/null +++ b/flake/nixos.nix @@ -0,0 +1,67 @@ +# Portions of this file are sourced from +# https://github.com/linyinfeng/dotfiles/blob/b618b0fd16fb9c79ab7199ed51c4c0f98a392cea/flake/hosts.nix +{ + inputs, + lib, + ... +}: +let + inherit (inputs.rebmit.lib.path) buildModuleList rakeLeaves; + buildSuites = profiles: f: lib.mapAttrs (_: lib.flatten) (lib.fix (f profiles)); + + nixosModules = buildModuleList ../nixos/modules; + nixosProfiles = rakeLeaves ../nixos/profiles; + nixosSuites = buildSuites nixosProfiles ( + profiles: suites: { + baseline = with profiles; [ + # keep-sorted start + programs.tools.common + security.polkit + services.dbus + services.journald + services.openssh + services.zram-generator + system.boot.kernel.latest + system.boot.systemd-initrd + system.common + system.global-persistence + system.nix.gc + system.nix.registry + system.nix.settings + system.nix.version + users.root + # keep-sorted end + ]; + + network = with profiles; [ + # keep-sorted start + programs.tools.network + services.firewall + services.networkd + services.resolved + system.boot.sysctl.tcp-bbr + # keep-sorted end + ]; + + desktop = with profiles; [ + # keep-sorted start + programs.dconf + programs.tools.system + security.rtkit + services.gnome-keyring + services.greetd + services.pipewire + # keep-sorted end + ]; + + workstation = suites.baseline ++ suites.network ++ suites.desktop; + + server = suites.baseline ++ suites.network; + } + ); +in +{ + passthru = { + inherit nixosModules nixosProfiles nixosSuites; + }; +} diff --git a/flake/nixpkgs.nix b/flake/nixpkgs.nix new file mode 100644 index 0000000..08c601d --- /dev/null +++ b/flake/nixpkgs.nix @@ -0,0 +1,56 @@ +{ + inputs, + ... +}: +let + overlays = [ + inputs.ranet.overlays.default + + (_final: prev: { + libadwaita = prev.libadwaita.overrideAttrs (old: { + patches = (old.patches or [ ]) ++ [ + ../patches/libadwaita-without-adwaita-theme.patch + ]; + doCheck = false; + }); + }) + ]; +in +{ + perSystem = + { config, lib, ... }: + { + nixpkgs = { + config = { + allowUnfree = false; + allowUnfreePredicate = + p: + builtins.elem (lib.getName p) [ + # keep-sorted start + # keep-sorted end + ]; + + allowNonSource = false; + allowNonSourcePredicate = + p: + builtins.elem (lib.getName p) [ + # keep-sorted start + "ant" + "cargo-bootstrap" + "dotnet-sdk" + "go" + "libreoffice" + "rustc-bootstrap" + "rustc-bootstrap-wrapper" + "sof-firmware" + "temurin-bin" + "zotero" + # keep-sorted end + ]; + + allowInsecurePredicate = p: (p.pname or null) == "olm"; + }; + inherit overlays; + }; + }; +} diff --git a/flake/packages.nix b/flake/packages.nix new file mode 100644 index 0000000..63cbcf3 --- /dev/null +++ b/flake/packages.nix @@ -0,0 +1,7 @@ +{ + perSystem = + { pkgs, ... }: + { + legacyPackages = pkgs; + }; +} diff --git a/flake/treefmt.nix b/flake/treefmt.nix new file mode 100644 index 0000000..7d07d55 --- /dev/null +++ b/flake/treefmt.nix @@ -0,0 +1,36 @@ +{ + perSystem = + { + config, + lib, + ... + }: + { + treefmt = { + projectRootFile = "flake.nix"; + programs = { + nixfmt.enable = true; + deadnix.enable = true; + terraform.enable = true; + prettier.enable = true; + keep-sorted.enable = true; + }; + settings.formatter = { + keep-sorted = { + includes = lib.mkForce [ "*.nix" ]; + }; + }; + }; + + devshells.default.packages = lib.singleton config.treefmt.build.wrapper; + + pre-commit.settings.hooks = { + treefmt = { + enable = true; + name = "treefmt"; + entry = lib.getExe config.treefmt.build.wrapper; + pass_filenames = false; + }; + }; + }; +} diff --git a/home-manager/modules/home/global-persistence.nix b/home-manager/modules/home/global-persistence.nix new file mode 100644 index 0000000..c39a6e3 --- /dev/null +++ b/home-manager/modules/home/global-persistence.nix @@ -0,0 +1,53 @@ +# Portions of this file are sourced from +# https://github.com/linyinfeng/dotfiles/blob/b618b0fd16fb9c79ab7199ed51c4c0f98a392cea/home-manager/modules/home/global-persistence.nix +{ + config, + lib, + osConfig, + ... +}: +with lib; +let + cfg = config.home.globalPersistence; + sysCfg = osConfig.environment.globalPersistence; +in +{ + options.home.globalPersistence = { + enable = mkEnableOption "global presistence storage"; + home = mkOption { + type = types.str; + description = '' + Home directory. + ''; + }; + directories = mkOption { + type = with types; listOf str; + default = [ ]; + description = '' + A list of directories in your home directory that you want to link to persistent storage. + ''; + }; + files = mkOption { + type = with types; listOf str; + default = [ ]; + description = '' + A list of files in your home directory you want to link to persistent storage. + ''; + }; + enabled = mkOption { + type = types.bool; + default = false; + description = '' + Is global home persistence storage enabled. + ''; + }; + }; + + config = mkIf (osConfig != null && sysCfg.enable) { + home.globalPersistence = { + inherit (sysCfg.user) directories; + inherit (sysCfg.user) files; + enabled = cfg.enable; + }; + }; +} diff --git a/home-manager/modules/theme.nix b/home-manager/modules/theme.nix new file mode 100644 index 0000000..0bb3b38 --- /dev/null +++ b/home-manager/modules/theme.nix @@ -0,0 +1,68 @@ +{ lib, ... }: +with lib; +let + themeOpts.options = { + iconTheme = mkOption { + type = types.str; + description = '' + The icon theme to use. + ''; + }; + gtkTheme = mkOption { + type = types.str; + description = '' + The GTK theme to use. + ''; + }; + wallpaper = mkOption { + type = types.str; + description = '' + The path to the wallpaper to use. + ''; + }; + kittyTheme = mkOption { + type = types.str; + description = '' + The path to the kitty theme to use. + ''; + }; + helixTheme = mkOption { + type = types.str; + description = '' + The path to the helix theme to use. + ''; + }; + base24Theme = mkOption { }; + }; +in +{ + options.theme = { + cursorTheme = mkOption { + type = types.str; + description = '' + The cursor theme to use. + ''; + }; + cursorSize = mkOption { + type = types.int; + description = '' + The size of the cursor. + ''; + }; + + light = mkOption { + type = types.submodule themeOpts; + default = { }; + description = '' + The light theme configuration. + ''; + }; + dark = mkOption { + type = types.submodule themeOpts; + default = { }; + description = '' + The dark theme configuration. + ''; + }; + }; +} diff --git a/home-manager/profiles/applications/base.nix b/home-manager/profiles/applications/base.nix new file mode 100644 index 0000000..97f793e --- /dev/null +++ b/home-manager/profiles/applications/base.nix @@ -0,0 +1,13 @@ +{ pkgs, ... }: +{ + home.packages = with pkgs; [ + # keep-sorted start + fastfetch + fd + ffmpeg + fzf + numbat + ripgrep + # keep-sorted end + ]; +} diff --git a/home-manager/profiles/applications/desktop.nix b/home-manager/profiles/applications/desktop.nix new file mode 100644 index 0000000..9b018e9 --- /dev/null +++ b/home-manager/profiles/applications/desktop.nix @@ -0,0 +1,29 @@ +{ pkgs, ... }: +{ + home.packages = with pkgs; [ + # keep-sorted start + celluloid + foliate + libreoffice-fresh + loupe + nheko + papers + seahorse + tdesktop + thunderbird + zotero-beta + # keep-sorted end + ]; + + home.globalPersistence.directories = [ + ".thunderbird" + ".zotero" + + ".config/nheko" + + ".local/share/nheko" + ".local/share/TelegramDesktop" + + "Zotero" + ]; +} diff --git a/home-manager/profiles/cliphist/default.nix b/home-manager/profiles/cliphist/default.nix new file mode 100644 index 0000000..d9310b8 --- /dev/null +++ b/home-manager/profiles/cliphist/default.nix @@ -0,0 +1,63 @@ +# Portions of this file are sourced from +# https://github.com/linyinfeng/dotfiles/blob/d40b75ca0955d2a999b36fa1bd0f8b3a6e061ef3/home-manager/profiles/niri/default.nix +{ + config, + lib, + pkgs, + ... +}: +let + cliphist = pkgs.cliphist; +in +lib.mkMerge [ + { + home.packages = lib.singleton cliphist; + + systemd.user.services.cliphist = { + Unit = { + Description = "Clipboard management daemon"; + ConditionEnvironment = lib.singleton "WAYLAND_DISPLAY"; + PartOf = [ "graphical-session.target" ]; + After = [ "graphical-session.target" ]; + Requisite = [ "graphical-session.target" ]; + }; + Install.WantedBy = [ "graphical-session.target" ]; + Service = { + Type = "simple"; + Restart = "on-failure"; + ExecStart = "${pkgs.wl-clipboard}/bin/wl-paste --watch ${cliphist}/bin/cliphist store"; + }; + }; + + systemd.user.services.cliphist-images = { + Unit = { + Description = "Clipboard management daemon - images"; + ConditionEnvironment = lib.singleton "WAYLAND_DISPLAY"; + PartOf = [ "graphical-session.target" ]; + After = [ "graphical-session.target" ]; + Requisite = [ "graphical-session.target" ]; + }; + Install.WantedBy = [ "graphical-session.target" ]; + Service = { + Type = "simple"; + Restart = "on-failure"; + ExecStart = "${pkgs.wl-clipboard}/bin/wl-paste --type image --watch ${cliphist}/bin/cliphist store"; + }; + }; + } + (lib.mkIf config.programs.fuzzel.enable { + home.packages = with pkgs; [ + (pkgs.writeShellApplication { + name = "cliphist-fuzzel"; + runtimeInputs = with pkgs; [ + wl-clipboard + config.programs.fuzzel.package + config.services.cliphist.package + ]; + text = '' + cliphist list | fuzzel -d | cliphist decode | wl-copy + ''; + }) + ]; + }) +] diff --git a/home-manager/profiles/darkman/default.nix b/home-manager/profiles/darkman/default.nix new file mode 100644 index 0000000..f7eaff7 --- /dev/null +++ b/home-manager/profiles/darkman/default.nix @@ -0,0 +1,35 @@ +{ + config, + pkgs, + lib, + ... +}: +let + defaultMode = pkgs.writeText "darkman-default-mode" "light"; +in +{ + services.darkman.enable = true; + + home.globalPersistence.directories = [ ".cache/darkman" ]; + + systemd.user.tmpfiles.rules = [ + "C %h/.cache/darkman/mode.txt - - - - ${defaultMode}" + "z %h/.cache/darkman/mode.txt 644 - - -" + ]; + + home.packages = with pkgs; [ + (writeShellApplication { + name = "toggle-theme"; + runtimeInputs = lib.singleton config.services.darkman.package; + text = '' + darkman toggle + ''; + }) + ]; + + home.activation.restartDarkman = lib.hm.dag.entryAfter [ "writeBoundary" ] '' + if ${config.systemd.user.systemctlPath} --user is-active darkman; then + ${config.systemd.user.systemctlPath} --user restart darkman + fi + ''; +} diff --git a/home-manager/profiles/development/default.nix b/home-manager/profiles/development/default.nix new file mode 100644 index 0000000..c87082a --- /dev/null +++ b/home-manager/profiles/development/default.nix @@ -0,0 +1,8 @@ +{ ... }: +{ + home.globalPersistence.directories = [ + "Projects" + + ".local/share/uv" + ]; +} diff --git a/home-manager/profiles/direnv/default.nix b/home-manager/profiles/direnv/default.nix new file mode 100644 index 0000000..da92adf --- /dev/null +++ b/home-manager/profiles/direnv/default.nix @@ -0,0 +1,9 @@ +{ ... }: +{ + programs.direnv = { + enable = true; + nix-direnv.enable = true; + }; + + home.globalPersistence.directories = [ ".local/share/direnv" ]; +} diff --git a/home-manager/profiles/fcitx5/_config/conf/classicui.conf b/home-manager/profiles/fcitx5/_config/conf/classicui.conf new file mode 100644 index 0000000..e2263de --- /dev/null +++ b/home-manager/profiles/fcitx5/_config/conf/classicui.conf @@ -0,0 +1,5 @@ +EnableFractionalScale=False +Font=Sans Serif 11 +MenuFont=Sans Serif 11 +TrayFont=Sans Serif 11 + diff --git a/home-manager/profiles/fcitx5/_config/conf/clipboard.conf b/home-manager/profiles/fcitx5/_config/conf/clipboard.conf new file mode 100644 index 0000000..debc169 --- /dev/null +++ b/home-manager/profiles/fcitx5/_config/conf/clipboard.conf @@ -0,0 +1,2 @@ +TriggerKey= + diff --git a/home-manager/profiles/fcitx5/_config/conf/cloudpinyin.conf b/home-manager/profiles/fcitx5/_config/conf/cloudpinyin.conf new file mode 100644 index 0000000..2c6b295 --- /dev/null +++ b/home-manager/profiles/fcitx5/_config/conf/cloudpinyin.conf @@ -0,0 +1,2 @@ +Toggle Key= + diff --git a/home-manager/profiles/fcitx5/_config/conf/pinyin.conf b/home-manager/profiles/fcitx5/_config/conf/pinyin.conf new file mode 100644 index 0000000..b0b9836 --- /dev/null +++ b/home-manager/profiles/fcitx5/_config/conf/pinyin.conf @@ -0,0 +1,2 @@ +FirstRun=False + diff --git a/home-manager/profiles/fcitx5/_config/config b/home-manager/profiles/fcitx5/_config/config new file mode 100644 index 0000000..3dbd7c2 --- /dev/null +++ b/home-manager/profiles/fcitx5/_config/config @@ -0,0 +1,26 @@ +[Hotkey] +ActivateKeys= +AltTriggerKeys= +DeactivateKeys= +EnumerateBackwardKeys= +EnumerateForwardKeys= +EnumerateGroupBackwardKeys= +EnumerateGroupForwardKeys= +EnumerateSkipFirst=False +EnumerateWithTriggerKeys=True +TogglePreedit= + +[Hotkey/NextCandidate] +0=Tab + +[Hotkey/NextPage] +0=Down + +[Hotkey/PrevCandidate] +0=Shift+Tab + +[Hotkey/PrevPage] +0=Up + +[Hotkey/TriggerKeys] +0=Super+space diff --git a/home-manager/profiles/fcitx5/_config/profile b/home-manager/profiles/fcitx5/_config/profile new file mode 100644 index 0000000..85f6bb7 --- /dev/null +++ b/home-manager/profiles/fcitx5/_config/profile @@ -0,0 +1,13 @@ +[GroupOrder] +0=Default + +[Groups/0] +Default Layout=us +DefaultIM=pinyin +Name=Default + +[Groups/0/Items/0] +Name=keyboard-us + +[Groups/0/Items/1] +Name=pinyin diff --git a/home-manager/profiles/fcitx5/default.nix b/home-manager/profiles/fcitx5/default.nix new file mode 100644 index 0000000..f120eb6 --- /dev/null +++ b/home-manager/profiles/fcitx5/default.nix @@ -0,0 +1,30 @@ +{ pkgs, lib, ... }: +let + fcitx5Package = pkgs.qt6Packages.fcitx5-with-addons.override { + addons = with pkgs; [ + qt6Packages.fcitx5-chinese-addons + fcitx5-pinyin-zhwiki + ]; + withConfigtool = false; + }; +in +{ + home.packages = lib.singleton fcitx5Package; + + systemd.user.services.fcitx5-daemon = { + Unit = { + Description = "Fcitx5 input method editor"; + PartOf = [ "graphical-session.target" ]; + After = [ "graphical-session.target" ]; + Requisite = [ "graphical-session.target" ]; + }; + Service.ExecStart = "${fcitx5Package}/bin/fcitx5"; + Install.WantedBy = [ "graphical-session.target" ]; + }; + + xdg.configFile."fcitx5" = { + source = ./_config; + force = true; + recursive = true; + }; +} diff --git a/home-manager/profiles/firefox/default.nix b/home-manager/profiles/firefox/default.nix new file mode 100644 index 0000000..cd80f59 --- /dev/null +++ b/home-manager/profiles/firefox/default.nix @@ -0,0 +1,158 @@ +# Portions of this file are sourced from +# https://github.com/NickCao/flakes/blob/3b03efb676ea602575c916b2b8bc9d9cd13b0d85/nixos/mainframe/home.nix +# https://github.com/llakala/nixos/blob/b3c5fbde5a5f78c91ee658250f9b42418b73a7b7/apps/gui/firefox.nix +{ + lib, + pkgs, + ... +}: +{ + programs.firefox.enable = true; + + programs.firefox.policies = { + AutofillAddressEnabled = false; + AutofillCreditCardEnabled = false; + DisableAccounts = true; + DisableFirefoxAccounts = true; + DisableFirefoxStudies = true; + DisablePocket = true; + DisableTelemetry = true; + EnableTrackingProtection = { + Value = true; + Locked = true; + Cryptomining = true; + Fingerprinting = true; + EmailTracking = true; + }; + FirefoxHome = { + Search = true; + TopSites = false; + SponsoredTopSites = false; + Highlights = false; + Pocket = false; + SponsoredPocket = false; + Snippets = false; + Locked = true; + }; + FirefoxSuggest = { + WebSuggestions = false; + SponsoredSuggestions = false; + ImproveSuggest = false; + Locked = true; + }; + PasswordManagerEnabled = false; + PostQuantumKeyAgreementEnabled = true; + SearchSuggestEnabled = false; + }; + + programs.firefox.policies.ExtensionSettings = { + "{446900e4-71c2-419f-a6a7-df9c091e268b}" = { + installation_mode = "force_installed"; + install_url = "https://addons.mozilla.org/firefox/downloads/latest/bitwarden-password-manager/latest.xpi"; + }; + "uBlock0@raymondhill.net" = { + installation_mode = "force_installed"; + install_url = "https://addons.mozilla.org/firefox/downloads/latest/ublock-origin/latest.xpi"; + }; + "addon@darkreader.org" = { + installation_mode = "force_installed"; + install_url = "https://addons.mozilla.org/firefox/downloads/latest/darkreader/latest.xpi"; + }; + "@testpilot-containers" = { + installation_mode = "force_installed"; + install_url = "https://addons.mozilla.org/firefox/downloads/latest/multi-account-containers/latest.xpi"; + }; + }; + + programs.firefox.policies.Preferences = { + "browser.urlbar.autoFill.adaptiveHistory.enabled" = true; + "browser.tabs.closeWindowWithLastTab" = false; + "browser.tabs.inTitlebar" = 0; + }; + + programs.firefox.policies.Preferences."browser.uiCustomization.state" = builtins.toJSON { + placements = { + widget-overflow-fixed-list = [ ]; + nav-bar = [ + "back-button" + "forward-button" + "stop-reload-button" + "sidebar-button" + "urlbar-container" + "downloads-button" + "unified-extensions-button" + "fxa-toolbar-menu-button" + ]; + toolbar-menubar = [ "menubar-items" ]; + TabsToolbar = [ ]; + vertical-tabs = [ "tabbrowser-tabs" ]; + PersonalToolbar = [ "personal-bookmarks" ]; + }; + currentVersion = 20; + newElementCount = 0; + }; + + programs.firefox.profiles.default = { + isDefault = true; + search = { + force = true; + default = "Google"; + }; + containersForce = true; + containers = { + "Domestic" = { + id = 1; + color = "green"; + icon = "fingerprint"; + }; + }; + settings = { + "sidebar.revamp" = true; + "sidebar.verticalTabs" = true; + }; + }; + + programs.firefox.profiles.default.search.engines = { + "Bing".metaData.hidden = true; + "eBay".metaData.hidden = true; + "Amazon.com".metaData.hidden = true; + "Wikipedia (en)".metaData.hidden = true; + "Nixpkgs" = { + urls = lib.singleton { + template = "https://search.nixos.org/packages"; + params = lib.attrsToList { + "channel" = "unstable"; + "query" = "{searchTerms}"; + }; + }; + icon = "${pkgs.nixos-icons}/share/icons/hicolor/scalable/apps/nix-snowflake.svg"; + definedAliases = [ "@np" ]; + }; + "NixOS Options" = { + urls = lib.singleton { + template = "https://search.nixos.org/options"; + params = lib.attrsToList { + "channel" = "unstable"; + "query" = "{searchTerms}"; + }; + }; + icon = "${pkgs.nixos-icons}/share/icons/hicolor/scalable/apps/nix-snowflake.svg"; + definedAliases = [ "@no" ]; + }; + "Home Manager Options" = { + urls = lib.singleton { + template = "https://home-manager-options.extranix.com"; + params = lib.attrsToList { + "release" = "master"; + "query" = "{searchTerms}"; + }; + }; + iconUpdateURL = "https://home-manager-options.extranix.com/images/favicon.png"; + definedAliases = [ "@ho" ]; + }; + }; + + home.globalPersistence.directories = [ ".mozilla" ]; + + programs.niri.browser = lib.mkDefault [ "firefox" ]; +} diff --git a/home-manager/profiles/fish/default.nix b/home-manager/profiles/fish/default.nix new file mode 100644 index 0000000..8bb40f0 --- /dev/null +++ b/home-manager/profiles/fish/default.nix @@ -0,0 +1,43 @@ +# Portions of this file are sourced from +# https://github.com/NickCao/flakes/blob/3b03efb676ea602575c916b2b8bc9d9cd13b0d85/nixos/mainframe/home.nix +{ pkgs, ... }: +{ + programs.fish = { + enable = true; + plugins = [ + { + name = "tide"; + src = pkgs.fishPlugins.tide.src; + } + { + name = "autopair"; + src = pkgs.fishPlugins.autopair.src; + } + ]; + shellInit = '' + set fish_greeting + + set fish_cursor_default block + set fish_cursor_insert line + set fish_cursor_replace_one underscore + set fish_cursor_replace underscore + set fish_cursor_external line + set fish_cursor_visual block + + function fish_user_key_bindings + fish_vi_key_bindings + bind f accept-autosuggestion + end + + string replace -r '^' 'set -g ' < ${pkgs.fishPlugins.tide.src}/functions/tide/configure/icons.fish | source + string replace -r '^' 'set -g ' < ${pkgs.fishPlugins.tide.src}/functions/tide/configure/configs/lean.fish | source + string replace -r '^' 'set -g ' < ${pkgs.fishPlugins.tide.src}/functions/tide/configure/configs/lean_16color.fish | source + set -g tide_prompt_add_newline_before false + + fish_config theme choose fish\ default + set fish_color_autosuggestion white + ''; + }; + + home.globalPersistence.directories = [ ".local/share/fish" ]; +} diff --git a/home-manager/profiles/fontconfig/default.nix b/home-manager/profiles/fontconfig/default.nix new file mode 100644 index 0000000..8997b01 --- /dev/null +++ b/home-manager/profiles/fontconfig/default.nix @@ -0,0 +1,15 @@ +{ pkgs, ... }: +{ + home.packages = with pkgs; [ + noto-fonts + noto-fonts-cjk-sans + noto-fonts-cjk-serif + noto-fonts-emoji + roboto-mono + (nerdfonts.override { fonts = [ "RobotoMono" ]; }) + ]; + + fonts.fontconfig.enable = true; + + xdg.configFile."fontconfig/conf.d/30-default-fonts.conf".source = ./fonts.conf; +} diff --git a/home-manager/profiles/fontconfig/fonts.conf b/home-manager/profiles/fontconfig/fonts.conf new file mode 100644 index 0000000..d1eb221 --- /dev/null +++ b/home-manager/profiles/fontconfig/fonts.conf @@ -0,0 +1,174 @@ + + + + + + + + system-ui + + + sans-serif + + + + + + sans-serif + + + Noto Sans + Noto Sans CJK SC + + + + + + serif + + + Noto Serif + Noto Serif CJK SC + + + + + + monospace + + + RobotoMono Nerd Font Mono + Noto Sans Mono CJK SC + + + + + + emoji + + + Noto Color Emoji + + + + + + ja + + + Noto Sans CJK SC + + + Noto Sans CJK JP + + + + + + ja + + + Noto Serif CJK SC + + + Noto Serif CJK JP + + + + + + ko + + + Noto Sans CJK SC + + + Noto Sans CJK KR + + + + + + ko + + + Noto Serif CJK SC + + + Noto Serif CJK KR + + + + + + zh-CN + + + Noto Sans + + + Noto Sans CJK SC + + + + + + zh-CN + + + Noto Serif + + + Noto Serif CJK SC + + + + + + zh-HK + + + Noto Sans CJK SC + + + Noto Sans CJK HK + + + + + + zh-HK + + + Noto Serif CJK SC + + + Noto Serif CJK HK + + + + + + zh-TW + + + Noto Sans CJK SC + + + Noto Sans CJK TC + + + + + + zh-TW + + + Noto Serif CJK SC + + + Noto Serif CJK TC + + + + diff --git a/home-manager/profiles/fuzzel/default.nix b/home-manager/profiles/fuzzel/default.nix new file mode 100644 index 0000000..c34ca24 --- /dev/null +++ b/home-manager/profiles/fuzzel/default.nix @@ -0,0 +1,69 @@ +{ + config, + pkgs, + lib, + ... +}: +let + mkTheme = + mode: + let + inherit (config.theme.${mode}.base24Theme) + base00 + base04 + base05 + base08 + base0D + ; + in + (pkgs.formats.ini { }).generate "fuzzel-theme-${mode}.ini" { + colors = { + background = "${base00}dd"; + text = "${base05}ff"; + match = "${base08}ff"; + selection = "${base04}ff"; + selection-text = "${base05}ff"; + selection-match = "${base08}ff"; + border = "${base0D}ff"; + }; + }; +in +{ + programs.fuzzel = { + enable = true; + settings = { + main = { + fields = "filename,name,generic,exec,keywords"; + font = "monospace:size=11"; + dpi-aware = "no"; + layer = "overlay"; + }; + border = { + width = "2"; + radius = "0"; + }; + }; + }; + + programs.fuzzel.settings.main.include = "~/.config/fuzzel/theme.ini"; + + systemd.user.tmpfiles.rules = [ + "L %h/.config/fuzzel/theme.ini - - - - ${mkTheme "light"}" + ]; + + services.darkman = + let + mkScript = + mode: + pkgs.writeShellApplication { + name = "darkman-switch-fuzzel-${mode}"; + text = '' + ln --force --symbolic --verbose "${mkTheme mode}" "$HOME/.config/fuzzel/theme.ini" + ''; + }; + in + { + lightModeScripts.fuzzel = "${lib.getExe (mkScript "light")}"; + darkModeScripts.fuzzel = "${lib.getExe (mkScript "dark")}"; + }; +} diff --git a/home-manager/profiles/git/default.nix b/home-manager/profiles/git/default.nix new file mode 100644 index 0000000..d34469e --- /dev/null +++ b/home-manager/profiles/git/default.nix @@ -0,0 +1,16 @@ +{ lib, ... }: +{ + programs.git = { + enable = true; + lfs.enable = true; + extraConfig = { + commit.gpgSign = true; + gpg.format = "ssh"; + pull.rebase = true; + init.defaultBranch = "master"; + fetch.prune = true; + }; + }; + + programs.git.signing.key = lib.mkDefault "~/.ssh/id_ed25519"; +} diff --git a/home-manager/profiles/gtk/default.nix b/home-manager/profiles/gtk/default.nix new file mode 100644 index 0000000..b98fde8 --- /dev/null +++ b/home-manager/profiles/gtk/default.nix @@ -0,0 +1,49 @@ +{ + config, + lib, + pkgs, + ... +}: +{ + gtk = { + enable = true; + gtk2.configLocation = "${config.xdg.configHome}/gtk-2.0/gtkrc"; + cursorTheme = { + name = config.theme.cursorTheme; + size = config.theme.cursorSize; + }; + }; + + # https://github.com/nix-community/home-manager/pull/5206 + # https://github.com/nix-community/home-manager/commit/e9b9ecef4295a835ab073814f100498716b05a96 + xdg.configFile."gtk-4.0/gtk.css" = lib.mkForce { + text = config.gtk.gtk4.extraCss; + }; + + services.darkman = + let + mkScript = + mode: + let + inherit (config.theme.${mode}) + gtkTheme + iconTheme + ; + in + pkgs.writeShellApplication { + name = "darkman-switch-gtk-${mode}"; + runtimeInputs = with pkgs; [ + dconf + ]; + text = '' + dconf write /org/gnome/desktop/interface/color-scheme "'prefer-${mode}'" + dconf write /org/gnome/desktop/interface/gtk-theme "'${gtkTheme}'" + dconf write /org/gnome/desktop/interface/icon-theme "'${iconTheme}'" + ''; + }; + in + { + lightModeScripts.gtk = "${lib.getExe (mkScript "light")}"; + darkModeScripts.gtk = "${lib.getExe (mkScript "dark")}"; + }; +} diff --git a/home-manager/profiles/helix/default.nix b/home-manager/profiles/helix/default.nix new file mode 100644 index 0000000..107314f --- /dev/null +++ b/home-manager/profiles/helix/default.nix @@ -0,0 +1,75 @@ +{ + config, + pkgs, + lib, + ... +}: +{ + programs.helix = { + enable = true; + defaultEditor = true; + settings = { + editor = { + line-number = "relative"; + cursorline = true; + bufferline = "multiple"; + color-modes = true; + lsp.display-messages = true; + cursor-shape = { + insert = "bar"; + normal = "block"; + select = "underline"; + }; + indent-guides.render = true; + }; + keys = { + normal = { + esc = [ + "keep_primary_selection" + "collapse_selection" + ]; + S = ":w"; + Q = ":q"; + J = lib.replicate 5 "move_visual_line_down"; + K = lib.replicate 5 "move_visual_line_up"; + H = lib.replicate 5 "move_char_left"; + L = lib.replicate 5 "move_char_right"; + }; + select = { + J = lib.replicate 5 "extend_line_down"; + K = lib.replicate 5 "extend_line_up"; + H = lib.replicate 5 "extend_char_left"; + L = lib.replicate 5 "extend_char_right"; + }; + }; + }; + }; + + programs.helix.settings.theme = "custom"; + + systemd.user.tmpfiles.rules = [ + "L %h/.config/helix/themes/custom.toml - - - - ${config.theme.light.helixTheme}" + ]; + + services.darkman = + let + mkScript = + mode: + pkgs.writeShellApplication { + name = "darkman-switch-helix-${mode}"; + runtimeInputs = with pkgs; [ + procps + ]; + text = '' + ln --force --symbolic --verbose "${ + config.theme.${mode}.helixTheme + }" "$HOME/.config/helix/themes/custom.toml" + pkill -USR1 -u "$USER" hx || true + ''; + }; + in + { + lightModeScripts.helix = "${lib.getExe (mkScript "light")}"; + darkModeScripts.helix = "${lib.getExe (mkScript "dark")}"; + }; +} diff --git a/home-manager/profiles/kitty/default.nix b/home-manager/profiles/kitty/default.nix new file mode 100644 index 0000000..1acacb8 --- /dev/null +++ b/home-manager/profiles/kitty/default.nix @@ -0,0 +1,55 @@ +{ + config, + lib, + pkgs, + ... +}: +{ + programs.kitty = { + enable = true; + font = { + name = "monospace"; + size = 12.0; + }; + settings = { + background_opacity = "0.95"; + hide_window_decorations = "yes"; + confirm_os_window_close = "0"; + enable_audio_bell = "no"; + map = "kitty_mod+t no_op"; + }; + extraConfig = '' + include theme.conf + ''; + }; + + programs.fuzzel.settings.main.terminal = lib.mkDefault "kitty"; + + programs.niri.terminal = lib.mkDefault [ "kitty" ]; + + systemd.user.tmpfiles.rules = [ + "L %h/.config/kitty/theme.conf - - - - ${config.theme.light.kittyTheme}" + ]; + + services.darkman = + let + mkScript = + mode: + pkgs.writeShellApplication { + name = "darkman-switch-kitty-${mode}"; + runtimeInputs = with pkgs; [ + procps + ]; + text = '' + ln --force --symbolic --verbose "${ + config.theme.${mode}.kittyTheme + }" "$HOME/.config/kitty/theme.conf" + pkill -USR1 -u "$USER" kitty || true + ''; + }; + in + { + lightModeScripts.kitty = "${lib.getExe (mkScript "light")}"; + darkModeScripts.kitty = "${lib.getExe (mkScript "dark")}"; + }; +} diff --git a/home-manager/profiles/mako/default.nix b/home-manager/profiles/mako/default.nix new file mode 100644 index 0000000..e317254 --- /dev/null +++ b/home-manager/profiles/mako/default.nix @@ -0,0 +1,56 @@ +{ + config, + pkgs, + lib, + ... +}: +let + mkConfig = + mode: + let + inherit (config.theme.${mode}.base24Theme) + base00 + base02 + base05 + base09 + base0D + ; + in + pkgs.writeText "mako-config-${mode}" '' + font=sans-serif 11 + background-color=#${base00} + text-color=#${base05} + border-color=#${base0D} + progress-color=over #${base02} + border-size=3 + border-radius=3 + + [urgency=high] + border-color=#${base09} + ''; + mako = pkgs.mako; +in +{ + home.packages = lib.singleton mako; + + systemd.user.tmpfiles.rules = [ + "L %h/.config/mako/config - - - - ${mkConfig "light"}" + ]; + + services.darkman = + let + mkScript = + mode: + pkgs.writeShellApplication { + name = "darkman-switch-mako-${mode}"; + text = '' + ln --force --symbolic --verbose "${mkConfig mode}" "$HOME/.config/mako/config" + ${mako}/bin/makoctl reload || true + ''; + }; + in + { + lightModeScripts.mako = "${lib.getExe (mkScript "light")}"; + darkModeScripts.mako = "${lib.getExe (mkScript "dark")}"; + }; +} diff --git a/home-manager/profiles/niri/default.nix b/home-manager/profiles/niri/default.nix new file mode 100644 index 0000000..05c4023 --- /dev/null +++ b/home-manager/profiles/niri/default.nix @@ -0,0 +1,305 @@ +# Portions of this file are sourced from +# https://github.com/linyinfeng/dotfiles/blob/d40b75ca0955d2a999b36fa1bd0f8b3a6e061ef3/home-manager/profiles/niri/default.nix +{ + config, + lib, + pkgs, + ... +}: +let + cfg = config.programs.niri; +in +{ + options.programs.niri = { + browser = lib.mkOption { + type = with lib.types; listOf str; + description = '' + The command of the default browser. + ''; + }; + terminal = lib.mkOption { + type = with lib.types; listOf str; + description = '' + The command of the default terminal. + ''; + }; + xwayland = lib.mkOption { + type = lib.types.bool; + default = false; + description = '' + Whether to enable xwayland support. + ''; + }; + }; + + config = lib.mkMerge [ + # niri + { + programs.niri = { + package = pkgs.niri; + settings = { + input = { + touchpad = { + tap = true; + natural-scroll = true; + dwt = true; + }; + }; + layout = { + gaps = 8; + center-focused-column = "never"; + preset-column-widths = [ + { proportion = 1.0 / 3.0; } + { proportion = 1.0 / 2.0; } + { proportion = 2.0 / 3.0; } + ]; + default-column-width = { + proportion = 1.0 / 2.0; + }; + focus-ring = { + enable = true; + width = 4; + active.color = "#7fc8ff"; + inactive.color = "#505050"; + }; + border = { + enable = false; + width = 4; + active.color = "#ffc87f"; + inactive.color = "#505050"; + }; + struts = { }; + }; + hotkey-overlay = { + skip-at-startup = true; + }; + spawn-at-startup = [ ]; + prefer-no-csd = true; + screenshot-path = "~/Pictures/Screenshots/Screenshot from %Y-%m-%d %H-%M-%S.png"; + animations.enable = true; + window-rules = [ + { + geometry-corner-radius = + let + radius = 12.0; + in + { + bottom-left = radius; + bottom-right = radius; + top-left = radius; + top-right = radius; + }; + clip-to-geometry = true; + } + ]; + binds = + let + modMove = "Shift"; + modMonitor = "Ctrl"; + keyUp = "K"; + keyDown = "J"; + keyLeft = "H"; + keyRight = "L"; + directions = { + left = { + keys = [ + keyLeft + "WheelScrollLeft" + ]; + windowTerm = "column"; + }; + down = { + keys = lib.singleton keyDown; + windowTerm = "window"; + }; + up = { + keys = lib.singleton keyUp; + windowTerm = "window"; + }; + right = { + keys = [ + keyRight + "WheelScrollRight" + ]; + windowTerm = "column"; + }; + }; + workspaceIndices = lib.range 1 9; + isWheelKey = lib.hasPrefix "Wheel"; + wheelCooldownMs = 100; + windowBindings = lib.mkMerge ( + lib.concatLists ( + lib.mapAttrsToList ( + direction: cfg: + (lib.lists.map ( + key: + let + cooldown-ms = lib.mkIf (isWheelKey key) wheelCooldownMs; + in + { + "Mod+${key}" = { + action."focus-${cfg.windowTerm}-${direction}" = [ ]; + inherit cooldown-ms; + }; + "Mod+${modMove}+${key}" = { + action."move-${cfg.windowTerm}-${direction}" = [ ]; + inherit cooldown-ms; + }; + "Mod+${modMonitor}+${key}" = { + action."focus-monitor-${direction}" = [ ]; + inherit cooldown-ms; + }; + "Mod+${modMove}+${modMonitor}+${key}" = { + action."move-column-to-monitor-${direction}" = [ ]; + inherit cooldown-ms; + }; + } + ) cfg.keys) + ) directions + ) + ); + indexedWorkspaceBindings = lib.mkMerge ( + map (index: { + "Mod+${toString index}" = { + action.focus-workspace = [ index ]; + }; + "Mod+${modMove}+${toString index}" = { + action.move-column-to-workspace = [ index ]; + }; + }) workspaceIndices + ); + specialBindings = { + "Mod+W".action.spawn = cfg.browser; + "Mod+Return".action.spawn = cfg.terminal; + "Mod+D".action.spawn = [ "fuzzel" ]; + "Mod+M".action.spawn = [ "swaylock" ]; + "Mod+V".action.spawn = [ "cliphist-fuzzel" ]; + "XF86AudioRaiseVolume" = { + allow-when-locked = true; + action.spawn = [ + "${pkgs.pulsemixer}/bin/pulsemixer" + "--change-volume" + "+5" + ]; + }; + "XF86AudioLowerVolume" = { + allow-when-locked = true; + action.spawn = [ + "${pkgs.pulsemixer}/bin/pulsemixer" + "--change-volume" + "-5" + ]; + }; + "XF86AudioMute" = { + allow-when-locked = true; + action.spawn = [ + "${pkgs.pulsemixer}/bin/pulsemixer" + "--toggle-mute" + ]; + }; + "Mod+P".action.spawn = [ + "${pkgs.playerctl}/bin/playerctl" + "play-pause" + ]; + "Mod+I".action.spawn = [ + "${pkgs.playerctl}/bin/playerctl" + "previous" + ]; + "Mod+O".action.spawn = [ + "${pkgs.playerctl}/bin/playerctl" + "next" + ]; + "Mod+Shift+Q".action.close-window = [ ]; + "Mod+Tab".action.focus-workspace-previous = [ ]; + "Mod+C".action.center-column = [ ]; + "Mod+Comma".action.consume-window-into-column = [ ]; + "Mod+Period".action.expel-window-from-column = [ ]; + "Mod+BracketLeft".action.consume-or-expel-window-left = [ ]; + "Mod+BracketRight".action.consume-or-expel-window-right = [ ]; + "Mod+R".action.switch-preset-column-width = [ ]; + "Mod+Shift+R".action.reset-window-height = [ ]; + "Mod+F".action.maximize-column = [ ]; + "Mod+Shift+F".action.fullscreen-window = [ ]; + "Mod+Minus".action.set-column-width = [ "-10%" ]; + "Mod+Equal".action.set-column-width = [ "+10%" ]; + "Mod+Shift+Minus".action.set-window-height = [ "-10%" ]; + "Mod+Shift+Equal".action.set-window-height = [ "+10%" ]; + "Mod+Shift+S".action.screenshot = [ ]; + "Mod+Ctrl+S".action.screenshot-window = [ ]; + "Mod+Shift+E".action.quit = [ ]; + }; + in + lib.mkMerge [ + windowBindings + indexedWorkspaceBindings + specialBindings + ]; + cursor = { + theme = config.theme.cursorTheme; + size = config.theme.cursorSize; + }; + }; + }; + + home.packages = with pkgs; [ + (hiPrio (writeShellApplication { + name = "wayland-session"; + runtimeInputs = [ cfg.package ]; + text = '' + niri-session + ''; + })) + + cfg.package + wl-clipboard + ]; + } + + # xdg-desktop-portal + { + xdg.portal = { + enable = true; + extraPortals = with pkgs; [ + xdg-desktop-portal-gtk + xdg-desktop-portal-gnome + ]; + config = { + common = { + "default" = [ + "gnome" + "gtk" + ]; + "org.freedesktop.impl.portal.Secret" = [ "gnome-keyring" ]; + }; + }; + }; + + home.packages = with pkgs; [ + xdg-utils + ]; + } + + # xwayland + (lib.mkIf cfg.xwayland { + systemd.user.services.xwayland-satellite = { + Unit = { + PartOf = [ "graphical-session.target" ]; + After = [ "graphical-session.target" ]; + Requisite = [ "graphical-session.target" ]; + }; + Install.WantedBy = [ "graphical-session.target" ]; + Service = { + Type = "simple"; + ExecStart = "${lib.getExe pkgs.xwayland-satellite} :1"; + NotifyAccess = "all"; + StandardOutput = "journal"; + Restart = "on-failure"; + }; + }; + + programs.niri.settings.environment = lib.singleton { + DISPLAY = ":1"; + }; + }) + ]; +} diff --git a/home-manager/profiles/qt/default.nix b/home-manager/profiles/qt/default.nix new file mode 100644 index 0000000..28e5848 --- /dev/null +++ b/home-manager/profiles/qt/default.nix @@ -0,0 +1,5 @@ +{ + systemd.user.sessionVariables = { + QT_QPA_PLATFORMTHEME = "gtk3"; + }; +} diff --git a/home-manager/profiles/swaylock/default.nix b/home-manager/profiles/swaylock/default.nix new file mode 100644 index 0000000..227256c --- /dev/null +++ b/home-manager/profiles/swaylock/default.nix @@ -0,0 +1,46 @@ +# Portions of this file are sourced from +# https://github.com/NickCao/flakes/blob/3b03efb676ea602575c916b2b8bc9d9cd13b0d85/nixos/mainframe/home.nix +{ + config, + pkgs, + lib, + ... +}: +let + mkBlurredWallpaper = + mode: + pkgs.runCommand "wallpaper-blurred-${mode}" { nativeBuildInputs = with pkgs; [ imagemagick ]; } '' + magick convert -blur 14x5 ${config.theme.${mode}.wallpaper} $out + ''; +in +{ + programs.swaylock = { + enable = true; + settings = { + show-failed-attempts = true; + daemonize = true; + image = "~/.config/swaylock/image"; + scaling = "fill"; + }; + }; + + systemd.user.tmpfiles.rules = [ + "L %h/.config/swaylock/image - - - - ${mkBlurredWallpaper "light"}" + ]; + + services.darkman = + let + mkScript = + mode: + pkgs.writeShellApplication { + name = "darkman-switch-swaylock-${mode}"; + text = '' + ln --force --symbolic --verbose "${mkBlurredWallpaper mode}" "$HOME/.config/swaylock/image" + ''; + }; + in + { + lightModeScripts.swaylock = "${lib.getExe (mkScript "light")}"; + darkModeScripts.swaylock = "${lib.getExe (mkScript "dark")}"; + }; +} diff --git a/home-manager/profiles/swww/default.nix b/home-manager/profiles/swww/default.nix new file mode 100644 index 0000000..a4a6a2b --- /dev/null +++ b/home-manager/profiles/swww/default.nix @@ -0,0 +1,54 @@ +{ + config, + pkgs, + lib, + ... +}: +let + swww = pkgs.swww; +in +{ + systemd.user.services.swww-daemon = { + Unit = { + Description = "A Solution to your Wayland Wallpaper Woes"; + Documentation = "https://github.com/LGFae/swww"; + PartOf = [ "graphical-session.target" ]; + After = [ "graphical-session.target" ]; + Requisite = [ "graphical-session.target" ]; + }; + + Service = { + ExecStart = "${swww}/bin/swww-daemon --no-cache"; + ExecStartPost = "${swww}/bin/swww img %h/.config/swww/wallpaper"; + Restart = "on-failure"; + KillMode = "mixed"; + }; + + Install.WantedBy = [ "graphical-session.target" ]; + }; + + systemd.user.tmpfiles.rules = [ + "L %h/.config/swww/wallpaper - - - - ${config.theme.light.wallpaper}" + ]; + + services.darkman = + let + mkScript = + mode: + pkgs.writeShellApplication { + name = "darkman-switch-swww-${mode}"; + text = '' + if ! ${config.systemd.user.systemctlPath} --user is-active swww-daemon; then + echo "swww-daemon is not active" + exit 1 + fi + ln --force --symbolic --verbose "${config.theme.${mode}.wallpaper}" "$HOME/.config/swww/wallpaper" + ${swww}/bin/swww img ~/.config/swww/wallpaper + ''; + }; + in + { + lightModeScripts.swww = "${lib.getExe (mkScript "light")}"; + darkModeScripts.swww = "${lib.getExe (mkScript "dark")}"; + }; +} diff --git a/home-manager/profiles/syncthing/default.nix b/home-manager/profiles/syncthing/default.nix new file mode 100644 index 0000000..305f96c --- /dev/null +++ b/home-manager/profiles/syncthing/default.nix @@ -0,0 +1,6 @@ +{ ... }: +{ + services.syncthing.enable = true; + + home.globalPersistence.directories = [ ".local/state/syncthing" ]; +} diff --git a/home-manager/profiles/theme/catppuccin/catppuccin-frappe.toml b/home-manager/profiles/theme/catppuccin/catppuccin-frappe.toml new file mode 100644 index 0000000..28ca421 --- /dev/null +++ b/home-manager/profiles/theme/catppuccin/catppuccin-frappe.toml @@ -0,0 +1,31 @@ +# This file is sourced from https://github.com/tinted-theming/schemes/tree/spec-0.11/base24 +system = "base24" +name = "Catppuccin Frappe" +author = "https://github.com/catppuccin/catppuccin" +variant = "dark" + +[palette] +base00 = "#303446" +base01 = "#292c3c" +base02 = "#414559" +base03 = "#51576d" +base04 = "#626880" +base05 = "#c6d0f5" +base06 = "#f2d5cf" +base07 = "#babbf1" +base08 = "#e78284" +base09 = "#ef9f76" +base0A = "#e5c890" +base0B = "#a6d189" +base0C = "#81c8be" +base0D = "#8caaee" +base0E = "#ca9ee6" +base0F = "#eebebe" +base10 = "#292c3c" +base11 = "#232634" +base12 = "#ea999c" +base13 = "#f2d5cf" +base14 = "#a6d189" +base15 = "#99d1db" +base16 = "#85c1dc" +base17 = "#f4b8e4" diff --git a/home-manager/profiles/theme/catppuccin/catppuccin-latte.toml b/home-manager/profiles/theme/catppuccin/catppuccin-latte.toml new file mode 100644 index 0000000..ad6a182 --- /dev/null +++ b/home-manager/profiles/theme/catppuccin/catppuccin-latte.toml @@ -0,0 +1,31 @@ +# This file is sourced from https://github.com/tinted-theming/schemes/tree/spec-0.11/base24 +system = "base24" +name = "Catppuccin Latte" +author = "https://github.com/catppuccin/catppuccin" +variant = "light" + +[palette] +base00 = "#eff1f5" +base01 = "#e6e9ef" +base02 = "#ccd0da" +base03 = "#bcc0cc" +base04 = "#acb0be" +base05 = "#4c4f69" +base06 = "#dc8a78" +base07 = "#7287fd" +base08 = "#d20f39" +base09 = "#fe640b" +base0A = "#df8e1d" +base0B = "#40a02b" +base0C = "#179299" +base0D = "#1e66f5" +base0E = "#8839ef" +base0F = "#dd7878" +base10 = "#e6e9ef" +base11 = "#dce0e8" +base12 = "#e64553" +base13 = "#dc8a78" +base14 = "#40a02b" +base15 = "#04a5e5" +base16 = "#209fb5" +base17 = "#ea76cb" diff --git a/home-manager/profiles/theme/catppuccin/catppuccin-macchiato.toml b/home-manager/profiles/theme/catppuccin/catppuccin-macchiato.toml new file mode 100644 index 0000000..a7c53dd --- /dev/null +++ b/home-manager/profiles/theme/catppuccin/catppuccin-macchiato.toml @@ -0,0 +1,31 @@ +# This file is sourced from https://github.com/tinted-theming/schemes/tree/spec-0.11/base24 +system = "base24" +name = "Catppuccin Macchiato" +author = "https://github.com/catppuccin/catppuccin" +variant = "dark" + +[palette] +base00 = "#24273a" +base01 = "#1e2030" +base02 = "#363a4f" +base03 = "#494d64" +base04 = "#5b6078" +base05 = "#cad3f5" +base06 = "#f4dbd6" +base07 = "#b7bdf8" +base08 = "#ed8796" +base09 = "#f5a97f" +base0A = "#eed49f" +base0B = "#a6da95" +base0C = "#8bd5ca" +base0D = "#8aadf4" +base0E = "#c6a0f6" +base0F = "#f0c6c6" +base10 = "#1e2030" +base11 = "#181926" +base12 = "#ee99a0" +base13 = "#f4dbd6" +base14 = "#a6da95" +base15 = "#91d7e3" +base16 = "#7dc4e4" +base17 = "#f5bde6" diff --git a/home-manager/profiles/theme/catppuccin/catppuccin-mocha.toml b/home-manager/profiles/theme/catppuccin/catppuccin-mocha.toml new file mode 100644 index 0000000..c1af179 --- /dev/null +++ b/home-manager/profiles/theme/catppuccin/catppuccin-mocha.toml @@ -0,0 +1,31 @@ +# This file is sourced from https://github.com/tinted-theming/schemes/tree/spec-0.11/base24 +system = "base24" +name = "Catppuccin Mocha" +author = "https://github.com/catppuccin/catppuccin" +variant = "dark" + +[palette] +base00 = "#1e1e2e" +base01 = "#181825" +base02 = "#313244" +base03 = "#45475a" +base04 = "#585b70" +base05 = "#cdd6f4" +base06 = "#f5e0dc" +base07 = "#b4befe" +base08 = "#f38ba8" +base09 = "#fab387" +base0A = "#f9e2af" +base0B = "#a6e3a1" +base0C = "#94e2d5" +base0D = "#89b4fa" +base0E = "#cba6f7" +base0F = "#f2cdcd" +base10 = "#181825" +base11 = "#11111b" +base12 = "#eba0ac" +base13 = "#f5e0dc" +base14 = "#a6e3a1" +base15 = "#89dceb" +base16 = "#74c7ec" +base17 = "#f5c2e7" diff --git a/home-manager/profiles/theme/catppuccin/default.nix b/home-manager/profiles/theme/catppuccin/default.nix new file mode 100644 index 0000000..12a49ed --- /dev/null +++ b/home-manager/profiles/theme/catppuccin/default.nix @@ -0,0 +1,48 @@ +{ pkgs, ... }: +let + importBase24Theme = + file: + let + inherit (builtins.fromTOML (builtins.readFile file)) palette; + in + builtins.mapAttrs (_name: value: builtins.substring 1 6 value) palette; +in +{ + theme = { + cursorTheme = "capitaine-cursors-white"; + cursorSize = 36; + + light = { + iconTheme = "Papirus-Light"; + gtkTheme = "catppuccin-latte-blue-compact"; + wallpaper = "${pkgs.nixos-artwork.wallpapers.nineish}/share/backgrounds/nixos/nix-wallpaper-nineish.png"; + kittyTheme = "${pkgs.kitty-themes}/share/kitty-themes/themes/Catppuccin-Latte.conf"; + helixTheme = "${pkgs.helix}/lib/runtime/themes/catppuccin_latte.toml"; + base24Theme = importBase24Theme ./catppuccin-latte.toml; + }; + + dark = { + iconTheme = "Papirus-Dark"; + gtkTheme = "catppuccin-frappe-blue-compact"; + wallpaper = "${pkgs.nixos-artwork.wallpapers.nineish-dark-gray}/share/backgrounds/nixos/nix-wallpaper-nineish-dark-gray.png"; + kittyTheme = "${pkgs.kitty-themes}/share/kitty-themes/themes/Catppuccin-Frappe.conf"; + helixTheme = "${pkgs.helix}/lib/runtime/themes/catppuccin_frappe.toml"; + base24Theme = importBase24Theme ./catppuccin-frappe.toml; + }; + }; + + home.packages = with pkgs; [ + papirus-icon-theme + capitaine-cursors + (catppuccin-gtk.override { + accents = [ "blue" ]; + size = "compact"; + variant = "latte"; + }) + (catppuccin-gtk.override { + accents = [ "blue" ]; + size = "compact"; + variant = "frappe"; + }) + ]; +} diff --git a/home-manager/profiles/tmux/default.nix b/home-manager/profiles/tmux/default.nix new file mode 100644 index 0000000..f981d83 --- /dev/null +++ b/home-manager/profiles/tmux/default.nix @@ -0,0 +1,73 @@ +{ pkgs, lib, ... }: +{ + programs.tmux = { + enable = true; + baseIndex = 1; + escapeTime = 10; + keyMode = "vi"; + terminal = "tmux-256color"; + historyLimit = 50000; + plugins = with pkgs.tmuxPlugins; [ + yank + open + ]; + extraConfig = '' + set -g set-clipboard on + set -g mouse on + set -g status-right "" + set -g renumber-windows on + set -g bell-action none + + # keybind + bind \; command-prompt + bind p paste-buffer + bind C-p choose-buffer + + # pane + bind k select-pane -U + bind j select-pane -D + bind h select-pane -L + bind l select-pane -R + bind -r C-k resize-pane -U 5 + bind -r C-j resize-pane -D 5 + bind -r C-h resize-pane -L 5 + bind -r C-l resize-pane -R 5 + + # copy mode + bind Escape copy-mode + bind -T copy-mode-vi k send -X cursor-up + bind -T copy-mode-vi K send -N 5 -X cursor-up + bind -T copy-mode-vi j send -X cursor-down + bind -T copy-mode-vi J send -N 5 -X cursor-down + bind -T copy-mode-vi h send -X cursor-left + bind -T copy-mode-vi H send -N 5 -X cursor-left + bind -T copy-mode-vi C-h send -X start-of-line + bind -T copy-mode-vi l send -X cursor-right + bind -T copy-mode-vi L send -N 5 -X cursor-right + bind -T copy-mode-vi C-l send -X end-of-line + bind -T copy-mode-vi v send -X begin-selection + + # window + bind -r [ previous-window + bind -r ] next-window + bind -r C-[ swap-window -d -t -1 + bind -r C-] swap-window -d -t +1 + bind -r - split-window -h -c "#{pane_current_path}" + bind -r = split-window -v -c "#{pane_current_path}" + bind C-x kill-window + bind c new-window -c "#{pane_current_path}" + bind r command-prompt "rename-window %%" + + # session + bind q confirm-before -p "kill-session #S? (y/n)" kill-session + bind R command-prompt "rename-session %%" + + # image preview + set -g allow-passthrough on + set -ga update-environment TERM + set -ga update-environment TERM_PROGRAM + ''; + }; + + programs.kitty.settings.shell = lib.mkDefault "tmux"; +} diff --git a/home-manager/profiles/waybar/_common.nix b/home-manager/profiles/waybar/_common.nix new file mode 100644 index 0000000..afd2ab4 --- /dev/null +++ b/home-manager/profiles/waybar/_common.nix @@ -0,0 +1,57 @@ +{ + pkgs, + ... +}: +{ + height = 36; + layer = "top"; + "niri/window" = { + format = "{}"; + max-length = 80; + }; + "wlr/taskbar" = { + all-outputs = false; + on-click = "activate"; + on-click-middle = "close"; + }; + tray = { + icon-size = 18; + spacing = 10; + }; + clock = { + format = "{:%a %b %d %H:%M}"; + }; + network = { + interval = 1; + format = "{ifname}"; + format-wifi = "󰇚 {bandwidthDownBytes} 󰕒 {bandwidthUpBytes}"; + format-ethernet = "󰇚 {bandwidthDownBytes} 󰕒 {bandwidthUpBytes}"; + format-disconnected = ""; + tooltip-format = "{ifname} via {gwaddr}"; + tooltip-format-wifi = "{essid} {signalStrength}%"; + tooltip-format-ethernet = "{ifname}"; + tooltip-format-disconnected = "disconnected"; + max-length = 40; + }; + pulseaudio = { + format = "{icon} {volume}% {format_source}"; + format-bluetooth = "󰂯 {volume}% {format_source}"; + format-bluetooth-muted = "󰝟 {volume}% {format_source}"; + format-icons = { + headphone = "󰋋"; + default = [ + "󰖀" + "󰕾" + ]; + }; + format-muted = "󰝟 {volume}% {format_source}"; + format-source = " {volume}%"; + format-source-muted = " {volume}%"; + on-click = "${pkgs.pavucontrol}/bin/pavucontrol"; + }; + "custom/nixos" = { + format = ""; + interval = "once"; + tooltip = false; + }; +} diff --git a/home-manager/profiles/waybar/_default.nix b/home-manager/profiles/waybar/_default.nix new file mode 100644 index 0000000..155ff48 --- /dev/null +++ b/home-manager/profiles/waybar/_default.nix @@ -0,0 +1,49 @@ +{ + config, + pkgs, + lib, + ... +}: +let + mkTheme = + mode: + let + inherit (config.theme.${mode}) base24Theme; + in + pkgs.writeText "waybar-style-${mode}.css" (import ./_style.nix base24Theme); +in +{ + programs.waybar = { + enable = true; + systemd.enable = true; + }; + + systemd.user.services.waybar = { + Unit = { + ConditionEnvironment = lib.singleton "WAYLAND_DISPLAY"; + Requisite = lib.singleton "graphical-session.target"; + After = lib.singleton "graphical-session.target"; + }; + }; + + systemd.user.tmpfiles.rules = [ + "L %h/.config/waybar/style.css - - - - ${mkTheme "light"}" + ]; + + services.darkman = + let + mkScript = + mode: + pkgs.writeShellApplication { + name = "darkman-switch-waybar-${mode}"; + text = '' + ln --force --symbolic --verbose "${mkTheme mode}" "$HOME/.config/waybar/style.css" + pkill -u "$USER" -USR2 waybar || true + ''; + }; + in + { + lightModeScripts.waybar = "${lib.getExe (mkScript "light")}"; + darkModeScripts.waybar = "${lib.getExe (mkScript "dark")}"; + }; +} diff --git a/home-manager/profiles/waybar/_style.nix b/home-manager/profiles/waybar/_style.nix new file mode 100644 index 0000000..80a5662 --- /dev/null +++ b/home-manager/profiles/waybar/_style.nix @@ -0,0 +1,72 @@ +{ + base00, + base02, + base05, + base07, + base0A, + ... +}: +'' + * { + border: none; + border-radius: 0; + font-family: 'RobotoMono Nerd Font', 'sans'; + font-size: 11pt; + font-weight: bold; + min-height: 0; + color: #${base05}; + } + + window#waybar { + padding: 0pt; + opacity: 0.95; + color: #${base05}; + background: #${base00}; + border-bottom: 2pt solid #${base02}; + } + + window#waybar.hidden { + opacity: 0.0; + } + + #workspaces button { + padding: 0pt; + background: transparent; + color: #${base05}; + border-bottom: 2pt solid transparent; + } + + #workspaces button.focused, + #workspaces button.active { + background: #${base02}; + border-bottom: 2pt solid #${base07}; + } + + #workspaces button.urgent { + background: #${base0A}; + } + + #custom-nixos { + padding-left: 12pt; + padding-right: 15pt; + } + + #window { + padding: 0pt 8pt; + } + + #clock, + #tray, + #network, + #pulseaudio { + margin: 0pt 0pt; + padding: 0pt 8pt; + } + + #clock, + #tray, + #network, + #pulseaudio { + border-left: 2pt solid #${base02}; + } +'' diff --git a/home-manager/profiles/waybar/niri.nix b/home-manager/profiles/waybar/niri.nix new file mode 100644 index 0000000..801f919 --- /dev/null +++ b/home-manager/profiles/waybar/niri.nix @@ -0,0 +1,32 @@ +{ + config, + pkgs, + lib, + ... +}: +let + args = { + inherit config pkgs lib; + }; +in +{ + imports = lib.singleton ./_default.nix; + + programs.waybar.settings = lib.singleton ( + { + position = "top"; + modules-left = [ + "custom/nixos" + "niri/workspaces" + "niri/window" + ]; + modules-right = [ + "network" + "pulseaudio" + "clock" + "tray" + ]; + } + // (import ./_common.nix args) + ); +} diff --git a/home-manager/profiles/xdg-user-dirs/default.nix b/home-manager/profiles/xdg-user-dirs/default.nix new file mode 100644 index 0000000..05c2b95 --- /dev/null +++ b/home-manager/profiles/xdg-user-dirs/default.nix @@ -0,0 +1,23 @@ +{ ... }: +{ + xdg.userDirs = { + enable = true; + createDirectories = true; + desktop = "/var/empty"; + documents = "$HOME/Documents"; + download = "$HOME/Downloads"; + music = "$HOME/Music"; + pictures = "$HOME/Pictures"; + publicShare = "/var/empty"; + templates = "/var/empty"; + videos = "$HOME/Videos"; + }; + + home.globalPersistence.directories = [ + "Documents" + "Downloads" + "Music" + "Pictures" + "Videos" + ]; +} diff --git a/home-manager/profiles/yazi/default.nix b/home-manager/profiles/yazi/default.nix new file mode 100644 index 0000000..4be0248 --- /dev/null +++ b/home-manager/profiles/yazi/default.nix @@ -0,0 +1,116 @@ +{ ... }: +{ + programs.yazi = { + enable = true; + enableBashIntegration = true; + enableFishIntegration = true; + shellWrapperName = "ra"; + settings = { + manager = { + sort_by = "natural"; + linemode = "size"; + }; + preview = { + tab_size = 2; + max_width = 1000; + max_height = 1000; + }; + open.rules = [ + { + name = "*/"; + use = [ + "open" + "edit" + "reveal" + ]; + } + { + mime = "text/*"; + use = [ + "edit" + "reveal" + ]; + } + { + mime = "{image,audio,video}/*"; + use = [ + "open" + "reveal" + ]; + } + { + mime = "application/{,g}zip"; + use = [ + "extract" + "reveal" + ]; + } + { + mime = "application/x-{tar,bzip*,7z-compressed,xz,rar}"; + use = [ + "extract" + "reveal" + ]; + } + { + mime = "application/{json,x-ndjson}"; + use = [ + "edit" + "reveal" + ]; + } + { + mime = "*/javascript"; + use = [ + "edit" + "reveal" + ]; + } + { + mime = "inode/x-empty"; + use = [ + "edit" + "reveal" + ]; + } + { + name = "*"; + use = [ + "open" + "reveal" + ]; + } + ]; + }; + keymap = { + manager.prepend_keymap = [ + { + on = [ "J" ]; + run = "arrow 5"; + } + { + on = [ "K" ]; + run = "arrow -5"; + } + { + on = [ "" ]; + run = "seek 5"; + } + { + on = [ "" ]; + run = "seek -5"; + } + ]; + input.prepend_keymap = [ + { + on = [ "H" ]; + run = "move -5"; + } + { + on = [ "L" ]; + run = "move 5"; + } + ]; + }; + }; +} diff --git a/infra/.gitignore b/infra/.gitignore new file mode 100644 index 0000000..30700b4 --- /dev/null +++ b/infra/.gitignore @@ -0,0 +1,3 @@ +/.terraform +/terraform.tfstate.* +/.terraform.lock.hcl diff --git a/infra/backend.tf b/infra/backend.tf new file mode 100644 index 0000000..672228b --- /dev/null +++ b/infra/backend.tf @@ -0,0 +1,14 @@ +terraform { + backend "local" { + path = "terraform.tfstate" + } + encryption { + method "aes_gcm" "default" { + keys = key_provider.pbkdf2.default + } + state { + method = method.aes_gcm.default + enforced = true + } + } +} diff --git a/infra/enthalpy.tf b/infra/enthalpy.tf new file mode 100644 index 0000000..a80159e --- /dev/null +++ b/infra/enthalpy.tf @@ -0,0 +1,27 @@ +locals { + enthalpy_network_prefix = "fde3:3be3:a244::/48" + enthalpy_organizations = { + core = "rebmit's core network" + edge = "rebmit's edge network" + } +} + +resource "tls_private_key" "enthalpy" { + for_each = local.enthalpy_organizations + algorithm = "ED25519" +} + +output "enthalpy_network_prefix" { + value = local.enthalpy_network_prefix + sensitive = false +} + +output "enthalpy_organizations" { + value = local.enthalpy_organizations + sensitive = false +} + +output "enthalpy_public_key_pem" { + value = { for k, v in tls_private_key.enthalpy : k => trimspace(v.public_key_pem) } + sensitive = false +} diff --git a/infra/hosts.tf b/infra/hosts.tf new file mode 100644 index 0000000..89a52d5 --- /dev/null +++ b/infra/hosts.tf @@ -0,0 +1,63 @@ +locals { + hosts = { + "flandre-m5p" = { + endpoints_v4 = [] + endpoints_v6 = [] + enthalpy_node_id = parseint("a23", 16) + enthalpy_node_organization = "edge" + } + "marisa-7d76" = { + endpoints_v4 = [] + endpoints_v6 = [] + enthalpy_node_id = parseint("d79", 16) + enthalpy_node_organization = "edge" + } + "marisa-a7s" = { + endpoints_v4 = [] + endpoints_v6 = [] + enthalpy_node_id = parseint("572", 16) + enthalpy_node_organization = "edge" + } + "reisen-sin0" = { + endpoints_v4 = ["194.156.163.233"] + endpoints_v6 = ["2407:b9c0:e002:20b:26a3:f0ff:fe46:a4d0"] + enthalpy_node_id = parseint("267", 16) + enthalpy_node_organization = "core" + } + "reisen-lax0" = { + endpoints_v4 = ["38.175.109.149"] + endpoints_v6 = ["2a0e:6901:110:276:5054:ff:fe81:ec3b"] + enthalpy_node_id = null + enthalpy_node_organization = null + } + } +} + +module "hosts" { + source = "./modules/host" + for_each = local.hosts + name = each.key + endpoints_v4 = each.value.endpoints_v4 + endpoints_v6 = each.value.endpoints_v6 + enthalpy_network_prefix = local.enthalpy_network_prefix + enthalpy_organizations = local.enthalpy_organizations + enthalpy_private_key = tls_private_key.enthalpy + enthalpy_node_id = each.value.enthalpy_node_id + enthalpy_node_organization = each.value.enthalpy_node_organization +} + +output "hosts" { + value = module.hosts + sensitive = true +} + +output "hosts_non_sensitive" { + value = { + for host, outputs in module.hosts : + host => { + for name, output in outputs : + name => output if !issensitive(output) + } + } + sensitive = false +} diff --git a/infra/modules/host/endpoints.tf b/infra/modules/host/endpoints.tf new file mode 100644 index 0000000..bdf714b --- /dev/null +++ b/infra/modules/host/endpoints.tf @@ -0,0 +1,22 @@ +variable "endpoints_v4" { + type = list(string) +} + +variable "endpoints_v6" { + type = list(string) +} + +output "endpoints" { + value = concat(var.endpoints_v4, var.endpoints_v6) + sensitive = false +} + +output "endpoints_v4" { + value = var.endpoints_v4 + sensitive = false +} + +output "endpoints_v6" { + value = var.endpoints_v6 + sensitive = false +} diff --git a/infra/modules/host/enthalpy.tf b/infra/modules/host/enthalpy.tf new file mode 100644 index 0000000..f92f30a --- /dev/null +++ b/infra/modules/host/enthalpy.tf @@ -0,0 +1,55 @@ +variable "enthalpy_network_prefix" { + type = string +} + +variable "enthalpy_organizations" { + type = map(string) +} + +variable "enthalpy_private_key" { + type = map(object({ + private_key_pem = string + })) +} + +variable "enthalpy_node_id" { + type = number +} + +variable "enthalpy_node_organization" { + type = string +} + +locals { + enthalpy_network_prefix_length = tonumber(regex(".*/([[:digit:]]+)", var.enthalpy_network_prefix)[0]) + enthalpy_node_enabled = var.enthalpy_node_id != null && var.enthalpy_node_organization != null + enthalpy_node_organization = local.enthalpy_node_enabled ? var.enthalpy_organizations[var.enthalpy_node_organization] : null + enthalpy_node_private_key_pem = local.enthalpy_node_enabled ? var.enthalpy_private_key[var.enthalpy_node_organization].private_key_pem : null + enthalpy_node_prefix = local.enthalpy_node_enabled ? cidrsubnet(var.enthalpy_network_prefix, 60 - local.enthalpy_network_prefix_length, var.enthalpy_node_id) : null + enthalpy_node_address = local.enthalpy_node_enabled ? cidrhost(local.enthalpy_node_prefix, 1) : null +} + +output "enthalpy_node_id" { + value = var.enthalpy_node_id + sensitive = false +} + +output "enthalpy_node_organization" { + value = local.enthalpy_node_organization + sensitive = false +} + +output "enthalpy_node_private_key_pem" { + value = local.enthalpy_node_private_key_pem + sensitive = true +} + +output "enthalpy_node_prefix" { + value = local.enthalpy_node_prefix + sensitive = false +} + +output "enthalpy_node_address" { + value = local.enthalpy_node_address + sensitive = false +} diff --git a/infra/modules/host/main.tf b/infra/modules/host/main.tf new file mode 100644 index 0000000..77e5cc9 --- /dev/null +++ b/infra/modules/host/main.tf @@ -0,0 +1,3 @@ +variable "name" { + type = string +} diff --git a/infra/modules/host/openssh.tf b/infra/modules/host/openssh.tf new file mode 100644 index 0000000..70f9e86 --- /dev/null +++ b/infra/modules/host/openssh.tf @@ -0,0 +1,28 @@ +resource "tls_private_key" "host_rsa" { + algorithm = "RSA" + rsa_bits = 4096 +} + +resource "tls_private_key" "host_ed25519" { + algorithm = "ED25519" +} + +output "ssh_host_rsa_key_pub" { + value = trimspace(tls_private_key.host_rsa.public_key_openssh) + sensitive = false +} + +output "ssh_host_rsa_key" { + value = tls_private_key.host_rsa.private_key_openssh + sensitive = true +} + +output "ssh_host_ed25519_key_pub" { + value = trimspace(tls_private_key.host_ed25519.public_key_openssh) + sensitive = false +} + +output "ssh_host_ed25519_key" { + value = tls_private_key.host_ed25519.private_key_openssh + sensitive = true +} diff --git a/infra/modules/host/providers.tf b/infra/modules/host/providers.tf new file mode 100644 index 0000000..80f1ff1 --- /dev/null +++ b/infra/modules/host/providers.tf @@ -0,0 +1,7 @@ +terraform { + required_providers { + tls = { + source = "registry.terraform.io/hashicorp/tls" + } + } +} diff --git a/infra/providers.tf b/infra/providers.tf new file mode 100644 index 0000000..e5c4e3e --- /dev/null +++ b/infra/providers.tf @@ -0,0 +1,10 @@ +terraform { + required_providers { + sops = { + source = "registry.terraform.io/carlpett/sops" + } + tls = { + source = "registry.terraform.io/hashicorp/tls" + } + } +} diff --git a/infra/secrets.tf b/infra/secrets.tf new file mode 100644 index 0000000..b605978 --- /dev/null +++ b/infra/secrets.tf @@ -0,0 +1,7 @@ +data "sops_file" "secrets" { + source_file = "secrets.yaml" +} + +locals { + secrets = yamldecode(data.sops_file.secrets.raw) +} diff --git a/infra/secrets.yaml b/infra/secrets.yaml new file mode 100644 index 0000000..e40a30b --- /dev/null +++ b/infra/secrets.yaml @@ -0,0 +1,21 @@ +tofu: ENC[AES256_GCM,data:wv2zsYRcwM8boVYSaH4EtI4poL/modLixJ8gDoP1T7+JLDyCRyZQsu6WkMR9JPJrRsbMvQ2tFFrk8LPZU2hhh6BqqPX/ZlYUAmAQACuZa1JnUYeskc2TLVNkaL9Glz+cpfylyHQr0ARwEw5Q/cWdC1Xg55pnRFmVOQSY9Sf9asE6fxZ0JIAMPQeVTCe+CQ==,iv:O3smIEUNBPh4pAGUgbnKqLrqjCCK+ZRzVa9mnx9P4s0=,tag:Iv8UFwnUKTUgU+YFQ3gaqg==,type:str] +sops: + kms: [] + gcp_kms: [] + azure_kv: [] + hc_vault: [] + age: + - recipient: age1sfnct03u4cvfj98x4yjrcrrnu5gg8qgxrwk4uqq8w4e6wveeaedq97rn44 + enc: | + -----BEGIN AGE ENCRYPTED FILE----- + YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSArdnlvV09oUWNERmJyM0ZW + WStza2xMdm1JTVRzR0ZBcFlwOFdxamZQMmdZCkVIZG1HOVNla3RQbjRzNmlUUDRX + YitxTXQwUVUzb1JHbEI3NFlMbjI0MmMKLS0tIDRkdjhCcWRNYTkyYWJwUmZENjh3 + Rk1mSHZicDNuVVFpL1NMcS9NS0NmRXcKT2GiNJ8L2ADuoJPm5XF1SrkNZtEzh/i5 + 8gGmswWnE+d7VM0BSnM64la/E4prcIhM4e4Ybyd8El6pwQN919gofQ== + -----END AGE ENCRYPTED FILE----- + lastmodified: "2024-11-23T07:54:24Z" + mac: ENC[AES256_GCM,data:03Bina9HvdovMlUBceqa321L628AR89knW+6wB1Do6fPv3JgDjnSByqq7uewzLms+npVJY6Vj1VtWfwplgnd/UZvvoE0m9yu0Kmv+hOKy5eF5gI+G43j9YKoGzFnqIV+pCXZBF0gqBU+7qpGz3w3C82CG5uHbd6hEQyS0rqDnHA=,iv:lYvY105TcODa3wwmQTJbPxoN3eam6RDNR2ZTI3I3zXw=,tag:h6FNgpN1Kj7sM1gSKZKE0g==,type:str] + pgp: [] + unencrypted_suffix: _unencrypted + version: 3.9.1 diff --git a/infra/terraform.tfstate b/infra/terraform.tfstate new file mode 100644 index 0000000..fc32f0a --- /dev/null +++ b/infra/terraform.tfstate @@ -0,0 +1 @@ +{"serial":2,"lineage":"21ff6099-7d96-2e29-9243-582207cdfdad","meta":{"key_provider.pbkdf2.default":"eyJzYWx0IjoiUFJOV0N0azdxd043dHF1U0tpeFl3NVVmb3FoZk4vclRYWDdGS21MM2lZTT0iLCJpdGVyYXRpb25zIjo2MDAwMDAsImhhc2hfZnVuY3Rpb24iOiJzaGE1MTIiLCJrZXlfbGVuZ3RoIjozMn0="},"encrypted_data":"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","encryption_version":"v0"} \ No newline at end of file diff --git a/justfile b/justfile new file mode 100644 index 0000000..7b7014f --- /dev/null +++ b/justfile @@ -0,0 +1,51 @@ +set shell := ["bash", "-c"] + +[linux] +[group('nix')] +remote name: + nixos-rebuild switch --flake .#{{name}} --target-host root@{{name}} --verbose --show-trace + +[linux] +[group('nix')] +local name: + nixos-rebuild switch --use-remote-sudo --flake .#{{name}} --verbose --show-trace + +[group('nix')] +up: + nix flake update + +[group('nix')] +upp input: + nix flake lock --update-input {{input}} + +[group('nix')] +history: + nix profile diff-closures --profile /nix/var/nix/profiles/system + +[group('nix')] +repl: + nix repl -f flake:nixpkgs + +[linux] +[group('infra')] +plan: + tofu -chdir="infra" plan + +[linux] +[group('infra')] +apply: + tofu -chdir="infra" apply + +[linux] +[group('infra')] +zone: + tofu -chdir="infra" output -json | jq -f zones/data.jq > zones/data.json + cat zones/data.json | jq -f zones/registry.jq > zones/registry.json + +[linux] +[group('infra')] +secret name: + nix eval --raw .#nixosConfigurations.{{name}}.config.sops.opentofuTemplate > test.json + tofu -chdir="infra" output -json | jq -f test.json > secrets/hosts/opentofu/{{name}}.yaml + sops --input-type json --output-type yaml --in-place --encrypt secrets/hosts/opentofu/{{name}}.yaml + rm -i test.json diff --git a/nixos/hosts/flandre-m5p/default.nix b/nixos/hosts/flandre-m5p/default.nix new file mode 100644 index 0000000..4a01360 --- /dev/null +++ b/nixos/hosts/flandre-m5p/default.nix @@ -0,0 +1,10 @@ +{ + suites, + mylib, + ... +}: +{ + imports = suites.server ++ (mylib.path.scanPaths ./. "default.nix"); + + system.stateVersion = "24.05"; +} diff --git a/nixos/hosts/flandre-m5p/disko-fs.nix b/nixos/hosts/flandre-m5p/disko-fs.nix new file mode 100644 index 0000000..7f0ea09 --- /dev/null +++ b/nixos/hosts/flandre-m5p/disko-fs.nix @@ -0,0 +1,84 @@ +{ + disko.devices = { + nodev = { + "/" = { + fsType = "tmpfs"; + mountOptions = [ + "defaults" + "size=8G" + "mode=755" + "nosuid" + "nodev" + ]; + }; + }; + disk = { + main = { + type = "disk"; + device = "/dev/disk/by-path/pci-0000:04:00.0-nvme-1"; + content = { + type = "gpt"; + partitions = { + esp = { + label = "ESP"; + size = "2G"; + type = "EF00"; + content = { + type = "filesystem"; + format = "vfat"; + mountpoint = "/boot"; + mountOptions = [ "umask=0077" ]; + }; + }; + cryptroot = { + label = "CRYPTROOT"; + size = "100%"; + content = { + type = "luks"; + name = "cryptroot"; + settings = { + allowDiscards = true; + bypassWorkqueues = true; + crypttabExtraOpts = [ + "same-cpu-crypt" + "submit-from-crypt-cpus" + ]; + # unattended boot via usb + keyFile = "/dev/disk/by-id/usb-aigo_U330_80101016-0:0"; + keyFileSize = 512 * 64; + }; + content = { + type = "btrfs"; + extraArgs = [ "-f" ]; + subvolumes = { + "/persist" = { + mountpoint = "/persist"; + mountOptions = [ "compress=zstd" ]; + }; + "/nix" = { + mountpoint = "/nix"; + mountOptions = [ "compress=zstd" ]; + }; + }; + }; + }; + }; + }; + }; + }; + }; + }; + + fileSystems."/persist".neededForBoot = true; + + environment.globalPersistence = { + enable = true; + root = "/persist"; + }; + + services.btrfs.autoScrub = { + enable = true; + interval = "weekly"; + fileSystems = [ "/persist" ]; + }; +} diff --git a/nixos/hosts/flandre-m5p/hardware-configuration.nix b/nixos/hosts/flandre-m5p/hardware-configuration.nix new file mode 100644 index 0000000..d67d029 --- /dev/null +++ b/nixos/hosts/flandre-m5p/hardware-configuration.nix @@ -0,0 +1,26 @@ +{ ... }: +{ + boot = { + initrd.availableKernelModules = [ + "xhci_pci" + "ahci" + "usbhid" + "usb_storage" + "sd_mod" + ]; + kernelModules = [ "kvm-amd" ]; + loader = { + efi.canTouchEfiVariables = false; + systemd-boot.enable = true; + }; + }; + + networking.wireless.iwd.enable = true; + + hardware = { + amdgpu.initrd.enable = true; + cpu.amd.updateMicrocode = true; + enableRedistributableFirmware = true; + graphics.enable = true; + }; +} diff --git a/nixos/hosts/flandre-m5p/networking.nix b/nixos/hosts/flandre-m5p/networking.nix new file mode 100644 index 0000000..5d3def0 --- /dev/null +++ b/nixos/hosts/flandre-m5p/networking.nix @@ -0,0 +1,67 @@ +{ profiles, lib, ... }: +{ + imports = with profiles; [ + services.enthalpy + ]; + + services.enthalpy.ipsec.interfaces = [ "enp2s0" ]; + + systemd.network = { + enable = true; + wait-online.anyInterface = true; + config = { + networkConfig = { + IPv4Forwarding = true; + IPv6Forwarding = true; + }; + }; + networks = { + "30-enp1s0" = { + matchConfig.Name = "enp1s0"; + networkConfig = { + DHCPServer = "yes"; + IPv6SendRA = "yes"; + IPv6PrivacyExtensions = true; + IPv6AcceptRA = "no"; + KeepConfiguration = true; + }; + dhcpServerConfig = { + ServerAddress = "100.64.0.1/20"; + EmitDNS = true; + }; + ipv6Prefixes = lib.singleton { + Prefix = "fdce:2962:c3c1:130c::/64"; + Assign = true; + }; + }; + "30-enp2s0" = { + matchConfig.Name = "enp2s0"; + networkConfig = { + DHCP = "yes"; + IPv6AcceptRA = true; + IPv6PrivacyExtensions = true; + KeepConfiguration = true; + }; + dhcpV4Config.RouteMetric = 1024; + dhcpV6Config.RouteMetric = 1024; + ipv6AcceptRAConfig.RouteMetric = 1024; + }; + }; + }; + + networking.nftables.tables.nat = { + family = "inet"; + content = '' + chain input { + type filter hook input priority mangle; policy accept; + iifname enp2s0 tcp dport { http, https } counter drop + iifname enp2s0 udp dport { http, https } counter drop + } + + chain postrouting { + type nat hook postrouting priority srcnat; policy accept; + oifname enp2s0 counter masquerade + } + ''; + }; +} diff --git a/nixos/hosts/marisa-7d76/default.nix b/nixos/hosts/marisa-7d76/default.nix new file mode 100644 index 0000000..f13313c --- /dev/null +++ b/nixos/hosts/marisa-7d76/default.nix @@ -0,0 +1,31 @@ +{ + suites, + profiles, + mylib, + ... +}: +{ + imports = + suites.workstation + ++ [ + profiles.system.boot.binfmt + profiles.system.boot.secure-boot + profiles.users.rebmit + ] + ++ (mylib.path.scanPaths ./. "default.nix"); + + home-manager.users.rebmit = + { suites, profiles, ... }: + { + imports = suites.desktop-workstation ++ [ + profiles.syncthing + ]; + + programs.niri.settings = { + input.tablet.map-to-output = "HDMI-A-1"; + outputs."HDMI-A-1".scale = 1.75; + }; + }; + + system.stateVersion = "24.05"; +} diff --git a/nixos/hosts/marisa-7d76/disko-fs.nix b/nixos/hosts/marisa-7d76/disko-fs.nix new file mode 100644 index 0000000..6ebeccf --- /dev/null +++ b/nixos/hosts/marisa-7d76/disko-fs.nix @@ -0,0 +1,81 @@ +{ + disko.devices = { + nodev = { + "/" = { + fsType = "tmpfs"; + mountOptions = [ + "defaults" + "size=8G" + "mode=755" + "nosuid" + "nodev" + ]; + }; + }; + disk = { + main = { + type = "disk"; + device = "/dev/disk/by-path/pci-0000:04:00.0-nvme-1"; + content = { + type = "gpt"; + partitions = { + esp = { + label = "ESP"; + size = "2G"; + type = "EF00"; + content = { + type = "filesystem"; + format = "vfat"; + mountpoint = "/boot"; + mountOptions = [ "umask=0077" ]; + }; + }; + cryptroot = { + label = "CRYPTROOT"; + size = "100%"; + content = { + type = "luks"; + name = "cryptroot"; + settings = { + allowDiscards = true; + bypassWorkqueues = true; + crypttabExtraOpts = [ + "same-cpu-crypt" + "submit-from-crypt-cpus" + ]; + }; + content = { + type = "btrfs"; + extraArgs = [ "-f" ]; + subvolumes = { + "/persist" = { + mountpoint = "/persist"; + mountOptions = [ "compress=zstd" ]; + }; + "/nix" = { + mountpoint = "/nix"; + mountOptions = [ "compress=zstd" ]; + }; + }; + }; + }; + }; + }; + }; + }; + }; + }; + + fileSystems."/persist".neededForBoot = true; + + environment.globalPersistence = { + enable = true; + root = "/persist"; + }; + + services.btrfs.autoScrub = { + enable = true; + interval = "weekly"; + fileSystems = [ "/persist" ]; + }; +} diff --git a/nixos/hosts/marisa-7d76/hardware-configuration.nix b/nixos/hosts/marisa-7d76/hardware-configuration.nix new file mode 100644 index 0000000..2fdd50c --- /dev/null +++ b/nixos/hosts/marisa-7d76/hardware-configuration.nix @@ -0,0 +1,34 @@ +{ lib, ... }: +{ + boot = { + initrd.availableKernelModules = [ + "nvme" + "ahci" + "xhci_pci" + "usbhid" + "sd_mod" + ]; + kernelModules = [ "kvm-amd" ]; + loader = { + efi.canTouchEfiVariables = true; + systemd-boot.enable = lib.mkDefault true; + }; + }; + + networking.wireless.iwd.enable = true; + + hardware = { + amdgpu.initrd.enable = true; + cpu.amd.updateMicrocode = true; + enableRedistributableFirmware = true; + graphics.enable = true; + }; + + services = { + udev.extraHwdb = '' + evdev:input:b*v046Dp4089* + KEYBOARD_KEY_70039=esc + KEYBOARD_KEY_70029=capslock + ''; + }; +} diff --git a/nixos/hosts/marisa-7d76/networking.nix b/nixos/hosts/marisa-7d76/networking.nix new file mode 100644 index 0000000..044c147 --- /dev/null +++ b/nixos/hosts/marisa-7d76/networking.nix @@ -0,0 +1,46 @@ +{ profiles, lib, ... }: +{ + imports = with profiles; [ + services.enthalpy + ]; + + services.enthalpy = { + ipsec.interfaces = [ "enp14s0" ]; + sing-box = { + enable = true; + clat = { + enable = true; + segment = lib.singleton "fde3:3be3:a244:2676::2"; + }; + }; + }; + + systemd.network = { + enable = true; + wait-online.anyInterface = true; + networks = { + "30-enp14s0" = { + matchConfig.Name = "enp14s0"; + networkConfig = { + DHCP = "yes"; + IPv6AcceptRA = true; + IPv6PrivacyExtensions = true; + }; + dhcpV4Config.RouteMetric = 1024; + dhcpV6Config.RouteMetric = 1024; + ipv6AcceptRAConfig.RouteMetric = 1024; + }; + "40-wlan0" = { + matchConfig.Name = "wlan0"; + networkConfig = { + DHCP = "yes"; + IPv6AcceptRA = true; + IPv6PrivacyExtensions = true; + }; + dhcpV4Config.RouteMetric = 2048; + dhcpV6Config.RouteMetric = 2048; + ipv6AcceptRAConfig.RouteMetric = 2048; + }; + }; + }; +} diff --git a/nixos/hosts/marisa-a7s/default.nix b/nixos/hosts/marisa-a7s/default.nix new file mode 100644 index 0000000..1221de1 --- /dev/null +++ b/nixos/hosts/marisa-a7s/default.nix @@ -0,0 +1,30 @@ +{ + suites, + profiles, + mylib, + ... +}: +{ + imports = + suites.workstation + ++ [ + profiles.users.rebmit + ] + ++ (mylib.path.scanPaths ./. "default.nix"); + + home-manager.users.rebmit = + { suites, profiles, ... }: + { + imports = suites.desktop-workstation ++ [ + profiles.syncthing + ]; + + programs.niri.settings = { + outputs."eDP-1".scale = 1.2; + }; + }; + + services.power-profiles-daemon.enable = true; + + system.stateVersion = "24.05"; +} diff --git a/nixos/hosts/marisa-a7s/disko-fs.nix b/nixos/hosts/marisa-a7s/disko-fs.nix new file mode 100644 index 0000000..6ebeccf --- /dev/null +++ b/nixos/hosts/marisa-a7s/disko-fs.nix @@ -0,0 +1,81 @@ +{ + disko.devices = { + nodev = { + "/" = { + fsType = "tmpfs"; + mountOptions = [ + "defaults" + "size=8G" + "mode=755" + "nosuid" + "nodev" + ]; + }; + }; + disk = { + main = { + type = "disk"; + device = "/dev/disk/by-path/pci-0000:04:00.0-nvme-1"; + content = { + type = "gpt"; + partitions = { + esp = { + label = "ESP"; + size = "2G"; + type = "EF00"; + content = { + type = "filesystem"; + format = "vfat"; + mountpoint = "/boot"; + mountOptions = [ "umask=0077" ]; + }; + }; + cryptroot = { + label = "CRYPTROOT"; + size = "100%"; + content = { + type = "luks"; + name = "cryptroot"; + settings = { + allowDiscards = true; + bypassWorkqueues = true; + crypttabExtraOpts = [ + "same-cpu-crypt" + "submit-from-crypt-cpus" + ]; + }; + content = { + type = "btrfs"; + extraArgs = [ "-f" ]; + subvolumes = { + "/persist" = { + mountpoint = "/persist"; + mountOptions = [ "compress=zstd" ]; + }; + "/nix" = { + mountpoint = "/nix"; + mountOptions = [ "compress=zstd" ]; + }; + }; + }; + }; + }; + }; + }; + }; + }; + }; + + fileSystems."/persist".neededForBoot = true; + + environment.globalPersistence = { + enable = true; + root = "/persist"; + }; + + services.btrfs.autoScrub = { + enable = true; + interval = "weekly"; + fileSystems = [ "/persist" ]; + }; +} diff --git a/nixos/hosts/marisa-a7s/hardware-configuration.nix b/nixos/hosts/marisa-a7s/hardware-configuration.nix new file mode 100644 index 0000000..f6bd14b --- /dev/null +++ b/nixos/hosts/marisa-a7s/hardware-configuration.nix @@ -0,0 +1,36 @@ +{ lib, ... }: +{ + boot = { + initrd.availableKernelModules = [ + "nvme" + "ahci" + "xhci_pci" + ]; + kernelModules = [ "kvm-amd" ]; + loader = { + efi.canTouchEfiVariables = true; + systemd-boot.enable = lib.mkDefault true; + }; + }; + + networking.wireless.iwd.enable = true; + + hardware = { + amdgpu.initrd.enable = true; + cpu.amd.updateMicrocode = true; + enableRedistributableFirmware = true; + graphics.enable = true; + }; + + services = { + udev.extraHwdb = '' + evdev:input:b*v046Dp4089* + KEYBOARD_KEY_70039=esc + KEYBOARD_KEY_70029=capslock + + evdev:atkbd:dmi:* + KEYBOARD_KEY_3a=esc + KEYBOARD_KEY_01=capslock + ''; + }; +} diff --git a/nixos/hosts/marisa-a7s/networking.nix b/nixos/hosts/marisa-a7s/networking.nix new file mode 100644 index 0000000..3a5a8ae --- /dev/null +++ b/nixos/hosts/marisa-a7s/networking.nix @@ -0,0 +1,49 @@ +{ profiles, lib, ... }: +{ + imports = with profiles; [ + services.enthalpy + ]; + + services.enthalpy = { + ipsec = { + interfaces = [ "wlan0" ]; + whitelist = [ "rebmit's edge network" ]; + }; + sing-box = { + enable = true; + clat = { + enable = true; + segment = lib.singleton "fde3:3be3:a244:2676::2"; + }; + }; + }; + + systemd.network = { + enable = true; + wait-online.anyInterface = true; + networks = { + "30-enp3s0" = { + matchConfig.Name = "enp3s0"; + networkConfig = { + DHCP = "yes"; + IPv6AcceptRA = true; + IPv6PrivacyExtensions = true; + }; + dhcpV4Config.RouteMetric = 1024; + dhcpV6Config.RouteMetric = 1024; + ipv6AcceptRAConfig.RouteMetric = 1024; + }; + "40-wlan0" = { + matchConfig.Name = "wlan0"; + networkConfig = { + DHCP = "yes"; + IPv6AcceptRA = true; + IPv6PrivacyExtensions = true; + }; + dhcpV4Config.RouteMetric = 2048; + dhcpV6Config.RouteMetric = 2048; + ipv6AcceptRAConfig.RouteMetric = 2048; + }; + }; + }; +} diff --git a/nixos/hosts/reisen-lax0/default.nix b/nixos/hosts/reisen-lax0/default.nix new file mode 100644 index 0000000..d6d3493 --- /dev/null +++ b/nixos/hosts/reisen-lax0/default.nix @@ -0,0 +1,20 @@ +{ + suites, + mylib, + ... +}: +{ + imports = suites.server ++ (mylib.path.scanPaths ./. "default.nix"); + + services.caddy = { + enable = true; + virtualHosts."rebmit.moe".extraConfig = '' + header /.well-known/matrix/* Content-Type application/json + header /.well-known/matrix/* Access-Control-Allow-Origin * + respond /.well-known/matrix/server `{"m.server": "matrix.rebmit.moe:443"}` + respond /.well-known/matrix/client `{"m.homeserver":{"base_url":"https://matrix.rebmit.moe"}}` + ''; + }; + + system.stateVersion = "24.05"; +} diff --git a/nixos/hosts/reisen-lax0/disko-fs.nix b/nixos/hosts/reisen-lax0/disko-fs.nix new file mode 100644 index 0000000..f39b29a --- /dev/null +++ b/nixos/hosts/reisen-lax0/disko-fs.nix @@ -0,0 +1,68 @@ +{ + disko.devices = { + nodev = { + "/" = { + fsType = "tmpfs"; + mountOptions = [ + "defaults" + "size=2G" + "mode=755" + "nosuid" + "nodev" + ]; + }; + }; + disk = { + main = { + type = "disk"; + device = "/dev/vda"; + content = { + type = "gpt"; + partitions = { + boot = { + type = "EF02"; + label = "BOOT"; + start = "0"; + end = "+1M"; + }; + root = { + label = "ROOT"; + end = "-0"; + content = { + type = "btrfs"; + extraArgs = [ "-f" ]; + subvolumes = { + "boot" = { + mountpoint = "/boot"; + mountOptions = [ "compress=zstd" ]; + }; + "nix" = { + mountpoint = "/nix"; + mountOptions = [ "compress=zstd" ]; + }; + "persist" = { + mountpoint = "/persist"; + mountOptions = [ "compress=zstd" ]; + }; + }; + }; + }; + }; + }; + }; + }; + }; + + fileSystems."/persist".neededForBoot = true; + + environment.globalPersistence = { + enable = true; + root = "/persist"; + }; + + services.btrfs.autoScrub = { + enable = true; + interval = "weekly"; + fileSystems = [ "/persist" ]; + }; +} diff --git a/nixos/hosts/reisen-lax0/hardware-configuration.nix b/nixos/hosts/reisen-lax0/hardware-configuration.nix new file mode 100644 index 0000000..2d5b37c --- /dev/null +++ b/nixos/hosts/reisen-lax0/hardware-configuration.nix @@ -0,0 +1,15 @@ +{ modulesPath, ... }: +{ + imports = [ + (modulesPath + "/profiles/qemu-guest.nix") + ]; + + boot.initrd.availableKernelModules = [ + "ahci" + "sym53c8xx" + "xhci_pci" + "virtio_pci" + "sr_mod" + "virtio_blk" + ]; +} diff --git a/nixos/hosts/reisen-lax0/matrix.nix b/nixos/hosts/reisen-lax0/matrix.nix new file mode 100644 index 0000000..ddca4b2 --- /dev/null +++ b/nixos/hosts/reisen-lax0/matrix.nix @@ -0,0 +1,185 @@ +# Portions of this file are sourced from +# https://github.com/NickCao/flakes/blob/3b03efb676ea602575c916b2b8bc9d9cd13b0d85/nixos/hcloud/hio0/matrix.nix +{ + config, + pkgs, + ... +}: +let + conf = { + default_server_config = { + "m.homeserver" = { + base_url = config.services.matrix-synapse.settings.public_baseurl; + server_name = config.services.matrix-synapse.settings.server_name; + }; + }; + show_labs_settings = true; + }; +in +{ + services.postgresql = { + enable = true; + package = pkgs.postgresql_16; + }; + + services.postgresqlBackup = { + enable = true; + location = "/var/lib/backup/postgresql"; + backupAll = true; + compression = "zstd"; + }; + + sops.secrets."synapse/signing-key" = { + sopsFile = config.sops.secretFiles.get "hosts/reisen-lax0.yaml"; + owner = config.systemd.services.matrix-synapse.serviceConfig.User; + }; + + sops.secrets."synapse/mautrix-telegram" = { + sopsFile = config.sops.secretFiles.get "hosts/reisen-lax0.yaml"; + }; + + systemd.services.matrix-synapse.serviceConfig.LoadCredential = [ + "telegram:/var/lib/mautrix-telegram/telegram-registration.yaml" + "irc:/var/lib/heisenbridge/registration.yml" + ]; + + services.matrix-synapse = { + enable = true; + withJemalloc = true; + settings = { + server_name = "rebmit.moe"; + public_baseurl = "https://matrix.rebmit.moe"; + signing_key_path = config.sops.secrets."synapse/signing-key".path; + + app_service_config_files = [ + "/run/credentials/matrix-synapse.service/telegram" + "/run/credentials/matrix-synapse.service/irc" + ]; + + enable_registration = true; + registration_requires_token = true; + + listeners = [ + { + bind_addresses = [ "127.0.0.1" ]; + port = 8196; + tls = false; + type = "http"; + x_forwarded = true; + resources = [ + { + compress = true; + names = [ + "client" + "federation" + ]; + } + ]; + } + ]; + + media_retention = { + remote_media_lifetime = "14d"; + }; + + experimental_features = { + # Room summary api + msc3266_enabled = true; + # Removing account data + msc3391_enabled = true; + # Thread notifications + msc3773_enabled = true; + # Remotely toggle push notifications for another client + msc3881_enabled = true; + # Remotely silence local notifications + msc3890_enabled = true; + }; + }; + }; + + systemd.services.mautrix-telegram.serviceConfig.RuntimeMaxSec = 86400; + + services.mautrix-telegram = { + enable = true; + environmentFile = config.sops.secrets."synapse/mautrix-telegram".path; + serviceDependencies = [ "matrix-synapse.service" ]; + settings = { + homeserver = { + address = "http://127.0.0.1:8196"; + domain = config.services.matrix-synapse.settings.server_name; + }; + appservice = { + address = "http://127.0.0.1:29317"; + database = "postgres:///mautrix-telegram?host=/run/postgresql"; + hostname = "127.0.0.1"; + port = 29317; + provisioning.enabled = false; + }; + bridge = { + displayname_template = "{displayname}"; + public_portals = true; + delivery_error_reports = true; + incoming_bridge_error_reports = true; + bridge_matrix_leave = false; + relay_user_distinguishers = [ ]; + create_group_on_invite = false; + encryption = { + allow = true; + default = true; + }; + animated_sticker = { + target = "webp"; + convert_from_webm = true; + }; + state_event_formats = { + join = ""; + leave = ""; + name_change = ""; + }; + permissions = { + "*" = "relaybot"; + "@i:rebmit.moe" = "admin"; + }; + relaybot = { + authless_portals = false; + }; + }; + telegram = { + device_info = { + app_version = "3.5.2"; + }; + }; + logging = { + loggers = { + mau.level = "INFO"; + telethon.level = "INFO"; + }; + }; + }; + }; + + services.heisenbridge = { + enable = true; + homeserver = "http://127.0.0.1:8196"; + address = "127.0.0.1"; + port = 9898; + owner = "@i:rebmit.moe"; + }; + + services.caddy = { + virtualHosts."matrix.rebmit.moe".extraConfig = '' + reverse_proxy /_matrix/* 127.0.0.1:8196 + reverse_proxy /_synapse/client/* 127.0.0.1:8196 + + header { + X-Frame-Options SAMEORIGIN + X-Content-Type-Options nosniff + X-XSS-Protection "1; mode=block" + Content-Security-Policy "frame-ancestors 'self'" + } + + file_server + root * "${pkgs.element-web.override { inherit conf; }}" + ''; + }; +} diff --git a/nixos/hosts/reisen-lax0/networking.nix b/nixos/hosts/reisen-lax0/networking.nix new file mode 100644 index 0000000..972bb9c --- /dev/null +++ b/nixos/hosts/reisen-lax0/networking.nix @@ -0,0 +1,21 @@ +{ ... }: +{ + systemd.network = { + enable = true; + wait-online.anyInterface = true; + networks = { + "30-enp3s0" = { + matchConfig.Name = "enp3s0"; + networkConfig = { + DHCP = "yes"; + IPv6AcceptRA = true; + IPv6PrivacyExtensions = false; + KeepConfiguration = true; + }; + dhcpV4Config.RouteMetric = 1024; + dhcpV6Config.RouteMetric = 1024; + ipv6AcceptRAConfig.RouteMetric = 1024; + }; + }; + }; +} diff --git a/nixos/hosts/reisen-sin0/default.nix b/nixos/hosts/reisen-sin0/default.nix new file mode 100644 index 0000000..4a01360 --- /dev/null +++ b/nixos/hosts/reisen-sin0/default.nix @@ -0,0 +1,10 @@ +{ + suites, + mylib, + ... +}: +{ + imports = suites.server ++ (mylib.path.scanPaths ./. "default.nix"); + + system.stateVersion = "24.05"; +} diff --git a/nixos/hosts/reisen-sin0/disko-fs.nix b/nixos/hosts/reisen-sin0/disko-fs.nix new file mode 100644 index 0000000..419a1e9 --- /dev/null +++ b/nixos/hosts/reisen-sin0/disko-fs.nix @@ -0,0 +1,68 @@ +{ + disko.devices = { + nodev = { + "/" = { + fsType = "tmpfs"; + mountOptions = [ + "defaults" + "size=1G" + "mode=755" + "nosuid" + "nodev" + ]; + }; + }; + disk = { + main = { + type = "disk"; + device = "/dev/vda"; + content = { + type = "gpt"; + partitions = { + boot = { + type = "EF02"; + label = "BOOT"; + start = "0"; + end = "+1M"; + }; + root = { + label = "ROOT"; + end = "-0"; + content = { + type = "btrfs"; + extraArgs = [ "-f" ]; + subvolumes = { + "boot" = { + mountpoint = "/boot"; + mountOptions = [ "compress=zstd" ]; + }; + "nix" = { + mountpoint = "/nix"; + mountOptions = [ "compress=zstd" ]; + }; + "persist" = { + mountpoint = "/persist"; + mountOptions = [ "compress=zstd" ]; + }; + }; + }; + }; + }; + }; + }; + }; + }; + + fileSystems."/persist".neededForBoot = true; + + environment.globalPersistence = { + enable = true; + root = "/persist"; + }; + + services.btrfs.autoScrub = { + enable = true; + interval = "weekly"; + fileSystems = [ "/persist" ]; + }; +} diff --git a/nixos/hosts/reisen-sin0/hardware-configuration.nix b/nixos/hosts/reisen-sin0/hardware-configuration.nix new file mode 100644 index 0000000..2d5b37c --- /dev/null +++ b/nixos/hosts/reisen-sin0/hardware-configuration.nix @@ -0,0 +1,15 @@ +{ modulesPath, ... }: +{ + imports = [ + (modulesPath + "/profiles/qemu-guest.nix") + ]; + + boot.initrd.availableKernelModules = [ + "ahci" + "sym53c8xx" + "xhci_pci" + "virtio_pci" + "sr_mod" + "virtio_blk" + ]; +} diff --git a/nixos/hosts/reisen-sin0/networking.nix b/nixos/hosts/reisen-sin0/networking.nix new file mode 100644 index 0000000..fdc7a49 --- /dev/null +++ b/nixos/hosts/reisen-sin0/networking.nix @@ -0,0 +1,51 @@ +{ profiles, ... }: +{ + imports = with profiles; [ + services.enthalpy + ]; + + services.enthalpy = { + ipsec.interfaces = [ "enp3s0" ]; + exit = { + enable = true; + prefix = [ "::/0" ]; + }; + srv6.enable = true; + nat64.enable = true; + }; + + networking.nftables.tables.nat = { + family = "inet"; + content = '' + chain postrouting { + type nat hook postrouting priority srcnat; policy accept; + oifname enp3s0 counter masquerade + } + ''; + }; + + systemd.network = { + enable = true; + wait-online.anyInterface = true; + config = { + networkConfig = { + IPv4Forwarding = true; + IPv6Forwarding = true; + }; + }; + networks = { + "30-enp3s0" = { + matchConfig.Name = "enp3s0"; + networkConfig = { + DHCP = "yes"; + IPv6AcceptRA = true; + IPv6PrivacyExtensions = false; + KeepConfiguration = true; + }; + dhcpV4Config.RouteMetric = 1024; + dhcpV6Config.RouteMetric = 1024; + ipv6AcceptRAConfig.RouteMetric = 1024; + }; + }; + }; +} diff --git a/nixos/modules/networking/ports.nix b/nixos/modules/networking/ports.nix new file mode 100644 index 0000000..57123aa --- /dev/null +++ b/nixos/modules/networking/ports.nix @@ -0,0 +1,31 @@ +{ config, lib, ... }: +with lib; +let + cfg = config.networking.ports; + noCollision = l: length (unique l) == length l; +in +{ + options.networking.ports = mkOption { + type = with types; attrsOf port; + default = { + http = 80; + https = 443; + ssh = 2222; + + # enthalpy + sing-box = 1080; + enthalpy-ipsec = 13000; + }; + readOnly = true; + description = '' + A mapping of network ports, each identified by a unique name. + ''; + }; + + config = { + assertions = singleton { + assertion = noCollision (attrValues cfg); + message = "port collision"; + }; + }; +} diff --git a/nixos/modules/networking/routing-tables.nix b/nixos/modules/networking/routing-tables.nix new file mode 100644 index 0000000..aa96c83 --- /dev/null +++ b/nixos/modules/networking/routing-tables.nix @@ -0,0 +1,95 @@ +{ + config, + lib, + ... +}: +with lib; +let + cfg = config.networking; + noCollision = l: length (unique l) == length l; + reservedTables = [ + "local" + "main" + "default" + "unspec" + ]; +in +{ + options.networking = { + routingTables = mkOption { + type = with types; attrsOf int; + default = { + # reserved + unspec = 0; + default = 253; + main = 254; + local = 255; + + # enthalpy + localsid = 300; + nat64 = 301; + sing-box = 302; + }; + readOnly = true; + description = '' + A mapping of routing tables, each identified by a unique name. + ''; + }; + routingMarks = mkOption { + type = with types; attrsOf int; + default = { + # enthalpy + sing-box = 1300; + }; + readOnly = true; + description = '' + A mapping of routing marks, each identified by a unique name. + ''; + }; + routingPolicyPriorities = mkOption { + type = with types; attrsOf int; + default = { + # reserved + local = 0; + main = 32766; + default = 32767; + + # enthalpy + localsid = 500; + sing-box = 13000; + }; + readOnly = true; + description = '' + A set of priorities for routing policies. + ''; + }; + }; + + config = { + assertions = [ + { + assertion = noCollision (attrValues cfg.routingTables); + message = "routing table id collision"; + } + { + assertion = noCollision (attrValues cfg.routingMarks); + message = "routing mark id collision"; + } + { + assertion = noCollision (attrValues cfg.routingPolicyPriorities); + message = "routing policy priority collision"; + } + ]; + + environment.etc."iproute2/rt_tables.d/routing_tables.conf" = { + mode = "0644"; + text = '' + ${concatStringsSep "\n" ( + mapAttrsToList (name: table: "${toString table} ${name}") ( + filterAttrs (name: _table: !(lib.elem name reservedTables)) cfg.routingTables + ) + )} + ''; + }; + }; +} diff --git a/nixos/modules/services/enthalpy/bird.nix b/nixos/modules/services/enthalpy/bird.nix new file mode 100644 index 0000000..2f921bb --- /dev/null +++ b/nixos/modules/services/enthalpy/bird.nix @@ -0,0 +1,127 @@ +# Portions of this file are sourced from +# https://github.com/NickCao/flakes/blob/3b03efb676ea602575c916b2b8bc9d9cd13b0d85/modules/gravity/default.nix +{ + config, + lib, + pkgs, + ... +}: +with lib; +let + cfg = config.services.enthalpy; +in +{ + options.services.enthalpy.bird = { + enable = mkEnableOption "bird for site-scope connectivity"; + socket = mkOption { + type = types.str; + default = "/run/enthalpy/bird.ctl"; + description = '' + Path to the bird control socket. + ''; + }; + config = mkOption { + type = types.lines; + description = '' + Configuration file for bird. + ''; + }; + checkConfig = mkOption { + type = types.bool; + default = true; + description = '' + Whether to check the config at build time. + ''; + }; + routerId = mkOption { + type = types.int; + description = '' + Router ID for the bird instance. + ''; + }; + }; + + config = mkIf (cfg.enable && cfg.bird.enable) { + environment.etc."enthalpy/bird2.conf".source = pkgs.writeTextFile { + name = "bird2"; + text = cfg.bird.config; + checkPhase = optionalString cfg.bird.checkConfig '' + ln -s $out bird2.conf + ${pkgs.buildPackages.bird}/bin/bird -d -p -c bird2.conf + ''; + }; + + systemd.services.enthalpy-bird2 = { + serviceConfig = { + NetworkNamespacePath = "/run/netns/${cfg.netns}"; + Type = "forking"; + Restart = "on-failure"; + RestartSec = 5; + DynamicUser = true; + RuntimeDirectory = "enthalpy"; + ExecStart = "${pkgs.bird}/bin/bird -s ${cfg.bird.socket} -c /etc/enthalpy/bird2.conf"; + ExecReload = "${pkgs.bird}/bin/birdc -s ${cfg.bird.socket} configure"; + ExecStop = "${pkgs.bird}/bin/birdc -s ${cfg.bird.socket} down"; + CapabilityBoundingSet = [ + "CAP_NET_ADMIN" + "CAP_NET_BIND_SERVICE" + "CAP_NET_RAW" + ]; + AmbientCapabilities = [ + "CAP_NET_ADMIN" + "CAP_NET_BIND_SERVICE" + "CAP_NET_RAW" + ]; + ProtectSystem = "full"; + ProtectHome = "yes"; + ProtectKernelTunables = true; + ProtectControlGroups = true; + PrivateTmp = true; + PrivateDevices = true; + SystemCallFilter = "~@cpu-emulation @debug @keyring @module @mount @obsolete @raw-io"; + MemoryDenyWriteExecute = "yes"; + }; + partOf = [ "enthalpy.service" ]; + after = [ "enthalpy.service" ]; + requires = [ "enthalpy.service" ]; + requiredBy = [ "enthalpy.service" ]; + wantedBy = [ "multi-user.target" ]; + reloadTriggers = [ config.environment.etc."enthalpy/bird2.conf".source ]; + }; + + services.enthalpy.bird.config = mkBefore '' + router id ${toString cfg.bird.routerId}; + ipv6 sadr table sadr6; + protocol device { + scan time 5; + } + protocol kernel { + ipv6 sadr { + export all; + import none; + }; + metric 512; + } + protocol static { + ipv6 sadr; + route ${cfg.prefix} from ::/0 unreachable; + route ${cfg.network} from ::/0 unreachable; + }; + protocol babel { + ipv6 sadr { + export all; + import all; + }; + randomize router id; + interface "enta*" { + type tunnel; + rxcost 32; + hello interval 20 s; + rtt cost 1024; + rtt max 1024 ms; + rx buffer 2000; + }; + } + ''; + }; +} diff --git a/nixos/modules/services/enthalpy/common.nix b/nixos/modules/services/enthalpy/common.nix new file mode 100644 index 0000000..586ee38 --- /dev/null +++ b/nixos/modules/services/enthalpy/common.nix @@ -0,0 +1,85 @@ +# Portions of this file are sourced from +# https://github.com/NickCao/flakes/blob/882da114b98389121d98d909f115d49d9af6613e/modules/gravity.nix +{ + config, + lib, + pkgs, + mylib, + ... +}: +with lib; +let + inherit (mylib.network) cidr; + cfg = config.services.enthalpy; +in +{ + options.services.enthalpy = { + enable = mkEnableOption "enthalpy overlay network"; + prefix = mkOption { + type = types.str; + description = '' + Prefix to be announced for the local node. + ''; + }; + netns = mkOption { + type = types.str; + default = "enthalpy"; + description = '' + Name of the network namespace for interfaces. + ''; + }; + interface = mkOption { + type = types.str; + default = "enthalpy"; + description = '' + Name of the interface to connect to the network namespace. + ''; + }; + network = mkOption { + type = types.str; + description = '' + Prefix of the enthalpy network. + ''; + }; + }; + + config = mkIf cfg.enable { + systemd.services.enthalpy = { + path = with pkgs; [ + iproute2 + coreutils + procps + ]; + script = '' + ip netns add ${cfg.netns} + ip link add ${cfg.interface} mtu 1400 address 02:00:00:00:00:01 type veth peer enthalpy mtu 1400 address 02:00:00:00:00:00 netns ${cfg.netns} + ip link set ${cfg.interface} up + ip -n ${cfg.netns} link set lo up + ip -n ${cfg.netns} link set enthalpy up + ip -n ${cfg.netns} addr add ${cidr.host 0 cfg.prefix}/127 dev enthalpy + ip netns exec ${cfg.netns} sysctl -w net.ipv6.conf.default.forwarding=1 + ip netns exec ${cfg.netns} sysctl -w net.ipv6.conf.all.forwarding=1 + ''; + preStop = '' + ip link del ${cfg.interface} + ip netns del ${cfg.netns} + ''; + serviceConfig = { + Type = "oneshot"; + RemainAfterExit = true; + }; + wants = [ "network-online.target" ]; + after = [ "network-online.target" ]; + wantedBy = [ "multi-user.target" ]; + }; + + systemd.network.networks."50-enthalpy" = { + matchConfig.Name = cfg.interface; + networkConfig.Address = "${cidr.host 1 cfg.prefix}/127"; + routes = singleton { + Destination = cfg.network; + Gateway = "fe80::ff:fe00:0"; + }; + }; + }; +} diff --git a/nixos/modules/services/enthalpy/exit.nix b/nixos/modules/services/enthalpy/exit.nix new file mode 100644 index 0000000..b837bc2 --- /dev/null +++ b/nixos/modules/services/enthalpy/exit.nix @@ -0,0 +1,63 @@ +# Portions of this file are sourced from +# https://github.com/NickCao/flakes/blob/3b03efb676ea602575c916b2b8bc9d9cd13b0d85/modules/gravity/default.nix +{ + config, + lib, + pkgs, + mylib, + ... +}: +with lib; +let + inherit (mylib.network) cidr; + cfg = config.services.enthalpy; + internalPrefix = filter (p: cidr.child p cfg.prefix) cfg.exit.prefix; + externalPrefix = subtractLists internalPrefix cfg.exit.prefix; +in +{ + options.services.enthalpy.exit = { + enable = mkEnableOption "netns route leaking"; + prefix = mkOption { + type = types.listOf types.str; + default = [ ]; + description = '' + Prefixes to be announced from the default netns to the enthalpy network. + ''; + }; + }; + + config = mkIf (cfg.enable && cfg.exit.enable) { + services.enthalpy.bird.config = '' + protocol static { + ipv6 sadr; + ${ + concatMapStringsSep "\n" (p: '' + route ${p} from ${cfg.network} via fe80::ff:fe00:1 dev "enthalpy"; + '') externalPrefix + } + } + ''; + + systemd.services.enthalpy-exit = + let + routes = map (p: "${p} via fe80::ff:fe00:1 dev enthalpy") internalPrefix; + in + mkIf (routes != [ ]) { + serviceConfig = { + Type = "oneshot"; + RemainAfterExit = true; + ExecStart = builtins.map (route: "${pkgs.iproute2}/bin/ip -n ${cfg.netns} -6 r a ${route}") routes; + ExecStop = builtins.map (route: "${pkgs.iproute2}/bin/ip -n ${cfg.netns} -6 r d ${route}") routes; + }; + partOf = [ "enthalpy.service" ]; + after = [ + "enthalpy.service" + "network-online.target" + ]; + requires = [ "enthalpy.service" ]; + requiredBy = [ "enthalpy.service" ]; + wants = [ "network-online.target" ]; + wantedBy = [ "multi-user.target" ]; + }; + }; +} diff --git a/nixos/modules/services/enthalpy/ipsec.nix b/nixos/modules/services/enthalpy/ipsec.nix new file mode 100644 index 0000000..2bae02c --- /dev/null +++ b/nixos/modules/services/enthalpy/ipsec.nix @@ -0,0 +1,204 @@ +# Portions of this file are sourced from +# https://github.com/NickCao/flakes/blob/3b03efb676ea602575c916b2b8bc9d9cd13b0d85/modules/gravity/default.nix +{ + config, + lib, + pkgs, + ... +}: +with lib; +let + cfg = config.services.enthalpy; +in +{ + options.services.enthalpy.ipsec = { + enable = mkEnableOption "IPSec/IKEv2 for link-scope connectivity"; + organization = mkOption { + type = types.str; + description = '' + Unique identifier of a keypair. + ''; + }; + commonName = mkOption { + type = types.str; + description = '' + Name of this node, should be unique within an organization. + ''; + }; + endpoints = mkOption { + type = types.listOf ( + types.submodule { + options = { + serialNumber = mkOption { type = types.str; }; + addressFamily = mkOption { type = types.str; }; + address = mkOption { + type = types.nullOr types.str; + default = null; + }; + }; + } + ); + description = '' + List of endpoints available on this node. + ''; + }; + port = mkOption { + type = types.port; + default = config.networking.ports.enthalpy-ipsec; + readOnly = true; + description = '' + UDP port used by IKEv2. NAT-T is enabled by default. + ''; + }; + interfaces = mkOption { + type = types.listOf types.str; + default = [ ]; + description = '' + List of network interfaces that should be used by charon daemon. + ''; + }; + privateKeyPath = mkOption { + type = types.str; + description = '' + Path to the private key of this organization. + ''; + }; + registry = mkOption { + type = types.path; + description = '' + Path to the registry. + ''; + }; + blacklist = mkOption { + type = types.nullOr (types.listOf types.str); + default = null; + description = '' + A list of organizations that are blacklisted. + ''; + }; + whitelist = mkOption { + type = types.nullOr (types.listOf types.str); + default = null; + description = '' + A list of organizations that are whitelisted. + ''; + }; + }; + + config = mkIf (cfg.enable && cfg.ipsec.enable) { + assertions = [ + { + assertion = builtins.all (lib.id) [ + (cfg.ipsec.blacklist != null -> cfg.ipsec.whitelist == null) + (cfg.ipsec.whitelist != null -> cfg.ipsec.blacklist == null) + ]; + message = '' + Only one of `config.services.enthalpy.ipsec.blacklist` or + `config.services.enthalpy.ipsec.whitelist` can be defined at a time. + ''; + } + ]; + + environment.systemPackages = with pkgs; [ strongswan ]; + + environment.etc."ranet/config.json".source = (pkgs.formats.json { }).generate "config.json" { + organization = cfg.ipsec.organization; + common_name = cfg.ipsec.commonName; + endpoints = builtins.map (ep: { + serial_number = ep.serialNumber; + address_family = ep.addressFamily; + address = ep.address; + port = cfg.ipsec.port; + updown = pkgs.writeShellScript "updown" '' + LINK=enta$(printf '%08x\n' "$PLUTO_IF_ID_OUT") + case "$PLUTO_VERB" in + up-client) + ip link add "$LINK" type xfrm if_id "$PLUTO_IF_ID_OUT" + ip link set "$LINK" netns ${cfg.netns} multicast on mtu 1400 up + ;; + down-client) + ip -n ${cfg.netns} link del "$LINK" + ;; + esac + ''; + }) cfg.ipsec.endpoints; + }; + + services.strongswan-swanctl = { + enable = true; + strongswan.extraConfig = '' + charon { + interfaces_use = ${strings.concatStringsSep "," cfg.ipsec.interfaces} + port = 0 + port_nat_t = ${toString cfg.ipsec.port} + retransmit_base = 1 + plugins { + socket-default { + set_source = yes + set_sourceif = yes + } + dhcp { + load = no + } + } + } + charon-systemd { + journal { + default = -1 + ike = 0 + } + } + ''; + }; + + systemd.services.enthalpy-ipsec = + let + registry = + if cfg.ipsec.whitelist != null then + pkgs.runCommand "filtered-registry" { } '' + ${pkgs.jq}/bin/jq "[.[] | select(.organization | IN(${ + concatMapStringsSep "," (org: "\\\"${org}\\\"") cfg.ipsec.whitelist + }))]" ${cfg.ipsec.registry} > $out + '' + else if cfg.ipsec.blacklist != null then + pkgs.runCommand "filtered-registry" { } '' + ${pkgs.jq}/bin/jq "[.[] | select(.organization | IN(${ + concatMapStringsSep "," (org: "\\\"${org}\\\"") cfg.ipsec.blacklist + }) | not)]" ${cfg.ipsec.registry} > $out + '' + else + cfg.ipsec.registry; + command = "ranet -c /etc/ranet/config.json -r ${registry} -k ${cfg.ipsec.privateKeyPath}"; + in + { + path = with pkgs; [ + iproute2 + ranet + ]; + script = "${command} up"; + reload = "${command} up"; + preStop = "${command} down"; + serviceConfig = { + Type = "oneshot"; + RemainAfterExit = true; + }; + bindsTo = [ + "strongswan-swanctl.service" + ]; + wants = [ + "network-online.target" + "strongswan-swanctl.service" + ]; + requires = [ + "enthalpy.service" + ]; + after = [ + "network-online.target" + "strongswan-swanctl.service" + "enthalpy.service" + ]; + wantedBy = [ "multi-user.target" ]; + reloadTriggers = [ config.environment.etc."ranet/config.json".source ]; + }; + }; +} diff --git a/nixos/modules/services/enthalpy/nat64.nix b/nixos/modules/services/enthalpy/nat64.nix new file mode 100644 index 0000000..68a7f92 --- /dev/null +++ b/nixos/modules/services/enthalpy/nat64.nix @@ -0,0 +1,92 @@ +# Portions of this file are sourced from +# https://github.com/NickCao/flakes/blob/3b03efb676ea602575c916b2b8bc9d9cd13b0d85/modules/gravity/default.nix +{ + config, + lib, + pkgs, + ... +}: +with lib; +let + cfg = config.services.enthalpy; +in +{ + options.services.enthalpy.nat64 = { + enable = mkEnableOption "NAT64"; + table = mkOption { + type = types.int; + default = config.networking.routingTables.nat64; + readOnly = true; + description = '' + Routing table used for NAT64 entries. + ''; + }; + prefix = mkOption { + type = types.str; + default = "64:ff9b::/96"; + description = '' + IPv6 prefix used for NAT64 translation in the network. + ''; + }; + dynamicPool = mkOption { + type = types.str; + default = "100.127.0.0/16"; + description = '' + IPv4 address prefix allocated for dynamic IP assignment. + ''; + }; + }; + + config = mkIf (cfg.enable && cfg.nat64.enable) { + systemd.network.config = { + networkConfig = { + IPv6Forwarding = true; + ManageForeignRoutes = false; + }; + }; + + systemd.network.networks."70-nat64" = { + matchConfig.Name = "nat64"; + routes = [ + { + Destination = cfg.nat64.prefix; + Table = cfg.nat64.table; + } + { Destination = cfg.nat64.dynamicPool; } + ]; + networkConfig.LinkLocalAddressing = false; + linkConfig.RequiredForOnline = false; + }; + + systemd.services.enthalpy-nat64 = { + serviceConfig = { + ExecStart = "${pkgs.tayga}/bin/tayga -d --config ${pkgs.writeText "tayga.conf" '' + tun-device nat64 + ipv6-addr fc00:: + ipv4-addr 100.127.0.1 + prefix ${cfg.nat64.prefix} + dynamic-pool ${cfg.nat64.dynamicPool} + ''}"; + }; + partOf = [ "enthalpy.service" ]; + after = [ + "enthalpy.service" + "network.target" + ]; + requires = [ "enthalpy.service" ]; + requiredBy = [ "enthalpy.service" ]; + wantedBy = [ "multi-user.target" ]; + }; + + networking.nftables.enable = true; + networking.nftables.tables.enthalpy4 = { + family = "ip"; + content = '' + chain forward { + type filter hook forward priority 0; + tcp flags syn tcp option maxseg size set 1200 + } + ''; + }; + }; +} diff --git a/nixos/modules/services/enthalpy/sing-box.nix b/nixos/modules/services/enthalpy/sing-box.nix new file mode 100644 index 0000000..a1d37d6 --- /dev/null +++ b/nixos/modules/services/enthalpy/sing-box.nix @@ -0,0 +1,232 @@ +# Portions of this file are sourced from +# https://github.com/NickCao/flakes/blob/3b03efb676ea602575c916b2b8bc9d9cd13b0d85/nixos/mainframe/gravity.nix +{ + config, + lib, + pkgs, + mylib, + ... +}: +with lib; +let + inherit (mylib.network) cidr; + cfg = config.services.enthalpy; +in +{ + options.services.enthalpy.sing-box = { + enable = mkEnableOption "sing-box universal proxy platform"; + tableName = mkOption { + type = types.str; + default = "sing-box"; + readOnly = true; + description = '' + Routing table used for sing-box. + ''; + }; + table = mkOption { + type = types.int; + default = config.networking.routingTables."${cfg.sing-box.tableName}"; + readOnly = true; + description = '' + Routing table ID associated with the sing-box routing table. + ''; + }; + priority = mkOption { + type = types.int; + default = config.networking.routingPolicyPriorities."${cfg.sing-box.tableName}"; + readOnly = true; + description = '' + Routing priority assigned to the sing-box routing table. + ''; + }; + fwmark = mkOption { + type = types.int; + default = config.networking.routingMarks."${cfg.sing-box.tableName}"; + readOnly = true; + description = '' + Firewall mark designated for the sing-box routing table. + ''; + }; + port = mkOption { + type = types.int; + default = config.networking.ports.sing-box; + readOnly = true; + description = '' + Port for the mixed proxy to listen on. + ''; + }; + clat = { + enable = mkEnableOption "464XLAT for IPv4 connectivity"; + address = mkOption { + type = types.str; + default = cidr.host 2 cfg.prefix; + description = '' + IPv6 address used for 464XLAT as the mapped source address. + ''; + }; + segment = mkOption { + type = types.listOf types.str; + description = '' + SRv6 segments used for NAT64. + ''; + }; + }; + }; + + config = mkIf (cfg.enable && cfg.sing-box.enable) (mkMerge [ + # IPv6 + { + systemd.network.networks."50-enthalpy" = { + routes = [ + { + Destination = "::/0"; + Gateway = "fe80::ff:fe00:0"; + Table = cfg.sing-box.table; + Metric = 1024; + } + { + Destination = "::0/0"; + Type = "blackhole"; + Table = cfg.sing-box.table; + Metric = 4096; + } + ]; + routingPolicyRules = lib.singleton { + Family = "both"; + FirewallMark = cfg.sing-box.fwmark; + Priority = cfg.sing-box.priority; + Table = cfg.sing-box.table; + }; + }; + + services.sing-box = { + enable = true; + settings = { + log = { + level = "info"; + }; + dns = { + servers = [ + { + tag = "cloudflare"; + address = "https://[2606:4700:4700::1111]/dns-query"; + strategy = "prefer_ipv6"; + } + { + tag = "local"; + address = "local"; + strategy = "prefer_ipv4"; + } + ]; + rules = [ + { + geosite = [ "cn" ]; + server = "local"; + } + ]; + final = "cloudflare"; + }; + inbounds = [ + { + type = "mixed"; + tag = "inbound"; + listen = "127.0.0.1"; + listen_port = cfg.sing-box.port; + sniff = true; + sniff_override_destination = true; + } + ]; + outbounds = [ + { + type = "direct"; + tag = "enthalpy"; + routing_mark = cfg.sing-box.fwmark; + domain_strategy = "prefer_ipv6"; + } + { + type = "direct"; + tag = "direct"; + } + ]; + route = { + rules = [ + { + geosite = [ "cn" ]; + geoip = [ "cn" ]; + ip_cidr = [ "10.0.0.0/8" ]; + outbound = "direct"; + } + ]; + final = "enthalpy"; + }; + }; + }; + + environment.systemPackages = with pkgs; [ gg ]; + + environment.etc."ggconfig.toml".source = (pkgs.formats.toml { }).generate "ggconfig.toml" { + allow_insecure = false; + no_udp = false; + node = "socks5://127.0.0.1:${toString cfg.sing-box.port}"; + proxy_private = false; + test_node_before_use = false; + }; + } + + # IPv4 (464XLAT) + (mkIf cfg.sing-box.clat.enable { + systemd.network.config = { + networkConfig = { + IPv6Forwarding = true; + ManageForeignRoutes = false; + }; + }; + + systemd.network.networks."50-clat" = { + name = "clat"; + linkConfig = { + MTUBytes = "1400"; + RequiredForOnline = false; + }; + addresses = singleton { Address = "192.0.0.2/32"; }; + routes = [ + { + Destination = "0.0.0.0/0"; + Table = cfg.sing-box.table; + PreferredSource = "192.0.0.2"; + Metric = 1024; + } + { Destination = cfg.sing-box.clat.address; } + ]; + }; + + services.enthalpy.exit.enable = true; + services.enthalpy.exit.prefix = singleton "${cfg.sing-box.clat.address}/128"; + + systemd.services.enthalpy-clatd = { + path = with pkgs; [ + iproute2 + tayga + ]; + script = '' + ip r replace 64:ff9b::/96 from ${cfg.sing-box.clat.address} encap seg6 mode encap \ + segs ${concatStringsSep "," cfg.sing-box.clat.segment} dev ${cfg.interface} mtu 1280 + exec tayga -d --config ${pkgs.writeText "tayga.conf" '' + tun-device clat + prefix 64:ff9b::/96 + ipv4-addr 192.0.0.1 + map 192.0.0.2 ${cfg.sing-box.clat.address} + ''} + ''; + partOf = [ "enthalpy.service" ]; + after = [ + "enthalpy.service" + "network.target" + ]; + requires = [ "enthalpy.service" ]; + requiredBy = [ "enthalpy.service" ]; + wantedBy = [ "multi-user.target" ]; + }; + }) + ]); +} diff --git a/nixos/modules/services/enthalpy/srv6.nix b/nixos/modules/services/enthalpy/srv6.nix new file mode 100644 index 0000000..70c0df7 --- /dev/null +++ b/nixos/modules/services/enthalpy/srv6.nix @@ -0,0 +1,109 @@ +# Portions of this file are sourced from +# https://github.com/NickCao/flakes/blob/3b03efb676ea602575c916b2b8bc9d9cd13b0d85/modules/gravity/default.nix +{ + config, + lib, + pkgs, + mylib, + ... +}: +with lib; +let + inherit (mylib.network) cidr; + cfg = config.services.enthalpy; +in +{ + options.services.enthalpy.srv6 = { + enable = mkEnableOption "segment routing over IPv6"; + tableName = mkOption { + type = types.str; + default = "localsid"; + readOnly = true; + description = '' + Routing table designated for SRv6 SID. + ''; + }; + table = mkOption { + type = types.int; + default = config.networking.routingTables."${cfg.srv6.tableName}"; + readOnly = true; + description = '' + Routing table ID associated with the localsid routing table. + ''; + }; + priority = mkOption { + type = types.int; + default = config.networking.routingPolicyPriorities."${cfg.srv6.tableName}"; + readOnly = true; + description = '' + Routing priority assigned to the localsid routing table. + ''; + }; + prefix = mkOption { + type = types.str; + default = cidr.subnet 4 6 cfg.prefix; + description = '' + Prefix used for SRv6 actions. + ''; + }; + actions = mkOption { + type = types.listOf types.str; + default = [ + "${cidr.host 1 cfg.srv6.prefix} encap seg6local action End.DT6 table main dev ${cfg.interface} table ${cfg.srv6.tableName}" + "${cidr.host 2 cfg.srv6.prefix} encap seg6local action End.DT6 table nat64 dev ${cfg.interface} table ${cfg.srv6.tableName}" + ]; + description = '' + List of SRv6 actions configured in the default network namespace. + ''; + }; + }; + + config = mkIf (cfg.enable && cfg.srv6.enable) { + systemd.network.config = { + networkConfig = { + IPv6Forwarding = true; + ManageForeignRoutes = false; + }; + }; + + systemd.network.networks."50-enthalpy" = { + routes = singleton { + Destination = "::/0"; + Type = "blackhole"; + Table = cfg.srv6.table; + }; + routingPolicyRules = singleton { + Priority = cfg.srv6.priority; + Family = "ipv6"; + Table = cfg.srv6.table; + From = cfg.network; + To = cfg.srv6.prefix; + }; + }; + + systemd.services.enthalpy-srv6 = { + path = with pkgs; [ iproute2 ]; + serviceConfig = { + Type = "oneshot"; + RemainAfterExit = true; + ExecStartPre = [ + "${pkgs.iproute2}/bin/ip -n ${cfg.netns} -6 r a ${cfg.srv6.prefix} from ${cfg.network} via fe80::ff:fe00:1 dev enthalpy" + ]; + ExecStart = builtins.map (route: "${pkgs.iproute2}/bin/ip -6 r a ${route}") cfg.srv6.actions; + ExecStop = builtins.map (route: "${pkgs.iproute2}/bin/ip -6 r d ${route}") cfg.srv6.actions; + ExecStopPost = [ + "${pkgs.iproute2}/bin/ip -n ${cfg.netns} -6 r d ${cfg.srv6.prefix} from ${cfg.network} via fe80::ff:fe00:1 dev enthalpy" + ]; + }; + partOf = [ "enthalpy.service" ]; + after = [ + "enthalpy.service" + "network-online.target" + ]; + requires = [ "enthalpy.service" ]; + requiredBy = [ "enthalpy.service" ]; + wants = [ "network-online.target" ]; + wantedBy = [ "multi-user.target" ]; + }; + }; +} diff --git a/nixos/modules/system/global-persistence.nix b/nixos/modules/system/global-persistence.nix new file mode 100644 index 0000000..af30cca --- /dev/null +++ b/nixos/modules/system/global-persistence.nix @@ -0,0 +1,79 @@ +# Portions of this file are sourced from +# https://github.com/linyinfeng/dotfiles/blob/b618b0fd16fb9c79ab7199ed51c4c0f98a392cea/nixos/modules/environment/global-persistence/default.nix +{ + config, + lib, + ... +}: +let + cfg = config.environment.globalPersistence; + userCfg = + name: + assert config.home-manager.users.${name}.home.globalPersistence.enabled; + { + inherit name; + value = { + inherit (config.home-manager.users.${name}.home.globalPersistence) home directories files; + }; + }; + usersCfg = lib.listToAttrs (map userCfg cfg.user.users); +in +with lib; +{ + options.environment.globalPersistence = { + enable = mkEnableOption "global persistence storage"; + root = mkOption { + type = types.str; + description = '' + The root of persistence storage. + ''; + }; + directories = mkOption { + type = with types; listOf str; + default = [ ]; + description = '' + Directories to bind mount to persistent storage. + ''; + }; + files = mkOption { + type = with types; listOf str; + default = [ ]; + description = '' + Files that should be stored in persistent storage. + ''; + }; + user = { + users = mkOption { + type = with types; listOf str; + default = [ ]; + description = '' + Persistence for users. + ''; + }; + directories = mkOption { + type = with types; listOf str; + default = [ ]; + description = '' + Directories to bind mount to persistent storage for users. + Paths should be relative to home of user. + ''; + }; + files = mkOption { + type = with types; listOf str; + default = [ ]; + description = '' + Files to link to persistent storage for users. + Paths should be relative to home of user. + ''; + }; + }; + }; + + config = mkIf cfg.enable { + environment.persistence."${cfg.root}" = { + hideMounts = true; + inherit (cfg) directories files; + users = usersCfg; + }; + }; +} diff --git a/nixos/modules/system/sops-secrets.nix b/nixos/modules/system/sops-secrets.nix new file mode 100644 index 0000000..2642d56 --- /dev/null +++ b/nixos/modules/system/sops-secrets.nix @@ -0,0 +1,100 @@ +# Portions of this file are sourced from +# https://github.com/linyinfeng/dotfiles/blob/b618b0fd16fb9c79ab7199ed51c4c0f98a392cea/nixos/modules/sops/terraform-output.nix +{ + config, + lib, + self, + ... +}: +let + inherit (config.networking) hostName; + globalConfig = config; + opentofuOpts = + { config, ... }: + { + options.opentofu = { + enable = lib.mkEnableOption "extract secrets from OpenTofu output"; + useHostOutput = lib.mkEnableOption "extract from host-specific output"; + jqPath = lib.mkOption { + type = lib.types.str; + default = + if config.opentofu.useHostOutput then + ".hosts.value.\"${hostName}\".${config.name}" + else + ".${config.name}.value"; + description = '' + The path used by jq to extract data from the output of OpenTofu. + ''; + }; + }; + config = lib.mkIf config.opentofu.enable { + sopsFile = globalConfig.sops.secretFiles.opentofu; + }; + }; + secretsFromOutputs = lib.filterAttrs (_: c: c.opentofu.enable) config.sops.secrets; +in +{ + options = { + sops = { + secretFiles = { + directory = lib.mkOption { + type = lib.types.path; + description = '' + The directory containing the sops-nix secrets file. + ''; + }; + get = lib.mkOption { + type = with lib.types; functionTo path; + description = '' + A function used to convert the relative path of + the secret file into an absolute path. + ''; + }; + host = lib.mkOption { + type = lib.types.path; + description = '' + The path to the manually maintained host secret file. + ''; + }; + opentofu = lib.mkOption { + type = lib.types.path; + description = '' + The path to the host secret file exported from OpenTofu. + ''; + }; + }; + opentofuTemplate = lib.mkOption { + type = lib.types.lines; + description = '' + The jq filter template for extracting OpenTofu secrets. + ''; + }; + secrets = lib.mkOption { type = with lib.types; attrsOf (submodule opentofuOpts); }; + }; + }; + + config = { + sops = { + age = { + keyFile = "/var/lib/sops.key"; + sshKeyPaths = [ ]; + }; + gnupg.sshKeyPaths = [ ]; + opentofuTemplate = '' + { + ${ + lib.concatMapStringsSep "\n, " (cfg: ''"${cfg.name}": ${cfg.opentofu.jqPath}'') ( + lib.attrValues secretsFromOutputs + ) + } + } + ''; + secretFiles = { + directory = lib.mkDefault "${self}/secrets"; + get = p: "${config.sops.secretFiles.directory}/${p}"; + host = config.sops.secretFiles.get "hosts/${hostName}.yaml"; + opentofu = config.sops.secretFiles.get "hosts/opentofu/${hostName}.yaml"; + }; + }; + }; +} diff --git a/nixos/profiles/programs/adb/default.nix b/nixos/profiles/programs/adb/default.nix new file mode 100644 index 0000000..3ee7bdb --- /dev/null +++ b/nixos/profiles/programs/adb/default.nix @@ -0,0 +1,4 @@ +{ ... }: +{ + programs.adb.enable = true; +} diff --git a/nixos/profiles/programs/dconf/default.nix b/nixos/profiles/programs/dconf/default.nix new file mode 100644 index 0000000..0dd1639 --- /dev/null +++ b/nixos/profiles/programs/dconf/default.nix @@ -0,0 +1,4 @@ +{ ... }: +{ + programs.dconf.enable = true; +} diff --git a/nixos/profiles/programs/tools/common.nix b/nixos/profiles/programs/tools/common.nix new file mode 100644 index 0000000..8afb965 --- /dev/null +++ b/nixos/profiles/programs/tools/common.nix @@ -0,0 +1,39 @@ +{ pkgs, ... }: +{ + programs = { + command-not-found.enable = false; + git = { + enable = true; + lfs.enable = true; + }; + htop = { + enable = true; + settings = { + show_program_path = 0; + highlight_base_name = 1; + hide_userland_threads = true; + }; + }; + }; + + environment.systemPackages = with pkgs; [ + # keep-sorted start + coreutils + file + findutils + gawk + gnugrep + gnused + gnutar + jq + lsof + p7zip + psmisc + tree + unzipNLS + which + zip + zstd + # keep-sorted end + ]; +} diff --git a/nixos/profiles/programs/tools/network.nix b/nixos/profiles/programs/tools/network.nix new file mode 100644 index 0000000..2da1022 --- /dev/null +++ b/nixos/profiles/programs/tools/network.nix @@ -0,0 +1,22 @@ +{ pkgs, ... }: +{ + programs = { + mtr.enable = true; + }; + + environment.systemPackages = with pkgs; [ + # keep-sorted start + aria2 + curl + dnsutils + ethtool + ipcalc + iperf3 + nmap + rsync + socat + tcpdump + wget + # keep-sorted end + ]; +} diff --git a/nixos/profiles/programs/tools/system.nix b/nixos/profiles/programs/tools/system.nix new file mode 100644 index 0000000..bedd9fa --- /dev/null +++ b/nixos/profiles/programs/tools/system.nix @@ -0,0 +1,13 @@ +{ pkgs, ... }: +{ + environment.systemPackages = with pkgs; [ + # keep-sorted start + dmidecode + hdparm + lm_sensors + pciutils + smartmontools + usbutils + # keep-sorted end + ]; +} diff --git a/nixos/profiles/security/polkit/default.nix b/nixos/profiles/security/polkit/default.nix new file mode 100644 index 0000000..758bfca --- /dev/null +++ b/nixos/profiles/security/polkit/default.nix @@ -0,0 +1,4 @@ +{ ... }: +{ + security.polkit.enable = true; +} diff --git a/nixos/profiles/security/rtkit/default.nix b/nixos/profiles/security/rtkit/default.nix new file mode 100644 index 0000000..2198a04 --- /dev/null +++ b/nixos/profiles/security/rtkit/default.nix @@ -0,0 +1,4 @@ +{ ... }: +{ + security.rtkit.enable = true; +} diff --git a/nixos/profiles/services/dbus/default.nix b/nixos/profiles/services/dbus/default.nix new file mode 100644 index 0000000..822f5ab --- /dev/null +++ b/nixos/profiles/services/dbus/default.nix @@ -0,0 +1,4 @@ +{ ... }: +{ + services.dbus.implementation = "broker"; +} diff --git a/nixos/profiles/services/enthalpy/default.nix b/nixos/profiles/services/enthalpy/default.nix new file mode 100644 index 0000000..1821f24 --- /dev/null +++ b/nixos/profiles/services/enthalpy/default.nix @@ -0,0 +1,40 @@ +{ + config, + data, + hostData, + self, + ... +}: +{ + sops.secrets."enthalpy_node_private_key_pem".opentofu = { + enable = true; + useHostOutput = true; + }; + + services.enthalpy = { + enable = true; + prefix = hostData.enthalpy_node_prefix; + network = data.enthalpy_network_prefix; + ipsec = { + enable = true; + organization = hostData.enthalpy_node_organization; + commonName = config.networking.hostName; + endpoints = [ + { + serialNumber = "0"; + addressFamily = "ip4"; + } + { + serialNumber = "1"; + addressFamily = "ip6"; + } + ]; + privateKeyPath = config.sops.secrets."enthalpy_node_private_key_pem".path; + registry = "${self}/zones/registry.json"; + }; + bird = { + enable = true; + routerId = hostData.enthalpy_node_id; + }; + }; +} diff --git a/nixos/profiles/services/firewall/default.nix b/nixos/profiles/services/firewall/default.nix new file mode 100644 index 0000000..1fc80b2 --- /dev/null +++ b/nixos/profiles/services/firewall/default.nix @@ -0,0 +1,7 @@ +{ lib, ... }: +{ + networking = { + nftables.enable = true; + firewall.enable = lib.mkDefault false; + }; +} diff --git a/nixos/profiles/services/gnome-keyring/default.nix b/nixos/profiles/services/gnome-keyring/default.nix new file mode 100644 index 0000000..462bbfb --- /dev/null +++ b/nixos/profiles/services/gnome-keyring/default.nix @@ -0,0 +1,6 @@ +{ ... }: +{ + services.gnome.gnome-keyring.enable = true; + + environment.globalPersistence.user.directories = [ ".local/share/keyrings" ]; +} diff --git a/nixos/profiles/services/greetd/default.nix b/nixos/profiles/services/greetd/default.nix new file mode 100644 index 0000000..e3da40e --- /dev/null +++ b/nixos/profiles/services/greetd/default.nix @@ -0,0 +1,11 @@ +{ pkgs, lib, ... }: +{ + services.greetd = { + enable = true; + settings = { + default_session.command = "${lib.getExe pkgs.greetd.tuigreet} --cmd wayland-session"; + }; + }; + + security.pam.services.swaylock = { }; +} diff --git a/nixos/profiles/services/journald/default.nix b/nixos/profiles/services/journald/default.nix new file mode 100644 index 0000000..58897e9 --- /dev/null +++ b/nixos/profiles/services/journald/default.nix @@ -0,0 +1,6 @@ +{ ... }: +{ + services.journald.extraConfig = '' + SystemMaxUse=1G + ''; +} diff --git a/nixos/profiles/services/networkd/default.nix b/nixos/profiles/services/networkd/default.nix new file mode 100644 index 0000000..eeae459 --- /dev/null +++ b/nixos/profiles/services/networkd/default.nix @@ -0,0 +1,10 @@ +{ ... }: +{ + networking = { + useNetworkd = true; + useDHCP = false; + domain = "rebmit.link"; + }; + + systemd.network.enable = true; +} diff --git a/nixos/profiles/services/openssh/default.nix b/nixos/profiles/services/openssh/default.nix new file mode 100644 index 0000000..60b97a0 --- /dev/null +++ b/nixos/profiles/services/openssh/default.nix @@ -0,0 +1,95 @@ +# Portions of this file are sourced from +# https://github.com/linyinfeng/dotfiles/blob/b618b0fd16fb9c79ab7199ed51c4c0f98a392cea/nixos/profiles/services/openssh/default.nix +{ + config, + lib, + data, + ... +}: +with lib; +let + aliveInterval = "15"; + aliveCountMax = "4"; + knownHosts = listToAttrs ( + flatten ( + mapAttrsToList (host: hostData: [ + (nameValuePair "${host}-ed25519" { + hostNames = [ + "${host}.rebmit.link" + "${host}.enta.rebmit.link" + ]; + publicKey = hostData.ssh_host_ed25519_key_pub; + }) + (nameValuePair "${host}-rsa" { + hostNames = [ + "${host}.rebmit.link" + "${host}.enta.rebmit.link" + ]; + publicKey = hostData.ssh_host_rsa_key_pub; + }) + ]) data.hosts + ) + ); +in +{ + services.openssh = { + enable = true; + ports = [ config.networking.ports.ssh ]; + openFirewall = true; + settings = { + PermitRootLogin = "prohibit-password"; + PasswordAuthentication = false; + }; + extraConfig = '' + ClientAliveInterval ${aliveInterval} + ClientAliveCountMax ${aliveCountMax} + ''; + hostKeys = [ + { + bits = 4096; + inherit (config.sops.secrets."ssh_host_rsa_key") path; + type = "rsa"; + } + { + inherit (config.sops.secrets."ssh_host_ed25519_key") path; + type = "ed25519"; + } + ]; + }; + + programs.ssh = { + startAgent = true; + knownHosts = knownHosts; + extraConfig = + '' + ServerAliveInterval ${aliveInterval} + ServerAliveCountMax ${aliveCountMax} + '' + + concatMapStringsSep "\n" (h: '' + Host ${h} + Hostname ${h}.rebmit.link + Port ${toString config.networking.ports.ssh} + Host ${h}.enta + Hostname ${h}.enta.rebmit.link + Port ${toString config.networking.ports.ssh} + '') (attrNames data.hosts); + }; + + sops.secrets."ssh_host_rsa_key" = { + opentofu = { + enable = true; + useHostOutput = true; + }; + restartUnits = [ "sshd.service" ]; + }; + + sops.secrets."ssh_host_ed25519_key" = { + opentofu = { + enable = true; + useHostOutput = true; + }; + restartUnits = [ "sshd.service" ]; + }; + + environment.globalPersistence.user.directories = [ ".ssh" ]; +} diff --git a/nixos/profiles/services/pipewire/default.nix b/nixos/profiles/services/pipewire/default.nix new file mode 100644 index 0000000..003df59 --- /dev/null +++ b/nixos/profiles/services/pipewire/default.nix @@ -0,0 +1,15 @@ +{ ... }: +{ + hardware.pulseaudio.enable = false; + + services.pipewire = { + enable = true; + pulse.enable = true; + jack.enable = true; + alsa.enable = true; + }; + + environment.globalPersistence.user.directories = [ + ".local/state/wireplumber" + ]; +} diff --git a/nixos/profiles/services/resolved/default.nix b/nixos/profiles/services/resolved/default.nix new file mode 100644 index 0000000..0891e07 --- /dev/null +++ b/nixos/profiles/services/resolved/default.nix @@ -0,0 +1,11 @@ +{ ... }: +{ + services.resolved = { + enable = true; + llmnr = "false"; + extraConfig = '' + MulticastDNS=off + DNSStubListener=no + ''; + }; +} diff --git a/nixos/profiles/services/zram-generator/default.nix b/nixos/profiles/services/zram-generator/default.nix new file mode 100644 index 0000000..d4d75d0 --- /dev/null +++ b/nixos/profiles/services/zram-generator/default.nix @@ -0,0 +1,10 @@ +{ ... }: +{ + services.zram-generator = { + enable = true; + settings.zram0 = { + compression-algorithm = "zstd"; + zram-size = "ram / 2"; + }; + }; +} diff --git a/nixos/profiles/system/boot/binfmt.nix b/nixos/profiles/system/boot/binfmt.nix new file mode 100644 index 0000000..541a136 --- /dev/null +++ b/nixos/profiles/system/boot/binfmt.nix @@ -0,0 +1,9 @@ +{ + lib, + pkgs, + mylib, + ... +}: +{ + boot.binfmt.emulatedSystems = lib.remove pkgs.stdenv.hostPlatform.system mylib.systems; +} diff --git a/nixos/profiles/system/boot/kernel/latest.nix b/nixos/profiles/system/boot/kernel/latest.nix new file mode 100644 index 0000000..5ac137b --- /dev/null +++ b/nixos/profiles/system/boot/kernel/latest.nix @@ -0,0 +1,4 @@ +{ pkgs, lib, ... }: +{ + boot.kernelPackages = lib.mkDefault pkgs.linuxPackages_latest; +} diff --git a/nixos/profiles/system/boot/secure-boot.nix b/nixos/profiles/system/boot/secure-boot.nix new file mode 100644 index 0000000..7842dbb --- /dev/null +++ b/nixos/profiles/system/boot/secure-boot.nix @@ -0,0 +1,13 @@ +{ pkgs, lib, ... }: +{ + environment.systemPackages = with pkgs; [ sbctl ]; + + boot.loader.systemd-boot.enable = lib.mkForce false; + + boot.lanzaboote = { + enable = true; + pkiBundle = "/etc/secureboot"; + }; + + environment.globalPersistence.directories = [ "/etc/secureboot" ]; +} diff --git a/nixos/profiles/system/boot/sysctl/tcp-bbr.nix b/nixos/profiles/system/boot/sysctl/tcp-bbr.nix new file mode 100644 index 0000000..50d0ba5 --- /dev/null +++ b/nixos/profiles/system/boot/sysctl/tcp-bbr.nix @@ -0,0 +1,7 @@ +{ ... }: +{ + boot.kernel.sysctl = { + "net.core.default_qdisc" = "fq"; + "net.ipv4.tcp_congestion_control" = "bbr"; + }; +} diff --git a/nixos/profiles/system/boot/systemd-initrd.nix b/nixos/profiles/system/boot/systemd-initrd.nix new file mode 100644 index 0000000..89ad157 --- /dev/null +++ b/nixos/profiles/system/boot/systemd-initrd.nix @@ -0,0 +1,4 @@ +{ ... }: +{ + boot.initrd.systemd.enable = true; +} diff --git a/nixos/profiles/system/common.nix b/nixos/profiles/system/common.nix new file mode 100644 index 0000000..1d292aa --- /dev/null +++ b/nixos/profiles/system/common.nix @@ -0,0 +1,14 @@ +{ lib, ... }: +{ + boot.tmp.useTmpfs = lib.mkDefault true; + + users.mutableUsers = lib.mkDefault false; + + time.timeZone = lib.mkDefault "Asia/Singapore"; + + i18n.defaultLocale = lib.mkDefault "en_SG.UTF-8"; + + environment.stub-ld.enable = lib.mkDefault false; + + documentation.nixos.enable = lib.mkForce false; +} diff --git a/nixos/profiles/system/global-persistence.nix b/nixos/profiles/system/global-persistence.nix new file mode 100644 index 0000000..485d829 --- /dev/null +++ b/nixos/profiles/system/global-persistence.nix @@ -0,0 +1,16 @@ +{ ... }: +{ + environment.globalPersistence = { + directories = [ + "/var/db" + "/var/lib" + "/var/log" + "/var/tmp" + ]; + files = [ + "/etc/machine-id" + ]; + }; + + systemd.suppressedSystemUnits = [ "systemd-machine-id-commit.service" ]; +} diff --git a/nixos/profiles/system/nix/gc.nix b/nixos/profiles/system/nix/gc.nix new file mode 100644 index 0000000..ea5e3c8 --- /dev/null +++ b/nixos/profiles/system/nix/gc.nix @@ -0,0 +1,12 @@ +{ ... }: +{ + nix = { + gc = { + automatic = true; + options = "--delete-older-than 14d"; + dates = "weekly"; + }; + + settings.min-free = 1024 * 1024 * 1024; # bytes + }; +} diff --git a/nixos/profiles/system/nix/registry.nix b/nixos/profiles/system/nix/registry.nix new file mode 100644 index 0000000..e30fe7b --- /dev/null +++ b/nixos/profiles/system/nix/registry.nix @@ -0,0 +1,18 @@ +{ + inputs, + lib, + self, + ... +}: +let + flakes = lib.filterAttrs (_name: value: value ? _type && value._type == "flake") inputs; + nixRegistry = (lib.mapAttrs (_name: value: { flake = value; }) flakes); +in +{ + nix = { + registry = nixRegistry // { + p.flake = self; + }; + settings.flake-registry = "/etc/nix/registry.json"; + }; +} diff --git a/nixos/profiles/system/nix/settings.nix b/nixos/profiles/system/nix/settings.nix new file mode 100644 index 0000000..8fa92f8 --- /dev/null +++ b/nixos/profiles/system/nix/settings.nix @@ -0,0 +1,28 @@ +{ ... }: +{ + nix = { + channel.enable = false; + settings = { + trusted-users = [ + "root" + "@wheel" + ]; + experimental-features = [ + "nix-command" + "flakes" + "auto-allocate-uids" + "cgroups" + ]; + auto-allocate-uids = true; + use-cgroups = true; + auto-optimise-store = true; + use-xdg-base-directories = true; + builders-use-substitutes = true; + }; + }; + + environment.globalPersistence.user.directories = [ + ".cache/nix" + ".local/share/nix" + ]; +} diff --git a/nixos/profiles/system/nix/version.nix b/nixos/profiles/system/nix/version.nix new file mode 100644 index 0000000..7ee62a6 --- /dev/null +++ b/nixos/profiles/system/nix/version.nix @@ -0,0 +1,4 @@ +{ pkgs, lib, ... }: +{ + nix.package = lib.mkDefault pkgs.nixVersions.stable; +} diff --git a/nixos/profiles/users/rebmit/default.nix b/nixos/profiles/users/rebmit/default.nix new file mode 100644 index 0000000..8428237 --- /dev/null +++ b/nixos/profiles/users/rebmit/default.nix @@ -0,0 +1,39 @@ +{ config, pkgs, ... }: +let + homeDirectory = "/home/rebmit"; +in +{ + programs.fish.enable = true; + + users.users.rebmit = { + hashedPasswordFile = config.sops.secrets."user-password/rebmit".path; + isNormalUser = true; + shell = pkgs.fish; + home = homeDirectory; + extraGroups = with config.users.groups; [ + wheel.name + ]; + openssh.authorizedKeys.keyFiles = config.users.users.root.openssh.authorizedKeys.keyFiles; + }; + + sops.secrets."user-password/rebmit" = { + neededForUsers = true; + sopsFile = config.sops.secretFiles.get "local.yaml"; + }; + + environment.globalPersistence.user.users = [ "rebmit" ]; + + home-manager.users.rebmit = + { ... }: + { + home.globalPersistence = { + enable = true; + home = homeDirectory; + }; + + programs.git = { + userName = "Lu Wang"; + userEmail = "rebmit@rebmit.moe"; + }; + }; +} diff --git a/nixos/profiles/users/root/_ssh/marisa-7d76 b/nixos/profiles/users/root/_ssh/marisa-7d76 new file mode 100644 index 0000000..3f05513 --- /dev/null +++ b/nixos/profiles/users/root/_ssh/marisa-7d76 @@ -0,0 +1 @@ +ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIDfKG/KKgC6IaK4uu9zn+0wbF4XXK1pcCP/S37u6OAmJ diff --git a/nixos/profiles/users/root/_ssh/marisa-a7s b/nixos/profiles/users/root/_ssh/marisa-a7s new file mode 100644 index 0000000..58e5d68 --- /dev/null +++ b/nixos/profiles/users/root/_ssh/marisa-a7s @@ -0,0 +1 @@ +ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIKxxTAqukqahIrZiJbqPpxpB1FQJSQ/E8+1toRLVZ2GW diff --git a/nixos/profiles/users/root/default.nix b/nixos/profiles/users/root/default.nix new file mode 100644 index 0000000..cbf472d --- /dev/null +++ b/nixos/profiles/users/root/default.nix @@ -0,0 +1,9 @@ +{ ... }: +{ + users.users.root = { + openssh.authorizedKeys.keyFiles = [ + ./_ssh/marisa-7d76 + ./_ssh/marisa-a7s + ]; + }; +} diff --git a/patches/libadwaita-without-adwaita-theme.patch b/patches/libadwaita-without-adwaita-theme.patch new file mode 100644 index 0000000..2d1514a --- /dev/null +++ b/patches/libadwaita-without-adwaita-theme.patch @@ -0,0 +1,74 @@ +diff --git a/src/adw-style-manager.c b/src/adw-style-manager.c +index 71f6915d..a90c0df1 100644 +--- a/src/adw-style-manager.c ++++ b/src/adw-style-manager.c +@@ -284,6 +284,23 @@ notify_high_contrast_cb (AdwStyleManager *self) + g_object_notify_by_pspec (G_OBJECT (self), props[PROP_HIGH_CONTRAST]); + } + ++static void ++adw_style_manager_theme_changed(GSettings *settings, const char *key, GdkDisplay *display) ++{ ++ char* theme = g_settings_get_string(settings, "gtk-theme"); ++ char* color_scheme = g_settings_get_string(settings, "color-scheme"); ++ ++ if(!theme) { ++ theme = "Adwaita-empty"; ++ } ++ ++ gboolean is_dark_variant = NULL != strstr(theme, "-dark") || NULL != strstr(theme, "-Dark") || 0 == strcmp(color_scheme, "prefer-dark"); ++ ++ g_object_set(gtk_settings_get_for_display(display), ++ "gtk-theme-name", theme, ++ "gtk-application-prefer-dark-theme", is_dark_variant, NULL); ++} ++ + static void + adw_style_manager_constructed (GObject *object) + { +@@ -308,27 +325,6 @@ adw_style_manager_constructed (GObject *object) + self, + G_CONNECT_SWAPPED); + +- if (!adw_is_granite_present () && !g_getenv ("GTK_THEME")) { +- g_object_set (gtk_settings_get_for_display (self->display), +- "gtk-theme-name", "Adwaita-empty", +- NULL); +- +- self->provider = gtk_css_provider_new (); +- gtk_style_context_add_provider_for_display (self->display, +- GTK_STYLE_PROVIDER (self->provider), +- GTK_STYLE_PROVIDER_PRIORITY_THEME); +- +- self->colors_provider = gtk_css_provider_new (); +- gtk_style_context_add_provider_for_display (self->display, +- GTK_STYLE_PROVIDER (self->colors_provider), +- GTK_STYLE_PROVIDER_PRIORITY_THEME); +- +- self->accent_provider = gtk_css_provider_new (); +- gtk_style_context_add_provider_for_display (self->display, +- GTK_STYLE_PROVIDER (self->accent_provider), +- GTK_STYLE_PROVIDER_PRIORITY_THEME); +- } +- + self->animations_provider = gtk_css_provider_new (); + gtk_css_provider_load_from_string (self->animations_provider, + "* { transition: none; }"); +@@ -364,6 +360,17 @@ adw_style_manager_constructed (GObject *object) + + update_dark (self); + update_stylesheet (self, UPDATE_ALL); ++ ++ if (self->display && !adw_is_granite_present () && !g_getenv ("GTK_THEME")) { ++ GSettingsSchemaSource *schema_source = ++ g_settings_schema_source_get_default(); ++ GSettingsSchema *schema = g_settings_schema_source_lookup( ++ schema_source, "org.gnome.desktop.interface", true); ++ GSettings *interface_settings = g_settings_new_full(schema, NULL, NULL); ++ ++ adw_style_manager_theme_changed(interface_settings, "gtk-theme", self->display); ++ g_signal_connect (interface_settings, "changed", G_CALLBACK (adw_style_manager_theme_changed), self->display); ++ } + } + + static void diff --git a/secrets/hosts/opentofu/flandre-m5p.yaml b/secrets/hosts/opentofu/flandre-m5p.yaml new file mode 100644 index 0000000..65e0eff --- /dev/null +++ b/secrets/hosts/opentofu/flandre-m5p.yaml @@ -0,0 +1,32 @@ +enthalpy_node_private_key_pem: ENC[AES256_GCM,data:yS8+ywV9gdosg5u2saxKwt7x/25xif/9BA4GGq61mD9yyqjZQpSCau2NjouaJm3PoB+MF+vRRGsnPz3jAzKlS/hfCa4JGNx4ue8nvtTPde8/WyHe745xWnUN+iOPYmWTQlRfACpNFjtB0MQ421clR1Uy7ySA/gc=,iv:5fKvh+eCmckx0UxGLFiwj+cmMJajfws5Bli+Hj3djVE=,tag:x1tUfgR1gaHkK8bCaA6K/w==,type:str] +ssh_host_ed25519_key: ENC[AES256_GCM,data:aIVWjDat554JxJHAkVIEMgtKW8CXZJCy8fdv5+ro9xudR1g6EjkveuCfsJbxr4ToJbttwjAhp3hH02fPjWDO4KM3lukuYbdx3WkXc0YZj2u/1KiXlMBW81Pj9utBM9a9HWnAJz0XVoisgBc8GvZtJMVgGnXtxizgj5DBfGkp36OgLFQqwHgom6FNtVOgN6flEwJXL2c/TB1HtMNr0Vk9Nm39Y00u8pmNPUGVsHGmxU095UtHL6SPIob/OeekvbYIoMF27EEpfk5waRhypqB335RziaS/3JDO/oVQEkzanibE3mCPwHAXL8sMBSdBgIRVEjc1XdgDirXghSMhqta5nqeG2NeG/VZzQWzKQoyFfNK9xTN1vWpWl9wJvKV6ZH87ngT4vHjdvcTjDgttFU/M4KEMuwjGqzb8gcc00D7tjWCjkz+wL96ZcvU6REQF/rigcBvYWAesn2DbC7jrJFBPH/+q5gF886h2yeBwSeUCrm1ZpVY3+OLwth9WnSdxJCacFifw,iv:4NOWoTn7FKWzO8VKrOYbe6XBxBzz1HcdOuFctjdRj7Q=,tag:+EDt8+AOQ+6MHz9vb2aXzQ==,type:str] +ssh_host_rsa_key: ENC[AES256_GCM,data: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,iv:o38ERPwvNuSi9vk10Vw572bK4pZe22Xv8AAfs/IJsGw=,tag:IFl6V9pd0eYtmmlJJwMDzA==,type:str] +sops: + kms: [] + gcp_kms: [] + azure_kv: [] + hc_vault: [] + age: + - recipient: age1sfnct03u4cvfj98x4yjrcrrnu5gg8qgxrwk4uqq8w4e6wveeaedq97rn44 + enc: | + -----BEGIN AGE ENCRYPTED FILE----- + YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBWZWo2Q3FFNUE3dlpUeEM0 + b0VHK21YRXVxTFh1MzN3RW5qMG5STFZhdlRNCkM0RG96VmpYZVMwQzBjTFFHRzds + UlZrTnE5bXJkcHZGWlpWbktXajBPdU0KLS0tIElRVUxGQTRwL2pWOHEyZDdtQzBH + SElNMmxlUzZYNFZNU3EyL25UM3hld1kKl7HY7xgeHlz7ghumMjbv2KyBLMhSYN7M + BdHdtazsTZj+FKKmy0tI/lk32Aii5X3sPMO+cDWtrw/RGPVqstUm+w== + -----END AGE ENCRYPTED FILE----- + - recipient: age166kxtrcx99fxlgtvz5mvyt5ctvk3dt09f42gvm94ngnkyztmmelsyzdn77 + enc: | + -----BEGIN AGE ENCRYPTED FILE----- + YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBZUS80cFM3em1JRFpLam1J + dmFnbUR3U05aUFFOZlRJZzhNVk5INkdLeXdNCjBYQTdlQ3JIdUNXUFdwVFVSWmxR + Q3EyVDU4c0lIOFNQTkZTMDRwUEVhSEEKLS0tIEdoV1JRWHg2QWZWZ0dEcnRSSGtX + dVh3TXhyblNybUNFY2RsdEsySTZRMDAKtjXm/wpJPPG7A82nLMJLf+I9+2GKWmLK + 6IAMVz2OPyKCAgS2thT2Ep/Yc0ScoT3aI11mPmq7iNtBvlpmS7i/xg== + -----END AGE ENCRYPTED FILE----- + lastmodified: "2024-11-23T13:02:22Z" + mac: ENC[AES256_GCM,data:y743aRnT9NfpJZHqqhDMjqbwTxtiYvqj1pVw+TnUqUx2iqThvWC7/1cEbKPQ5W8UXB3iM9KMA63wGC23V1acFdox1jKn5ZH2T9L+s2EeUMYz4EYy8UFH5sCE1y2/IP9wD47CzUq9Uo6rfnzOTnucI0b1tVrTMdk+5rcP+d2mJIc=,iv:fbHX1K7NQjYVTbOAUD06PwL5H39pWtLk/9QSMR1MJ/0=,tag:L/2QtFr2jM57PZ7xMJAC/Q==,type:str] + pgp: [] + unencrypted_suffix: _unencrypted + version: 3.9.1 diff --git a/secrets/hosts/opentofu/marisa-7d76.yaml b/secrets/hosts/opentofu/marisa-7d76.yaml new file mode 100644 index 0000000..e5f3438 --- /dev/null +++ b/secrets/hosts/opentofu/marisa-7d76.yaml @@ -0,0 +1,23 @@ +enthalpy_node_private_key_pem: ENC[AES256_GCM,data:+aVxXKHC6OpNNNbQ0n6Eq3mJT19dcvREC27ENxB9+wgeErb+HL2m9+QjHKAzW8i/RhPA3cANLS/W8PsvWdxi3lo831U9jGrCI52TgggyxTWQDAgCPwsd2ihLtWzsHDCor80W1Wcs115dlWJS/E/ySWt3zPP3iAI=,iv:hXKxxys2KhhsRK+Bk/B1SBCibvSHFHkWU+pMAQUehDI=,tag:z4mDolGC6Leh69l+vC+ohA==,type:str] +ssh_host_ed25519_key: ENC[AES256_GCM,data:bLNAFi9d8JOWSWAnJrgB0tqgBqfON7APBbOA7g/UXfJLwx5hdICBkTQpxvZPjjTMdUVa4eoPQ0AG5b2mcnGfU35LoQ3xAx11yvmfaxuxoor+YcNc+rrU2puEsh4vFQESc4Ud0XY8tY3NnZa4F4RHDqEFd8DRN3FUpZ7T7dvxPkUAjzed719Wf5U4rLnWZQK9KZcAuX5Th58X4hl/d5UEEAaY2IDNb4F6gvLk6jFlzV7Ixagd6mfnKbP/UhxEoArW0JTjC7ZAO/qPaANLL3vNAgcLAV9X9O5rkipagZ2AzD6Ln0pp6Gc7N0sHjBWBQuIAnpCy50ilroxjIbCbChCB94TPw7QeeCkmcYKuiaUei5EppSEWxRQX03wAwqx2xN0XGborPBu9JJpEc9hY2GINrvMuDVM71pw1CTrJJsyZqFt5G9eVvLg07EPHKe1YsYpiCSgaDYQg+E8QAFfDgfEU6hMcNz1Sa7MhYP2kc4fzON8ahNujZm51XvBuKLzPdGxBskED,iv:FPyG9ISZrNmmmdiq2xuXOdEs9HDRQbXk0PTBCLipsdA=,tag:ZdUTwLxB9AqfSDMGT0PHxA==,type:str] +ssh_host_rsa_key: ENC[AES256_GCM,data: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,iv:l+g0e8zdN24qtnnjz7cYvm9ZWXr18k98myHtb6UNMXg=,tag:GLy2a8Q7av88b4XaCr/9rw==,type:str] +sops: + kms: [] + gcp_kms: [] + azure_kv: [] + hc_vault: [] + age: + - recipient: age1sfnct03u4cvfj98x4yjrcrrnu5gg8qgxrwk4uqq8w4e6wveeaedq97rn44 + enc: | + -----BEGIN AGE ENCRYPTED FILE----- + YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSB5YkFhU2NxUms5M2ViclJO + RDZ0ZkhjZElnNFhBK1lNVllnampLeUMyMnpjCitmamIwZjgyUkRFSkdkVktTUXcz + aTB0NnRjdUZuRFFkQU95QW1XakxidEUKLS0tIGNRbXlYaENhS1FIbzUrSjZ6SlBK + TjhyZ3hrZ0MycGNDL3pJUGFFdGhiaTAKHCxJWqleL/W/lCfJ3qdreSlLKNoj242x + sJb49qJ/NaiJ3AOybO6NgTI92zxYRjsG0dSgL3igmm/Yunjx2FMLjA== + -----END AGE ENCRYPTED FILE----- + lastmodified: "2024-11-23T13:02:29Z" + mac: ENC[AES256_GCM,data:PBwxyzKuvTnOmDfEbhSCDuGudxblsJLO9/ullP9jHQMqsuHwozrFzbWiiXG6YPya75A14iDOgpcfIjPtq67zW85BApuwiWm4V5JTSdgPif8leQEJUJ16KMkuEM3UL55Cq78TwsJ1R6rndJW4gABhcxYYlS2a/DldnQPyek/Pi/s=,iv:/jlu8qLfVkUsEtz29Bf8X9Bx8Rg8d7JTlU9M9uMWlsw=,tag:2UbD4u/jP1on62jR+GhTLw==,type:str] + pgp: [] + unencrypted_suffix: _unencrypted + version: 3.9.1 diff --git a/secrets/hosts/opentofu/marisa-a7s.yaml b/secrets/hosts/opentofu/marisa-a7s.yaml new file mode 100644 index 0000000..ec79e55 --- /dev/null +++ b/secrets/hosts/opentofu/marisa-a7s.yaml @@ -0,0 +1,23 @@ +enthalpy_node_private_key_pem: ENC[AES256_GCM,data:qyrO8IPIbK7FEVRn7HI20hq4sbT0W9ty1Vez14plUWgiqx+lf/J1qYShbR/jyDc38RBDq98n6SoTXye3o1YBwLA1ByhqpL6pNLc/87V0u3gi4UqdhwywkVYnwI0eD67eTXohtDXT9yj2dh5ZvTEOBoFxmId/Tz4=,iv:70d1v6BIP+dBldhD3fogthKf84sk1RIMTa/PG1paYgo=,tag:wasQmxA35YWlLXLfBPJxNQ==,type:str] +ssh_host_ed25519_key: ENC[AES256_GCM,data:511WhLFJolJ7h9MxMsRgugTK8xkQrNg3nI9RwJNj5ZFrFiUq0BYtoOq5SUElozAgwNyZkG3jHiFp3VMIoL2F5x5SwP4Vp2DyuPOMGzud7AJYo9tIZ+ROpMADhhiSBhdE8iSxaAleH+wiu2cLSIuston6LXMQ5u06kZ+d1mASmnrUYCDXSf/TPBKwgKXjxsIk1AsqZ9lP8QsGLWFWqAf1z2F9jrW7JqawDhcR0JuGs501laYN/9jbBA3p1Z9fEapOQoqToYzueEeibBWPyTp2CeP5sMlI1CyfbWo8G2sAVvANaWO9rKH67QRchGFd+bAHNgsTuVETdqKaBL0cs92MLfhwvoNDDibG3RCDyMxWcHDlimRv/NeG+cUS2z0ZdcjEAG8h097ezzO0eKZoiripEWjYTN0EGbFlTJ8i7e38Rh5dlKxUOJvmTz1AcvBLe5NDm2FRfFZ/DFr1V4pyadjrvDIYSwI0FuzJb8/1cf1KOCMPbS+EU1JhFVAmJw/kvCQ/LSK3,iv:KSBg22Gntjobtw9NTXTDX/hVV4LpGgyLOAzz09j41yM=,tag:wCNGgDQpIMF6CDkxCpLQpQ==,type:str] +ssh_host_rsa_key: ENC[AES256_GCM,data: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,iv:mg2JewecyTscKir1lqQJzZKLA64B4I9OytnfwvxFN4o=,tag:9bnF182q1rSDn17WjFe72Q==,type:str] +sops: + kms: [] + gcp_kms: [] + azure_kv: [] + hc_vault: [] + age: + - recipient: age1sfnct03u4cvfj98x4yjrcrrnu5gg8qgxrwk4uqq8w4e6wveeaedq97rn44 + enc: | + -----BEGIN AGE ENCRYPTED FILE----- + YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSB4TnlUd29pWEVmRjNoNTRa + Qm5OZ0dhSVRNcGNJby9GQ1NrRmJLZTdmUzBFCkhKQWRFb0JHZzUrZm81dlJoMmRS + TUUrVlZBZHJvYVlzcGU4bjJ6SkxOV1EKLS0tIDUzb3VvNVRkS05tTXRxcTZvU1pB + S0I4QXhHRGExYkpKTjFmSHk1M0tWbVUK05KTew5+eWgZOaU2IvqaTGNdIKJvvCL+ + JWGeZyQ2TTYeSwd1EIqZ51pLMEYuz6d+xJcmwc9sYq3DGpXHsOBrGg== + -----END AGE ENCRYPTED FILE----- + lastmodified: "2024-11-23T13:02:35Z" + mac: ENC[AES256_GCM,data:45A63uzsyJeo2u9cCtHFJ+NuCxjuSZiIFo0uWWzP6Q0xdV6XMXqgTYbY4XegPopTR12wGZzuPKI172T7o/sTmaUByDl5HzvtF00dadOtjnG8HPLvtuJAtdfN3MP81w2UqQHJDiDsC6ofu8X1KkgjVyu8hVkP8e7pU52aIimb0pQ=,iv:SzM0cBwm1YQmyVe8AIXFJrrkX8SAAfnIXTYwnINsNlM=,tag:BtVL+egZYL1itxwsoI8aiQ==,type:str] + pgp: [] + unencrypted_suffix: _unencrypted + version: 3.9.1 diff --git a/secrets/hosts/opentofu/reisen-lax0.yaml b/secrets/hosts/opentofu/reisen-lax0.yaml new file mode 100644 index 0000000..fdcfcc2 --- /dev/null +++ b/secrets/hosts/opentofu/reisen-lax0.yaml @@ -0,0 +1,31 @@ +ssh_host_ed25519_key: ENC[AES256_GCM,data:M1rySgMTXRKp4hkc0RQQ+6fAKGyl+F2nzZxX6mkCY3mW6oMdK7Un3ZTU1c2C3t2jFWPRaVWQFgUFg8cGPaWVnPXHbWVzGrgs8ja8m7MErUfoz3QV5aLlYSXk+BglCgQDE/g4LFiOO3/XNaFMEsWTRbu0T27TuS/FTaFIa+p57gIgb0dyoFHDX7ZR/RWodFr/wFvud3v1iLww7b5DJAZVkjGpzXK4gkpC4x4y4xA5UMZwf4Ne7asqHOzkE8lVjLacopMAq5VDghWgF3cRrUtsYBNyJQfJtqas3JDT68Y62Z87ODVVwjWT4s01hAPJzEFwVFzWsh/oQpAqdn3RBfWvJEUymUSJ/vJymcPGXOOebGzYrCOqVMl4mn6TGMxPvOO+upSLeT3RIJn6cVwcWdWkorizmrqW01vAeqPXB1cR2sXLYJiwrduQNEZqO56aYQ7zGS2dIegNHyTuo2kUd84O54TeX+vV60KvDGoAwo9+I1hNOL4dQipTuFDODqE9LAUBeGUq,iv:NS2IqE9KHeCpGk2d1qAO2NgfPThyIv65lkoALOrP8Sk=,tag:5FVELChpVtVsTJXPNbBmVQ==,type:str] +ssh_host_rsa_key: ENC[AES256_GCM,data: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,iv:e2yNhh9UHfweBi8nOXagCE+n+u7NtFIcWvLpio16EO4=,tag:13Shlnne6v3Vy4gs1OU4PA==,type:str] +sops: + kms: [] + gcp_kms: [] + azure_kv: [] + hc_vault: [] + age: + - recipient: age1sfnct03u4cvfj98x4yjrcrrnu5gg8qgxrwk4uqq8w4e6wveeaedq97rn44 + enc: | + -----BEGIN AGE ENCRYPTED FILE----- + YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBhN3RKYWNxWlJ1SEp0cEJQ + cmxDYjU1ODlNdFNrQ0drdmNmRllkTlB6bkFvCnNZRlFMdmRFeWc4N3VpS0ZHZjBa + M1RMaWVzWk5vNDA1STV2WWN0c2ZwR2cKLS0tIHJWTmJSMDlGR3RqaFpkOHhmQ1Bl + d3FKOFgrM0pQR2Z1cG9nVFg3N3hlNU0KEc+qKVlHB9fBT6Ws4pJ7R93T5bu/G3ZS + H8OhsKhPQIpPJrIuPCj2Y+0NwVUBsNO4KUGM+KOpyX9Y1PRcy1YDcg== + -----END AGE ENCRYPTED FILE----- + - recipient: age1uf2h3hlv373ppdstjlngyuu7q5mee3u3ww3674lsj9rlt9ax7vqsv7wpe8 + enc: | + -----BEGIN AGE ENCRYPTED FILE----- + YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBRR3VlTWFMZFlmd09ySGR0 + a3gwYTNxdmlsOUdRQkFPZkl0cHRQRWdhY2x3CitBU0gwbGJSc1B3UEluZmVSSTI3 + WGEzOHp3QlcvM3h5SlpqRzRBbW1wZ3cKLS0tIG5LVE1PMGs0UGlHeUI0NzdCR2o5 + YmdMZ1NaK1MrM0h5L1ZJVlBLRC9uMmsKx5AcT0RumQwUu23rCC2mIkxMHWZDaNX3 + 596RhJUBGtFc5S1hfYQUl5QZg5KX2AUdQqY/+JOck0xqa+zcdP4pXg== + -----END AGE ENCRYPTED FILE----- + lastmodified: "2024-11-27T16:02:26Z" + mac: ENC[AES256_GCM,data:2vce0mh6b4N/O98JD7Un15WVkL0IvS/fnZTjrL1LEAwbuRp+yqgF2agANn7Cp5B2J/VSjdCxWHlcsU0V2VNn8T373uLa1Ea5UOj4cu26ANZUOZX26aaaMvb/qkkX0t6W9uVQaFN83LLK/PjMgpMcAhKB3uBMpmRNZr3+BkQT14g=,iv:ZjGMKaJ9cFPds/zU2yuJsoYnfR93lXoBUfj89rLCmXg=,tag:+mt3VHAvj5AMJtZjo7UdGg==,type:str] + pgp: [] + unencrypted_suffix: _unencrypted + version: 3.9.1 diff --git a/secrets/hosts/opentofu/reisen-sin0.yaml b/secrets/hosts/opentofu/reisen-sin0.yaml new file mode 100644 index 0000000..035a785 --- /dev/null +++ b/secrets/hosts/opentofu/reisen-sin0.yaml @@ -0,0 +1,32 @@ +enthalpy_node_private_key_pem: ENC[AES256_GCM,data:dipY9ncwdWYTJY+39umZ3iyLzz2Ivr+f8eRxFN6funofORKv73IRn9koHmq1i3khZS0BRpUEj13wMV/R74EKilAhpN6Mitv1UpwlFZhvtQQHERGdb2wX52Z4JMFCMQsiG8qPqaJBjNTg4twjacyc67Zm7WofCpc=,iv:cPALr82vv1FFx52RZAafVIYVDeENX8up/ESaaeWGMQM=,tag:JFd9Vsw+jNzDajtNLUEOtA==,type:str] +ssh_host_ed25519_key: ENC[AES256_GCM,data:+POO1TxesQWTvdlHVjzr5FCnYZeAZftl2lkv/2YvVjSIOTEwXcJ5D/gniJ1/QUXM73uDgXQMlk78wS1tATnYlZNn5mJnCFght/vXev4+CtUsv/NsTQ7Coo6uFf8xdHxQVTsyoBk9s90tubFtlzlLnS7q85/4FYoMnXTJtsj7e6C2fev8eRSjhGWoKCkUdhNUm9QZj6hEUuuir+hHbFm3Ab0U7+OO806HEOZlIWLUr6PoUnHCZejXfL1FSUQwiqTmqT43kAXLguzXyrAQbA761PNCLFQroS4//3gD5vMUj/bz5XDbusE7gFmBluO+f/8YC8QAJ3uDs/ml2Qn/Pd20iUAmYHw+/xSK5pQ2n42axpnfRTy0Q2HTb+D+VzH8CpTZLIuGBXbH0egpOrLp5Cv1w7mj/nuDqgXxSJALNRk0O/UKUtp/kZ54jeqki98Y4Rw13pgPDMbZpb1g6st17OtsBPfDzcHnOO9of6cnTJ6mpOVygqABN55mIxAri7/42TGdAN4k,iv:C0EPh1jLfSipmKi7EHOoOpSV5VU2lbdNr8yxOiekFpU=,tag:UD3YdXxj4bHVI36mGKWXnA==,type:str] +ssh_host_rsa_key: ENC[AES256_GCM,data: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,iv:pr1rV+DJVxFMZ4F9IrjyTdHg54vEtyXVjrBaqpBEmY4=,tag:oKRWLIHjzw2vbns5Uq3JEA==,type:str] +sops: + kms: [] + gcp_kms: [] + azure_kv: [] + hc_vault: [] + age: + - recipient: age1sfnct03u4cvfj98x4yjrcrrnu5gg8qgxrwk4uqq8w4e6wveeaedq97rn44 + enc: | + -----BEGIN AGE ENCRYPTED FILE----- + YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBPZ0dvQ0Q4NjczOUpEc2Vi + UjVDOVJvdXZpWHh3WHNmQmV0VFNLejV5QTNVCko0R3FKZkhvR2ZINzB6VCswOXI1 + SjB2Ky91MzI3SnY2MTRXd1NZZVhkd2sKLS0tIGhCZzd6Q0g4cHhLZEtvS01ORU1D + ejZidXVaZ2g3eXpiQll4OXEvYjhZZUUKNTJ44wtxOZB/+3gVwqyINvlaWarnvyBl + xwJMFHEqPX0APomUWZ+hgXeVqst/6hybmof+wlgbrL2DVbr6cRmMFA== + -----END AGE ENCRYPTED FILE----- + - recipient: age1uf2h3hlv373ppdstjlngyuu7q5mee3u3ww3674lsj9rlt9ax7vqsv7wpe8 + enc: | + -----BEGIN AGE ENCRYPTED FILE----- + YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBuQUl6cEVUNlhSYzh2Y2FD + cUZWWEZUZVRPZDdESzFVRTlzZlphdm00TFFRCkpObkZHeDRyZzVxaEI0bGdKSVcv + MU9RVFBwTzNHS2dtOFpxcmZTWHpzV1kKLS0tIEpDMEY0aThzdkpjSEVxaW9uVkxr + OUNWZWZKeThaamdWZnpuY0RlbHRvSGcKJrVaRhVsxUjvInaN9eRTe+WED4arhpuM + 9gDCtvApkmOqQ9kJh7V3cFvR3v5pshS/aypWL0/3lTD3CYwOL/6Rww== + -----END AGE ENCRYPTED FILE----- + lastmodified: "2024-11-23T13:02:08Z" + mac: ENC[AES256_GCM,data:N2C2tvrHDA774pgHZYKE6AGY74j/4ZKiFzbI0A8VbsFGTOylT+mpsd1BP5vPNb9EYqmYimuuTrnOmE65pKgotDF/6pOI05PYhFg9UwxLst9cZzw8zxp6UkSLC2lmf5caFMBeLz/7R/4VFCfdqjsLAnJZry3y7WVCWOwWjM0FxjU=,iv:fQ78vsu3lTg5lqD2jepEF/F4J112ReIJdQ7B6YdWGoc=,tag:R/BcFeOormLNPttoqWqZ1A==,type:str] + pgp: [] + unencrypted_suffix: _unencrypted + version: 3.9.1 diff --git a/secrets/hosts/reisen-lax0.yaml b/secrets/hosts/reisen-lax0.yaml new file mode 100644 index 0000000..d8e80c1 --- /dev/null +++ b/secrets/hosts/reisen-lax0.yaml @@ -0,0 +1,41 @@ +synapse: + signing-key: ENC[AES256_GCM,data:dD/0x3sC87wNJAvrGB9bU+FHJhD5kCfZ1cUPsmbyq7Yf1xIuplSN3gdFBStpeM668m1E3zdG7VYjGkk=,iv:V9A1hwp/EURh62dhEoDjc4FaOUDPsj6vUMhvTJqLOu0=,tag:wPSSfTEvr+XTW03f0BJHiQ==,type:str] + mautrix-telegram: ENC[AES256_GCM,data:kbGlvWU5m5bKZiSoW3Dl2/hyMo63SHaJxYMopISXSQEg7t3m2R+LVuigyrgvqrU5joJUPYi6pb8WnuxxEAuQgexyrXKeqNorM33z7CEki7jhT7yehuottEkrTeQp2GDzzBQRc3dZ8cvOhts6qCDpkhczemUfp1nHzOLUTx1aB/o5R9Zm9BAeoC+mVW3rMyOUR757U2E9AR+a6HTcICZMhFc7wkb7c7Mj0ejfwJFN+aDZNOQ+EmY08utMstDi6f3cICnt+Jz4Myh5NFO4x/NuGpolyjZEw2vjIFI/DgNZBtF0kZggEc6i2pNq8+p29iu47syE7cMh8o6LWZNCzWYmmjuPC5+Kn2E821IFSwoRbefxVjogeLc6P13K7m90OElwJ71V7CKbHMT6cReyGEqN8pFXv15Z4kwCm94EasVZYHdMF492QwwLFXf1kC9cYNxKG9Mp2Az1dR7ynXSPTkJcGR4x76NCL2e8klIWP5vTnOMOpP0QCQ7MeStNoX630TbrhzWKjHWDkosuaeQ=,iv:/XNK1hiruxyObKyfs+XGxhGAP8t+BNP5zyBebV3q5Vc=,tag:ThelxSu74EmFJnnKdh6sTg==,type:str] +sops: + kms: [] + gcp_kms: [] + azure_kv: [] + hc_vault: [] + age: + - recipient: age1sfnct03u4cvfj98x4yjrcrrnu5gg8qgxrwk4uqq8w4e6wveeaedq97rn44 + enc: | + -----BEGIN AGE ENCRYPTED FILE----- + YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBxVmppaW4wdlFHaUlHWkNF + b2lrUlFic01rTG9IMEVmM2JETVdtYytEMlNNCm95RjRBcHA3WWUwUmVBTm02ZDgz + SW9qenFxNC82cG44Qit0ZjlDa1EyQW8KLS0tIHh6L1ZRVFBIOHIwZzhKS3RVRW9q + VjVvYnRMUGNHYjg2T1ZtZlg1b1Ryd2sKA1MD3nVkk/NjxQkYF4ul7zNcmGAAaRC9 + 9I3IS5x+M2zeTCe8QbIT6Yr1zmzjZDtFFG9U/xNPwGU4JTS703GhfQ== + -----END AGE ENCRYPTED FILE----- + - recipient: age166kxtrcx99fxlgtvz5mvyt5ctvk3dt09f42gvm94ngnkyztmmelsyzdn77 + enc: | + -----BEGIN AGE ENCRYPTED FILE----- + YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBuUlQvK2lPdjU2UjRVYWtZ + dTVJbm16cXhoTjh0Ui9nUlY0ME9uOSs1UUJVClFOTVE4VS9FdW4vVDBXeXdRSkNV + VVlFMHhkUTVueXliS1JnZ3QwUUd5SW8KLS0tIFlBazJCQnZYMDlwNzV2K2xlWUt1 + ZWUzUUYvTWp0SFdLakpCY3dQY2dCd0EKr8rzC+I+v88N+jHuUHBSzLtrpPPEzYO7 + NOT7PvbFt5xHojU6zJGoLdp1AGRWvTJHhJd5uZe6CSl60rJ1rq37Ow== + -----END AGE ENCRYPTED FILE----- + - recipient: age1uf2h3hlv373ppdstjlngyuu7q5mee3u3ww3674lsj9rlt9ax7vqsv7wpe8 + enc: | + -----BEGIN AGE ENCRYPTED FILE----- + YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBDczdTT09BbStBQ0JsR2JB + SHpnMjY3UFZEK2FkaEdPVkVTM0M3NTdNeVZrCjQ1R0I4MGZxNDdMRnJGZUR0Tkp5 + emxmdmFFVEtvTFJGV0ZyMlJCNUFGcUUKLS0tIC9HalRpdzVzd0hXbnRDS1JKMXZY + T3BrRExrRnRHaXk4SHRnQW1hWVFIWjQKBr/jhoHIcMximk1Lg1uO1fYSwObuVioN + zxylpVRrPDat3d6rnXesSz9vCNW8vNzkre8d4fBJbpOfDNxG3mUuGA== + -----END AGE ENCRYPTED FILE----- + lastmodified: "2024-11-02T10:50:15Z" + mac: ENC[AES256_GCM,data:nyHmR642PIXCnNNddI9sJvl7fx3Nr/kL5NhxHk8WOHEeinaDPtyBr5iWsRvi/gvWoHs2Hcwu2/n+ODsv781Ci+b2l2eVl6UGDPIpNtiY+qdXVbMi6Z8upCcMKx+YXr45C/6yxR73E2XZeffVaaI5dMRrzc3qj9jFmQ0ZmpcOl28=,iv:jEX9H1vROmhHr58/wlolLILtR/qGeOBLtfG3t6MLwMg=,tag:hyO0JE2b79px6ArgruwT3A==,type:str] + pgp: [] + unencrypted_suffix: _unencrypted + version: 3.9.0 diff --git a/secrets/local.yaml b/secrets/local.yaml new file mode 100644 index 0000000..892c2e9 --- /dev/null +++ b/secrets/local.yaml @@ -0,0 +1,33 @@ +wireless: + edu: ENC[AES256_GCM,data:pJywIoTlEBSeAiSbLxKhmMHSM6Jl+hlAQJcwN35wTySgjKp0bavwe12lUmRh9uqYsD0dOqylEp+E8k2RqnKv7tTa8o90m8sfLDYbnZhcxc6b5PqLqrOy1w/kt1Yyalw2lF0L7kHxwJIMw0AOzbvTCo4MJJ6fP60o1qufGehDWkbTfruo1ykoFZ7XHxsDTgnx0cmXdN14R8dzx42Sb6XyVRHcJuuIelN619gojgmJERRjdDwpU4RuhpdNxXT0FizMxPW401tQFGuLzveUTghjDe29YKiNquN9ZKU=,iv:PCB19C+7xwKirjcd7kwa3HP4Vv18dO0KcZfATJoT8Gg=,tag:CcM5zX5tyHl/xqT2r2f5qQ==,type:str] +user-password: + rebmit: ENC[AES256_GCM,data:0gVXGbkY5W2GWSZF2WBVS2tySstaxQ4iTcBbXheT1lGYrk3VMXzK3bYgwqndsZJoHTz4ik99apiFgGn9B1BqFVosFfTNmNqnVw==,iv:5wgcAgNgv68iKLLcP/UzWXihvN1/vMBkyIAws+AoXAs=,tag:95QDKOY012ifSwpJyRlJJw==,type:str] +sops: + kms: [] + gcp_kms: [] + azure_kv: [] + hc_vault: [] + age: + - recipient: age1sfnct03u4cvfj98x4yjrcrrnu5gg8qgxrwk4uqq8w4e6wveeaedq97rn44 + enc: | + -----BEGIN AGE ENCRYPTED FILE----- + YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBBU0pFeEhobHRBcHluV1Np + bXBGUzlNV3JRRkNNNisxYWhNWTlicldYNWdRClBVQWhGVmpLYzM2TUlrMFdRRllV + RGhsWmw5WWVMaXAwdXpKODVldi9rakEKLS0tIEQrc3VyVjVkb0hUZDRpUDZKTTNN + Q2k2RTIrM1BrSFdnOVQ2SkpFNFBKS2cKwd5Qq51jrbTVIC1LTaB2lLgJuOIQ+LUb + Z0eHZSvAE9hfim2eBvGXwKwR36nrEtySYhaG/Ho1QmVncgD3CI0xVw== + -----END AGE ENCRYPTED FILE----- + - recipient: age166kxtrcx99fxlgtvz5mvyt5ctvk3dt09f42gvm94ngnkyztmmelsyzdn77 + enc: | + -----BEGIN AGE ENCRYPTED FILE----- + YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSB4N243NmM3SDI3ZmpVN2V5 + QVY5V0dQajVrWitqSEJaMjdFT3J2SjVUNnc0CnRaV3EwYnRqQmM0VGJ5UjBCbUdn + VGhMaXlzUkk3K3hRQzhOazhoOUVieUEKLS0tIFZFQ3lpNFNvaTV5UlRIdGpId3E3 + RlFlbHVGcS9FaXAxa2duQXJBVWFlY1UKCuD0GMf/CzeGaGZKxCaNdaYCOplpv9lx + rWKn3wGi8FHkJVj85U8Nl99uN64nwfTh+8MB8GXNwG0fv/jjVRiWfA== + -----END AGE ENCRYPTED FILE----- + lastmodified: "2024-11-02T06:58:25Z" + mac: ENC[AES256_GCM,data:bVj4YD7lmQrs1pbES0CbnnbcCbcTCfUCF3PKUwWTqMJqDCbDchIFc0u+5drdDU8XevStUa6lNq/Ffu2GXoDjt3ybXYt22GJ9RN6ADXKSvNwzjIM4JYp9lxEwp5Z5StxM0/F7PBx3n+DJfsRM4xkRnZQ3cNJAYYl4KevDL0naOsY=,iv:YFV+MdpJQUN/Powqr37PfVPHUQl9kO2tkZSAldZAGOM=,tag:DGoedXDQqYc+jxE0hfP4uQ==,type:str] + pgp: [] + unencrypted_suffix: _unencrypted + version: 3.9.0 diff --git a/zones/data.jq b/zones/data.jq new file mode 100644 index 0000000..a97b35d --- /dev/null +++ b/zones/data.jq @@ -0,0 +1,8 @@ +with_entries( + select( + .value.sensitive == false + ) | + .value |= .value +) | +.hosts = .hosts_non_sensitive | +del(.hosts_non_sensitive) diff --git a/zones/data.json b/zones/data.json new file mode 100644 index 0000000..ce6107e --- /dev/null +++ b/zones/data.json @@ -0,0 +1,71 @@ +{ + "enthalpy_network_prefix": "fde3:3be3:a244::/48", + "enthalpy_organizations": { + "core": "rebmit's core network", + "edge": "rebmit's edge network" + }, + "enthalpy_public_key_pem": { + "core": "-----BEGIN PUBLIC KEY-----\nMCowBQYDK2VwAyEA8Oqlkh1JAW6IbMOVlhdlVKC9xQ75hzBeWHklcdJENFE=\n-----END PUBLIC KEY-----", + "edge": "-----BEGIN PUBLIC KEY-----\nMCowBQYDK2VwAyEAXaBaGumao95/j4M7nWNNytd8u8r1KAGSbKDs0aT2mVU=\n-----END PUBLIC KEY-----" + }, + "hosts": { + "flandre-m5p": { + "endpoints": [], + "endpoints_v4": [], + "endpoints_v6": [], + "enthalpy_node_address": "fde3:3be3:a244:a230::1", + "enthalpy_node_id": 2595, + "enthalpy_node_organization": "rebmit's edge network", + "enthalpy_node_prefix": "fde3:3be3:a244:a230::/60", + "ssh_host_ed25519_key_pub": "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIDVLnLJQLiSquUSKC1aH9+mZuCHJex5B73BGY4TNDlxv", + "ssh_host_rsa_key_pub": "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQD3HwcBWColirOvlDd9oqP5BOuCxA85rfKEQ+d6Ey12s53qcykIfojg4EisFw+tQmLTijj9FfzTZFkcvd/caBOelUFbKavjS0jZ/r/zn2ThLu/kXVWrKmDlme8H/JircTBwUCkDYWnpMghPq7DEm3OCBU/lsVUJK0akKhZvvx4vlj/CD3uLXDuDDXVJCfxbRcw9NH+l57OhVDR4DD5P5zU/cP0ttBk84MqxygHeAtiK6gtwdSNl3V3fYiBO+nBlap0fU3rZh+yzzLYJU831FRAS85E2DnEK698hVmjInNKIxWzOv8O+EiriHfHvU4A3XQN31s0Mi+exPJHWp7UMN8oTgSg01kq2MCD9Lg5yAZ0t509g89u8uJ90LRQky8KOn1JNwng45+21GnLtH5Q65inlAFi1kXbl9Lr85Uy/9LpTZJDJGgGtlC4YWO21hMMqyCjgiVctKoT+wkf2S0ePUazWBq4/bWTwh5mTva+FbougcMaC+eqOJDzQIfwqIxRsR4n5txCRLM5J5hfASnJmoHqj7ipYXb3pWcPsxc3k/iE9aZOTlv66RaJ5d9V4GxyWzxM08dGIEw58sjQiFpqmlDEPmzPLfu3nzMPmIsh834OUWrUMtIr1Gae11QAudAd2oKFhWnIdEUkl2+P0OVqUqrFoVZZokaK7uPrNJFy5iKxaNQ==" + }, + "marisa-7d76": { + "endpoints": [], + "endpoints_v4": [], + "endpoints_v6": [], + "enthalpy_node_address": "fde3:3be3:a244:d790::1", + "enthalpy_node_id": 3449, + "enthalpy_node_organization": "rebmit's edge network", + "enthalpy_node_prefix": "fde3:3be3:a244:d790::/60", + "ssh_host_ed25519_key_pub": "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIBBdcVQak4mnur3LpBd9TMWeOdh8LBeWkNQKQtNmK03x", + "ssh_host_rsa_key_pub": "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQCoGltlUb0Uptzulodhko/lP2Obux/w9A92zxf5yQAqrEXhyth4eHPWV305PRXYDjrCC3zqQqzNjxQ5eiJmIhFwh4iVV36AQhDGgPfHrW41Oaw1owPOYNu42KEfjti6NbyLOIoaXL8jaA4nrjMqppHi4j4ll49KUmcWi4u1uE13tY0W8ua+0N2BIe94jBfuPUjp4/0jgXGwPPNlUaTCnoU16XKIr4EFs/XPZcMfNxekdxXGS8QRjMWd4jjCm6htoX/7cYj/xndGzEdHb8f/9Z1VzS0wXOrKNrH3ewxYgkNjLUx3OlhbKO/WzOHaFyGDcbBnelMi56YqDDnAur6+F7dXjQ2Lu6Zw1XdqzEugFkpz6xPnDquTRVSrB9tljr0SP0Z1Y58QHP1Q/ahliK2ou915XnqYNM3M/fOWzsqlY89390sJxgPFyaOGeeDz+YGQ9uVqXJzupDagy/XU8GmQHHWvFuN6Hr1tT2S9QjsosHhDotqVSxm8KgiEmeLnQnVjTnL/cHI1HiOQH1ZLds/iHQJZzholn5GRk+HaOeIpIJLyAstL48QheUTbBR//LLVTVLpN4iKiLfVYbWeNhn5S8msCLXVZa317ns2k1614j0nrZnAXpymL091DO/y8QfYacG+w2tmpiAtGEADRagXQ5mC5oMqstUyM22G2SzH9GAFSFw==" + }, + "marisa-a7s": { + "endpoints": [], + "endpoints_v4": [], + "endpoints_v6": [], + "enthalpy_node_address": "fde3:3be3:a244:5720::1", + "enthalpy_node_id": 1394, + "enthalpy_node_organization": "rebmit's edge network", + "enthalpy_node_prefix": "fde3:3be3:a244:5720::/60", + "ssh_host_ed25519_key_pub": "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIN9fXHmGnidVo2MoV4ayYBbFmQebM7ldDT/o+fCP4mMU", + "ssh_host_rsa_key_pub": "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQC/IIzE70sM77KfOHas/WXa5D6vCBMP6cQVforOxpmoYyTmIB5we0n0YuZlp8giimN8E4yRfq/9Kc7hdpog9UR2sTb19YqpiCUsTEWJSP5NXWY0KALwE6Na6rijCprsuf6rv/ndT3MbCcDdi0myZGZV8Qe6g/+JfWlfWtsjvHkph+/U9QqZSmNnU1WlDHS1SlCkchjpJlPN2jx7dgJ61vqO0+0yTu76pl1kl8lFoMlsI8jIGAAluJMp2ktxs+sE34qpWCmCiWtU2CzgS+XVG53sZdjIXQhb3hBKCyjdBr36bNWfMNNB2FXgSqQOzQJxR3SRn+3PKQSuP+uQCrAX68hzQZg7x7gsA3tM8W+XtkDjaejUJ3USnouh5D8tYLMroeAbBwulS+4mQaCvC5CWE8MdqMwAwGC6unjbfq3tC3QkrWohOFZyXJ862TTOywJiVk1qP/kz63yeXD5pbFx/WyfpQW12TKlzIClHnbfTCTY7AuxoXnhJTKIXN28QIB6ZNwba3nOg34HhAXXgJF+l+UENN1MZ/mg0jOJ0IlVmGjEulZdI+G/eCfvfYv8pU7ItZvrge98vX0aWqAE54RQGO+dpkFz651LEBeCe+UB2xzjxnm0dMmhdUKsV/KEKRhSiKPNk3iBy52DVXCoBGPG/3b6Hc6c7ARiv0EGYm81xxrktkw==" + }, + "reisen-lax0": { + "endpoints": ["38.175.109.149", "2a0e:6901:110:276:5054:ff:fe81:ec3b"], + "endpoints_v4": ["38.175.109.149"], + "endpoints_v6": ["2a0e:6901:110:276:5054:ff:fe81:ec3b"], + "enthalpy_node_address": null, + "enthalpy_node_id": null, + "enthalpy_node_organization": null, + "enthalpy_node_prefix": null, + "ssh_host_ed25519_key_pub": "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIM85np9WYG/RXWvQETJhvHAC4OVp7w/8PbQ5lAEaEHDR", + "ssh_host_rsa_key_pub": "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQDURKDaakQjKr7dYDr0a9UZZsO/Rz2lqqiP5bCo5q22UvYa0hdvHSt+2OHL6FTTxfs1VAW36ygA7/UcHgfAhs1eilPhvfeLQjgQa+IcUvNty2PILL/1XrOm3Uqi63nGVenLm0Lib2hPKYg4Veuo8DrKEkScMTi+FXKn3erDeJT/dVwG9v0xfyRN/tx9kvu4I2zeXkqR84X56sQsLOhYWntNYLYeXue76XtIlNTDrfCtmQmUbt+Cxqypcvu+1xep1TuiEubpaAcqjofXnSBu+eq8+Oy7BuEud9kprniF3uX3fqzzgQCB2w3IHK9PE3mQFBkXMZ1kHTLD/UEuB2quTqFdrHpAAIPJrHRghqmuD/+KassG3+KQAj3D4ZNMv+A+vmNRWJ7p/d6lGQrhLR3FMhZBUEG4S7t+G7/00hI1EM7nBw1uDEuzv9SN+eZd3dZ6mP8zEK42+wsUXE0HWeDylkcUDDrrSv1boSIVkMKfeTEn739Jki2pV1LVrrJnYPv7kBfWw6TZUqEvQmeTkmw2x2NT2eVELI+gBUfGXsPACG60dbHwwcnit3qf2Qeg+mWdGTnqA532cUEl4CTrT04FKAHus01DgYpW8VOE6+7Jb3bpT6fUILmTHihOnqRXLzlNYfpnOgRSk/0DwFnIIMhKmRX6wWoIuuWksu5na4ajf/5/eQ==" + }, + "reisen-sin0": { + "endpoints": [ + "194.156.163.233", + "2407:b9c0:e002:20b:26a3:f0ff:fe46:a4d0" + ], + "endpoints_v4": ["194.156.163.233"], + "endpoints_v6": ["2407:b9c0:e002:20b:26a3:f0ff:fe46:a4d0"], + "enthalpy_node_address": "fde3:3be3:a244:2670::1", + "enthalpy_node_id": 615, + "enthalpy_node_organization": "rebmit's core network", + "enthalpy_node_prefix": "fde3:3be3:a244:2670::/60", + "ssh_host_ed25519_key_pub": "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIA4sFno9JeH0787wN/gKJx1RgnTARnR8XEq7xogQt108", + "ssh_host_rsa_key_pub": "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQDYudfdvzw7yEA3onZf4+PJbOecxzinYnThKGI+K7uoOUw/RDwWNWxgh+o9j+/crGGazytg8yNe/fmIGovZ9nl2IYCH6rTBIe9bvM1p0TzcOXBrIZFOtXUGj4fHT+56MzdLHzlaMUGBLCV1NXXm4HFztN/iQKIwS4B2lvv8EtHsFybzUwWvw9d3nfQItDoBKzKhwFPg33bmAyF6JVLncZiMY1q78XZXAYfWGO3ba61f2ScsgsAxHSELkIWKXpjnxXGuHZGUNk4j5LSctVsM5RIkl37th4CWjKsTp1Iw5vwHXLou+xDrvtjdU3UxGWTYtx2KhIwzNR+WdLHCQ6RaPLvsRemuHhfhkcHfVBpYwL/LeQEHdfNX/Ulb9B8GzAfgGRzKzSyrkR8WhtCtOYQ0Zr/TpbGgzkS8cY4RLIEqZ4R8hFCEJw28za3kMKov4P2t2gI0RL5yVN0TzyMi1i46eMRN2DgPkzDG+kMqXBXzWDbeiX86/z5N5l7KCLNLQ4R2R46g8FqigRPhXEmhxkUjsnsYwOlGjwqEIRvzUpQ6SGF5LPv0E8KncEZUPDhXufBe70pySJi2dZQJu4CJpgi88rKRelJAX2eS9Ba49gXxmQjXWXDvk/9HBqoE3QAw/iXQlwi0G9gRja68FSKKq8K2maGj6KFdUw4Zz8zFuHn2HkSbaQ==" + } + } +} diff --git a/zones/registry.jq b/zones/registry.jq new file mode 100644 index 0000000..71b3147 --- /dev/null +++ b/zones/registry.jq @@ -0,0 +1,21 @@ +[.enthalpy_public_key_pem as $keys | .hosts as $hosts | .enthalpy_organizations | to_entries[] as $org | { + "public_key": $keys[$org.key], + "organization": $org.value, + "nodes": [$hosts | to_entries[] | select(.value.enthalpy_node_organization == $org.value) | { + "common_name": .key, + "endpoints": [ + { + "serial_number": "0", + "address_family": "ip4", + "address": "\(.key).rebmit.link", + "port": 13000 + }, + { + "serial_number": "1", + "address_family": "ip6", + "address": "\(.key).rebmit.link", + "port": 13000 + } + ], + }] +}] diff --git a/zones/registry.json b/zones/registry.json new file mode 100644 index 0000000..1b5223d --- /dev/null +++ b/zones/registry.json @@ -0,0 +1,82 @@ +[ + { + "public_key": "-----BEGIN PUBLIC KEY-----\nMCowBQYDK2VwAyEA8Oqlkh1JAW6IbMOVlhdlVKC9xQ75hzBeWHklcdJENFE=\n-----END PUBLIC KEY-----", + "organization": "rebmit's core network", + "nodes": [ + { + "common_name": "reisen-sin0", + "endpoints": [ + { + "serial_number": "0", + "address_family": "ip4", + "address": "reisen-sin0.rebmit.link", + "port": 13000 + }, + { + "serial_number": "1", + "address_family": "ip6", + "address": "reisen-sin0.rebmit.link", + "port": 13000 + } + ] + } + ] + }, + { + "public_key": "-----BEGIN PUBLIC KEY-----\nMCowBQYDK2VwAyEAXaBaGumao95/j4M7nWNNytd8u8r1KAGSbKDs0aT2mVU=\n-----END PUBLIC KEY-----", + "organization": "rebmit's edge network", + "nodes": [ + { + "common_name": "flandre-m5p", + "endpoints": [ + { + "serial_number": "0", + "address_family": "ip4", + "address": "flandre-m5p.rebmit.link", + "port": 13000 + }, + { + "serial_number": "1", + "address_family": "ip6", + "address": "flandre-m5p.rebmit.link", + "port": 13000 + } + ] + }, + { + "common_name": "marisa-7d76", + "endpoints": [ + { + "serial_number": "0", + "address_family": "ip4", + "address": "marisa-7d76.rebmit.link", + "port": 13000 + }, + { + "serial_number": "1", + "address_family": "ip6", + "address": "marisa-7d76.rebmit.link", + "port": 13000 + } + ] + }, + { + "common_name": "marisa-a7s", + "endpoints": [ + { + "serial_number": "0", + "address_family": "ip4", + "address": "marisa-a7s.rebmit.link", + "port": 13000 + }, + { + "serial_number": "1", + "address_family": "ip6", + "address": "marisa-a7s.rebmit.link", + "port": 13000 + } + ] + } + ] + } +]