diff --git a/.github/workflows/eval.yaml b/.github/workflows/eval.yaml deleted file mode 100644 index 528dd53..0000000 --- a/.github/workflows/eval.yaml +++ /dev/null @@ -1,51 +0,0 @@ -name: Eval NixOS Configurations - -on: - push: - branches: - - deploy - workflow_dispatch: - -permissions: - contents: write - -jobs: - deploy: - runs-on: ubuntu-latest - steps: - - name: Checkout repository - uses: actions/checkout@v4 - with: - ref: deploy - - - name: Install Nix - uses: cachix/install-nix-action@v25 - - - name: Configure Git - run: | - git config --global user.name "GitHub Actions Bot" - git config --global user.email "actions@github.com" - - - name: Process Configurations - run: | - git checkout -b deploy-comin-eval - mkdir -p eval - hosts=$(nix flake show --json | jq -r '.nixosConfigurations | keys[]') - echo "Found hosts: $hosts" - - for host in $hosts; do - echo "Eval derivation for $host" - if ! nix show-derivation -L ".#nixosConfigurations.$host.config.system.build.toplevel" > "eval/$host.json"; then - echo "❌ Failed to evaluate $host" - else - echo "✅ Successfully evaluated $host" - fi - done - - echo "Total hosts: $(echo "$hosts" | wc -w)" - echo "Failed hosts: $failed_hosts" - - git add eval/ - git commit -m "Update deployment configurations for all hosts" - - git push origin deploy-comin-eval diff --git a/.sops.yaml b/.sops.yaml index ad2d8e4..c092203 100644 --- a/.sops.yaml +++ b/.sops.yaml @@ -15,7 +15,6 @@ creation_rules: - age: - *xin - *host-calcite - - *host-weilite - *host-massicot - *host-thorite - *host-biotite diff --git a/flake.lock b/flake.lock index 8b8ea79..c23bdb6 100644 --- a/flake.lock +++ b/flake.lock @@ -2,11 +2,11 @@ "nodes": { "catppuccin": { "locked": { - "lastModified": 1733001911, - "narHash": "sha256-uX/9m0TbdhEzuWA0muM5mI/AaWcLiDLjCCyu5Qr9MRk=", + "lastModified": 1731232837, + "narHash": "sha256-0aIwr/RC/oe7rYkfJb47xjdEQDSNcqpFGsEa+EPlDEs=", "owner": "catppuccin", "repo": "nix", - "rev": "a817009ebfd2cca7f70a77884e5098d0a8c83f8e", + "rev": "32359bf226fe874d3b7a0a5753d291a4da9616fe", "type": "github" }, "original": { @@ -68,11 +68,11 @@ ] }, "locked": { - "lastModified": 1733168902, - "narHash": "sha256-8dupm9GfK+BowGdQd7EHK5V61nneLfr9xR6sc5vtDi0=", + "lastModified": 1732645828, + "narHash": "sha256-+4U2I2653JvPFxcux837ulwYS864QvEueIljUkwytsk=", "owner": "nix-community", "repo": "disko", - "rev": "785c1e02c7e465375df971949b8dcbde9ec362e5", + "rev": "869ba3a87486289a4197b52a6c9e7222edf00b3e", "type": "github" }, "original": { @@ -167,27 +167,6 @@ "type": "github" } }, - "flake-parts_3": { - "inputs": { - "nixpkgs-lib": [ - "nur", - "nixpkgs" - ] - }, - "locked": { - "lastModified": 1733312601, - "narHash": "sha256-4pDvzqnegAfRkPwO3wmwBhVi/Sye1mzps0zHWYnP88c=", - "owner": "hercules-ci", - "repo": "flake-parts", - "rev": "205b12d8b7cd4802fbcb8e8ef6a0f1408781a4f9", - "type": "github" - }, - "original": { - "owner": "hercules-ci", - "repo": "flake-parts", - "type": "github" - } - }, "flake-utils": { "locked": { "lastModified": 1659877975, @@ -259,11 +238,11 @@ ] }, "locked": { - "lastModified": 1730814269, - "narHash": "sha256-fWPHyhYE6xvMI1eGY3pwBTq85wcy1YXqdzTZF+06nOg=", + "lastModified": 1730302582, + "narHash": "sha256-W1MIJpADXQCgosJZT8qBYLRuZls2KSiKdpnTVdKBuvU=", "owner": "cachix", "repo": "git-hooks.nix", - "rev": "d70155fdc00df4628446352fc58adc640cd705c2", + "rev": "af8a16fe5c264f5e9e18bcee2859b40a656876cf", "type": "github" }, "original": { @@ -302,11 +281,11 @@ ] }, "locked": { - "lastModified": 1733754861, - "narHash": "sha256-3JKzIou54yjiMVmvgdJwopekEvZxX3JDT8DpKZs4oXY=", + "lastModified": 1731786860, + "narHash": "sha256-130gQ5k8kZlxjBEeLpE+SvWFgSOFgQFeZlqIik7KgtQ=", "owner": "nix-community", "repo": "home-manager", - "rev": "9ebaa80a227eaca9c87c53ed515ade013bc2bca9", + "rev": "1bd5616e33c0c54d7a5b37db94160635a9b27aeb", "type": "github" }, "original": { @@ -324,11 +303,11 @@ ] }, "locked": { - "lastModified": 1731235328, - "narHash": "sha256-NjavpgE9/bMe/ABvZpyHIUeYF1mqR5lhaep3wB79ucs=", + "lastModified": 1730490306, + "narHash": "sha256-AvCVDswOUM9D368HxYD25RsSKp+5o0L0/JHADjLoD38=", "owner": "nix-community", "repo": "home-manager", - "rev": "60bb110917844d354f3c18e05450606a435d2d10", + "rev": "1743615b61c7285976f85b303a36cdf88a556503", "type": "github" }, "original": { @@ -353,16 +332,16 @@ ] }, "locked": { - "lastModified": 1729958008, - "narHash": "sha256-EiOq8jF4Z/zQe0QYVc3+qSKxRK//CFHMB84aYrYGwEs=", + "lastModified": 1729544999, + "narHash": "sha256-YcyJLvTmN6uLEBGCvYoMLwsinblXMkoYkNLEO4WnKus=", "owner": "NuschtOS", "repo": "ixx", - "rev": "9fd01aad037f345350eab2cd45e1946cc66da4eb", + "rev": "65c207c92befec93e22086da9456d3906a4e999c", "type": "github" }, "original": { "owner": "NuschtOS", - "ref": "v0.0.6", + "ref": "v0.0.5", "repo": "ixx", "type": "github" } @@ -376,17 +355,17 @@ "nixvim": "nixvim" }, "locked": { - "lastModified": 1732936640, - "narHash": "sha256-NcluA0L+ZV5MUj3UuQhlkGCj8KoEhX/ObWlMHZ/F/ac=", + "lastModified": 1730642581, + "narHash": "sha256-Tcq+RnctJTm+TUr1fN3ivqYNcd1pJnHYzLDQdgUCX70=", "ref": "refs/heads/master", - "rev": "a3709a89797ea094f82d38edeb4a538c07c8c3fa", - "revCount": 20, + "rev": "a09d2b94efb5e2d801275a244eedaab0816f3702", + "revCount": 18, "type": "git", - "url": "https://git.xiny.li/xin/nixvim" + "url": "https://git.xinyang.life/xin/nixvim" }, "original": { "type": "git", - "url": "https://git.xiny.li/xin/nixvim" + "url": "https://git.xinyang.life/xin/nixvim" } }, "nix-darwin": { @@ -398,11 +377,11 @@ ] }, "locked": { - "lastModified": 1731153869, - "narHash": "sha256-3Ftf9oqOypcEyyrWJ0baVkRpvQqroK/SVBFLvU3nPuc=", + "lastModified": 1730448474, + "narHash": "sha256-qE/cYKBhzxHMtKtLK3hlSR3uzO1pWPGLrBuQK7r0CHc=", "owner": "lnl7", "repo": "nix-darwin", - "rev": "5c74ab862c8070cbf6400128a1b56abb213656da", + "rev": "683d0c4cd1102dcccfa3f835565378c7f3cbe05e", "type": "github" }, "original": { @@ -439,11 +418,11 @@ ] }, "locked": { - "lastModified": 1733629314, - "narHash": "sha256-U0vivjQFAwjNDYt49Krevs1murX9hKBFe2Ye0cHpgbU=", + "lastModified": 1731814505, + "narHash": "sha256-l9ryrx1Twh08a+gxrMGM9O/aZKEimZfa6sZVyPCImgI=", "owner": "Mic92", "repo": "nix-index-database", - "rev": "f1e477a7dd11e27e7f98b646349cd66bbabf2fb8", + "rev": "bdba246946fb079b87b4cada4df9b1cdf1c06132", "type": "github" }, "original": { @@ -463,11 +442,11 @@ ] }, "locked": { - "lastModified": 1733795858, - "narHash": "sha256-K595Q2PrZv2iiumdBkwM2G456T2lKsLD71bn/fbJiQ0=", + "lastModified": 1731808759, + "narHash": "sha256-WwJqguc/5Q7HEwHlgDzDT8mtd8ZxInxZM2neJKC1oh8=", "owner": "nix-community", "repo": "nix-vscode-extensions", - "rev": "66ced222ef9235f90dbdd754ede3d6476722aaa9", + "rev": "5cf92678e6799ce45442dee4c9cb8094843c7cfa", "type": "github" }, "original": { @@ -478,11 +457,11 @@ }, "nixos-hardware": { "locked": { - "lastModified": 1733481457, - "narHash": "sha256-IS3bxa4N1VMSh3/P6vhEAHQZecQ3oAlKCDvzCQSO5Is=", + "lastModified": 1731797098, + "narHash": "sha256-UhWmEZhwJZmVZ1jfHZFzCg+ZLO9Tb/v3Y6LC0UNyeTo=", "owner": "NixOS", "repo": "nixos-hardware", - "rev": "e563803af3526852b6b1d77107a81908c66a9fcf", + "rev": "672ac2ac86f7dff2f6f3406405bddecf960e0db6", "type": "github" }, "original": { @@ -494,11 +473,11 @@ }, "nixpkgs": { "locked": { - "lastModified": 1731139594, - "narHash": "sha256-IigrKK3vYRpUu+HEjPL/phrfh7Ox881er1UEsZvw9Q4=", + "lastModified": 1730200266, + "narHash": "sha256-l253w0XMT8nWHGXuXqyiIC/bMvh1VRszGXgdpQlfhvU=", "owner": "NixOS", "repo": "nixpkgs", - "rev": "76612b17c0ce71689921ca12d9ffdc9c23ce40b2", + "rev": "807e9154dcb16384b1b765ebe9cd2bba2ac287fd", "type": "github" }, "original": { @@ -522,11 +501,11 @@ }, "nixpkgs-stable": { "locked": { - "lastModified": 1733730953, - "narHash": "sha256-dlK7n82FEyZlHH7BFHQAM5tua+lQO1Iv7aAtglc1O5s=", + "lastModified": 1731652201, + "narHash": "sha256-XUO0JKP1hlww0d7mm3kpmIr4hhtR4zicg5Wwes9cPMg=", "owner": "nixos", "repo": "nixpkgs", - "rev": "7109b680d161993918b0a126f38bc39763e5a709", + "rev": "c21b77913ea840f8bcf9adf4c41cecc2abffd38d", "type": "github" }, "original": { @@ -536,13 +515,29 @@ "type": "github" } }, + "nixpkgs-stable_2": { + "locked": { + "lastModified": 1731797254, + "narHash": "sha256-df3dJApLPhd11AlueuoN0Q4fHo/hagP75LlM5K1sz9g=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "e8c38b73aeb218e27163376a2d617e61a2ad9b59", + "type": "github" + }, + "original": { + "owner": "NixOS", + "ref": "release-24.05", + "repo": "nixpkgs", + "type": "github" + } + }, "nixpkgs_2": { "locked": { - "lastModified": 1733805440, - "narHash": "sha256-AQdCeGt3dMV9/cchlWGMcP0Z8qM47V+B0p7cSRr+HhA=", + "lastModified": 1731819057, + "narHash": "sha256-nfqKsQhFCakM+eIKGf/JWu/g56rOPoGny10EZN8q7R0=", "owner": "xinyangli", "repo": "nixpkgs", - "rev": "61b1078fca3a097ce06ada68a6f2766347eed02c", + "rev": "b2644ed7258502987ad4a70cf8959bf5a26ce26d", "type": "github" }, "original": { @@ -552,22 +547,6 @@ "type": "github" } }, - "nixpkgs_3": { - "locked": { - "lastModified": 1733581040, - "narHash": "sha256-Qn3nPMSopRQJgmvHzVqPcE3I03zJyl8cSbgnnltfFDY=", - "owner": "nixos", - "repo": "nixpkgs", - "rev": "22c3f2cf41a0e70184334a958e6b124fb0ce3e01", - "type": "github" - }, - "original": { - "owner": "nixos", - "ref": "nixos-unstable", - "repo": "nixpkgs", - "type": "github" - } - }, "nixvim": { "inputs": { "devshell": "devshell", @@ -581,11 +560,11 @@ "treefmt-nix": "treefmt-nix" }, "locked": { - "lastModified": 1731527733, - "narHash": "sha256-12OpSgbLDiKmxvBXwVracIfGI9FpjFyHpa1r0Ho+NFA=", + "lastModified": 1730569492, + "narHash": "sha256-NByr7l7JetL9kIrdCOcRqBu+lAkruYXETp1DMiDHNQs=", "owner": "nix-community", "repo": "nixvim", - "rev": "f11a877bcc1d66cc8bd7990c704f91c1e99c7d08", + "rev": "6f210158b03b01a1fd44bf3968165e6da80635ce", "type": "github" }, "original": { @@ -595,17 +574,12 @@ } }, "nur": { - "inputs": { - "flake-parts": "flake-parts_3", - "nixpkgs": "nixpkgs_3", - "treefmt-nix": "treefmt-nix_2" - }, "locked": { - "lastModified": 1733805328, - "narHash": "sha256-5F49/mOzFb40uUZh71uNr7kBXjDCw5ZfHMbpZjjUVBQ=", + "lastModified": 1731819675, + "narHash": "sha256-GGp/rEfxRdi1BD9TlHoXxp2g9IuKDp0Jk7wYh1LacP8=", "owner": "nix-community", "repo": "NUR", - "rev": "b54fa3d8c020e077d88be036a12a711b84fe2031", + "rev": "59740d792bea5caa547c9bc7ce366802ecfafb7f", "type": "github" }, "original": { @@ -625,11 +599,11 @@ ] }, "locked": { - "lastModified": 1731060242, - "narHash": "sha256-43yLsOm/wxBbfYSNDWVJeVv5Ij+23X3BIjFUfsdx/6M=", + "lastModified": 1730515563, + "narHash": "sha256-8lklUZRV7nwkPLF3roxzi4C2oyLydDXyAzAnDvjkOms=", "owner": "NuschtOS", "repo": "search", - "rev": "ef493352f9e1f051e01a55c062731503a6b36b4e", + "rev": "9e22bd742480916ff5d0ab20ca2522eaa3fa061e", "type": "github" }, "original": { @@ -659,14 +633,15 @@ "inputs": { "nixpkgs": [ "nixpkgs" - ] + ], + "nixpkgs-stable": "nixpkgs-stable_2" }, "locked": { - "lastModified": 1733785344, - "narHash": "sha256-pm4cfEcPXripE36PYCl0A2Tu5ruwHEvTee+HzNk+SQE=", + "lastModified": 1731814239, + "narHash": "sha256-TGnMXCeXS924w9W6CvRFtUCUFr8E/RK138lHxU3vcw8=", "owner": "Mic92", "repo": "sops-nix", - "rev": "a80af8929781b5fe92ddb8ae52e9027fae780d2a", + "rev": "47fc1d8c72dbd69b32ecb2019b5b648da3dd20ce", "type": "github" }, "original": { @@ -742,27 +717,6 @@ "repo": "treefmt-nix", "type": "github" } - }, - "treefmt-nix_2": { - "inputs": { - "nixpkgs": [ - "nur", - "nixpkgs" - ] - }, - "locked": { - "lastModified": 1733222881, - "narHash": "sha256-JIPcz1PrpXUCbaccEnrcUS8jjEb/1vJbZz5KkobyFdM=", - "owner": "numtide", - "repo": "treefmt-nix", - "rev": "49717b5af6f80172275d47a418c9719a31a78b53", - "type": "github" - }, - "original": { - "owner": "numtide", - "repo": "treefmt-nix", - "type": "github" - } } }, "root": "root", diff --git a/flake.nix b/flake.nix index 4da0466..7e725f2 100644 --- a/flake.nix +++ b/flake.nix @@ -43,7 +43,7 @@ }; my-nixvim = { - url = "git+https://git.xiny.li/xin/nixvim"; + url = "git+https://git.xinyang.life/xin/nixvim"; inputs.nixpkgs.follows = "nixpkgs"; }; @@ -84,16 +84,11 @@ overlayModule = { ... }: { - options.my-lib = nixpkgs.lib.mkOption { - type = nixpkgs.lib.types.attrs; - default = import ./overlays/my-lib; - }; - config = { - nixpkgs.overlays = [ - editorOverlay - (import ./overlays/add-pkgs.nix) - ]; - }; + _module.args.my-lib = import ./overlays/my-lib; + nixpkgs.overlays = [ + editorOverlay + (import ./overlays/add-pkgs.nix) + ]; }; deploymentModule = { deployment.targetUser = "xin"; @@ -111,6 +106,7 @@ nodeNixosModules = { calcite = [ nixos-hardware.nixosModules.asus-zephyrus-ga401 + nur.nixosModules.nur catppuccin.nixosModules.catppuccin machines/calcite/configuration.nix (mkHome "xin" "calcite") @@ -146,15 +142,17 @@ user: host: { ... }: { - imports = [ home-manager.nixosModules.home-manager ]; - config = { - home-manager = { - sharedModules = sharedHmModules; - useGlobalPkgs = true; - useUserPackages = true; - }; - home-manager.users.${user} = (import ./home).${user}.${host}; - }; + imports = [ + home-manager.nixosModules.home-manager + { + home-manager = { + sharedModules = sharedHmModules; + useGlobalPkgs = true; + useUserPackages = true; + }; + home-manager.users.${user} = (import ./home).${user}.${host}; + } + ]; }; mkNixos = { @@ -286,22 +284,16 @@ { imports = nodeNixosModules.biotite ++ sharedColmenaModules; }; - - osmium = - { ... }: - { - deployment = { - targetHost = "osmium.coho-tet.ts.net"; - buildOnTarget = false; - }; - imports = nodeNixosModules.osmium ++ sharedColmenaModules; - }; }; nixosConfigurations = { calcite = mkNixos { hostname = "calcite"; }; + + osmium = mkNixos { + hostname = "osmium"; + }; } // self.colmenaHive.nodes; } @@ -311,7 +303,7 @@ pkgs = nixpkgs.legacyPackages.${system}; mkHomeConfiguration = user: host: { - name = "${user}-${host}"; + name = user; value = home-manager.lib.homeManagerConfiguration { inherit pkgs; modules = [ diff --git a/home/xin/calcite.nix b/home/xin/calcite.nix index d90cc4d..9f246cf 100644 --- a/home/xin/calcite.nix +++ b/home/xin/calcite.nix @@ -125,8 +125,7 @@ in profiles.default = { isDefault = true; userChrome = '' - - #TabsToolbar { + #titlebar { display: none; } @@ -137,7 +136,7 @@ in [titlepreface*="."] #sidebar-header { visibility: collapse !important; } - [titlepreface*="."] #TabsToolbar { + [titlepreface*="."] #titlebar { visibility: collapse; } @@ -149,7 +148,7 @@ in min-width: var(--uc-sidebar-width) !important; width: var(--uc-sidebar-width) !important; max-width: var(--uc-sidebar-width) !important; - z-index: calc(var(--browser-area-z-index-tabbox) + 1); + z-index:1; } #sidebar-box[positionend]{ direction: rtl } @@ -191,12 +190,12 @@ in transition-delay: 0ms !important; } - .sidebar-placeTree { - /* background-color: transparent !important; */ + .sidebar-panel{ + background-color: transparent !important; color: var(--newtab-text-primary-color) !important; } - .sidebar-placeTree #search-box{ + .sidebar-panel #search-box{ -moz-appearance: none !important; background-color: rgba(249,249,250,0.1) !important; color: inherit !important; diff --git a/home/xin/common/default.nix b/home/xin/common/default.nix index 728dd93..8fbf3bb 100644 --- a/home/xin/common/default.nix +++ b/home/xin/common/default.nix @@ -5,12 +5,13 @@ ... }: { - imports = [ - ./modern-unix.nix - ]; + imports = [ ]; home.packages = with pkgs; [ dig + du-dust # du + rust + zoxide # autojumper + ripgrep file man-pages unar @@ -18,6 +19,7 @@ wget tmux ffmpeg + tealdeer rclone wl-clipboard diff --git a/home/xin/common/modern-unix.nix b/home/xin/common/modern-unix.nix deleted file mode 100644 index 298fae2..0000000 --- a/home/xin/common/modern-unix.nix +++ /dev/null @@ -1,17 +0,0 @@ -{ pkgs, ... }: -{ - home.packages = with pkgs; [ - httpie - curlie - bat - htop - procs - rust-parallel - jq - fd - du-dust # du + rust - zoxide # autojumper - ripgrep - tealdeer - ]; -} diff --git a/machines/biotite/default.nix b/machines/biotite/default.nix index 741e281..a507675 100644 --- a/machines/biotite/default.nix +++ b/machines/biotite/default.nix @@ -1,7 +1,5 @@ { - pkgs, lib, - config, ... }: @@ -9,12 +7,6 @@ imports = [ ./hardware-configurations.nix ./services/gotosocial.nix - ./services/synapse.nix - ./services/restic.nix - ./services/miniflux.nix - ./services/hedgedoc.nix - ./services/forgejo.nix - ./services/vaultwarden.nix ]; networking.hostName = "biotite"; @@ -36,56 +28,20 @@ commonSettings = { auth.enable = true; + autoupgrade.enable = true; }; custom.monitoring = { promtail.enable = true; }; - custom.prometheus.exporters = { - enable = true; - node.enable = true; - }; - - services.tailscale.enable = true; - - services.caddy.enable = true; - sops = { defaultSopsFile = ./secrets.yaml; age.sshKeyPaths = [ "/etc/ssh/ssh_host_ed25519_key" ]; }; - services.postgresql = { - enable = true; - package = pkgs.postgresql_17; - settings = { - allow_alter_system = false; - # DB Version: 17 - # OS Type: linux - # DB Type: mixed - # Total Memory (RAM): 8 GB - # CPUs num: 4 - # Data Storage: ssd - max_connections = 100; - shared_buffers = "2GB"; - effective_cache_size = "6GB"; - maintenance_work_mem = "512MB"; - checkpoint_completion_target = 0.9; - wal_buffers = "16MB"; - default_statistics_target = 100; - random_page_cost = 1.1; - effective_io_concurrency = 200; - work_mem = "5242kB"; - huge_pages = "off"; - min_wal_size = "1GB"; - max_wal_size = "4GB"; - max_worker_processes = 4; - max_parallel_workers_per_gather = 2; - max_parallel_workers = 4; - max_parallel_maintenance_workers = 2; - }; - }; + services.caddy.enable = true; + services.tailscale.enable = true; users.users.root.hashedPassword = "$y$j9T$NToEZWJBONjSgRnMd9Ur9/$o6n7a9b8eUILQz4d37oiHCCVnDJ8hZTZt.c.37zFfU."; diff --git a/machines/biotite/secrets.yaml b/machines/biotite/secrets.yaml index 1e71c85..5d8f181 100644 --- a/machines/biotite/secrets.yaml +++ b/machines/biotite/secrets.yaml @@ -1,16 +1,5 @@ gotosocial: oidc_client_secret: ENC[AES256_GCM,data:KVQxzs67sohax2h0Y/jjhnbY4fetrdVvWhBGbqgDSGgBC7QazrOmTA++BSRzMmVv,iv:HIRMc56aLanqQRTWH9E0wzzXymImi0pxK/ccPEP8Fcc=,tag:PMhOLeE3mKIIQveRdfpgpA==,type:str] -synapse: - oidc_client_secret: ENC[AES256_GCM,data:TdZF8Bo+h34fn03sPpt7JEqmP8Cwm8V++q9VDvaapMBc3rlkrVu3iDUhQE2DvJri,iv:/QNX+aYUPpDKIqWZ13TLAznR3ZpUPI8rQHrJuqv7R+g=,tag:lcBIpeWiIXK/NV84uuxNiA==,type:str] -restic: - repo_url: ENC[AES256_GCM,data:ZcBMqwEsyc7zyEftJZj4XkKBzUHwlqd6cjX8xVDn9m26jBL7aP5atpnXDRE9FXY4CuAllFyQZyAOQ2L61Nfx+iplL2ADbSoH,iv:fhNODiyoOlZEqYR2O/GsH2IWTPDr3rXSJgWC/EFDLSA=,tag:nZdKKnpiszSiXxdZI1KQ/A==,type:str] - repo_password: ENC[AES256_GCM,data:9YDOz1tiyykz6zSXboWtIg==,iv:j96mRLXGuD4NZcC0Nv1yXFbtOlr6UborqclefZ7J94w=,tag:MqhSewK2NuckTJBf7xu+lA==,type:str] -miniflux: - oauth2_secret: ENC[AES256_GCM,data:/WtZemrdKU8bQbxzrAn437uqoJSO+yZSUDCnxovXV0HFZYQvAn2rbMrgOdoc1OuP,iv:xENKuGDYS1ctnO/WkGv1TxjtQYZ8p64Ik/lMIIam4Q0=,tag:RbAA0LUmsAQDqEM5+a2quQ==,type:str] -hedgedoc: - client_secret: ENC[AES256_GCM,data:J6lRBM7V6F+gPYVyEbOzsFUQe8+3ggP0r58c655DNt7TGgKGdq95pRvLaghMmBCc,iv:i+eLYwnmG1/bKtad2iM2pwEAC3GZLNaKS5ldbubRvyY=,tag:yxaug6YdYo8RR3YOyHd/iA==,type:str] -forgejo: - client_secret: ENC[AES256_GCM,data:5OXhaGzBCbge2tvTaU4ry6/KoavQeYJ45EuakCQJlxb5gMXjRK/s+feF25YJSr2f,iv:TT8j+ciKeSQCZzu1E7D70hWNFpn0cGiomz7jURXjavc=,tag:JVJR033Pc2vaLudaovkl8w==,type:str] sops: kms: [] gcp_kms: [] @@ -35,8 +24,8 @@ sops: RzBMVDNjS29SUkdRK3dIV01sU0hYR3cK1SbvKAM6Gpsffv3HIi/WtWnCZUBic0AT ZRv4pvJBx1oxWsKIHW0t6VrqWMQ+suup8p6dW+h5HE8Z4ciIMrXLEg== -----END AGE ENCRYPTED FILE----- - lastmodified: "2024-12-04T05:07:32Z" - mac: ENC[AES256_GCM,data:hD7645epMVYHU6K1AZsHu+fp/PMIqqiZpv7K4Vxzo84slzn0CfZSYaVaYxKNGjOIgEGN9D2FFmq9WL6ChMskMfqqafY7qDpSQqFp9TUwb5jN34XcQg9vplfNw+lMqsnDCt1HENWErRnlDxTI2ctSEcx3UKGBOQ3ttLzUIySdnFY=,iv:reOsqvc8E3l8yxb5gVcqF/rU2o2yKmaUyGNRNT+Skx8=,tag:eBoV8G+X0cPs3Q1xAuv55w==,type:str] + lastmodified: "2024-12-02T05:10:32Z" + mac: ENC[AES256_GCM,data:ZAdFsjVuk1Fiv+DKmHrc1yu1XQpRDmRHaQhu5hduSZUa1W1cXdTlChvIW5vADFg5tVCjuYptuLvCMW+ZSQeqqG2ntHHZ+IkuovZzKFuc+BIiL/jF2ZzbyJ7X4Wj1GziCScHVxx98dgbpFoufHe6N3wCaHmngo1RYsY5N1RRbRdU=,iv:5IMQ0kOX9UAOm8bcsQRyu6zu8GJjvnHFufCNjY0s9UI=,tag:zBEPSR9DZDpwbCaIka8mXA==,type:str] pgp: [] unencrypted_suffix: _unencrypted version: 3.9.1 diff --git a/machines/biotite/services/forgejo.nix b/machines/biotite/services/forgejo.nix deleted file mode 100644 index 7321b89..0000000 --- a/machines/biotite/services/forgejo.nix +++ /dev/null @@ -1,115 +0,0 @@ -{ - config, - pkgs, - lib, - ... -}: -let - inherit (lib) getExe; - inherit (config.my-lib.settings) idpUrl forgejoDomain forgejoGitDomain; - settings = { - service.DISABLE_REGISTRATION = true; - server = { - DOMAIN = forgejoDomain; - ROOT_URL = "https://${forgejoDomain}"; - HTTP_ADDR = "/var/run/forgejo/forgejo.sock"; - START_SSH_SERVER = false; - SSH_USER = config.services.forgejo.user; - SSH_DOMAIN = forgejoGitDomain; - SSH_PORT = 22; - PROTOCOL = "http+unix"; - LFS_MAX_FILE_SIZE = 10737418240; - LANDING_PAGE = "/explore/repos"; - }; - repository = { - ENABLE_PUSH_CREATE_USER = true; - }; - service = { - ENABLE_BASIC_AUTHENTICATION = false; - }; - oauth2 = { - ENABLED = false; # Disable forgejo as oauth2 provider - }; - oauth2_client = { - ACCOUNT_LINKING = "auto"; - USERNAME = "email"; - ENABLE_AUTO_REGISTRATION = true; - UPDATE_AVATAR = false; - OPENID_CONNECT_SCOPES = "openid profile email groups"; - }; - metrics = { - # ENABLED = true; - }; - other = { - SHOW_FOOTER_VERSION = false; - }; - }; -in -{ - sops.secrets."forgejo/client_secret" = { }; - sops.templates."forgejo/env" = { - content = '' - CLIENT_SECRET=${config.sops.placeholder."forgejo/client_secret"} - ''; - owner = config.systemd.services.forgejo.serviceConfig.User; - }; - - services.forgejo = { - enable = true; - inherit settings; - # Use cutting edge instead of lts - package = pkgs.forgejo; - # repositoryRoot = "/mnt/storage/forgejo/repositories"; - lfs = { - enable = true; - # contentDir = "/mnt/storage/forgejo/lfs"; - }; - }; - - systemd.services.forgejo = { - serviceConfig = { - EnvironmentFile = config.sops.templates."forgejo/env".path; - preStart = - let - providerName = "kanidm"; - args = lib.concatStringsSep " " [ - "--name ${providerName}" - "--provider openidConnect" - "--key forgejo" - "--secret $CLIENT_SECRET" - "--icon-url ${idpUrl}/pkg/img/favicon.png" - "--group-claim-name forgejo_role --admin-group Admin" - ]; - exe = getExe config.services.forgejo.package; - in - '' - provider_id=$(${exe} admin auth list | ${pkgs.gnugrep}/bin/grep -w '${providerName}' | cut -f1) - if [[ -z "$provider_id" ]]; then - ${exe} admin auth add-oauth ${args} - else - ${exe} admin auth update-oauth --id "$provider_id" ${args} - fi - ''; - }; - }; - - users.users.git = { - isSystemUser = true; - useDefaultShell = true; - group = "git"; - extraGroups = [ "forgejo" ]; - }; - users.groups.git = { }; - - services.caddy = { - virtualHosts."https://${forgejoDomain}".extraConfig = with settings; '' - ${ - if server.PROTOCOL == "http+unix" then - "reverse_proxy unix/${server.HTTP_ADDR}" - else - "reverse_proxy http://${server.HTTP_ADDR}:${toString server.HTTP_PORT}" - } - ''; - }; - users.users.caddy.extraGroups = lib.optional (settings.server.PROTOCOL == "http+unix") "forgejo"; -} diff --git a/machines/biotite/services/gotosocial.nix b/machines/biotite/services/gotosocial.nix index 3114cf6..743b3f7 100644 --- a/machines/biotite/services/gotosocial.nix +++ b/machines/biotite/services/gotosocial.nix @@ -1,7 +1,4 @@ { config, ... }: -let - inherit (config.my-lib.settings) idpUrl; -in { sops.secrets."gotosocial/oidc_client_secret" = { owner = "gotosocial"; @@ -26,17 +23,17 @@ in instance-expose-public-timeline = true; oidc-enabled = true; oidc-idp-name = "Kanidm"; - oidc-issuer = "${idpUrl}/oauth2/openid/gotosocial"; + oidc-issuer = "https://auth.xinyang.life/oauth2/openid/gotosocial"; oidc-client-id = "gotosocial"; oidc-link-existing = true; }; - setupPostgresqlDB = true; environmentFile = config.sops.templates."gotosocial.env".path; }; services.caddy = { virtualHosts."https://gts.xiny.li".extraConfig = '' - reverse_proxy http://${config.services.gotosocial.settings.bind-address}:${toString config.services.gotosocial.settings.port} { + encode zstd gzip + reverse_proxy * http://${config.services.gotosocial.settings.bind-address}:${toString config.services.gotosocial.settings.port} { flush_interval -1 } ''; diff --git a/machines/biotite/services/hedgedoc.nix b/machines/biotite/services/hedgedoc.nix deleted file mode 100644 index c8b33bc..0000000 --- a/machines/biotite/services/hedgedoc.nix +++ /dev/null @@ -1,45 +0,0 @@ -{ config, pkgs, ... }: -let - inherit (config.my-lib.settings) hedgedocDomain idpUrl; -in -{ - sops.secrets."hedgedoc/client_secret" = { }; - sops.templates."hedgedoc/env" = { - content = '' - CMD_OAUTH2_CLIENT_SECRET=${config.sops.placeholder."hedgedoc/client_secret"} - ''; - owner = config.systemd.services.hedgedoc.serviceConfig.User; - }; - services.hedgedoc = { - enable = true; - environmentFile = config.sops.templates."hedgedoc/env".path; - settings = { - domain = hedgedocDomain; - protocolUseSSL = true; # use SSL for resources - path = "/run/hedgedoc/hedgedoc.sock"; - email = false; - allowEmailRegister = false; - oauth2 = { - baseURL = "${idpUrl}/oauth2/openid/hedgedoc"; - authorizationURL = "${idpUrl}/ui/oauth2"; - tokenURL = "${idpUrl}/oauth2/token"; - userProfileURL = "${idpUrl}/oauth2/openid/hedgedoc/userinfo"; - userProfileEmailAttr = "email"; - userProfileUsernameAttr = "name"; - userProfileDisplayNameAttr = "preferred_name"; - scope = "openid email profile"; - clientID = "hedgedoc"; - }; - enableStatsApi = true; - allowAnonymous = false; - defaultPermission = "private"; - }; - }; - services.caddy = { - enable = true; - virtualHosts."https://${hedgedocDomain}".extraConfig = '' - reverse_proxy unix/${config.services.hedgedoc.settings.path} - ''; - }; - users.users.caddy.extraGroups = [ "hedgedoc" ]; -} diff --git a/machines/biotite/services/miniflux.nix b/machines/biotite/services/miniflux.nix deleted file mode 100644 index 1bee3dc..0000000 --- a/machines/biotite/services/miniflux.nix +++ /dev/null @@ -1,35 +0,0 @@ -{ config, pkgs, ... }: -let - inherit (config.my-lib.settings) idpUrl minifluxUrl; -in -{ - sops = { - secrets."miniflux/oauth2_secret" = { }; - }; - - services.miniflux = { - enable = true; - config = { - LOG_LEVEL = "debug"; - LISTEN_ADDR = "127.0.0.1:58173"; - BASE_URL = "https://rss.xiny.li/"; - OAUTH2_PROVIDER = "oidc"; - OAUTH2_CLIENT_ID = "miniflux"; - OAUTH2_CLIENT_SECRET_FILE = "%d/oauth2_secret"; - OAUTH2_REDIRECT_URL = "${minifluxUrl}/oauth2/oidc/callback"; - OAUTH2_OIDC_DISCOVERY_ENDPOINT = "${idpUrl}/oauth2/openid/miniflux"; - OAUTH2_USER_CREATION = 1; - CREATE_ADMIN = 0; - }; - createDatabaseLocally = true; - }; - - systemd.services.miniflux.serviceConfig.LoadCredential = [ - "oauth2_secret:${config.sops.secrets."miniflux/oauth2_secret".path}" - ]; - - services.caddy.virtualHosts.${minifluxUrl}.extraConfig = '' - reverse_proxy ${config.services.miniflux.config.LISTEN_ADDR} - ''; - -} diff --git a/machines/biotite/services/restic.nix b/machines/biotite/services/restic.nix deleted file mode 100644 index 2e53c46..0000000 --- a/machines/biotite/services/restic.nix +++ /dev/null @@ -1,55 +0,0 @@ -{ - config, - lib, - pkgs, - ... -}: -let - sqliteBackup = fromPath: toPath: file: '' - mkdir -p ${toPath} - ${lib.getExe pkgs.sqlite} ${fromPath} ".backup '${toPath}/${file}'" - ''; -in -{ - sops.secrets = { - "restic/repo_url" = { - sopsFile = ../secrets.yaml; - }; - "restic/repo_password" = { - sopsFile = ../secrets.yaml; - }; - }; - - custom.restic = { - enable = true; - paths = [ - "/backup/db" - "/backup/var/lib" - ]; - backupPrepareCommand = [ - '' - mkdir -p /backup/var - ${pkgs.btrfs-progs}/bin/btrfs subvolume snapshot -r /var/lib /backup/var/lib - '' - ]; - backupCleanupCommand = [ - '' - ${pkgs.btrfs-progs}/bin/btrfs subvolume delete /backup/var/lib - '' - ]; - btrfsRoots = [ ]; - }; - - services.postgresqlBackup = { - enable = true; - compression = "zstd"; - compressionLevel = 9; - location = "/backup/db/postgresql"; - }; - - services.restic.backups.${config.networking.hostName} = { - extraBackupArgs = [ - "--limit-upload=1024" - ]; - }; -} diff --git a/machines/biotite/services/synapse.nix b/machines/biotite/services/synapse.nix deleted file mode 100644 index e352495..0000000 --- a/machines/biotite/services/synapse.nix +++ /dev/null @@ -1,120 +0,0 @@ -{ - config, - lib, - pkgs, - ... -}: -let - inherit (config.my-lib.settings) idpUrl synapseDelegateUrl synapseUrl; - port-synapse = 6823; -in -{ - sops.secrets."synapse/oidc_client_secret" = { - owner = "matrix-synapse"; - }; - - nixpkgs.config.permittedInsecurePackages = [ - "olm-3.2.16" - ]; - - services.postgresql = { - # Not using ensure here because LC_COLLATE and LC_CTYPE must be provided - # at db creation - initialScript = pkgs.writeText "synapse-init.sql" '' - CREATE ROLE "matrix-synapse" WITH LOGIN PASSWORD 'synapse'; - CREATE DATABASE "matrix-synapse" WITH OWNER "matrix-synapse" - TEMPLATE template0 - LC_COLLATE = "C" - LC_CTYPE = "C"; - ''; - }; - - services.matrix-synapse = { - enable = true; - withJemalloc = true; - settings = { - server_name = "xiny.li"; - public_baseurl = synapseDelegateUrl; - database = { - name = "psycopg2"; - args = { - user = "matrix-synapse"; - }; - }; - listeners = [ - { - bind_addresses = [ - "127.0.0.1" - ]; - port = port-synapse; - resources = [ - { - compress = true; - names = [ - "client" - "federation" - ]; - } - ]; - tls = false; - type = "http"; - x_forwarded = true; - } - ]; - 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; - # Remove legacy mentions - msc4210_enabled = true; - }; - oidc_providers = [ - { - idp_id = "Kanidm"; - idp_name = lib.removePrefix "https://" idpUrl; - issuer = "${idpUrl}/oauth2/openid/synapse"; - authorization_endpoint = "${idpUrl}/ui/oauth2"; - token_endpoint = "${idpUrl}/oauth2/token"; - userinfo_endpoint = "${idpUrl}/oauth2/openid/synapse/userinfo"; - client_id = "synapse"; - client_secret_path = config.sops.secrets."synapse/oidc_client_secret".path; - scopes = [ - "openid" - "profile" - ]; - allow_existing_users = true; - backchannel_logout_enabled = true; - user_mapping_provider.config = { - confirm_localpart = true; - localpart_template = "{{ user.preferred_username }}"; - display_name_template = "{{ user.name }}"; - }; - } - ]; - }; - }; - - services.caddy = { - virtualHosts.${synapseUrl}.extraConfig = '' - header /.well-known/matrix/* Content-Type application/json - header /.well-known/matrix/* Access-Control-Allow-Origin * - respond /.well-known/matrix/server `{"m.server":"synapse.xiny.li:443"}` - respond /.well-known/matrix/client `{"m.homeserver":{"base_url":"${synapseDelegateUrl}"}}` - ''; - virtualHosts.${synapseDelegateUrl}.extraConfig = '' - reverse_proxy /_matrix/* 127.0.0.1:${toString port-synapse} - reverse_proxy /_synapse/client/* 127.0.0.1:${toString port-synapse} - ''; - }; - - networking.firewall.allowedTCPPorts = [ - 443 - ]; -} diff --git a/machines/biotite/services/vaultwarden.nix b/machines/biotite/services/vaultwarden.nix deleted file mode 100644 index f7c55c3..0000000 --- a/machines/biotite/services/vaultwarden.nix +++ /dev/null @@ -1,25 +0,0 @@ -{ config, pkgs, ... }: -let - inherit (config.my-lib.settings) vaultwardenUrl; -in -{ - services.vaultwarden = { - enable = true; - dbBackend = "sqlite"; - config = { - DOMAIN = "${vaultwardenUrl}"; - SIGNUPS_ALLOWED = false; - - ROCKET_ADDRESS = "127.0.0.1"; - ROCKET_PORT = 8222; - - ROCKET_LOG = "normal"; - }; - }; - - services.caddy = { - virtualHosts.${vaultwardenUrl}.extraConfig = with config.services.vaultwarden.config; '' - reverse_proxy ${ROCKET_ADDRESS}:${toString ROCKET_PORT} - ''; - }; -} diff --git a/machines/calcite/configuration.nix b/machines/calcite/configuration.nix index c5afb73..27760b5 100644 --- a/machines/calcite/configuration.nix +++ b/machines/calcite/configuration.nix @@ -16,7 +16,7 @@ in ]; commonSettings = { - # auth.enable = true; + auth.enable = true; nix = { signing.enable = true; }; @@ -51,6 +51,7 @@ in }; # services.gnome.gnome-keyring.enable = lib.mkForce false; security.pam.services.login.enableGnomeKeyring = lib.mkForce false; + services.ssh-tpm-agent.enable = true; programs.ssh.agentPKCS11Whitelist = "${config.security.tpm2.pkcs11.package}/lib/libtpm_pkcs11.so"; @@ -65,7 +66,18 @@ in }; }; - programs.vim.enable = true; + programs.oidc-agent.enable = true; + programs.oidc-agent.providers = [ + { + issuer = "https://home.xinyang.life:9201"; + pubclient = { + client_id = "xdXOt13JKxym1B1QcEncf2XDkLAexMBFwiT9j6EfhhHFJhs2KM9jbjTmf8JBXE69"; + client_secret = "UBntmLjC2yYCeHwsyj73Uwo9TAaecAetRwMw0xYcvNL9yRdLSUi0hUAHfvCHFeFh"; + scope = "openid offline_access profile email"; + }; + } + ]; + programs.vim.defaultEditor = true; # Keep this even if enabled in home manager @@ -295,22 +307,23 @@ in bitwarden # Browser - chromium + (chromium.override { + commandLineArgs = [ + "--ozone-platform-hint=auto" + "--enable-wayland-ime" + ]; + }) + brave # Writting zotero # onlyoffice-bin - wemeet + config.nur.repos.linyinfeng.wemeet virt-manager - wineWowPackages.waylandFull - winetricks ]; - services.esphome.enable = true; - users.groups.dialout.members = [ "xin" ]; - system.stateVersion = "22.05"; system.switch.enable = false; @@ -339,16 +352,16 @@ in ]; }; - # custom.forgejo-actions-runner = { - # enable = false; - # tokenFile = config.sops.secrets."gitea/envfile".path; - # settings = { - # runner.capacity = 2; - # runner.fetch_timeout = "120s"; - # runner.fetch_interval = "30s"; - # }; - # }; - # + custom.forgejo-actions-runner = { + enable = false; + tokenFile = config.sops.secrets."gitea/envfile".path; + settings = { + runner.capacity = 2; + runner.fetch_timeout = "120s"; + runner.fetch_interval = "30s"; + }; + }; + custom.prometheus = { exporters.node.enable = true; }; @@ -366,12 +379,15 @@ in # Fonts fonts = { packages = with pkgs; [ - nerd-fonts.ubuntu-sans - nerd-fonts.ubuntu - nerd-fonts.fira-code - nerd-fonts.fira-mono - nerd-fonts.jetbrains-mono - nerd-fonts.roboto-mono + (nerdfonts.override { + fonts = [ + "FiraCode" + "FiraMono" + "JetBrainsMono" + "RobotoMono" + "Ubuntu" + ]; + }) noto-fonts noto-fonts-emoji liberation_ttf diff --git a/machines/calcite/network.nix b/machines/calcite/network.nix index 27e77ee..31203ad 100644 --- a/machines/calcite/network.nix +++ b/machines/calcite/network.nix @@ -1,9 +1,4 @@ -{ - config, - pkgs, - lib, - ... -}: +{ config, pkgs, lib, ... }: { imports = [ ]; @@ -29,9 +24,16 @@ services.dae.enable = true; services.dae.configFile = "/var/lib/dae/config.dae"; - systemd.services.dae.after = lib.mkIf (config.networking.networkmanager.enable) [ - "NetworkManager-wait-online.service" - ]; + systemd.services.dae.after = lib.mkIf (config.networking.networkmanager.enable) [ "NetworkManager-wait-online.service" ]; + + custom.sing-box = { + enable = false; + configFile = { + urlFile = config.sops.secrets.sing_box_url.path; + hash = "6ca5bc8a16f8c413227690aceeee2c12c02cab09473c216b849af1e854b98588"; + }; + overrideSettings.experimental.clash_api.external_ui = "${config.nur.repos.linyinfeng.yacd}"; + }; # Open ports in the firewall. networking.firewall.enable = true; diff --git a/machines/dolomite/common.nix b/machines/dolomite/common.nix index 65b10c7..c50c1a9 100644 --- a/machines/dolomite/common.nix +++ b/machines/dolomite/common.nix @@ -3,7 +3,6 @@ config = { sops = { age.sshKeyPaths = [ "/etc/ssh/ssh_host_ed25519_key" ]; - defaultSopsFile = ./secrets/secrets.yaml; secrets = { wg_private_key = { owner = "root"; @@ -13,6 +12,14 @@ owner = "root"; sopsFile = ./secrets + "/${config.networking.hostName}.yaml"; }; + "sing-box/password" = { + owner = "root"; + sopsFile = ./secrets/secrets.yaml; + }; + "sing-box/uuid" = { + owner = "root"; + sopsFile = ./secrets/secrets.yaml; + }; }; }; swapDevices = [ @@ -25,8 +32,6 @@ custom.prometheus.exporters = { enable = true; node.enable = true; - blackbox.enable = true; - v2ray.enable = true; }; custom.monitoring = { @@ -39,11 +44,6 @@ auth.enable = true; proxyServer = { enable = true; - users = [ - "wyj" - "yhb" - "xin" - ]; }; }; }; diff --git a/machines/dolomite/secrets/secrets.yaml b/machines/dolomite/secrets/secrets.yaml index e0df929..53a7131 100644 --- a/machines/dolomite/secrets/secrets.yaml +++ b/machines/dolomite/secrets/secrets.yaml @@ -1,14 +1,6 @@ sing-box: - users: - wyj: - password: ENC[AES256_GCM,data:yp+T3eci9RiuZzdmRSq5nTjHaz8e/Rri,iv:hIPc+7YHUnaIdU9O8GGx3r7l3oBA6prQb+KBQV0G+8k=,tag:2GNiBP4PQy+KGHgLupKGSg==,type:str] - uuid: ENC[AES256_GCM,data:Qrgil6G7pjQAQzCCOlstDi27EqqmSuBMhs+RTl9++wrPrIgJ,iv:u+3Z17uX4I6li2qd9UP3y+WaKn7aKfbb3J6H1Pyc1QY=,tag:hSa4AB383/B58XMmZ8LIfQ==,type:str] - yhb: - password: ENC[AES256_GCM,data:TwRct68TePpcZcnpWIQpFaF23WGMre8=,iv:YU4mQNm0rt2u4ItJwQ8nZPEmJi0+lmEIPG2Kxh/nI58=,tag:ukZem38O/b42dEKM3CYa+w==,type:str] - uuid: ENC[AES256_GCM,data:6hVhEqWPLVrn8rCS4x/eapd+iL7JRaXtOGCj9uuPlkGjBTMK,iv:VZ27KWCY6/K5GoNwRNmaRWzqfV7+8iFjtias1vKeGfA=,tag:8mhmZPooxHaGNYdznuFhMQ==,type:str] - xin: - password: ENC[AES256_GCM,data:SRiPFO+Uwy/PT41SIg7eI68wk4AX6so=,iv:aXwP5wa1IrlnvFo/ZL+DYFFHDdWw2Z83de3ApHUTsXo=,tag:sxXoy1FnDxZBQCDeNxphzQ==,type:str] - uuid: ENC[AES256_GCM,data:7xK53SO4x0tOIEIYl6kmmAvnpdsR/tYQoG1t/ytsnO4QqWY3,iv:i694Fnu7g1OA3IGzSaoSGA5/eMPo+I/1TZbYuaQrgNA=,tag:4cUlioJn/IvsvZclgboOSA==,type:str] + password: ENC[AES256_GCM,data:qCc1v8nAL0oYisRinMDXGrBQA+r6XNoa,iv:eTxtad4kEdE28XqnrZEek8BtXNY1rNgLvGLxlMzRtl4=,tag:s/shWAkYE4DSnScpTY8ulQ==,type:str] + uuid: ENC[AES256_GCM,data:lEpz15sLOVrGDzQwTJyS+tFJY0bMeO265bxocWAjB6qrvxYx,iv:lhk5jl/udUH3AZEuk5ffuvin/qhRUaOZ/3nk1Jaw+DI=,tag:4mKFIVKT+D47njfDsxe9iA==,type:str] sops: kms: [] gcp_kms: [] @@ -51,8 +43,8 @@ sops: K1F1SzI2NFNIKzlreVBXSjAxaUxQd28KFaf1uu7OlqIe0TirJFgS3iPjhXPyfNDE m2XUjzdXp+chJCzVOFvpYStqz+e08ADEc+jp3YsTLcxyqvXhQdyL/Q== -----END AGE ENCRYPTED FILE----- - lastmodified: "2024-12-06T04:35:52Z" - mac: ENC[AES256_GCM,data:DAg4UTwNv+rs6hye2z5UUtA1a4yZbFaAWjLoKAXf87tKgBCZzK8C1q6gLyTQOqp07ptYQd5Q951kfE1a/35SFJsubREzJmu6haxznRgq7pO5HDGqgtjYEHsngsWZh3bUSX/aG2dLISdD81VY68nLzTO0r4h/SL6DNG36RzJgL8E=,iv:V0WhENNt/Szi5VWVD2t5AsWP1tOZUGjFjMNYPDq59XI=,tag:ThRstdzVNtSs6E7qlvKPOw==,type:str] + lastmodified: "2024-12-02T05:26:17Z" + mac: ENC[AES256_GCM,data:K94zFWPWGUisLCqDjSLs17QxHXPH4tPU/98Sb4lCnt7IRAIn14x/T+BnInY/DK+DOVLLtzSfuN0kgzzGjSzwJx5Vq1G3MkhngRQQRT9dvODTCMAw6lPt98Ofw1CEEsFQnpYo9zIUlCGKg2YPKFLqE7OjkPxqw7VYvgzr5dDw58s=,iv:3xcJfNX5v/e9HgZt3UrHs2/C5ivaBV1rXKIBs9hKKFg=,tag:RQPQQ1cmZiOpQjUwqnzZQA==,type:str] pgp: [] unencrypted_suffix: _unencrypted version: 3.9.1 diff --git a/machines/massicot/default.nix b/machines/massicot/default.nix index 7b56e15..da2cbd5 100644 --- a/machines/massicot/default.nix +++ b/machines/massicot/default.nix @@ -15,9 +15,24 @@ defaultSopsFile = ./secrets.yaml; age.sshKeyPaths = [ "/etc/ssh/ssh_host_ed25519_key" ]; secrets = { + storage_box_mount = { + owner = "root"; + }; gts_env = { owner = "gotosocial"; }; + hedgedoc_env = { + owner = "hedgedoc"; + }; + grafana_oauth_secret = { + owner = "grafana"; + }; + "miniflux/oauth2_secret" = { + owner = "root"; + }; + "forgejo/env" = { + owner = "forgejo"; + }; }; }; diff --git a/machines/massicot/kanidm-provision.nix b/machines/massicot/kanidm-provision.nix index e44c729..8a95a99 100644 --- a/machines/massicot/kanidm-provision.nix +++ b/machines/massicot/kanidm-provision.nix @@ -1,14 +1,4 @@ -{ pkgs, config, ... }: -let - inherit (config.my-lib.settings) - gotosocialUrl - minifluxUrl - hedgedocDomain - forgejoDomain - grafanaUrl - synapseDelegateUrl - ; -in +{ config, lib, ... }: { services.kanidm.provision = { enable = true; @@ -55,9 +45,6 @@ in miniflux-users = { members = [ "xin" ]; }; - synapse-users = { - members = [ "xin" ]; - }; idm_people_self_mail_write = { members = [ ]; }; @@ -86,8 +73,8 @@ in systems.oauth2 = { forgejo = { displayName = "ForgeJo"; - originUrl = "https://${forgejoDomain}/user/oauth2/kanidm/callback"; - originLanding = "https://${forgejoDomain}/user/oauth2/kanidm"; + originUrl = "https://git.xinyang.life/user/oauth2/kanidm/callback"; + originLanding = "https://git.xinyang.life/user/oauth2/kanidm"; allowInsecureClientDisablePkce = true; scopeMaps = { forgejo-access = [ @@ -123,8 +110,8 @@ in }; gotosocial = { displayName = "GoToSocial"; - originUrl = "${gotosocialUrl}/auth/callback"; - originLanding = "${gotosocialUrl}/auth/callback"; + originUrl = "https://gts.xiny.li/auth/callback"; + originLanding = "https://gts.xiny.li/auth/callback"; allowInsecureClientDisablePkce = true; scopeMaps = { gts-users = [ @@ -160,8 +147,8 @@ in hedgedoc = { displayName = "HedgeDoc"; - originUrl = "https://${hedgedocDomain}/auth/oauth2/callback"; - originLanding = "https://${hedgedocDomain}/auth/oauth2"; + originUrl = "https://docs.xinyang.life/auth/oauth2/callback"; + originLanding = "https://docs.xinyang.life/auth/oauth2"; allowInsecureClientDisablePkce = true; scopeMaps = { hedgedoc-users = [ @@ -190,8 +177,9 @@ in }; miniflux = { displayName = "Miniflux"; - originUrl = "${minifluxUrl}/oauth2/oidc/callback"; - originLanding = "${minifluxUrl}/oauth2/oidc/redirect"; + originUrl = "https://rss.xinyang.life/oauth2/oidc/callback"; + + originLanding = "https://rss.xinyang.life/oauth2/oidc/redirect"; scopeMaps = { miniflux-users = [ "openid" @@ -202,8 +190,8 @@ in }; grafana = { displayName = "Grafana"; - originUrl = "${grafanaUrl}/login/generic_oauth"; - originLanding = "${grafanaUrl}/"; + originUrl = "https://grafana.xinyang.life/login/generic_oauth"; + originLanding = "https://grafana.xinyang.life/"; scopeMaps = { grafana-users = [ "openid" @@ -223,17 +211,6 @@ in }; }; }; - synapse = { - displayName = "Synapse"; - originUrl = "${synapseDelegateUrl}/_synapse/client/oidc/callback"; - originLanding = "${synapseDelegateUrl}/"; - scopeMaps = { - synapse-users = [ - "openid" - "profile" - ]; - }; - }; }; }; } diff --git a/machines/massicot/services.nix b/machines/massicot/services.nix index a4f0d72..14dc9d9 100644 --- a/machines/massicot/services.nix +++ b/machines/massicot/services.nix @@ -23,6 +23,26 @@ in 8448 ]; + custom.vaultwarden = { + enable = true; + domain = "vaultwarden.xinyang.life"; + }; + + custom.hedgedoc = { + enable = true; + caddy = true; + domain = "docs.xinyang.life"; + mediaPath = "/mnt/storage/hedgedoc"; + oidc = { + enable = true; + baseURL = "https://auth.xinyang.life/oauth2/openid/hedgedoc"; + authorizationURL = "https://auth.xinyang.life/ui/oauth2"; + tokenURL = "https://auth.xinyang.life/oauth2/token"; + userProfileURL = "https://auth.xinyang.life/oauth2/openid/hedgedoc/userinfo"; + }; + environmentFile = config.sops.secrets.hedgedoc_env.path; + }; + custom.monitoring = { promtail.enable = true; }; @@ -46,6 +66,18 @@ in }; }; + services.ntfy-sh = { + enable = true; + group = "caddy"; + settings = { + listen-unix = "/var/run/ntfy-sh/ntfy.sock"; + listen-unix-mode = 432; # octal 0660 + base-url = "https://ntfy.xinyang.life"; + }; + }; + + systemd.services.ntfy-sh.serviceConfig.RuntimeDirectory = "ntfy-sh"; + services.kanidm = { package = pkgs.kanidm.withSecretProvisioning; enableServer = true; @@ -60,6 +92,40 @@ in }; }; + custom.miniflux = { + enable = true; + environment = { + LOG_LEVEL = "debug"; + LISTEN_ADDR = "127.0.0.1:58173"; + BASE_URL = "https://rss.xinyang.life/"; + OAUTH2_PROVIDER = "oidc"; + OAUTH2_CLIENT_ID = "miniflux"; + OAUTH2_REDIRECT_URL = "https://rss.xinyang.life/oauth2/oidc/callback"; + OAUTH2_OIDC_DISCOVERY_ENDPOINT = "https://auth.xinyang.life/oauth2/openid/miniflux"; + OAUTH2_USER_CREATION = 1; + }; + oauth2SecretFile = config.sops.secrets."miniflux/oauth2_secret".path; + }; + + services.matrix-conduit = { + enable = true; + package = pkgs.matrix-conduit; + settings.global = { + server_name = "xinyang.life"; + port = 6167; + # database_path = "/var/lib/matrix-conduit/"; + max_concurrent_requests = 100; + log = "info"; + database_backend = "rocksdb"; + allow_registration = false; + + well_known = { + client = "https://msg.xinyang.life"; + server = "msg.xinyang.life:443"; + }; + }; + }; + users.users.conduit = { isSystemUser = true; group = "conduit"; @@ -84,8 +150,128 @@ in environmentFile = config.sops.secrets.gts_env.path; }; + services.forgejo = { + enable = true; + # Use cutting edge instead of lts + package = pkgs.forgejo; + repositoryRoot = "/mnt/storage/forgejo/repositories"; + lfs = { + enable = true; + contentDir = "/mnt/storage/forgejo/lfs"; + }; + settings = { + service.DISABLE_REGISTRATION = true; + server = { + ROOT_URL = "https://git.xinyang.life/"; + START_SSH_SERVER = false; + SSH_USER = config.services.forgejo.user; + SSH_DOMAIN = "ssh.xinyang.life"; + SSH_PORT = 22; + LFS_MAX_FILE_SIZE = 10737418240; + LANDING_PAGE = "/explore/repos"; + }; + repository = { + ENABLE_PUSH_CREATE_USER = true; + }; + service = { + ENABLE_BASIC_AUTHENTICATION = false; + }; + oauth2 = { + ENABLED = false; # Disable forgejo as oauth2 provider + }; + oauth2_client = { + ACCOUNT_LINKING = "auto"; + USERNAME = "email"; + ENABLE_AUTO_REGISTRATION = true; + UPDATE_AVATAR = false; + OPENID_CONNECT_SCOPES = "openid profile email groups"; + }; + other = { + SHOW_FOOTER_VERSION = false; + }; + }; + }; + + systemd.services.forgejo = { + serviceConfig = { + EnvironmentFile = config.sops.secrets."forgejo/env".path; + ExecStartPost = '' + ${lib.getExe config.services.forgejo.package} admin auth update-oauth \ + --id 1 \ + --name kanidm \ + --provider openidConnect \ + --key forgejo \ + --secret $CLIENT_SECRET \ + --icon-url https://auth.xinyang.life/pkg/img/favicon.png \ + --group-claim-name forgejo_role --admin-group Admin + ''; + }; + }; + + services.grafana = { + enable = true; + settings = { + server = { + http_addr = "127.0.0.1"; + http_port = 3003; + root_url = "https://grafana.xinyang.life"; + domain = "grafana.xinyang.life"; + }; + "auth.generic_oauth" = { + enabled = true; + name = "Kanidm"; + client_id = "grafana"; + scopes = "openid,profile,email,groups"; + auth_url = "https://auth.xinyang.life/ui/oauth2"; + token_url = "https://auth.xinyang.life/oauth2/token"; + api_url = "https://auth.xinyang.life/oauth2/openid/grafana/userinfo"; + use_pkce = true; + use_refresh_token = true; + allow_sign_up = true; + login_attribute_path = "preferred_username"; + groups_attribute_path = "groups"; + role_attribute_path = "contains(grafana_role[*], 'GrafanaAdmin') && 'GrafanaAdmin' || contains(grafana_role[*], 'Admin') && 'Admin' || contains(grafana_role[*], 'Editor') && 'Editor' || 'Viewer'"; + allow_assign_grafana_admin = true; + auto_login = true; + }; + "auth" = { + disable_login_form = true; + }; + }; + }; + + systemd.services.grafana.serviceConfig.EnvironmentFile = + config.sops.secrets.grafana_oauth_secret.path; + + users.users.git = { + isSystemUser = true; + useDefaultShell = true; + group = "git"; + extraGroups = [ "forgejo" ]; + }; + users.groups.git = { }; + + users.users = { + ${config.services.caddy.user}.extraGroups = [ config.services.ntfy-sh.group ]; + }; + services.caddy = { enable = true; + virtualHosts."xinyang.life:443".extraConfig = '' + tls internal + encode zstd gzip + reverse_proxy /.well-known/matrix/* localhost:6167 + reverse_proxy * http://localhost:8080 { + flush_interval -1 + } + ''; + virtualHosts."https://msg.xinyang.life:443".extraConfig = '' + reverse_proxy /_matrix/* localhost:6167 + ''; + virtualHosts."https://git.xinyang.life:443".extraConfig = '' + reverse_proxy http://${config.services.gitea.settings.server.DOMAIN}:${toString config.services.gitea.settings.server.HTTP_PORT} + ''; + virtualHosts."http://auth.xinyang.life:80".extraConfig = '' reverse_proxy ${config.security.acme.certs."auth.xinyang.life".listenHTTP} ''; @@ -98,5 +284,27 @@ in } } ''; + + virtualHosts."https://rss.xinyang.life".extraConfig = '' + reverse_proxy ${config.custom.miniflux.environment.LISTEN_ADDR} + ''; + + virtualHosts."https://ntfy.xinyang.life".extraConfig = '' + reverse_proxy unix/${config.services.ntfy-sh.settings.listen-unix} + @httpget { + protocol http + method GET + path_regexp ^/([-_a-z0-9]{0,64}$|docs/|static/) + } + redir @httpget https://{host}{uri} + ''; + + virtualHosts."https://grafana.xinyang.life".extraConfig = + let + grafanaSettings = config.services.grafana.settings.server; + in + '' + reverse_proxy http://${grafanaSettings.http_addr}:${toString grafanaSettings.http_port} + ''; }; } diff --git a/machines/massicot/services/restic.nix b/machines/massicot/services/restic.nix index e8d2501..c205989 100644 --- a/machines/massicot/services/restic.nix +++ b/machines/massicot/services/restic.nix @@ -34,6 +34,13 @@ in ]; }; + services.postgresqlBackup = { + enable = true; + compression = "zstd"; + compressionLevel = 9; + location = "/backup/postgresql"; + }; + services.restic.backups.${config.networking.hostName} = { extraBackupArgs = [ "--limit-upload=1024" diff --git a/machines/secrets.yaml b/machines/secrets.yaml index 6d94d7e..69456c4 100644 --- a/machines/secrets.yaml +++ b/machines/secrets.yaml @@ -10,83 +10,74 @@ sops: - recipient: age1uw059wcwfvd9xuj0hpqzqpeg7qemecspjrsatg37wc7rs2pumfdsgken0c enc: | -----BEGIN AGE ENCRYPTED FILE----- - YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSA5SjAzOEozUzh1bzVvaHgr - T2xsVUszTHVSdWIyM3B5TFhtUEFMeVZlYzNrCk5IOWFNbTErbTVkQnNlVllMZWlV - Q2lHZXRIdzBiRFRSZnNUVWd2NXVXVGcKLS0tIERhcjh3VVlqSGxHUHpnc1JzVksv - VXpQVVVCUC9xR3crWm9rTk13LzVhK1EKwiuvwx3ZhcDE+9w7/dR4PrZSSoJMvklT - m7I32dMRk0o9zcl5KYU5L9Hwb+z+EBE34raoGKBF5K4aQcbZQUX3Cw== + YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSAwMHB1bFQ3dWJIU3NiOVVP + Yi9LZE1PTVdMY1BqS1JHV3VPLzZIY0hGK0NZClNlclVXKzBvNTBrTlhiR0VsaVoz + RlVLNVBEVDgzSXB5ZGxDd3hqNDh2V2MKLS0tIEhBZHFUY3c2VXJBVEVKamZ6TzBa + MlFsNnVEV0xCdlJoRnBhUHF2MmswUEUKNYD9zssGBy9SaKeOMvTz71B6KMPW87cM + tFJzgnQceEQF658lVa5cCzG1gzraCgBtQU15XzC7e8zWI9CHquRRlQ== -----END AGE ENCRYPTED FILE----- - recipient: age1ytwfqfeez3dqtazyjltn7mznccwx3ua8djhned7n8mxqhw4p6e5s97skfa enc: | -----BEGIN AGE ENCRYPTED FILE----- - YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSA5R1ZIRlN2b3M2OUQ0T2cw - eE5DTm9KY1NUY1p5eDhLNG4xMDVkVjRyWDNRClp3MTRWeGJMYTczcC9YQTNZdkxx - ejJ3QnhjcUcyUldUNEVqVUh6Z2grd00KLS0tIDVvbDZWbmZPZVhDNHM1K1kzaE95 - aHJqSU16dlJiRGl0VWNMVXVYMmhPb2MKMboq9ShGIJMFVENgLPlQdwdtTOjVb0CC - 4ttM3xWnYkf8416a0OYFrda5l1kfJJzQakbk/tbGcTu1yTcd+6lOtA== - -----END AGE ENCRYPTED FILE----- - - recipient: age17r3fxfmt6hgwe984w4lds9u0cnkf5ttq8hnqt800ayfmx7t8t5gqjddyml - enc: | - -----BEGIN AGE ENCRYPTED FILE----- - YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBVby8wYS9pa0szTlVUS3FI - VWhjaCtyUzNLbkw2VXRlWkVMZlRkeXJMZGlRCnBTWklnZ0Uzd2lTMGt1M2wxZ0px - NFl2RW5hSUZVdHI0aVFRMHJtMFQ3ODAKLS0tIFlYOHVRYVFGbkcvUWRmQitQQnI5 - bG5vemMvcWdpOEtxNGRpS0doQmtuUFkK8Hxl//kOtbEw3jf96ZZ4G1Yb94f4Jeb4 - TfPs7O/ESJY8ovNsoXRQEt99vOR5D1wBzyZBY9E3f2ZzY/uBmup0cw== + YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBTTnZLTlZQRzc1enVEa1BN + SHdoSi9oOXk4UTV0SlRZS2tLS2FFL3VjNzNNClVWTTNKekF6T0RTUzdEeWhLbHoz + WFZKaHJEaVBWa04zRWRiVnJZRjU0YVEKLS0tIFJVL0FEemowS3V6MmsxbWJMU2I1 + U2NnUnVKdFlRSGVzUFQ4ZFcwL0lWTlkKz1t3yqjgIdMWS/Nsy2nq3oCjOhGDP+UT + L+LAuFExJPV0qlsOG/kCGB/WtCJfnBvcp6vPDBLqjK8NllIX/iPI5g== -----END AGE ENCRYPTED FILE----- - recipient: age1jle2auermhswqtehww9gqada8car5aczrx43ztzqf9wtcld0sfmqzaecta enc: | -----BEGIN AGE ENCRYPTED FILE----- - YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBPSmRYMkNIdERJZVBxV1p1 - emlqOTBpN3l2WXkzNjRRcFI5NUZDZnQ1WXdnCkRVbm8xais5aGVCTmtSTGxaTXlT - L2ZWQ0p5WFZNRWl5SWVkRUYwc2R3b1UKLS0tIEZEck4yMmJUQWVvNHRJQnpCQTBo - cDJsaG83MTdXWVd2NUpLczhjWTBBZVUK5BxBIYVqkqVLw9LTbnJ8SQWN2i4USdI8 - 8m/hZFXTJ4GI0f795DEmbcZq9xET14aQqta0wSASqwP/5Ld1mo0a0w== + YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBETWpkcjhINktqeGxjdWxz + UTVVNC9kalorcVJOdHpJSkZJNXlGUHZ2VUdrCjRCclBTZnJEZ3JGOVpqS1Y0b0dt + eldFMS91WUc2Y1FnWWZoN0grc01pT0UKLS0tIC96TjlEaVBGRkZhZ0hac2lmbEdI + eHMzTFhsQ0FqY05uUEZSbExCcmdscEkKdxITlc0V5ayq+9fmj77SnEMFxKJhOOta + RfJhOQUv8g3nCN+SsuaOy0TitUCiDWh5XoB0DufEQPcS/kzGZN1Inw== -----END AGE ENCRYPTED FILE----- - recipient: age12ng08vjx5jde5ncqutwkd5vm4ygfwy33mzhzwe0lkxzglulgpqusc89r96 enc: | -----BEGIN AGE ENCRYPTED FILE----- - YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSAwSkhjRTdBWklZUEpUanM0 - Wjl4b2c3K0g0ZUxxMlRrUFhhZzhNRXhPVnpvCmpNWVBNTXNYczV3aWhCd05FOGJ0 - YlNobFhWdStGbDRZV2NlUWV6ZFRVNEkKLS0tIGd1RUR4K21GOEQ0aWtqRi9RREpE - RXBXcXFYUDVXVzN4Q25zSklFU21wbFkKQuTHkgFC5HRPO7/PuVhJzbbHOTPaFXvN - +Y31AK3OAVdUETMEuJ2mk50Bi5BiiUeOnnv1bZ6O+iX0o20ysUseTg== + YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBydlQ4S1duQU53Wk1nd21K + d2RqM1F0VDFJVXB2aGRTZ2hxczI2V1lndVdrCjArVlE2N0RGZ0htUEZYdVlQMlU5 + SWIwWHVCaWxaQTJMNzg3WC8xRS9IYzgKLS0tIDRvSS8ybVlrSy9zYjQ2NXBaMlZk + Ulg4cUFBejRoS3VEWkRaZEUxMExUeWMKNeq6TN1gaBNU9vAitGttcU+8HmFQipdm + LPwo4/toyf27emb4KGs0AV0Dm4Sxj9S3Xvrv1B+qvhfT638/RIUm2w== -----END AGE ENCRYPTED FILE----- - recipient: age1v5h946jfke6ae8pcgz52mhj26cacqcpl9dmmrrkf37x55rnq2v3szqctvv enc: | -----BEGIN AGE ENCRYPTED FILE----- - YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBnc3NOZFRYT1VnaVZSaTRi - WnluSEk4d1U5TWx2REZRZ3VCRVp2ZzlKY0NvCjNlUnIwdWVqSnlQOWp1dlJ5THlW - c2xTNHhnaE94a2ZTeXJjQTVxeGRLTmsKLS0tIFV4c2NZK1ZnL2xtUlVvSksxNi9o - L3dodkJXVjZrekVldTVsRFRxSFlrTmMKiokjgIRIsI8D2aFP/Qem4iGzC4yr5lm2 - ZwggC/UfD56ysTEqrVaDnR7f5fSqZLWdstPJn7I/vr5CwKRMbMPYSA== + YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSB4YXpyOXE3MFovWEQvMVRr + TGVST3U0N2dCVDJGT1A3eUtlRis3bFEvTHlFClZHQ2xRWklMMCtER01QNEVHaVYr + MC94V3R4MVdNdUU3eXQ2RGFFVGo4VFEKLS0tIDQ4b2ZuMy9URUswWUZqNHlxandU + OFducVVzdGZGY0tnbFFBZDdjVzVkaUEKN8qAbbrd4pAHRGIN8O64fl7bQ6hx6Isr + Qx0xKeuhJCVXgtE8xc7xmnEhqrcONlflJ/XUnYV9jOkB71zSBJxruA== -----END AGE ENCRYPTED FILE----- - recipient: age1p2dlc8gfgyrvtta6mty2pezjycn244gmvh456qd3wvkfwesp253qnwyta9 enc: | -----BEGIN AGE ENCRYPTED FILE----- - YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBpN0llOTBJU1pNNVFxVWxt - aFdKdStKL1ZlZ0p6WFRQbHpGNnpmdlJXdG1FCkx5eDhZWWJvQ2xSWEJqWnZ6NmNt - Y0MzNDg5QzVSbEZteW1LNlFyRFg5Q0EKLS0tIDBrT0dEZlBoTExYcGRNZjZ5Znpz - cnE4YWRTMmRsTENhOTl5R2dYSzQwazAKvnTvZz842Mg5AVlIoYHI2BG+0/hO5zIv - jRVJri98fgGterXADTPmeoY3p+fFQggTPhs/5s5GSQxd5aiX8vvvrA== + YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSAzczdPMDdWU1ZtckJRQm5j + UWJub0Yzd3NzOEh4YWdId01nYWI1YVY3dng0ClpEYXBJV2cvWEdjdXcwUFI3Y0NG + MDgvTmNZOXRQQndyVmRHamNRbzVaVU0KLS0tIGFKVTI4TkE2UjhDUSsxQTlNQ0Vk + QmFMNnlqbnhScC90T012K1QxRnRUOHcKAV7NxUn0CMcjKwK8zrocoLO1P9jc22uG + eG+vdJ6xzA99UX51aPxQOeEJgdFPEd3y1QJszQmRzThvid7y4lv0Cw== -----END AGE ENCRYPTED FILE----- - recipient: age18u4mqrhqkrpcytxfxfex6aeap04u38emhy6u4wrp5k62sz2vae4qm5jj7s enc: | -----BEGIN AGE ENCRYPTED FILE----- - YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBPQWljdGg4VTlDdGhoblpk - LytxK2FnQVI1dzB2bnFaWUtoUVNGS3lpU3prCnRwUTNnZVVXTnZ6eCtScTk5YzI3 - TGM2MmNhaHQ3NXAzMk0rcnJoTlp5STQKLS0tIEp2U3YvUUhXTkt3VFczY3J1LzMv - ZzM0VHpqamRIZVROS2lQdXFhQTNBekEKEySldC+VvZvPY398ZVkB5s73bT3QbuLh - IqTv+wbkbjlvZJUavVyycY5SwMXkSX3ge9W/64mt/RDs88gSXFS+Sw== + YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBsVmpzenRvWE5EK2wzRFkx + SERZV0s1Rkt0ZnZ1U3JQSFNhdGVvaWhWcTA4CjVxK0Z0MHI0ZnMrUS9YYWhTTG1z + L2lVS1Q2UkVQd2x5b1E1eWpQVGp2ZHMKLS0tIHNLOGhTYjkzWkFEM05wYkRZeXFQ + SXNTSGZZSFE2bFhybXdIc1FUb1ZBd0kKkYzflPRk6GrE6t9oVGOzc8xcyZDxiIw8 + 9SVXIgV0WVpY4lnFKYKH2i4+1sIm6tKOpizlQxTg5VgmmrTtfazWAA== -----END AGE ENCRYPTED FILE----- - recipient: age1fw2sqaa5s9c8ml6ncsexkj8ar4288387ju92ytjys4awf9aw6smqqz94dh enc: | -----BEGIN AGE ENCRYPTED FILE----- - YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSA4bGppem15NlVod2hCRkM5 - MzY1aUZOdEVzRzdEYTRNakdMQWJlRkk0eEZzClRLSnRrQUoreU5MVG40KzRKSGcw - bUU4ZnpLU0VtOWxXVllrSW5lN0NWb0kKLS0tIE1iemRlVVpieEhxRnlIb2dFUHZr - am04NVRtU2N6SThYZWdXVE5RZ1B2aE0KVcHvB5k2Gcu/St0P8WPFzlCtuZthZTKo - hwVc0lC6Xxt25hriaUFinwnyvcjxrLCx0Nq7f9Zn16nJcza5kev1nQ== + YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSB0NHpkOTFHaXRhVGNua0dV + alRieWJ6WG5ZNzlvcTR2aTVUeWFBVGVVUUNZCnY2VUZUOWVlNGY1ZldyVGE2bkpi + VXVtQ3IyK0kyV1cyMU5nN1lYaW1oOUkKLS0tIFRVRGFCNWlGendSVEhHY0w0QTl6 + emJEQkQ3QlU0TFVWaW1uQytaUndmQlEKKahqJpX8vI+PASOzzod/sFvXSkQFnJ9O + YmnmiFxm5WZDPLHwkgVx8FgCq9RfAad4HybhsMjYPKXJ/fNa/WVZRA== -----END AGE ENCRYPTED FILE----- lastmodified: "2024-11-30T06:31:42Z" mac: ENC[AES256_GCM,data:xh8x9IrQ01ZzdcCTIfBrifIGduMYVmSSP52BkTyr/bx7AgQAz2WeA7LFrccxIayCGHrQKfMQDLUKJ/EBamG/6p8AX6QqZBTfqFD688ZhmRfxgpj7fYR9jPYnhb/9XHI9R2jTaJWwrorXvu3pa+Gy/hWB3Kb+WZc3fslmIuKuLH0=,iv:GDrHSFZxPbpACdusVDPHXEjeEusYfk53N/KGHtdvrYo=,tag:ap38sCSTZVDQ0ZazXM3vlg==,type:str] diff --git a/machines/thorite/default.nix b/machines/thorite/default.nix index f2de662..b85bab8 100644 --- a/machines/thorite/default.nix +++ b/machines/thorite/default.nix @@ -1,10 +1,7 @@ -{ config, ... }: { imports = [ ./hardware-configurations.nix ./monitoring.nix - ./restic.nix - ./ntfy.nix ]; config = { @@ -31,10 +28,6 @@ 443 ]; - services.tailscale.enable = true; - - services.caddy.enable = true; - commonSettings = { auth.enable = true; }; diff --git a/machines/thorite/monitoring.nix b/machines/thorite/monitoring.nix index 981fd14..bc10492 100644 --- a/machines/thorite/monitoring.nix +++ b/machines/thorite/monitoring.nix @@ -1,20 +1,5 @@ -{ - config, - lib, - pkgs, - ... -}: -with config.my-lib; -let - inherit (config.my-lib.settings) - minifluxUrl - gotosocialUrl - hedgedocDomain - grafanaUrl - ntfyUrl - ; - removeHttps = s: lib.removePrefix "https://" s; -in +{ config, my-lib, ... }: +with my-lib; { config = { sops = { @@ -29,23 +14,11 @@ in custom.monitoring = { grafana.enable = true; - loki = { - enable = true; - rules = { - sshd_closed = { - expr = ''count_over_time({unit="sshd.service"} |~ "Connection closed by authenticating user" [15m]) > 25''; - description = "More then 25 login attemps in last 15 min without success"; - }; - unusual_log_volume = { - expr = ''sum by (unit) (rate({unit=~".+"}[5m])) > 80''; - description = "Unit {{ $labels.unit }} is logging at an unusually high rate"; - }; - }; - }; + loki.enable = true; promtail.enable = true; }; - services.caddy.virtualHosts.${grafanaUrl}.extraConfig = + services.caddy.virtualHosts."https://grafana.xinyang.life".extraConfig = with config.services.grafana.settings.server; '' reverse_proxy http://${http_addr}:${toString http_port} ''; @@ -57,28 +30,19 @@ in blackbox.enable = true; node.enable = true; }; - ruleModules = - (mkCaddyRules [ { host = "thorite"; } ]) - ++ (mkNodeRules [ { host = "thorite"; } ]) - ++ (mkBlackboxRules [ { host = "thorite"; } ]); + ruleModules = (mkCaddyRules [ { host = "thorite"; } ]) ++ (mkNodeRules [ { host = "thorite"; } ]); }; services.prometheus.scrapeConfigs = let probeList = [ "la-00.video.namely.icu:8080" - "fra-00.video.namely.icu:8080" + "fre-00.video.namely.icu:8080" "hk-00.video.namely.icu:8080" + "49.13.13.122:443" + "45.142.178.32:22" "home.xinyang.life:8000" ]; - chinaTargets = [ - "bj-cu-v4.ip.zstaticcdn.com:80" - "bj-cm-v4.ip.zstaticcdn.com:80" - "bj-ct-v4.ip.zstaticcdn.com:80" - "sh-cu-v4.ip.zstaticcdn.com:80" - "sh-cm-v4.ip.zstaticcdn.com:80" - "sh-ct-v4.ip.zstaticcdn.com:80" - ]; passwordFile = config.sops.secrets."prometheus/metrics_password".path; in (mkScrapes [ @@ -88,50 +52,32 @@ in address = "weilite.coho-tet.ts.net"; port = 8082; } - { - name = "restic_rest_server"; - address = "backup.xinyang.life"; - port = 8443; - } { inherit passwordFile; name = "gotosocial"; - address = removeHttps gotosocialUrl; + address = "xinyang.life"; } { inherit passwordFile; name = "miniflux"; - address = removeHttps minifluxUrl; - } - { - name = "hedgedoc"; - address = hedgedocDomain; + address = "rss.xinyang.life"; } { name = "ntfy"; - address = removeHttps ntfyUrl; + address = "ntfy.xinyang.life"; } { name = "grafana-eu"; - address = removeHttps grafanaUrl; - } - { - name = "loki"; - scheme = "http"; - address = "thorite.coho-tet.ts.net"; - port = 3100; + address = "grafana.xinyang.life"; } ]) ++ (mkCaddyScrapes [ { address = "thorite.coho-tet.ts.net"; } - { address = "biotite.coho-tet.ts.net"; } - { address = "weilite.coho-tet.ts.net"; } ]) ++ (mkNodeScrapes [ { address = "thorite.coho-tet.ts.net"; } { address = "massicot.coho-tet.ts.net"; } { address = "weilite.coho-tet.ts.net"; } - { address = "biotite.coho-tet.ts.net"; } { address = "hk-00.coho-tet.ts.net"; } { address = "la-00.coho-tet.ts.net"; } { address = "fra-00.coho-tet.ts.net"; } @@ -139,37 +85,20 @@ in ++ (mkBlackboxScrapes [ { hostAddress = "thorite.coho-tet.ts.net"; - targetAddresses = probeList ++ [ "49.13.13.122:443" ]; + targetAddresses = probeList; } { hostAddress = "massicot.coho-tet.ts.net"; - targetAddresses = probeList ++ [ "45.142.178.32:443" ]; + targetAddresses = probeList; } { hostAddress = "weilite.coho-tet.ts.net"; targetAddresses = [ "la-00.video.namely.icu:8080" - "fra-00.video.namely.icu:8080" + "fre-00.video.namely.icu:8080" "hk-00.video.namely.icu:8080" ]; } - { - hostAddress = "la-00.coho-tet.ts.net"; - targetAddresses = chinaTargets; - } - { - hostAddress = "hk-00.coho-tet.ts.net"; - targetAddresses = chinaTargets; - } - { - hostAddress = "fra-00.coho-tet.ts.net"; - targetAddresses = chinaTargets; - } - ]) - ++ (mkV2rayScrapes [ - { address = "la-00.coho-tet.ts.net"; } - { address = "hk-00.coho-tet.ts.net"; } - { address = "fra-00.coho-tet.ts.net"; } ]); }; diff --git a/machines/thorite/ntfy.nix b/machines/thorite/ntfy.nix deleted file mode 100644 index 8e950f8..0000000 --- a/machines/thorite/ntfy.nix +++ /dev/null @@ -1,29 +0,0 @@ -{ config, ... }: -let - inherit (config.my-lib.settings) ntfyUrl; -in -{ - - services.ntfy-sh = { - enable = true; - group = "caddy"; - settings = { - listen-unix = "/var/run/ntfy-sh/ntfy.sock"; - listen-unix-mode = 432; # octal 0660 - base-url = ntfyUrl; - }; - }; - - systemd.services.ntfy-sh.serviceConfig.RuntimeDirectory = "ntfy-sh"; - - services.caddy.virtualHosts.${ntfyUrl}.extraConfig = '' - reverse_proxy unix/${config.services.ntfy-sh.settings.listen-unix} - @httpget { - protocol http - method GET - path_regexp ^/([-_a-z0-9]{0,64}$|docs/|static/) - } - redir @httpget https://{host}{uri} - ''; - -} diff --git a/machines/thorite/restic.nix b/machines/thorite/restic.nix deleted file mode 100644 index d359304..0000000 --- a/machines/thorite/restic.nix +++ /dev/null @@ -1,51 +0,0 @@ -{ - config, - lib, - pkgs, - ... -}: -let - sqliteBackup = fromPath: toPath: file: '' - mkdir -p ${toPath} - ${lib.getExe pkgs.sqlite} ${fromPath} ".backup '${toPath}/${file}'" - ''; -in -{ - sops.secrets = { - "restic/repo_url" = { }; - "restic/repo_password" = { }; - }; - - custom.restic = { - enable = true; - paths = [ - "/backup/db" - "/backup/var/lib" - ]; - backupPrepareCommand = [ - '' - mkdir -p /backup/var - ${pkgs.btrfs-progs}/bin/btrfs subvolume snapshot -r /var/lib /backup/var/lib - '' - ]; - backupCleanupCommand = [ - '' - ${pkgs.btrfs-progs}/bin/btrfs subvolume delete /backup/var/lib - '' - ]; - btrfsRoots = [ ]; - }; - - services.postgresqlBackup = lib.mkIf config.services.postgresql.enable { - enable = true; - compression = "zstd"; - compressionLevel = 9; - location = "/backup/db/postgresql"; - }; - - services.restic.backups.${config.networking.hostName} = { - extraBackupArgs = [ - "--limit-upload=1024" - ]; - }; -} diff --git a/machines/thorite/secrets.yaml b/machines/thorite/secrets.yaml index c246e2b..60d475f 100644 --- a/machines/thorite/secrets.yaml +++ b/machines/thorite/secrets.yaml @@ -1,8 +1,5 @@ grafana: oauth_secret: ENC[AES256_GCM,data:angZR3sl8vGcbAXyKFBvCSm+YhF5OooCcxRiSxR2zBoXMz5wv5/uMJFynwOTRVI6,iv:hVpOlM89lNbK6AsGf4Is/tLv3xPfg/XdtA8vuEK52L8=,tag:zCER+IdRnTcG2WHQ/AhxZA==,type:str] -restic: - repo_url: ENC[AES256_GCM,data:tc7wYRN20sHxATTZYEBpf6tNafzq9vcvqdUHYJDmJIArxprNd6WiyqPXowzbksZcEi5JwSwwJH/MYminnPGtrR8erWZg8OB3,iv:/z7mF58tMAviscFWHd4NJw7UZlq7Bzz+LU88J+kE9qg=,tag:i97FP4SmmNXOuxylkHhYCA==,type:str] - repo_password: ENC[AES256_GCM,data:o3MbXJRwR5UE9uCELN2ejQ==,iv:cYPNjJAV7H2BNCuFLDJoJvPk+CFvagXJwW9LRAGc0G0=,tag:qF6Di2W+8kESCRAphC/c0g==,type:str] sops: kms: [] gcp_kms: [] @@ -27,8 +24,8 @@ sops: M2pqMUJoMGlBZnpBaVBUTFFRZUMzb2sKrlWy26Cv55/8XQEl9hee8P29uj582sIx mUjaYE0U2qOP9bklXUQyyzQjfkBLWTLc1PTX9BjqOOsqXwkRQIYppA== -----END AGE ENCRYPTED FILE----- - lastmodified: "2024-12-03T08:18:54Z" - mac: ENC[AES256_GCM,data:jqSt34avoMfL9g3LmvjrPTzW4xGLgX70CXI8qk4isaLbZ8FkxjVU8QY1ot9GZnFEQWUkReSuGD4gFxi8TjetlNdx0zDPcv6zGJUSfcYpyKDCqGdyL/2x8xnYtI2pWINBZxR/2XxT3cus39FJdXVcz3l7KX4DvYvm8t/D9+r4ef0=,iv:KY/OTbDOOD/bBDTIuIk1ck7wDxLogo2EKeSOfOe4j5o=,tag:B17iF5O32KDZfctubpXCng==,type:str] + lastmodified: "2024-11-28T17:02:03Z" + mac: ENC[AES256_GCM,data:14FOUXuKP+8+sad1UlhBW37fWzmutpyn6d4q2qKtBiOyT5ivHunFHJfHrtX83X2fLDmUfiD42bXf+rYfdtKzVUmQ6vutCUQk+Hal8NElhjcq5Ns5kT4VZRKG7/ya9+eNEEkajtq/7OFEM5KOQKTKjyOBqBq/AdYQ+ni9r45c1sM=,iv:WrdWSfrZrGalZO4WGk3JpgACY7W0odt3vP+pRkMXHfA=,tag:jeRBfR2QYjLBylOLHxU3hQ==,type:str] pgp: [] unencrypted_suffix: _unencrypted version: 3.9.1 diff --git a/machines/weilite/default.nix b/machines/weilite/default.nix index 9d8cd04..b694f40 100644 --- a/machines/weilite/default.nix +++ b/machines/weilite/default.nix @@ -52,8 +52,9 @@ owner = "caddy"; mode = "400"; }; - "restic/localpass" = { - owner = "restic"; + "immich/oauth_client_secret" = { + owner = "immich"; + mode = "400"; }; }; }; @@ -68,10 +69,6 @@ }; }; - custom.monitoring = { - promtail.enable = true; - }; - systemd.mounts = [ { what = "immich"; @@ -108,6 +105,43 @@ 2222 ]; + services.immich = { + enable = true; + mediaLocation = "/mnt/XinPhotos/immich"; + host = "127.0.0.1"; + port = 3001; + openFirewall = true; + machine-learning.enable = true; + environment = { + IMMICH_MACHINE_LEARNING_ENABLED = "true"; + }; + database.enable = true; + }; + + custom.immich.jsonSettings = { + oauth = { + enabled = true; + issuerUrl = "https://auth.xinyang.life/oauth2/openid/immich/"; + clientId = "immich"; + clientSecret = { + _secret = config.sops.secrets."immich/oauth_client_secret".path; + }; + scope = "openid email profile"; + signingAlgorithm = "ES256"; + storageLabelClaim = "email"; + buttonText = "Login with Kanidm"; + autoLaunch = true; + mobileOverrideEnabled = true; + mobileRedirectUri = "https://immich.xinyang.life:8000/api/oauth/mobile-redirect/"; + }; + passwordLogin = { + enabled = false; + }; + newVersionCheck = { + enabled = false; + }; + }; + services.dae = { enable = true; configFile = "/var/lib/dae/config.dae"; diff --git a/machines/weilite/secrets.yaml b/machines/weilite/secrets.yaml index 0394a80..8446f0a 100644 --- a/machines/weilite/secrets.yaml +++ b/machines/weilite/secrets.yaml @@ -2,8 +2,6 @@ cloudflare_dns_token: ENC[AES256_GCM,data:m4euSkxxJmiMk9UPyeni/hwpl1W9A4MM0ssg71 dnspod_dns_token: ENC[AES256_GCM,data:uZfr3g103amywxh3NMU+AkwuYb61svzyavvQ4rxJijIMIbfPvERrVNcyivoOrFWYXHpPWkhZFdU=,iv:mArVAcebW9i+u26GmQmfmJTsFkR4ZRMIisTqjpMYan8=,tag:Zsmv1Wzfi3+PHigjReToHQ==,type:str] immich: oauth_client_secret: ENC[AES256_GCM,data:EFs2hPjGMj0idwY3oQVIDTOIWkdwoAoAVjDQE9Z2eAKzUDH3grmYpYE+33V8d/Ux,iv:A9cjwFr/ZqltG62/N8MQ1LhdDbSIVVAqIPVB492zYJw=,tag:VTTtE697BZTVsI32UF53/w==,type:str] -restic: - localpass: ENC[AES256_GCM,data:GIQAmkpDmGu4+sSG5/b5yQ==,iv:dcu6F8NnVjeQzEG2vM3fOV5owI0PWc86ts20UP3vN18=,tag:vsG8x062FG1pH5YNcAajeg==,type:str] sops: kms: [] gcp_kms: [] @@ -28,8 +26,8 @@ sops: V0thRjU4WGpQRGFpcnoxSjZTZHhTTkUKzNMHh9p7GUY3hL5XZ9S4x20CwaItsXFV RKujsFVVBd8Kuq/jyOCBTRCscuHI4LW/wYeZYHFEZFSTK2liAqspgw== -----END AGE ENCRYPTED FILE----- - lastmodified: "2024-12-03T05:59:51Z" - mac: ENC[AES256_GCM,data:0dLbfkm7fJvH5Mmct0/qHulg2AtDCeeeOgWMXfeGRUaX3GlLDiLga0zW4uNPDuahVecdh6ofvYfBOxFaGUdBCHk9vq5GzrwrzBNhqObWQ3AqVuq5rjqSxEKoFM4Eb5qoqaOefFzT/9qC94NDETTsHhjiEeIgd4fgSr2dazNiFPE=,iv:Ggw0FHzkrhKh5Uzo3seHGwwHsWW/tTAgAl0iIq9PVk4=,tag:rJvUI5/wsLJ01XyKmkRghw==,type:str] + lastmodified: "2024-09-13T12:02:54Z" + mac: ENC[AES256_GCM,data:c5p+B2mPCDyS/Q4QH4MkzCww6jFDhP8RfHqrKLf4e/8XuNEGfNmPKaeliZG26j1YQWRvFHiGQX3AMnQ3Q+fSRUQCVi5KV+KW7fADNIB3TiTT5hAFuynhiWWQSmIrWP0GGek3GDGi7OJ1PrFbxWP9bwaf+zBegiaUcWoTorJg7No=,iv:6MohNgPpq80eTUlf3RvPKsxdx69V0jl+/hrMxAPpPQE=,tag:BtWp1FChP2hdclbGl5W+vQ==,type:str] pgp: [] unencrypted_suffix: _unencrypted - version: 3.9.1 + version: 3.9.0 diff --git a/machines/weilite/services/default.nix b/machines/weilite/services/default.nix index 0a6e4ca..d70e175 100644 --- a/machines/weilite/services/default.nix +++ b/machines/weilite/services/default.nix @@ -3,6 +3,5 @@ ./ocis.nix ./restic.nix ./media-download.nix - ./immich.nix ]; } diff --git a/machines/weilite/services/immich.nix b/machines/weilite/services/immich.nix deleted file mode 100644 index 33a98d3..0000000 --- a/machines/weilite/services/immich.nix +++ /dev/null @@ -1,63 +0,0 @@ -{ - config, - ... -}: -let - user = config.systemd.services.immich-server.serviceConfig.User; - jsonSettings = { - oauth = { - enabled = true; - issuerUrl = "https://auth.xinyang.life/oauth2/openid/immich/"; - clientId = "immich"; - clientSecret = config.sops.placeholder."immich/oauth_client_secret"; - scope = "openid email profile"; - signingAlgorithm = "ES256"; - storageLabelClaim = "email"; - buttonText = "Login with Kanidm"; - autoLaunch = true; - mobileOverrideEnabled = true; - mobileRedirectUri = "https://immich.xinyang.life:8000/api/oauth/mobile-redirect/"; - }; - passwordLogin = { - enabled = false; - }; - image = { - extractEmbedded = true; - }; - newVersionCheck = { - enabled = false; - }; - }; -in -{ - config = { - sops.secrets."immich/oauth_client_secret" = { }; - - sops.templates."immich/config.json" = { - owner = user; # Read when running - content = builtins.toJSON jsonSettings; - }; - - systemd.services.immich-server = { - serviceConfig = { - Environment = "IMMICH_CONFIG_FILE=${config.sops.templates."immich/config.json".path}"; - }; - }; - - services.immich = { - enable = true; - mediaLocation = "/mnt/XinPhotos/immich"; - host = "127.0.0.1"; - port = 3001; - openFirewall = true; - machine-learning.enable = true; - environment = { - IMMICH_MACHINE_LEARNING_ENABLED = "true"; - }; - database.enable = true; - }; - - # https://github.com/NixOS/nixpkgs/pull/324127/files#r1723763510 - services.immich.redis.host = "/run/redis-immich/redis.sock"; - }; -} diff --git a/machines/weilite/services/media-download.nix b/machines/weilite/services/media-download.nix index 6f22744..0e1ab58 100644 --- a/machines/weilite/services/media-download.nix +++ b/machines/weilite/services/media-download.nix @@ -13,13 +13,6 @@ openFirewall = false; }; - nixpkgs.config.permittedInsecurePackages = [ - "aspnetcore-runtime-6.0.36" - "aspnetcore-runtime-wrapped-6.0.36" - "dotnet-sdk-6.0.428" - "dotnet-sdk-wrapped-6.0.428" - ]; - services.sonarr = { enable = true; }; diff --git a/machines/weilite/services/restic.nix b/machines/weilite/services/restic.nix index f62786e..4858590 100644 --- a/machines/weilite/services/restic.nix +++ b/machines/weilite/services/restic.nix @@ -35,8 +35,6 @@ in services.restic.backups = builtins.listToAttrs [ (mkPrune "xin" "calcite") (mkPrune "xin" "massicot") - (mkPrune "xin" "biotite") - (mkPrune "xin" "thorite") ]; networking.firewall.allowedTCPPorts = [ 8443 ]; diff --git a/modules/home-manager/fish.nix b/modules/home-manager/fish.nix index 1b9f626..4d265d5 100644 --- a/modules/home-manager/fish.nix +++ b/modules/home-manager/fish.nix @@ -91,10 +91,6 @@ in ${pkgs.comma}/bin/comma $argv end set -gx LS_COLORS (${lib.getExe pkgs.vivid} generate catppuccin-mocha) - alias ctlsp="systemctl stop" - alias ctlst="systemctl start" - alias ctlrt="systemctl restart" - alias ctls="systemctl status" '' else ""; diff --git a/modules/home-manager/git.nix b/modules/home-manager/git.nix index 56bc382..d28eb50 100644 --- a/modules/home-manager/git.nix +++ b/modules/home-manager/git.nix @@ -25,9 +25,8 @@ in }; }; }; - config = mkIf cfg.enable { - home.packages = [ pkgs.git-absorb ]; - programs.git = { + config = { + programs.git = mkIf cfg.enable { enable = true; delta.enable = true; userName = "Xinyang Li"; @@ -43,10 +42,6 @@ in signByDefault = true; key = cfg.signing.keyFile; }; - extraConfig.absorb = { - oneFixupPerCommit = true; - maxStack = 20; - }; extraConfig.user = mkIf cfg.signing.enable { signingkey = cfg.signing.keyFile; }; extraConfig.gpg = mkIf cfg.signing.enable { format = "ssh"; }; }; diff --git a/modules/nixos/common-settings/auth.nix b/modules/nixos/common-settings/auth.nix index 1cd85ec..d0a54cb 100644 --- a/modules/nixos/common-settings/auth.nix +++ b/modules/nixos/common-settings/auth.nix @@ -9,6 +9,8 @@ let inherit (lib) mkIf mkEnableOption + mkOption + types ; cfg = config.commonSettings.auth; @@ -19,43 +21,25 @@ in }; config = mkIf cfg.enable { - services.kanidm = { - enableClient = true; - clientSettings = { - uri = "https://auth.xinyang.life"; - }; - enablePam = true; - unixSettings = { - pam_allowed_login_groups = [ "linux_users" ]; - default_shell = "/bin/sh"; + custom.kanidm-client = { + enable = true; + uri = "https://auth.xinyang.life"; + asSSHAuth = { + enable = true; + allowedGroups = [ "linux_users" ]; }; + sudoers = [ "xin@auth.xinyang.life" ]; }; services.openssh = { - enable = true; - authorizedKeysCommand = "/etc/ssh/auth %u"; - authorizedKeysCommandUser = "kanidm-ssh-runner"; settings = { PasswordAuthentication = false; KbdInteractiveAuthentication = false; - PermitRootLogin = lib.mkForce "no"; + PermitRootLogin = "no"; + GSSAPIAuthentication = "no"; + KerberosAuthentication = "no"; }; }; - - environment.etc."ssh/auth" = { - mode = "0555"; - text = '' - #!${pkgs.stdenv.shell} - ${pkgs.kanidm}/bin/kanidm_ssh_authorizedkeys $1 - ''; - }; - users.groups.wheel.members = [ "xin@auth.xinyang.life" ]; - users.groups.kanidm-ssh-runner = { }; - users.users.kanidm-ssh-runner = { - isSystemUser = true; - group = "kanidm-ssh-runner"; - }; - services.fail2ban.enable = true; security.sudo = { diff --git a/modules/nixos/common-settings/proxy-server.nix b/modules/nixos/common-settings/proxy-server.nix index 2384900..b54774a 100644 --- a/modules/nixos/common-settings/proxy-server.nix +++ b/modules/nixos/common-settings/proxy-server.nix @@ -1,6 +1,5 @@ { config, - pkgs, lib, ... }: @@ -22,117 +21,106 @@ let config.security.acme.certs.${config.deployment.targetHost}.directory + "/cert.pem"; }; - mkSingConfig = users: { - log = { - level = "warn"; - }; - inbounds = - [ - { - tag = "sg0"; - type = "trojan"; - listen = "::"; - listen_port = cfg.trojan.port; - tcp_multi_path = true; - tcp_fast_open = true; - users = map (user: { - name = user.name; - password = { - _secret = user.passwordFile; - }; - }) users; - tls = singTls; - } - ] - ++ lib.forEach (lib.range 6311 6314) (port: { - tag = "sg" + toString (port - 6310); - type = "tuic"; - listen = "::"; - listen_port = port; - congestion_control = "bbr"; - users = map (user: { - name = user.name; - uuid = { - _secret = user.uuidFile; - }; - password = { - _secret = user.passwordFile; - }; - }) users; - tls = singTls; - }); - outbounds = - # warp outbound goes first to make it default outbound - (lib.optionals (cfg.warp.onTuic or cfg.warp.onTrojan) [ - { - type = "wireguard"; - tag = "wg-out"; - private_key = { - _secret = config.sops.secrets.wg_private_key.path; - }; - local_address = [ - "172.16.0.2/32" - { _secret = config.sops.secrets.wg_ipv6_local_addr.path; } - ]; - peers = [ - { - public_key = "bmXOC+F1FxEMF9dyiK2H5/1SUtzH0JuVo51h2wPfgyo="; - allowed_ips = [ - "0.0.0.0/0" - "::/0" - ]; - server = "162.159.192.1"; - server_port = 500; - } - ]; - } - ]) - ++ [ - - { - type = "direct"; - tag = "direct"; - } - ]; - route = { - rules = + mkSingConfig = + { uuid, password, ... }: + { + log = { + level = "warn"; + }; + inbounds = [ { - inbound = "sg4"; - outbound = "direct"; + tag = "sg0"; + type = "trojan"; + listen = "::"; + listen_port = cfg.trojan.port; + tcp_multi_path = true; + tcp_fast_open = true; + users = [ + { + name = "proxy"; + password = { + _secret = password; + }; + } + ]; + tls = singTls; } ] - ++ (lib.optionals (!cfg.warp.onTuic) ( - lib.forEach (lib.range 1 3) (i: { - inbound = "sg${toString i}"; - outbound = "direct"; - }) - )) - ++ (lib.optionals (!cfg.warp.onTrojan) [ + ++ lib.forEach (lib.range 6311 6314) (port: { + tag = "sg" + toString (port - 6310); + type = "tuic"; + listen = "::"; + listen_port = port; + congestion_control = "bbr"; + users = [ + { + name = "proxy"; + uuid = { + _secret = uuid; + }; + password = { + _secret = password; + }; + } + ]; + tls = singTls; + }); + outbounds = + # warp outbound goes first to make it default outbound + (lib.optionals (cfg.warp.onTuic or cfg.warp.onTrojan) [ { - inbound = "sg0"; - outbound = "direct"; + type = "wireguard"; + tag = "wg-out"; + private_key = { + _secret = config.sops.secrets.wg_private_key.path; + }; + local_address = [ + "172.16.0.2/32" + { _secret = config.sops.secrets.wg_ipv6_local_addr.path; } + ]; + peers = [ + { + public_key = "bmXOC+F1FxEMF9dyiK2H5/1SUtzH0JuVo51h2wPfgyo="; + allowed_ips = [ + "0.0.0.0/0" + "::/0" + ]; + server = "162.159.192.1"; + server_port = 500; + } + ]; } - ]); - }; - experimental = { - v2ray_api = { - listen = "127.0.0.1:15175"; - stats = { - users = map (u: u.name) users; - enabled = true; - inbounds = map (p: "sg" + toString p) (lib.range 0 4); - }; + ]) + ++ [ + + { + type = "direct"; + tag = "direct"; + } + ]; + route = { + rules = + [ + { + inbound = "sg4"; + outbound = "direct"; + } + ] + ++ (lib.optionals (!cfg.warp.onTuic) ( + lib.forEach (lib.range 1 3) (i: { + inbound = "sg${toString i}"; + outbound = "direct"; + }) + )) + ++ (lib.optionals (!cfg.warp.onTrojan) [ + { + inbound = "sg0"; + outbound = "direct"; + } + ]); }; }; - }; - sing-box = pkgs.sing-box.overrideAttrs ( - finalAttrs: previousAttrs: { - tags = previousAttrs.tags ++ [ - "with_v2ray_api" - ]; - } - ); in { options.commonSettings.proxyServer = { @@ -149,62 +137,40 @@ in onTrojan = mkEnableOption "forward to warp in trojan"; onTuic = mkEnableOption "forward to warp in first two port of tuic"; }; - - users = mkOption { - type = lib.types.listOf lib.types.str; - }; }; - config = mkIf cfg.enable ( - { - boot.kernel.sysctl = { - "net.core.default_qdisc" = "fq"; - "net.ipv4.tcp_congestion_control" = "bbr"; + config = mkIf cfg.enable { + boot.kernel.sysctl = { + "net.core.default_qdisc" = "fq"; + "net.ipv4.tcp_congestion_control" = "bbr"; + }; + + networking.firewall.trustedInterfaces = [ "tun0" ]; + + security.acme = { + acceptTerms = true; + certs.${config.deployment.targetHost} = { + email = "me@namely.icu"; + # Avoid port conflict + listenHTTP = if config.services.caddy.enable then ":30310" else ":80"; }; + }; + services.caddy.virtualHosts."http://${config.deployment.targetHost}:80".extraConfig = '' + reverse_proxy 127.0.0.1:30310 + ''; - networking.firewall.trustedInterfaces = [ "tun0" ]; + networking.firewall.allowedTCPPorts = [ + 80 + cfg.trojan.port + ]; + networking.firewall.allowedUDPPorts = [ ] ++ (lib.range 6311 6314); - security.acme = { - acceptTerms = true; - certs.${config.deployment.targetHost} = { - email = "me@namely.icu"; - # Avoid port conflict - listenHTTP = if config.services.caddy.enable then ":30310" else ":80"; - }; + services.sing-box = { + enable = true; + settings = mkSingConfig { + uuid = config.sops.secrets."sing-box/uuid".path; + password = config.sops.secrets."sing-box/password".path; }; - services.caddy.virtualHosts."http://${config.deployment.targetHost}:80".extraConfig = '' - reverse_proxy 127.0.0.1:30310 - ''; - - networking.firewall.allowedTCPPorts = [ - 80 - cfg.trojan.port - ]; - networking.firewall.allowedUDPPorts = [ ] ++ (lib.range 6311 6314); - - services.sing-box = { - enable = true; - package = sing-box; - settings = ( - mkSingConfig ( - map (n: { - name = n; - uuidFile = config.sops.secrets."sing-box/users/${n}/uuid".path; - passwordFile = config.sops.secrets."sing-box/users/${n}/password".path; - }) cfg.users - ) - ); - }; - } - // { - sops.secrets = ( - builtins.foldl' (a: b: a // b) { } ( - map (u: { - "sing-box/users/${u}/uuid" = { }; - "sing-box/users/${u}/password" = { }; - }) cfg.users - ) - ); - } - ); + }; + }; } diff --git a/modules/nixos/default.nix b/modules/nixos/default.nix index d2f210d..4669a94 100644 --- a/modules/nixos/default.nix +++ b/modules/nixos/default.nix @@ -7,6 +7,15 @@ ./common-settings/mainland.nix ./disk-partitions ./restic.nix + ./vaultwarden.nix ./monitor + ./hedgedoc.nix + ./sing-box.nix + ./kanidm-client.nix + ./ssh-tpm-agent.nix # FIXME: Waiting for upstream merge + ./forgejo-actions-runner.nix + ./oidc-agent.nix + ./miniflux.nix + ./immich.nix ]; } diff --git a/modules/nixos/hedgedoc.nix b/modules/nixos/hedgedoc.nix new file mode 100644 index 0000000..a632a78 --- /dev/null +++ b/modules/nixos/hedgedoc.nix @@ -0,0 +1,78 @@ +{ + config, + pkgs, + lib, + ... +}: + +with lib; + +let + cfg = config.custom.hedgedoc; +in +{ + options = { + custom.hedgedoc = { + enable = mkEnableOption "HedgeDoc Markdown Editor"; + domain = mkOption { + type = types.str; + default = "docs.example.com"; + description = "Domain name of the HedgeDoc server"; + }; + caddy = mkOption { + type = types.bool; + default = true; + description = "Enable Caddy as reverse proxy"; + }; + mediaPath = mkOption { + type = types.path; + default = /var/lib/hedgedoc/uploads; + description = "Directory for storing medias"; + }; + oidc = { + enable = mkEnableOption "OIDC support for HedgeDoc"; + baseURL = mkOption { type = types.str; }; + authorizationURL = mkOption { type = types.str; }; + tokenURL = mkOption { type = types.str; }; + userProfileURL = mkOption { type = types.str; }; + }; + environmentFile = mkOption { type = types.path; }; + }; + }; + config = mkIf cfg.enable { + services.hedgedoc = { + enable = true; + environmentFile = cfg.environmentFile; + settings = { + domain = cfg.domain; + protocolUseSSL = cfg.caddy; + uploadsPath = cfg.mediaPath; + path = "/run/hedgedoc/hedgedoc.sock"; + email = false; + allowEmailRegister = false; + oauth2 = mkIf cfg.oidc.enable { + baseURL = cfg.oidc.baseURL; + authorizationURL = cfg.oidc.authorizationURL; + tokenURL = cfg.oidc.tokenURL; + userProfileURL = cfg.oidc.userProfileURL; + userProfileEmailAttr = "email"; + userProfileUsernameAttr = "name"; + userProfileDisplayNameAttr = "preferred_name"; + scope = "openid email profile"; + clientID = "$HEDGEDOC_CLIENT_ID"; + clientSecret = "$HEDGEDOC_CLIENT_SECRET"; + }; + allowAnonymous = false; + defaultPermission = "private"; + }; + }; + services.caddy = mkIf cfg.caddy { + enable = true; + virtualHosts."https://${cfg.domain}".extraConfig = '' + reverse_proxy unix/${config.services.hedgedoc.settings.path} + ''; + }; + users.users.caddy.extraGroups = mkIf cfg.caddy [ "hedgedoc" ]; + + }; +} diff --git a/modules/nixos/immich.nix b/modules/nixos/immich.nix new file mode 100644 index 0000000..d79afc1 --- /dev/null +++ b/modules/nixos/immich.nix @@ -0,0 +1,60 @@ +{ + config, + lib, + pkgs, + utils, + ... +}: +let + cfg = config.custom.immich; + upstreamCfg = config.services.immich; + settingsFormat = pkgs.formats.json { }; + user = config.systemd.services.immich-server.serviceConfig.User; + group = config.systemd.services.immich-server.serviceConfig.Group; +in +{ + options = { + custom.immich.jsonSettings = lib.mkOption { + type = lib.types.submodule { + freeformType = settingsFormat.type; + }; + default = { }; + }; + }; + config = { + /* + LoadCredential happens before preStart. We need to ensure the + configuration file exist, otherwise LoadCredential will fail. + */ + systemd.tmpfiles.settings = lib.mkIf upstreamCfg.enable { + "10-etc-immich" = { + "/etc/immich" = { + d = { + inherit user group; + mode = "0700"; + }; + }; + "/etc/immich/config.json" = { + "f+" = { + inherit user group; + mode = "0600"; + }; + }; + }; + }; + + systemd.services.immich-server = { + preStart = '' + umask 0077 + ${utils.genJqSecretsReplacementSnippet cfg.jsonSettings "/etc/immich/config.json"} + ''; + serviceConfig = { + LoadCredential = "config:/etc/immich/config.json"; + Environment = "IMMICH_CONFIG_FILE=%d/config"; + }; + }; + + # https://github.com/NixOS/nixpkgs/pull/324127/files#r1723763510 + services.immich.redis.host = "/run/redis-immich/redis.sock"; + }; +} diff --git a/modules/nixos/inbounds.nix b/modules/nixos/inbounds.nix new file mode 100644 index 0000000..cd6fb9e --- /dev/null +++ b/modules/nixos/inbounds.nix @@ -0,0 +1,134 @@ +{ config, lib, ... }: +let + cfg = config.custom.sing-box-server; + + secretFileType = lib.types.submodule { _secret = lib.types.path; }; + singTls = { + enabled = true; + server_name = config.deployment.targetHost; + key_path = config.security.acme.certs.${config.deployment.targetHost}.directory + "/key.pem"; + certificate_path = + config.security.acme.certs.${config.deployment.targetHost}.directory + "/cert.pem"; + }; +in +{ + options = { + enable = lib.mkEnableOption "sing-box proxy server"; + users = lib.types.listOf lib.types.submodule { + name = lib.mkOption { + type = lib.types.str; + default = "proxy"; + }; + password = lib.mkOption { type = secretFileType; }; + uuid = lib.mkOption { type = secretFileType; }; + }; + wgOut = { + privKeyFile = lib.mkOption { type = lib.types.path; }; + pubkey = lib.mkOption { + type = lib.types.str; + default = "bmXOC+F1FxEMF9dyiK2H5/1SUtzH0JuVo51h2wPfgyo="; + }; + }; + inbounds = { + trojan = { + enable = lib.mkOption { + type = lib.types.bool; + default = true; + }; + }; + tuic = { + enable = lib.mkOption { + type = lib.types.bool; + default = true; + }; + ports = lib.mkOption { + type = lib.types.listOf lib.types.int; + default = lib.range 6311 6313; + }; + directPorts = lib.mkOption { + type = lib.types.listOf lib.types.int; + default = [ 6314 ]; + }; + }; + }; + }; + config = lib.mkIf cfg.enable { + services.sing-box = { + enable = true; + settings = { + dns = { + servers = [ + { + address = "1.1.1.1"; + detour = "wg-out"; + } + ]; + }; + inbounds = + [ + # TODO: Trojan and tuic enable + { + tag = "trojan-in"; + type = "trojan"; + listen = "::"; + listen_port = 8080; + users = map (u: removeAttrs u [ "uuid" ]) cfg.users; + tls = singTls; + } + ] + ++ lib.forEach (cfg.tuic.ports ++ cfg.tuic.directPorts) (port: { + tag = "tuic-in" + toString port; + type = "tuic"; + listen = "::"; + listen_port = port; + congestion_control = "bbr"; + users = cfg.users; + tls = singTls; + }); + outbounds = [ + { + type = "wireguard"; + tag = "wg-out"; + private_key = cfg.wgOut.privKeyFile; + local_address = [ + "172.16.0.2/32" + "2606:4700:110:82ed:a443:3c62:6cbc:b59b/128" + ]; + peers = [ + { + public_key = cfg.wgOut.pubkey; + allowed_ips = [ + "0.0.0.0/0" + "::/0" + ]; + server = "162.159.192.1"; + server_port = 500; + } + ]; + } + { + type = "direct"; + tag = "direct-out"; + } + { + type = "dns"; + tag = "dns-out"; + } + ]; + route = { + rules = + [ + { + outbound = "dns-out"; + protocol = "dns"; + } + ] + ++ lib.forEach cfg.tuic.directPorts (port: { + inbound = "tuic-in" + toString port; + outbound = "direct-out"; + }); + }; + }; + }; + }; +} diff --git a/modules/nixos/kanidm-client.nix b/modules/nixos/kanidm-client.nix index 881d48b..80e2bf9 100644 --- a/modules/nixos/kanidm-client.nix +++ b/modules/nixos/kanidm-client.nix @@ -59,6 +59,8 @@ in PasswordAuthentication = false; KbdInteractiveAuthentication = false; PermitRootLogin = lib.mkForce "no"; + GSSAPIAuthentication = "no"; + KerberosAuthentication = "no"; }; }; diff --git a/modules/nixos/miniflux.nix b/modules/nixos/miniflux.nix new file mode 100644 index 0000000..0653f41 --- /dev/null +++ b/modules/nixos/miniflux.nix @@ -0,0 +1,165 @@ +{ + config, + pkgs, + lib, + ... +}: +let + inherit (lib) + mkEnableOption + mkPackageOption + mkOption + types + literalExpression + mkIf + mkDefault + ; + cfg = config.custom.miniflux; + + defaultAddress = "localhost:8080"; + + pgbin = "${config.services.postgresql.package}/bin"; + preStart = pkgs.writeScript "miniflux-pre-start" '' + #!${pkgs.runtimeShell} + ${pgbin}/psql "miniflux" -c "CREATE EXTENSION IF NOT EXISTS hstore" + ''; +in +{ + options = { + custom.miniflux = { + enable = mkEnableOption "miniflux"; + + package = mkPackageOption pkgs "miniflux" { }; + + oauth2SecretFile = mkOption { type = types.path; }; + + environment = mkOption { + type = + with types; + attrsOf (oneOf [ + int + str + ]); + }; + + createDatabaseLocally = mkOption { + type = types.bool; + default = true; + description = '' + Whether a PostgreSQL database should be automatically created and + configured on the local host. If set to `false`, you need provision a + database yourself and make sure to create the hstore extension in it. + ''; + }; + }; + }; + + config = lib.mkIf cfg.enable { + services.miniflux.enable = false; + custom.miniflux.environment = { + LISTEN_ADDR = mkDefault defaultAddress; + RUN_MIGRATIONS = mkDefault 1; + DATABASE_URL = lib.mkIf cfg.createDatabaseLocally "user=miniflux host=/run/postgresql dbname=miniflux"; + OAUTH2_CLIENT_SECRET_FILE = "%d/oauth2_secret"; + WATCHDOG = mkDefault 1; + }; + + services.postgresql = lib.mkIf cfg.createDatabaseLocally { + enable = true; + ensureUsers = [ + { + name = "miniflux"; + ensureDBOwnership = true; + } + ]; + ensureDatabases = [ "miniflux" ]; + }; + + systemd.services.miniflux-dbsetup = lib.mkIf cfg.createDatabaseLocally { + description = "Miniflux database setup"; + requires = [ "postgresql.service" ]; + after = [ + "network.target" + "postgresql.service" + ]; + serviceConfig = { + Type = "oneshot"; + User = config.services.postgresql.superUser; + ExecStart = preStart; + }; + }; + + systemd.services.miniflux = { + description = "Miniflux service"; + wantedBy = [ "multi-user.target" ]; + requires = lib.optional cfg.createDatabaseLocally "miniflux-dbsetup.service"; + after = + [ "network.target" ] + ++ lib.optionals cfg.createDatabaseLocally [ + "postgresql.service" + "miniflux-dbsetup.service" + ]; + + serviceConfig = { + Type = "notify"; + ExecStart = lib.getExe cfg.package; + User = "miniflux"; + DynamicUser = true; + LoadCredential = [ "oauth2_secret:${cfg.oauth2SecretFile}" ]; + RuntimeDirectory = "miniflux"; + RuntimeDirectoryMode = "0750"; + WatchdogSec = 60; + WatchdogSignal = "SIGKILL"; + Restart = "always"; + RestartSec = 5; + + # Hardening + CapabilityBoundingSet = [ "" ]; + DeviceAllow = [ "" ]; + LockPersonality = true; + MemoryDenyWriteExecute = true; + PrivateDevices = true; + PrivateUsers = true; + ProcSubset = "pid"; + ProtectClock = true; + ProtectControlGroups = true; + ProtectHome = true; + ProtectHostname = true; + ProtectKernelLogs = true; + ProtectKernelModules = true; + ProtectKernelTunables = true; + ProtectProc = "invisible"; + RestrictAddressFamilies = [ + "AF_INET" + "AF_INET6" + "AF_UNIX" + ]; + RestrictNamespaces = true; + RestrictRealtime = true; + RestrictSUIDSGID = true; + SystemCallArchitectures = "native"; + SystemCallFilter = [ + "@system-service" + "~@privileged" + ]; + UMask = "0077"; + }; + + environment = lib.mapAttrs (_: toString) cfg.environment; + }; + environment.systemPackages = [ cfg.package ]; + + security.apparmor.policies."bin.miniflux".profile = '' + include + ${cfg.package}/bin/miniflux { + include + include + include + include "${pkgs.apparmorRulesFromClosure { name = "miniflux"; } cfg.package}" + r ${cfg.package}/bin/miniflux, + r @{sys}/kernel/mm/transparent_hugepage/hpage_pmd_size, + rw /run/miniflux/**, + } + ''; + }; +} diff --git a/modules/nixos/monitor/default.nix b/modules/nixos/monitor/default.nix index 71ec05e..249f13b 100644 --- a/modules/nixos/monitor/default.nix +++ b/modules/nixos/monitor/default.nix @@ -11,7 +11,6 @@ let mkMerge types ; - inherit (config.my-lib.settings) ntfyUrl; cfg = config.custom.prometheus; mkRulesOption = mkOption { @@ -57,13 +56,6 @@ in default = "${config.networking.hostName}.coho-tet.ts.net"; }; }; - v2ray = { - enable = mkEnableOption "blackbox exporter"; - listenAddress = mkOption { - type = types.str; - default = "${config.networking.hostName}.coho-tet.ts.net"; - }; - }; }; }; }; @@ -89,9 +81,19 @@ in ]; } (mkIf cfg.enable { - services.caddy.virtualHosts."${config.networking.hostName}.coho-tet.ts.net".extraConfig = '' - reverse_proxy 127.0.0.1:${toString config.services.prometheus.port} - ''; + + services.tailscale = { + enable = true; + permitCertUid = config.services.caddy.user; + openFirewall = true; + }; + + services.caddy = { + enable = true; + virtualHosts."${config.networking.hostName}.coho-tet.ts.net".extraConfig = '' + reverse_proxy 127.0.0.1:${toString config.services.prometheus.port} + ''; + }; services.prometheus = mkIf cfg.enable { enable = true; port = 9091; @@ -119,11 +121,12 @@ in name = "ntfy"; webhook_configs = [ { - url = "${ntfyUrl}/prometheus-alerts?tpl=yes&m=${lib.escapeURL '' - {{range .alerts}}[{{ if eq .status "resolved" }}✅ RESOLVED{{ else }}{{ if eq .status "firing" }}🔥 FIRING{{end}}{{end}}]{{range $k,$v := .labels}} + url = "https://ntfy.xinyang.life/prometheus-alerts?tpl=yes&m=${lib.escapeURL '' + Alert {{.status}} + {{range .alerts}}-----{{range $k,$v := .labels}} {{$k}}={{$v}}{{end}} - - {{end}}''}"; + {{end}} + ''}"; send_resolved = true; } ]; diff --git a/modules/nixos/monitor/exporters.nix b/modules/nixos/monitor/exporters.nix index 56750ef..0c9b95d 100644 --- a/modules/nixos/monitor/exporters.nix +++ b/modules/nixos/monitor/exporters.nix @@ -5,8 +5,7 @@ ... }: let - inherit (lib) mkIf concatStringsSep; - inherit (config.my-lib.settings) prometheusCollectors; + inherit (lib) mkIf; cfg = config.custom.prometheus.exporters; in { @@ -47,13 +46,6 @@ in ); }; - services.prometheus.exporters.v2ray = mkIf cfg.v2ray.enable { - enable = true; - listenAddress = cfg.v2ray.listenAddress; - port = 9516; - v2rayEndpoint = config.services.sing-box.settings.experimental.v2ray_api.listen; - }; - # gotosocial sops.templates."gotosocial_metrics.env" = { content = '' @@ -79,7 +71,7 @@ in services.restic.server.prometheus = true; - # miniflux + # miniflux sops.templates."miniflux_metrics_env" = { content = '' METRICS_COLLECTOR=1 @@ -103,28 +95,8 @@ in metrics } - admin unix//var/run/caddy/admin.sock { - origins 127.0.0.1 ${config.networking.hostName}.coho-tet.ts.net:2019 + admin ${config.networking.hostName}.coho-tet.ts.net:2019 { } ''; - - systemd.services.caddy.serviceConfig = { - RuntimeDirectory = "caddy"; - RuntimeDirectoryMode = "0700"; - }; - - services.tailscale = { - permitCertUid = config.services.caddy.user; - openFirewall = true; - }; - - services.caddy = { - virtualHosts."https://${config.networking.hostName}.coho-tet.ts.net:2019".extraConfig = '' - handle /metrics { - reverse_proxy unix//var/run/caddy/admin.sock - } - respond 403 - ''; - }; }; } diff --git a/modules/nixos/monitor/grafana.nix b/modules/nixos/monitor/grafana.nix index 9692fb5..e1b2cf3 100644 --- a/modules/nixos/monitor/grafana.nix +++ b/modules/nixos/monitor/grafana.nix @@ -1,6 +1,5 @@ { config, lib, ... }: let - inherit (config.my-lib.settings) grafanaUrl idpUrl; cfg = config.custom.monitoring.grafana; in { @@ -14,17 +13,17 @@ in server = { http_addr = "127.0.0.1"; http_port = 3003; - root_url = grafanaUrl; - domain = lib.removePrefix "https://" grafanaUrl; + root_url = "https://grafana.xinyang.life"; + domain = "grafana.xinyang.life"; }; "auth.generic_oauth" = { enabled = true; name = "Kanidm"; client_id = "grafana"; scopes = "openid,profile,email,groups"; - auth_url = "${idpUrl}/ui/oauth2"; - token_url = "${idpUrl}/oauth2/token"; - api_url = "${idpUrl}/oauth2/openid/grafana/userinfo"; + auth_url = "https://auth.xinyang.life/ui/oauth2"; + token_url = "https://auth.xinyang.life/oauth2/token"; + api_url = "https://auth.xinyang.life/oauth2/openid/grafana/userinfo"; use_pkce = true; use_refresh_token = true; allow_sign_up = true; diff --git a/modules/nixos/monitor/loki.nix b/modules/nixos/monitor/loki.nix index 105a33a..324235f 100644 --- a/modules/nixos/monitor/loki.nix +++ b/modules/nixos/monitor/loki.nix @@ -1,159 +1,68 @@ { - pkgs, config, lib, ... }: let inherit (lib) - mkOption mkEnableOption mkIf mkMerge - types - literalExpression - ; - inherit (config.my-lib.settings) - alertmanagerPort ; cfg = config.custom.monitoring; - lokiPort = 3100; + port-loki = 3100; in { options = { custom.monitoring = { - loki = { - enable = mkEnableOption "loki"; - rules = mkOption { - type = types.attrsOf ( - types.submodule { - options = { - expr = mkOption { - type = types.str; - description = '' - Loki alert expression. - ''; - example = ''count_over_time({job=~"secure"} |="sshd[" |~": Failed|: Invalid|: Connection closed by authenticating user" | __error__="" [15m]) > 15''; - default = null; - }; - description = mkOption { - type = types.str; - description = '' - Loki alert message. - ''; - example = "Prometheus encountered value {{ $value }} with {{ $labels }}"; - default = null; - }; - labels = mkOption { - type = types.nullOr (types.attrsOf types.str); - description = '' - Additional alert labels. - ''; - example = literalExpression '' - { severity = "page" }; - ''; - default = { }; - }; - time = mkOption { - type = types.str; - description = '' - Time until the alert is fired. - ''; - example = "5m"; - default = "2m"; - }; - }; - } - ); - description = '' - Defines the loki rules. - ''; - default = { }; - }; - }; + loki.enable = mkEnableOption "loki"; promtail.enable = mkEnableOption "promtail"; }; }; config = mkMerge [ - ( - let - rulerConfig = { - groups = [ + (mkIf cfg.loki.enable { + services.loki = { + enable = true; + configuration = { + auth_enabled = false; + server.http_listen_address = "${config.networking.hostName}.coho-tet.ts.net"; + server.http_listen_port = port-loki; + + common = { + ring = { + instance_addr = "${config.networking.hostName}.coho-tet.ts.net"; + kvstore.store = "inmemory"; + }; + replication_factor = 1; + path_prefix = "/var/lib/loki"; + }; + + schema_config.configs = [ { - name = "alerting-rules"; - rules = lib.mapAttrsToList (name: opts: { - alert = name; - inherit (opts) expr labels; - for = opts.time; - annotations.description = opts.description; - }) cfg.loki.rules; + from = "2024-12-01"; + store = "boltdb-shipper"; + object_store = "filesystem"; + schema = "v13"; + index = { + prefix = "index_"; + period = "24h"; + }; } ]; - }; - rulerFile = pkgs.writeText "ruler.yml" (builtins.toJSON rulerConfig); - in - mkIf cfg.loki.enable { - services.loki = { - enable = true; - configuration = { - auth_enabled = false; - server.http_listen_address = "${config.networking.hostName}.coho-tet.ts.net"; - server.http_listen_port = lokiPort; - common = { - ring = { - instance_addr = "${config.networking.hostName}.coho-tet.ts.net"; - kvstore.store = "inmemory"; - }; - replication_factor = 1; - path_prefix = "/var/lib/loki"; - }; + storage_config = { + filesystem.directory = "/var/lib/loki/chunks"; + }; - schema_config.configs = [ - { - from = "2024-12-01"; - store = "boltdb-shipper"; - object_store = "filesystem"; - schema = "v13"; - index = { - prefix = "index_"; - period = "24h"; - }; - } - ]; - - storage_config = { - filesystem.directory = "/var/lib/loki/chunks"; - }; - - limits_config = { - reject_old_samples = true; - reject_old_samples_max_age = "168h"; - allow_structured_metadata = false; - }; - - ruler = { - storage = { - type = "local"; - local.directory = "${config.services.loki.dataDir}/rules"; - }; - rule_path = "${config.services.loki.dataDir}/rules-temp"; - enable_api = true; - alertmanager_url = "http://127.0.0.1:${toString alertmanagerPort}"; - }; + limits_config = { + reject_old_samples = true; + reject_old_samples_max_age = "168h"; + allow_structured_metadata = false; }; }; - systemd.tmpfiles.rules = [ - "d /var/lib/loki 0700 loki loki - -" - "d /var/lib/loki/rules-temp 0700 loki loki - -" - "d /var/lib/loki/rules 0700 loki loki - -" - "d /var/lib/loki/rules/fake 0700 loki loki - -" - "L /var/lib/loki/rules/fake/ruler.yml - - - - ${rulerFile}" - ]; - systemd.services.loki.restartTriggers = [ rulerFile ]; - } - ) + }; + }) (mkIf cfg.promtail.enable { services.promtail = { enable = true; @@ -169,7 +78,7 @@ in clients = [ { - url = "http://thorite.coho-tet.ts.net:${toString lokiPort}/loki/api/v1/push"; + url = "http://thorite.coho-tet.ts.net:${toString port-loki}/loki/api/v1/push"; } ]; @@ -241,42 +150,17 @@ in ]; } # { - # job_name = "caddy"; - # static_configs = [ - # { - # targets = [ "localhost" ]; - # labels = { - # job = "caddy"; - # __path__ = "/var/log/caddy/*log"; - # agent = "caddy-promtail"; - # }; - # } - # ]; - # pipeline_stages = [ - # { - # json = { - # expressions = { - # duration = "duration"; - # status = "status"; - # }; - # }; - # } - # { - # labels = { - # duration = null; - # status = null; - # }; - # } - # ]; + # job_name = "caddy-access"; + # file_sd_configs = { + # files = [ + # "/var/log/caddy/*.log" + # ]; + # refresh_interval = "5m"; + # }; # } ]; }; }; - - services.caddy.logFormat = '' - format json - level INFO - ''; }) ]; } diff --git a/modules/nixos/restic.nix b/modules/nixos/restic.nix index f07bdfb..bef9c44 100644 --- a/modules/nixos/restic.nix +++ b/modules/nixos/restic.nix @@ -39,7 +39,7 @@ let echo "Creating snapshot for ${rootDir}" subvolumes=$(${pkgs.btrfs-progs}/bin/btrfs subvolume list -o "${rootDir}" | ${awk} '{print $NF}') mkdir -p "${backupDir}" - ${pkgs.btrfs-progs}/bin/btrfs subvolume snapshot -r "${rootDir}" "${backupDir}/rootDirectory" + ${pkgs.btrfs-progs}/bin/btrfs subvolume snapshot -r "${rootDir}" "${backupDir}/rootfs" for subvol in $subvolumes; do ${continueIfInExclude} [[ /"$subvol" == "${backupDir}"* ]] && continue diff --git a/modules/nixos/sing-box.nix b/modules/nixos/sing-box.nix new file mode 100644 index 0000000..695356e --- /dev/null +++ b/modules/nixos/sing-box.nix @@ -0,0 +1,87 @@ +{ + config, + pkgs, + lib, + utils, + ... +}: +let + cfg = config.custom.sing-box; + settingsFormat = pkgs.formats.json { }; +in +{ + options = { + custom.sing-box = { + enable = lib.mkEnableOption "sing-box"; + + package = lib.mkPackageOption pkgs "sing-box" { }; + + stateDir = lib.mkOption { + type = lib.types.path; + default = "/var/lib/sing-box"; + }; + + configFile = { + urlFile = lib.mkOption { type = lib.types.path; }; + name = lib.mkOption { + type = lib.types.str; + default = "config.json"; + }; + hash = lib.mkOption { + type = lib.types.str; + example = "9a304bcb87d4c3f1e50f6281f25dd78635255ebde06cd4d2555729ecda43aed4"; + }; + }; + + overrideSettings = lib.mkOption { + type = lib.types.submodule { + freeformType = settingsFormat.type; + options = { + route = { + geoip.path = lib.mkOption { + type = lib.types.path; + default = "${pkgs.sing-geoip}/share/sing-box/geoip.db"; + defaultText = lib.literalExpression "\${pkgs.sing-geoip}/share/sing-box/geoip.db"; + description = lib.mdDoc '' + The path to the sing-geoip database. + ''; + }; + geosite.path = lib.mkOption { + type = lib.types.path; + default = "${pkgs.sing-geosite}/share/sing-box/geosite.db"; + defaultText = lib.literalExpression "\${pkgs.sing-geosite}/share/sing-box/geosite.db"; + description = lib.mdDoc '' + The path to the sing-geosite database. + ''; + }; + }; + }; + }; + default = { }; + }; + }; + }; + config = lib.mkIf cfg.enable { + networking.firewall.trustedInterfaces = [ "tun0" ]; + + systemd.packages = [ cfg.package ]; + + systemd.services.sing-box = + let + configFile = cfg.stateDir + "/${cfg.configFile.name}"; + in + { + preStart = '' + umask 0077 + mkdir -p /etc/sing-box + if ! [ -e ${configFile} ]; then + ${pkgs.curl}/bin/curl "$(${pkgs.coreutils}/bin/cat ${cfg.configFile.urlFile})" > '${configFile}' + test "${cfg.configFile.hash}" $(${pkgs.coreutils}/bin/sha256sum '${configFile}' | ${pkgs.coreutils}/bin/cut -d ' ' -f 1) + fi + ${utils.genJqSecretsReplacementSnippet cfg.overrideSettings "/etc/sing-box/config.json"} + ${cfg.package}/bin/sing-box merge -c '${configFile}' -c /etc/sing-box/config.json /etc/sing-box/config.json + ''; + wantedBy = [ "multi-user.target" ]; + }; + }; +} diff --git a/note.md b/note.md index 6b25aae..93a14d6 100644 --- a/note.md +++ b/note.md @@ -1,10 +1,3 @@ # nix-tree Demonstrate disk usage by nix-store path. - -## TODO -- [x] change caddy admin to unix socket -- [ ] admin config persist = false -- [x] synapse jmalloc -- [ ] backup all directories under /var/lib/forgejo -- [ ] collect caddy access logs with promtail (waiting for caddy v2.9.0 release after which log file mode can be set) diff --git a/overlays/my-lib/default.nix b/overlays/my-lib/default.nix index c684e36..8d07bc1 100644 --- a/overlays/my-lib/default.nix +++ b/overlays/my-lib/default.nix @@ -1,11 +1,3 @@ { - mkSystemdDebug = - { lib, pkgs }: - { - ExecStart = lib.mkForce "${pkgs.tmux}/bin/tmux -S /tmp/tmux.socket new-session -s my-session -d"; - ExecStop = lib.mkForce "${pkgs.tmux}/bin/tmux -S /tmp/tmux.socket kill-session -t my-session"; - Type = "forking"; - }; } // (import ./prometheus.nix) -// (import ./settings.nix) diff --git a/overlays/my-lib/prometheus.nix b/overlays/my-lib/prometheus.nix index c79f131..da43f77 100644 --- a/overlays/my-lib/prometheus.nix +++ b/overlays/my-lib/prometheus.nix @@ -28,51 +28,17 @@ in ) ); - mkV2rayScrapes = targets: [ + mkCaddyScrapes = mkFunction ( { - job_name = "v2ray-exporter"; - scheme = "http"; - static_configs = map ( - { - address, - port ? 9516, - }: - { - targets = [ "${address}${mkPort port}" ]; - } - ) targets; - } + address, + port ? 2019, + ... + }: { - job_name = "singbox_stat"; - scheme = "http"; - metrics_path = "/scrape"; - static_configs = map ( - { - address, - port ? 9516, - }: - { - targets = [ "${address}${mkPort port}" ]; - } - ) targets; + job_name = "caddy_${address}"; + static_configs = [ { targets = [ "${address}${mkPort port}" ]; } ]; } - ]; - - mkCaddyScrapes = targets: [ - { - job_name = "caddy"; - scheme = "https"; - static_configs = map ( - { - address, - port ? 2019, - }: - { - targets = [ "${address}${mkPort port}" ]; - } - ) targets; - } - ]; + ); mkCaddyRules = mkFunction ( { @@ -97,20 +63,17 @@ in } ); - mkNodeScrapes = targets: [ + mkNodeScrapes = mkFunction ( { - job_name = "node_exporter"; - static_configs = map ( - { - address, - port ? 9100, - }: - { - targets = [ "${address}${mkPort port}" ]; - } - ) targets; + address, + port ? 9100, + ... + }: + { + job_name = "node_${address}"; + static_configs = [ { targets = [ "${address}${mkPort port}" ]; } ]; } - ]; + ); mkNodeRules = mkFunction ( { @@ -146,9 +109,21 @@ in }; } { - alert = "NetworkTrafficExceedLimit"; - expr = ''sum by(instance) (increase(node_network_transmit_bytes_total{device!="lo", device!~"tailscale.*", device!~"wg.*", device!~"br.*"}[30d])) > 322122547200''; + alert = "HighTransmitTraffic"; + expr = "rate(node_network_transmit_bytes_total{device!=\"lo\"}[5m]) > 100000000"; for = "1m"; + labels = { + severity = "warning"; + }; + annotations = { + summary = "High network transmit traffic on {{ $labels.instance }} ({{ $labels.device }})"; + description = "The network interface {{ $labels.device }} on {{ $labels.instance }} is transmitting data at a rate exceeding 100 MB/s for the last 1 minute."; + }; + } + { + alert = "NetworkTrafficExceedLimit"; + expr = ''increase(node_network_transmit_bytes_total{device!="lo",device!~"tailscale.*",device!~"wg.*",device!~"br.*"}[30d]) > 322122547200''; + for = "0m"; labels = { severity = "critical"; }; @@ -156,66 +131,6 @@ in summary = "Outbound network traffic exceed 300GB for last 30 day"; }; } - { - alert = "HighDiskUsage"; - expr = ''(1 - node_filesystem_free_bytes{fstype!~"vfat|ramfs"} / node_filesystem_size_bytes) * 100 > 85''; - for = "5m"; - labels = { - severity = "warning"; - }; - annotations = { - summary = "High disk usage on {{ $labels.instance }}"; - }; - } - { - alert = "DiskWillFull"; - expr = ''predict_linear(node_filesystem_free_bytes{fstype!~"vfat|ramfs"}[1h], 12 * 3600) < (node_filesystem_size_bytes * 0.05)''; - - for = "3m"; - labels = { - severity = "critical"; - }; - annotations = { - summary = "Disk usage will exceed 95% in 12 hours on {{ $labels.instance }}"; - description = "Disk {{ $labels.mountpoint }} is predicted to exceed 92% usage within 12 hours at current growth rate"; - }; - } - { - alert = "HighSwapUsage"; - expr = ''(1 - (node_memory_SwapFree_bytes / node_memory_SwapTotal_bytes)) * 100 > 80''; - for = "5m"; - labels = { - severity = "warning"; - }; - annotations = { - summary = "High swap usage on {{ $labels.instance }}"; - description = "Swap usage is above 80% for 5 minutes\n Current value: {{ $value }}%"; - }; - } - { - alert = "OOMKillDetected"; - expr = ''increase(node_vmstat_oom_kill[5m]) > 0''; - for = "1m"; - labels = { - severity = "critical"; - }; - annotations = { - summary = "OOM kill detected on {{ $labels.instance }}"; - description = "Out of memory killer was triggered in the last 5 minutes"; - }; - } - { - alert = "HighMemoryUsage"; - expr = ''(1 - (node_memory_MemAvailable_bytes / node_memory_MemTotal_bytes)) * 100 > 90''; - for = "5m"; - labels = { - severity = "warning"; - }; - annotations = { - summary = "High memory usage on {{ $labels.instance }}"; - description = "Memory usage is above 90% for 5 minutes\n Current value: {{ $value }}%"; - }; - } ]; } ); @@ -237,9 +152,6 @@ in static_configs = [ { targets = targetAddresses; - labels = { - from = hostAddress; - }; } ]; relabel_configs = [ @@ -267,17 +179,6 @@ in { inherit name; rules = [ - { - alert = "ProbeError"; - expr = "probe_success != 1"; - for = "3m"; - labels = { - severity = "critical"; - }; - annotations = { - summary = "Probing {{ $labels.instance }} from {{ $labels.from }} failed"; - }; - } { alert = "HighProbeLatency"; expr = "probe_duration_seconds > 0.5"; @@ -286,25 +187,23 @@ in severity = "warning"; }; annotations = { - summary = "High request latency from {{ $labels.from }} to {{ $labels.instance }}"; - description = "Request latency is above 0.5 seconds for the last 2 minutes."; + summary = "High request latency on {{ $labels.instance }}"; + description = "Request latency is above 0.5 seconds for the last 3 minutes."; }; } { alert = "VeryHighProbeLatency"; - expr = "probe_duration_seconds > 2"; + expr = "probe_duration_seconds > 1"; for = "3m"; labels = { severity = "critical"; }; annotations = { - summary = "Very high request latency from {{ $labels.from }} to {{ $labels.instance }}"; - description = "Request latency is above 2 seconds for the last 2 minutes."; + summary = "High request latency on {{ $labels.instance }}"; + description = "Request latency is above 0.5 seconds for the last 3 minutes."; }; } ]; } ); - - # mkResticScrapes = mkFunction () ; } diff --git a/overlays/my-lib/settings.nix b/overlays/my-lib/settings.nix deleted file mode 100644 index 46bdb04..0000000 --- a/overlays/my-lib/settings.nix +++ /dev/null @@ -1,20 +0,0 @@ -{ - settings = { - alertmanagerPort = 9093; - idpUrl = "https://auth.xinyang.life"; - gotosocialUrl = "https://gts.xiny.li"; - minifluxUrl = "https://rss.xiny.li"; - hedgedocDomain = "docs.xiny.li"; - forgejoDomain = "git.xiny.li"; - forgejoGitDomain = "git.xiny.li"; - vaultwardenUrl = "https://vaultwarden.xiny.li"; - ntfyUrl = "https://ntfy.xiny.li"; - grafanaUrl = "https://grafana.xiny.li"; - synapseUrl = "https://xiny.li"; - synapseDelegateUrl = "https://synapse.xiny.li"; - - prometheusCollectors = [ - "thorite.coho-tet.ts.net" - ]; - }; -} diff --git a/overlays/pkgs/oidc-agent/default.nix b/overlays/pkgs/oidc-agent/default.nix new file mode 100644 index 0000000..9634c4c --- /dev/null +++ b/overlays/pkgs/oidc-agent/default.nix @@ -0,0 +1,56 @@ +{ + lib, + stdenv, + fetchFromGitHub, + curl, + webkitgtk, + libmicrohttpd, + libsecret, + qrencode, + libsodium, + pkg-config, + help2man, +}: + +stdenv.mkDerivation rec { + pname = "oidc-agent"; + version = "5.1.0"; + + src = fetchFromGitHub { + owner = "indigo-dc"; + repo = "oidc-agent"; + rev = "v${version}"; + sha256 = "sha256-cOK/rZ/jnyALLuhDM3+qvwwe4Fjkv8diQBkw7NfVo0c="; + }; + + buildInputs = [ + pkg-config + help2man + ]; + nativeBuildInputs = [ + curl + webkitgtk + libmicrohttpd + libsecret + qrencode + libsodium + ]; + enableParallelBuilding = true; + + installPhase = '' + make -j $NIX_BUILD_CORES PREFIX=$out BIN_PATH=$out LIB_PATH=$out/lib \ + install_bin install_lib install_conf + ''; + postFixup = '' + # Override with patched binary to be used by help2man + cp -r $out/bin/* bin + make install_man PREFIX=$out + ''; + + meta = with lib; { + description = "oidc-agent for managing OpenID Connect tokens on the command line"; + homepage = "https://github.com/indigo-dc/oidc-agent"; + maintainers = [ ]; + license = licenses.mit; + }; +}