diff --git a/.github/workflows/eval.yaml b/.github/workflows/eval.yaml index 528dd53..1bc00bd 100644 --- a/.github/workflows/eval.yaml +++ b/.github/workflows/eval.yaml @@ -1,10 +1,8 @@ name: Eval NixOS Configurations on: - push: - branches: - - deploy - workflow_dispatch: + check_suite: + types: [completed] permissions: contents: write @@ -20,6 +18,10 @@ jobs: - name: Install Nix uses: cachix/install-nix-action@v25 + with: + extra_nix_conf: | + extra-trusted-public-keys = cache.garnix.io:CTFPyKSLcx5RMJKfLo5EEPUObbA78b0YQ2DTCJXqr9g= + extra-substituters = https://cache.garnix.io - name: Configure Git run: | @@ -33,19 +35,26 @@ jobs: hosts=$(nix flake show --json | jq -r '.nixosConfigurations | keys[]') echo "Found hosts: $hosts" + failed_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 + if ! nix derivation show ".#nixosConfigurations.$host.config.system.build.toplevel" > "eval/$host.json"; then echo "❌ Failed to evaluate $host" + failed_hosts+="$host " + rm "eval/$host.json" 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 + git push -f origin deploy-comin-eval + + # After success, reset deploy-comin to new deploy + git checkout -b deploy-comin + git reset --hard deploy + git push -f origin deploy-comin diff --git a/flake.lock b/flake.lock index 8b8ea79..c207939 100644 --- a/flake.lock +++ b/flake.lock @@ -1,12 +1,17 @@ { "nodes": { "catppuccin": { + "inputs": { + "nixpkgs": [ + "nixpkgs" + ] + }, "locked": { - "lastModified": 1733001911, - "narHash": "sha256-uX/9m0TbdhEzuWA0muM5mI/AaWcLiDLjCCyu5Qr9MRk=", + "lastModified": 1739283129, + "narHash": "sha256-GXJllf1wY7tOF6uei9S3PnSEghFbnJP1vkxM0kkMOoI=", "owner": "catppuccin", "repo": "nix", - "rev": "a817009ebfd2cca7f70a77884e5098d0a8c83f8e", + "rev": "d4e258e29075a86a82dacaf4f5e0985935ae4658", "type": "github" }, "original": { @@ -26,11 +31,11 @@ "stable": "stable" }, "locked": { - "lastModified": 1731527002, - "narHash": "sha256-dI9I6suECoIAmbS4xcrqF8r2pbmed8WWm5LIF1yWPw8=", + "lastModified": 1734897875, + "narHash": "sha256-LLpiqfOGBippRax9F33kSJ/Imt8gJXb6o0JwSBiNHCk=", "owner": "zhaofengli", "repo": "colmena", - "rev": "e3ad42138015fcdf2524518dd564a13145c72ea1", + "rev": "a6b51f5feae9bfb145daa37fd0220595acb7871e", "type": "github" }, "original": { @@ -39,6 +44,26 @@ "type": "github" } }, + "comin": { + "inputs": { + "nixpkgs": [ + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1734693645, + "narHash": "sha256-Vw3YpuQxwBse5JiTGBH5MSPmqXOXFI4ROs7IF3tRc7k=", + "owner": "xinyangli", + "repo": "comin", + "rev": "c8a66bbd129e88ad916cac59f1ad9f45d39b3190", + "type": "github" + }, + "original": { + "owner": "xinyangli", + "repo": "comin", + "type": "github" + } + }, "devshell": { "inputs": { "nixpkgs": [ @@ -68,11 +93,11 @@ ] }, "locked": { - "lastModified": 1733168902, - "narHash": "sha256-8dupm9GfK+BowGdQd7EHK5V61nneLfr9xR6sc5vtDi0=", + "lastModified": 1739517743, + "narHash": "sha256-CPfA2Wdfxz16CTsPFltFj65T0/HikkOa4pQvcts1df4=", "owner": "nix-community", "repo": "disko", - "rev": "785c1e02c7e465375df971949b8dcbde9ec362e5", + "rev": "40da43e8e5620505b9c8aacc4f0d7577ad1aff73", "type": "github" }, "original": { @@ -302,11 +327,11 @@ ] }, "locked": { - "lastModified": 1733754861, - "narHash": "sha256-3JKzIou54yjiMVmvgdJwopekEvZxX3JDT8DpKZs4oXY=", + "lastModified": 1739470101, + "narHash": "sha256-NxNe32VB4XI/xIXrsKmIfrcgtEx5r/5s52pL3CpEcA4=", "owner": "nix-community", "repo": "home-manager", - "rev": "9ebaa80a227eaca9c87c53ed515ade013bc2bca9", + "rev": "5031c6d2978109336637977c165f82aa49fa16a7", "type": "github" }, "original": { @@ -376,11 +401,11 @@ "nixvim": "nixvim" }, "locked": { - "lastModified": 1732936640, - "narHash": "sha256-NcluA0L+ZV5MUj3UuQhlkGCj8KoEhX/ObWlMHZ/F/ac=", + "lastModified": 1741086060, + "narHash": "sha256-35fw6MoEXEutctwNS0z7VQ0AX8thHhU2KT0UxD/s3P4=", "ref": "refs/heads/master", - "rev": "a3709a89797ea094f82d38edeb4a538c07c8c3fa", - "revCount": 20, + "rev": "9240bb4db98fe13b3fdaa0e15a06949959df568a", + "revCount": 26, "type": "git", "url": "https://git.xiny.li/xin/nixvim" }, @@ -439,11 +464,11 @@ ] }, "locked": { - "lastModified": 1733629314, - "narHash": "sha256-U0vivjQFAwjNDYt49Krevs1murX9hKBFe2Ye0cHpgbU=", + "lastModified": 1739071773, + "narHash": "sha256-/Ak+Quinhmdxa9m3shjm4lwwwqmzG8zzGhhhhgR1k9I=", "owner": "Mic92", "repo": "nix-index-database", - "rev": "f1e477a7dd11e27e7f98b646349cd66bbabf2fb8", + "rev": "895d81b6228bbd50a6ef22f5a58a504ca99763ea", "type": "github" }, "original": { @@ -463,11 +488,11 @@ ] }, "locked": { - "lastModified": 1733795858, - "narHash": "sha256-K595Q2PrZv2iiumdBkwM2G456T2lKsLD71bn/fbJiQ0=", + "lastModified": 1739497746, + "narHash": "sha256-Bfok+AZ/iTOmJNndwR7wOZbsuL5/gks3GH2qvWTxpGs=", "owner": "nix-community", "repo": "nix-vscode-extensions", - "rev": "66ced222ef9235f90dbdd754ede3d6476722aaa9", + "rev": "6113f471097e12ff293e86b36e74aee21c55204e", "type": "github" }, "original": { @@ -478,11 +503,11 @@ }, "nixos-hardware": { "locked": { - "lastModified": 1733481457, - "narHash": "sha256-IS3bxa4N1VMSh3/P6vhEAHQZecQ3oAlKCDvzCQSO5Is=", + "lastModified": 1738816619, + "narHash": "sha256-5yRlg48XmpcX5b5HesdGMOte+YuCy9rzQkJz+imcu6I=", "owner": "NixOS", "repo": "nixos-hardware", - "rev": "e563803af3526852b6b1d77107a81908c66a9fcf", + "rev": "2eccff41bab80839b1d25b303b53d339fbb07087", "type": "github" }, "original": { @@ -492,6 +517,27 @@ "type": "github" } }, + "nixos-sbc": { + "inputs": { + "nixpkgs": [ + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1739031922, + "narHash": "sha256-h1kw65FOtgTbSqhKc/hsvQaqimZ9D0x1FzifuGGbsho=", + "owner": "nakato", + "repo": "nixos-sbc", + "rev": "d0e87bfd6623cce0b730f8919d6f21e02f917264", + "type": "github" + }, + "original": { + "owner": "nakato", + "ref": "main", + "repo": "nixos-sbc", + "type": "github" + } + }, "nixpkgs": { "locked": { "lastModified": 1731139594, @@ -522,11 +568,11 @@ }, "nixpkgs-stable": { "locked": { - "lastModified": 1733730953, - "narHash": "sha256-dlK7n82FEyZlHH7BFHQAM5tua+lQO1Iv7aAtglc1O5s=", + "lastModified": 1735563628, + "narHash": "sha256-OnSAY7XDSx7CtDoqNh8jwVwh4xNL/2HaJxGjryLWzX8=", "owner": "nixos", "repo": "nixpkgs", - "rev": "7109b680d161993918b0a126f38bc39763e5a709", + "rev": "b134951a4c9f3c995fd7be05f3243f8ecd65d798", "type": "github" }, "original": { @@ -538,11 +584,11 @@ }, "nixpkgs_2": { "locked": { - "lastModified": 1733805440, - "narHash": "sha256-AQdCeGt3dMV9/cchlWGMcP0Z8qM47V+B0p7cSRr+HhA=", + "lastModified": 1739519992, + "narHash": "sha256-9NNxUjwQ4Ty6n8EI1GcMtsEb3Knkho7FZ/QS5crB+Bc=", "owner": "xinyangli", "repo": "nixpkgs", - "rev": "61b1078fca3a097ce06ada68a6f2766347eed02c", + "rev": "90466175893e2e48b5f660eb90daa7e510c2f1c4", "type": "github" }, "original": { @@ -554,11 +600,11 @@ }, "nixpkgs_3": { "locked": { - "lastModified": 1733581040, - "narHash": "sha256-Qn3nPMSopRQJgmvHzVqPcE3I03zJyl8cSbgnnltfFDY=", + "lastModified": 1739446958, + "narHash": "sha256-+/bYK3DbPxMIvSL4zArkMX0LQvS7rzBKXnDXLfKyRVc=", "owner": "nixos", "repo": "nixpkgs", - "rev": "22c3f2cf41a0e70184334a958e6b124fb0ce3e01", + "rev": "2ff53fe64443980e139eaa286017f53f88336dd0", "type": "github" }, "original": { @@ -601,11 +647,11 @@ "treefmt-nix": "treefmt-nix_2" }, "locked": { - "lastModified": 1733805328, - "narHash": "sha256-5F49/mOzFb40uUZh71uNr7kBXjDCw5ZfHMbpZjjUVBQ=", + "lastModified": 1739519565, + "narHash": "sha256-coB/rCQx3FOIyBSa9nLfchlkGDL7ehHZc8U7CJ7YhP4=", "owner": "nix-community", "repo": "NUR", - "rev": "b54fa3d8c020e077d88be036a12a711b84fe2031", + "rev": "6ced3aa7dffa39ccfb771ac90c39756f9558d489", "type": "github" }, "original": { @@ -642,6 +688,7 @@ "inputs": { "catppuccin": "catppuccin", "colmena": "colmena", + "comin": "comin", "disko": "disko", "flake-utils": "flake-utils_2", "home-manager": "home-manager", @@ -649,6 +696,7 @@ "nix-index-database": "nix-index-database", "nix-vscode-extensions": "nix-vscode-extensions", "nixos-hardware": "nixos-hardware", + "nixos-sbc": "nixos-sbc", "nixpkgs": "nixpkgs_2", "nixpkgs-stable": "nixpkgs-stable", "nur": "nur", @@ -662,11 +710,11 @@ ] }, "locked": { - "lastModified": 1733785344, - "narHash": "sha256-pm4cfEcPXripE36PYCl0A2Tu5ruwHEvTee+HzNk+SQE=", + "lastModified": 1739262228, + "narHash": "sha256-7JAGezJ0Dn5qIyA2+T4Dt/xQgAbhCglh6lzCekTVMeU=", "owner": "Mic92", "repo": "sops-nix", - "rev": "a80af8929781b5fe92ddb8ae52e9027fae780d2a", + "rev": "07af005bb7d60c7f118d9d9f5530485da5d1e975", "type": "github" }, "original": { diff --git a/flake.nix b/flake.nix index 4da0466..f81f61a 100644 --- a/flake.nix +++ b/flake.nix @@ -49,12 +49,23 @@ catppuccin = { url = "github:catppuccin/nix"; + inputs.nixpkgs.follows = "nixpkgs"; }; disko = { url = "github:nix-community/disko"; inputs.nixpkgs.follows = "nixpkgs"; }; + + comin = { + url = "github:xinyangli/comin"; + inputs.nixpkgs.follows = "nixpkgs"; + }; + + nixos-sbc = { + url = "github:nakato/nixos-sbc/main"; + inputs.nixpkgs.follows = "nixpkgs"; + }; }; outputs = @@ -72,6 +83,8 @@ colmena, nix-index-database, disko, + comin, + nixos-sbc, ... }: let @@ -107,8 +120,12 @@ sharedNixosModules = [ self.nixosModules.default sops-nix.nixosModules.sops + comin.nixosModules.comin ]; nodeNixosModules = { + weilite = [ + ./machines/weilite + ]; calcite = [ nixos-hardware.nixosModules.asus-zephyrus-ga401 catppuccin.nixosModules.catppuccin @@ -138,6 +155,11 @@ disko.nixosModules.disko ./machines/biotite ]; + baryte = [ + nixos-sbc.nixosModules.default + nixos-sbc.nixosModules.boards.bananapi.bpir4 + ./machines/baryte + ]; }; sharedColmenaModules = [ deploymentModule @@ -193,18 +215,6 @@ }; }; - massicot = - { ... }: - { - deployment.targetHost = "49.13.13.122"; - deployment.buildOnTarget = true; - - imports = [ - { nixpkgs.system = "aarch64-linux"; } - machines/massicot - ] ++ sharedColmenaModules; - }; - la-00 = { ... }: { @@ -262,17 +272,6 @@ ] ++ sharedColmenaModules; }; - weilite = - { ... }: - { - imports = [ machines/weilite ] ++ sharedColmenaModules; - deployment = { - targetHost = "weilite.coho-tet.ts.net"; - targetPort = 22; - buildOnTarget = false; - }; - nixpkgs.system = "x86_64-linux"; - }; thorite = { ... }: { @@ -302,6 +301,14 @@ calcite = mkNixos { hostname = "calcite"; }; + + weilite = mkNixos { + hostname = "weilite"; + }; + + baryte = mkNixos { + hostname = "baryte"; + }; } // self.colmenaHive.nodes; } @@ -327,7 +334,6 @@ packages = with pkgs; [ nix git - colmena.packages.${system}.colmena sops nix-output-monitor nil diff --git a/garnix.yaml b/garnix.yaml index 38563a7..f602857 100644 --- a/garnix.yaml +++ b/garnix.yaml @@ -1,10 +1,19 @@ builds: - include: - - '*.x86_64-linux.*' - - defaultPackage.x86_64-linux - - devShell.x86_64-linux - - homeConfigurations.x86_64-linux.* - - homeConfigurations.aarch64-linux.* - - darwinConfigurations.* - - nixosConfigurations.* - + - include: + - '*.x86_64-linux.*' + - defaultPackage.x86_64-linux + - devShell.x86_64-linux + - homeConfigurations.x86_64-linux.* + - homeConfigurations.aarch64-linux.* + - darwinConfigurations.* + - nixosConfigurations.* + branch: deploy + - include: + - '*.x86_64-linux.*' + - defaultPackage.x86_64-linux + - devShell.x86_64-linux + - homeConfigurations.x86_64-linux.* + - homeConfigurations.aarch64-linux.* + - darwinConfigurations.* + - nixosConfigurations.* + branch: testing-calcite diff --git a/home/default.nix b/home/default.nix index ddd31bf..ea2911a 100644 --- a/home/default.nix +++ b/home/default.nix @@ -1,5 +1,6 @@ { xin = { calcite = import ./xin/calcite.nix; + gold = import ./xin/gold; }; } diff --git a/home/xin/calcite.nix b/home/xin/calcite.nix index d90cc4d..8d83d35 100644 --- a/home/xin/calcite.nix +++ b/home/xin/calcite.nix @@ -5,6 +5,9 @@ in { imports = [ ./common + ./common/pentesting.nix + ./common/gui/foot.nix + ./common/gui/default.nix ]; programs.nix-index-database.comma.enable = true; @@ -58,12 +61,6 @@ in xdg.enable = true; custom-hm = { - alacritty = { - enable = true; - }; - cosmic-term = { - enable = true; - }; direnv = { enable = true; }; @@ -108,10 +105,12 @@ in xdg.systemDirs.data = [ "/usr/share" - "/var/lib/flatpak/exports/share" - "${homeDirectory}/.local/share/flatpak/exports/share" ]; + xdg.configFile."distrobox/distrobox.conf".text = '' + container_additional_volumes="/nix/store:/nix/store:ro /etc/profiles/per-user:/etc/profiles/per-user:ro" + ''; + programs.man.generateCaches = false; programs.atuin = { @@ -119,6 +118,14 @@ in flags = [ "--disable-up-arrow" ]; }; + programs.zathura = { + enable = true; + options = { + recolor = false; + selection-clipboard = "clipboard"; + }; + }; + programs.firefox = { enable = true; policies.DefaultDownloadDirectory = "/media/data/Downloads"; diff --git a/home/xin/common/gui/default.nix b/home/xin/common/gui/default.nix new file mode 100644 index 0000000..38af792 --- /dev/null +++ b/home/xin/common/gui/default.nix @@ -0,0 +1,12 @@ +{ config, pkgs, ... }: +{ + home.packages = with pkgs; [ + # File Manager + xfce.thunar + xfce.thunar-archive-plugin + xfce.thunar-media-tags-plugin + xfce.thunar-volman + + swayimg + ]; +} diff --git a/home/xin/common/gui/foot.nix b/home/xin/common/gui/foot.nix new file mode 100644 index 0000000..0ec411a --- /dev/null +++ b/home/xin/common/gui/foot.nix @@ -0,0 +1,15 @@ +{ pkgs, lib, ... }: +{ + programs.foot = { + enable = true; + settings = { + main = { + font = "monospace:size=14"; + }; + desktop-notifications = { + command = "${lib.getExe pkgs.libnotify} --wait --app-name \${app-id} --icon \${app-id} --category \${category} --urgency \${urgency} --expire-time \${expire-time} --hint STRING:image-path:\${icon} --hint BOOLEAN:suppress-sound:\${muted} --hint STRING:sound-name:\${sound-name} --replace-id \${replace-id} \${action-argument} --print-id -- \${title} \${body}"; + inhibit-when-focused = "yes"; + }; + }; + }; +} diff --git a/home/xin/common/pentesting.nix b/home/xin/common/pentesting.nix new file mode 100644 index 0000000..92601a6 --- /dev/null +++ b/home/xin/common/pentesting.nix @@ -0,0 +1,6 @@ +{ pkgs, ... }: +{ + home.packages = with pkgs; [ + burpsuite + ]; +} diff --git a/home/xin/raspite/default.nix b/home/xin/raspite/default.nix deleted file mode 100644 index 888383c..0000000 --- a/home/xin/raspite/default.nix +++ /dev/null @@ -1,25 +0,0 @@ -{ config, pkgs, ... }: -{ - imports = [ ../common ]; - - home.username = "xin"; - home.homeDirectory = "/home/xin"; - home.stateVersion = "23.05"; - - # Let Home Manager install and manage itself. - programs.home-manager.enable = true; - - accounts.email.accounts.gmail = { - primary = true; - address = "lixinyang411@gmail.com"; - flavor = "gmail.com"; - }; - - accounts.email.accounts.whu = { - address = "lixinyang411@whu.edu.cn"; - }; - - accounts.email.accounts.foxmail = { - address = "lixinyang411@foxmail.com"; - }; -} diff --git a/machines/baryte/default.nix b/machines/baryte/default.nix new file mode 100644 index 0000000..e9cfdd6 --- /dev/null +++ b/machines/baryte/default.nix @@ -0,0 +1,22 @@ +{ config, lib, ... }: +{ + imports = [ + ]; + config = { + nixpkgs.hostPlatform = "aarch64-linux"; + system.stateVersion = "25.05"; + users.users.root.hashedPassword = "$y$j9T$NToEZWJBONjSgRnMd9Ur9/$o6n7a9b8eUILQz4d37oiHCCVnDJ8hZTZt.c.37zFfU."; + + commonSettings = { + auth.enable = true; + }; + + services.openssh.enable = true; + services.dae = { + enable = true; + configFile = "/var/lib/dae/config.dae"; + }; + services.tailscale.enable = true; + time.timeZone = "Asia/Shanghai"; + }; +} diff --git a/machines/biotite/default.nix b/machines/biotite/default.nix index 741e281..e643950 100644 --- a/machines/biotite/default.nix +++ b/machines/biotite/default.nix @@ -15,6 +15,7 @@ ./services/hedgedoc.nix ./services/forgejo.nix ./services/vaultwarden.nix + ./services/kanidm.nix ]; networking.hostName = "biotite"; @@ -36,6 +37,7 @@ commonSettings = { auth.enable = true; + comin.enable = true; }; custom.monitoring = { diff --git a/machines/biotite/services/forgejo.nix b/machines/biotite/services/forgejo.nix index 7321b89..b60352f 100644 --- a/machines/biotite/services/forgejo.nix +++ b/machines/biotite/services/forgejo.nix @@ -69,28 +69,29 @@ in 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 - ''; }; + preStart = + let + providerName = "kanidm"; + args = lib.concatStringsSep " " [ + "--name ${providerName}" + "--provider openidConnect" + "--key forgejo" + "--secret $CLIENT_SECRET" + "--auto-discover-url https://${idpUrl}/oauth2/openid/forgejo/.well-known/openid-configuration" + "--icon-url https://${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 = { diff --git a/machines/biotite/services/gotosocial.nix b/machines/biotite/services/gotosocial.nix index 3114cf6..e2f4581 100644 --- a/machines/biotite/services/gotosocial.nix +++ b/machines/biotite/services/gotosocial.nix @@ -26,7 +26,7 @@ in instance-expose-public-timeline = true; oidc-enabled = true; oidc-idp-name = "Kanidm"; - oidc-issuer = "${idpUrl}/oauth2/openid/gotosocial"; + oidc-issuer = "https://${idpUrl}/oauth2/openid/gotosocial"; oidc-client-id = "gotosocial"; oidc-link-existing = true; }; diff --git a/machines/biotite/services/hedgedoc.nix b/machines/biotite/services/hedgedoc.nix index c8b33bc..af64be5 100644 --- a/machines/biotite/services/hedgedoc.nix +++ b/machines/biotite/services/hedgedoc.nix @@ -20,10 +20,10 @@ in email = false; allowEmailRegister = false; oauth2 = { - baseURL = "${idpUrl}/oauth2/openid/hedgedoc"; - authorizationURL = "${idpUrl}/ui/oauth2"; - tokenURL = "${idpUrl}/oauth2/token"; - userProfileURL = "${idpUrl}/oauth2/openid/hedgedoc/userinfo"; + baseURL = "https://${idpUrl}/oauth2/openid/hedgedoc"; + authorizationURL = "https://${idpUrl}/ui/oauth2"; + tokenURL = "https://${idpUrl}/oauth2/token"; + userProfileURL = "https://${idpUrl}/oauth2/openid/hedgedoc/userinfo"; userProfileEmailAttr = "email"; userProfileUsernameAttr = "name"; userProfileDisplayNameAttr = "preferred_name"; diff --git a/machines/massicot/kanidm-provision.nix b/machines/biotite/services/kanidm-provision.nix similarity index 95% rename from machines/massicot/kanidm-provision.nix rename to machines/biotite/services/kanidm-provision.nix index e44c729..82bbd49 100644 --- a/machines/massicot/kanidm-provision.nix +++ b/machines/biotite/services/kanidm-provision.nix @@ -177,8 +177,11 @@ in "https://immich.xinyang.life:8000/api/oauth/mobile-redirect/" "https://immich.xinyang.life:8000/auth/login" "https://immich.xinyang.life:8000/user-settings" + "https://immich.xiny.li:8443/api/oauth/mobile-redirect/" + "https://immich.xiny.li:8443/auth/login" + "https://immich.xiny.li:8443/user-settings" ]; - originLanding = "https://immich.xinyang.life:8000/auth/login?autoLaunch=0"; + originLanding = "https://immich.xiny.li:8443/auth/login?autoLaunch=0"; allowInsecureClientDisablePkce = true; scopeMaps = { immich-users = [ diff --git a/machines/biotite/services/kanidm.nix b/machines/biotite/services/kanidm.nix new file mode 100644 index 0000000..975f31b --- /dev/null +++ b/machines/biotite/services/kanidm.nix @@ -0,0 +1,54 @@ +{ + config, + pkgs, + lib, + ... +}: +let + kanidm_listen_port = 5324; + inherit (config.my-lib.settings) idpUrl; +in +{ + imports = [ + ./kanidm-provision.nix + ]; + + security.acme = { + acceptTerms = true; + certs.${idpUrl} = { + email = "lixinyang411@gmail.com"; + listenHTTP = "127.0.0.1:1360"; + group = "kanidm"; + }; + }; + + services.kanidm = { + package = pkgs.kanidm.withSecretProvisioning; + enableServer = true; + serverSettings = { + domain = idpUrl; + origin = "https://${idpUrl}"; + bindaddress = "[::]:${toString kanidm_listen_port}"; + tls_key = ''${config.security.acme.certs.${idpUrl}.directory}/key.pem''; + tls_chain = ''${config.security.acme.certs.${idpUrl}.directory}/fullchain.pem''; + online_backup.versions = 7; + # db_path = "/var/lib/kanidm/kanidm.db"; + }; + }; + + services.caddy = { + enable = true; + virtualHosts."http://${idpUrl}".extraConfig = '' + reverse_proxy ${config.security.acme.certs.${idpUrl}.listenHTTP} + ''; + virtualHosts."https://${idpUrl}".extraConfig = '' + reverse_proxy https://127.0.0.1:${toString kanidm_listen_port} { + header_up Host {upstream_hostport} + header_down Access-Control-Allow-Origin "*" + transport http { + tls_server_name ${config.services.kanidm.serverSettings.domain} + } + } + ''; + }; +} diff --git a/machines/biotite/services/miniflux.nix b/machines/biotite/services/miniflux.nix index 1bee3dc..7662b7e 100644 --- a/machines/biotite/services/miniflux.nix +++ b/machines/biotite/services/miniflux.nix @@ -17,7 +17,7 @@ in 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_OIDC_DISCOVERY_ENDPOINT = "https://${idpUrl}/oauth2/openid/miniflux"; OAUTH2_USER_CREATION = 1; CREATE_ADMIN = 0; }; diff --git a/machines/biotite/services/synapse.nix b/machines/biotite/services/synapse.nix index e352495..72e7516 100644 --- a/machines/biotite/services/synapse.nix +++ b/machines/biotite/services/synapse.nix @@ -29,6 +29,13 @@ in ''; }; + # TODO: Waiting for https://github.com/NixOS/nixpkgs/issues/367976 + nixpkgs.overlays = [ + (final: prev: { + matrix-synapse-unwrapped = prev.matrix-synapse-unwrapped.overridePythonAttrs { doCheck = false; }; + }) + ]; + services.matrix-synapse = { enable = true; withJemalloc = true; @@ -78,11 +85,11 @@ in oidc_providers = [ { idp_id = "Kanidm"; - idp_name = lib.removePrefix "https://" idpUrl; + idp_name = idpUrl; issuer = "${idpUrl}/oauth2/openid/synapse"; - authorization_endpoint = "${idpUrl}/ui/oauth2"; - token_endpoint = "${idpUrl}/oauth2/token"; - userinfo_endpoint = "${idpUrl}/oauth2/openid/synapse/userinfo"; + authorization_endpoint = "https://${idpUrl}/ui/oauth2"; + token_endpoint = "https://${idpUrl}/oauth2/token"; + userinfo_endpoint = "https://${idpUrl}/oauth2/openid/synapse/userinfo"; client_id = "synapse"; client_secret_path = config.sops.secrets."synapse/oidc_client_secret".path; scopes = [ diff --git a/machines/calcite/configuration.nix b/machines/calcite/configuration.nix index c5afb73..c9afcd5 100644 --- a/machines/calcite/configuration.nix +++ b/machines/calcite/configuration.nix @@ -6,6 +6,7 @@ }: let inherit (lib) mkForce getExe; + inherit (config.my-lib.settings) idpUrl; in { imports = [ @@ -20,6 +21,7 @@ in nix = { signing.enable = true; }; + comin.enable = true; }; # Bootloader. @@ -32,6 +34,7 @@ in "nvidia_modeset" "nvidia_uvm" ]; + hardware.nvidia.package = config.boot.kernelPackages.nvidiaPackages.latest; boot.supportedFilesystems = [ "ntfs" ]; boot.binfmt.emulatedSystems = [ "aarch64-linux" ]; @@ -151,6 +154,15 @@ in services.keyd = { enable = true; keyboards = { + default = { + ids = [ "*" ]; + settings = { + main = { + capslock = "overload(control, esc)"; + control = "overload(control, esc)"; + }; + }; + }; "internal" = { ids = [ "0b05:1866" ]; settings = { @@ -169,17 +181,6 @@ in }; }; }; - "keydous" = { - ids = [ - "25a7:fa14" - "3151:4002" - ]; - settings = { - main = { - capslock = "overload(control, esc)"; - }; - }; - }; }; }; @@ -187,9 +188,13 @@ in services.printing.enable = true; services.printing.drivers = [ pkgs.hplip + pkgs.gutenprint pkgs.gutenprintBin - pkgs.canon-cups-ufr2 ]; + hardware.sane = { + enable = true; + extraBackends = [ pkgs.hplipWithPlugin ]; + }; hardware.pulseaudio.enable = false; security.rtkit.enable = true; @@ -212,13 +217,14 @@ in "wheel" "wireshark" "tss" + "scanner" ]; }; services.kanidm = { enableClient = true; clientSettings = { - uri = "https://auth.xinyang.life"; + uri = "https://${idpUrl}"; }; }; @@ -301,6 +307,7 @@ in zotero # onlyoffice-bin + # wemeet wemeet virt-manager diff --git a/machines/calcite/network.nix b/machines/calcite/network.nix index 27e77ee..0626cc9 100644 --- a/machines/calcite/network.nix +++ b/machines/calcite/network.nix @@ -12,19 +12,41 @@ networking = { networkmanager = { enable = true; - dns = "systemd-resolved"; + dns = "default"; + settings = { + main = { + rc-manager = "resolvconf"; + }; + }; }; }; - services.resolved = { + networking.resolvconf = { enable = true; + dnsExtensionMechanism = false; + useLocalResolver = false; + }; + + services.kresd = { + enable = true; + listenPlain = [ ]; extraConfig = '' - Cache=no + log_level("notice") + net.listen('127.0.0.1', 53) + modules = { 'hints > iterate', 'stats', 'predict' } + cache.size = 100 * MB + trust_anchors.remove(".") + policy.add(policy.all(policy.TLS_FORWARD( { + { "8.8.8.8", hostname="dns.google" } }))) ''; + # policy.add(policy.suffix(policy.FORWARD({ "100.100.100.100" }), policy.todnames({ 'coho-tet.ts.net' }))) }; # Enable Tailscale - services.tailscale.enable = true; + services.tailscale = { + enable = true; + extraUpFlags = [ "--accept-dns=false" ]; + }; # services.tailscale.useRoutingFeatures = "both"; services.dae.enable = true; diff --git a/machines/dolomite/common.nix b/machines/dolomite/common.nix index 65b10c7..322786f 100644 --- a/machines/dolomite/common.nix +++ b/machines/dolomite/common.nix @@ -37,12 +37,14 @@ commonSettings = { auth.enable = true; + comin.enable = true; proxyServer = { enable = true; users = [ "wyj" "yhb" "xin" + "zx" ]; }; }; diff --git a/machines/dolomite/secrets/secrets.yaml b/machines/dolomite/secrets/secrets.yaml index e0df929..87c4677 100644 --- a/machines/dolomite/secrets/secrets.yaml +++ b/machines/dolomite/secrets/secrets.yaml @@ -9,6 +9,9 @@ sing-box: 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] + zx: + password: ENC[AES256_GCM,data:UkRaj5aadq8Ea3j3wh6YQDzxmew=,iv:vrJ7h97KaWmp7+rkYowdTDI7HIq71ZUIERE3o0BY5Fc=,tag:YEPydn9fLmEBYBDD//6Pfw==,type:str] + uuid: ENC[AES256_GCM,data:W+qXN1Xa5ZMXRQh+7dtZkExFrp6qqEOkoxn8Fj5qQ5U23ytz,iv:559UEoMyY3/RfmwJLFCerkuV0DjTbhaRPbW56toxMEU=,tag:pv706bZgEblyGS7V9mwABA==,type:str] sops: kms: [] gcp_kms: [] @@ -51,8 +54,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: "2025-01-31T07:11:08Z" + mac: ENC[AES256_GCM,data:CYOPIN29pg5ldsLgkMaqSqKmTKusSBKVVifU2eGPIEILcYEwMmmGkvCH7jG8+QnOicfSTIonA0sPBO/g36X5bLhQIcmzUEnImSXVFLXpvHM2haIxPSHG/xvaLbIPcHMKvHbeyIGIhIdfPp7ssyH1Aa/+PgtfTIMUeOFbIWykgfE=,iv:+u7kyGUgmeEJ2T6rnBS9ACAk4Ka2OPJrz4sCZLVTPP8=,tag:d2eimY7wGwoQZZEh3d0UZA==,type:str] pgp: [] unencrypted_suffix: _unencrypted - version: 3.9.1 + version: 3.9.2 diff --git a/machines/massicot/default.nix b/machines/massicot/default.nix deleted file mode 100644 index 7b56e15..0000000 --- a/machines/massicot/default.nix +++ /dev/null @@ -1,74 +0,0 @@ -{ - pkgs, - ... -}: - -{ - imports = [ - ./hardware-configuration.nix - ./networking.nix - ./services.nix - ./services - ]; - - sops = { - defaultSopsFile = ./secrets.yaml; - age.sshKeyPaths = [ "/etc/ssh/ssh_host_ed25519_key" ]; - secrets = { - gts_env = { - owner = "gotosocial"; - }; - }; - }; - - boot.loader.efi.canTouchEfiVariables = true; - boot.loader.efi.efiSysMountPoint = "/boot"; - boot.loader.grub = { - enable = true; - efiSupport = true; - configurationLimit = 5; - }; - environment.systemPackages = with pkgs; [ - cifs-utils - git - ]; - - # Disable docs on servers - documentation.nixos.enable = false; - documentation.man.enable = false; - - system.stateVersion = "22.11"; - - networking = { - hostName = "massicot"; - }; - - services.tailscale.enable = true; - - commonSettings = { - auth.enable = true; - nix = { - enable = true; - }; - }; - - security.sudo = { - execWheelOnly = true; - wheelNeedsPassword = false; - }; - - services.openssh = { - enable = true; - settings = { - PasswordAuthentication = false; - KbdInteractiveAuthentication = false; - PermitRootLogin = "no"; - GSSAPIAuthentication = "no"; - KerberosAuthentication = "no"; - }; - }; - services.fail2ban.enable = true; - programs.mosh.enable = true; - - systemd.services.sshd.wantedBy = pkgs.lib.mkForce [ "multi-user.target" ]; -} diff --git a/machines/massicot/hardware-configuration.nix b/machines/massicot/hardware-configuration.nix deleted file mode 100644 index 36e673c..0000000 --- a/machines/massicot/hardware-configuration.nix +++ /dev/null @@ -1,32 +0,0 @@ -{ modulesPath, ... }: -{ - imports = [ (modulesPath + "/profiles/qemu-guest.nix") ]; - boot.loader.grub = { - efiSupport = true; - device = "nodev"; - }; - fileSystems."/boot" = { - device = "/dev/disk/by-uuid/AC27-D9D6"; - fsType = "vfat"; - }; - boot.initrd.availableKernelModules = [ - "ata_piix" - "uhci_hcd" - "xen_blkfront" - ]; - boot.initrd.kernelModules = [ "nvme" ]; - fileSystems."/" = { - device = "/dev/disk/by-id/scsi-0QEMU_QEMU_HARDDISK_35068215-part1"; - fsType = "ext4"; - }; - - fileSystems."/mnt/storage" = { - device = "/dev/disk/by-id/scsi-0HC_Volume_101302395"; - fsType = "btrfs"; - options = [ - "subvol=storage" - "compress=zstd" - "noatime" - ]; - }; -} diff --git a/machines/massicot/networking.nix b/machines/massicot/networking.nix deleted file mode 100644 index 2a4c529..0000000 --- a/machines/massicot/networking.nix +++ /dev/null @@ -1,14 +0,0 @@ -{ pkgs, ... }: -{ - networking.useNetworkd = true; - systemd.network.networks."10-wan" = { - matchConfig.MACAddress = "96:00:02:68:7d:2d"; - networkConfig = { - DHCP = "ipv4"; - Gateway = "fe80::1"; - }; - address = [ - "2a01:4f8:c17:345f::3/64" - ]; - }; -} diff --git a/machines/massicot/secrets.yaml b/machines/massicot/secrets.yaml deleted file mode 100644 index 9393192..0000000 --- a/machines/massicot/secrets.yaml +++ /dev/null @@ -1,40 +0,0 @@ -storage_box_mount: ENC[AES256_GCM,data:9lOAL3tkfB0pN4/cuM4SX0xoMrW0UUEzTN8spw3MQ3BWrfsRc3Stsce3puXz1sRf,iv:7Q9wzpBgQ3tqcfy0n/c6Ya84Kg60nhR/e2H0pVntWsY=,tag:9a0xvNBGQpCvhxgmV3hrww==,type:str] -gts_env: ENC[AES256_GCM,data:StggMdJPevrDbrVDrBDETdQYnSOaTESkgSqpGKrSHXhS21nyCE5ya7/X4l0GVTXoGCyfWG7vK+PDW22mJxpYcj2CBaVUYDu/,iv:2fqWDaWAWxTXdG7w5HU6jBcappFEByNtYs0Jd6PaYnA=,tag:KGhrMemao6g4FkEAZmmacg==,type:str] -hedgedoc_env: ENC[AES256_GCM,data:+rjEctM6IJUpn7WcAnBS9TkQi2lCq4wKPxbaOApffH0tFyu56SpECrLpmM749I7th3N+UGb0pLM7+Ywr7fbuuMfUuIWom6Y+CKYw4yMlgjzTaaNqBmstvMxLaPnmA01G9ie1rQ==,iv:YBIyQQ6xiUyxSnR5epE5hV9OqETLKC5CFTEaRJdErGU=,tag:77kHYQ2i2APVyadhMhmvWA==,type:str] -grafana_oauth_secret: ENC[AES256_GCM,data:43+EBnN912eK/08MdJokWPxi2Lxn/D4hSHPhNmHOk9awWQ7ut/el0vaAa+Epqnui3le2p4VuotQT6XlIuDLrixIomrc6Qw5HERAEdZmbrGvDlrrNhw==,iv:Pfn8rL0LtG3hym9EdSZRjaPLMlWlut/nt2FEtRWnULo=,tag:moDWqF3aBbnO4aG0Cysfcw==,type:str] -miniflux: - oauth2_secret: ENC[AES256_GCM,data:jcZR9E9jXNKfkAoGgBI19qQeaz26R6qiAWjP4XrftHSCQV974tjJl+fiU8Xgi0bViA==,iv:/aY0bL/oAAHBhohy3FHB/UEDYryw7A7JOKvEbLtDHJg=,tag:Fn/6NurNkRphXySR+y9S9Q==,type:str] -forgejo: - env: ENC[AES256_GCM,data:TMeguXfanISeyvsay9SBqm3SSGKpp5nCkqhHblf0QHNzHWGQKwpORmWfOtVfgOh9qdDqq8wYBpXznmbvixjV,iv:IR/rMoAIvZCw9FURmau4+g8c3pvI9BRs7v1NJ5ia4jI=,tag:kjwf6RN5HN8I2sUhDcr4UQ==,type:str] -restic: - repo_url: ENC[AES256_GCM,data:GMHbrjgwajnYSiqtoYaKiFT/aDWDwlzEkvMLPzYf7C9PvLr7T4zeWyAA9//8huldyxO3+nk6O9lR9ORZKZfb8/MYB7nRB03sZQ==,iv:6uBhsksOGDjoc13U2xWLz7I+0fzGRhnw0nStACqlnug=,tag:uhH28NYq+ly1bmCV/cpxkQ==,type:str] - repo_password: ENC[AES256_GCM,data:jRHNgOk5ChWdqMKsd/V4Xg==,iv:wrgF5pau/RylG1nmJYmvrZ02o67qkkT5PrZAQlXb6Qo=,tag:X0WVpMqi8xeoATss/sSPMA==,type:str] -sops: - kms: [] - gcp_kms: [] - azure_kv: [] - hc_vault: [] - age: - - recipient: age1uw059wcwfvd9xuj0hpqzqpeg7qemecspjrsatg37wc7rs2pumfdsgken0c - enc: | - -----BEGIN AGE ENCRYPTED FILE----- - YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSB1aGRvUUtjcDU2bnhaNDJD - K3c5TnFJeHQzM2VpeHphR2dGeS9NYzcyYjJnCnNrQ3dxL1hqR2MyQXhldUZ1VEJp - N25nVHZ1QjRydW9hTWE5d0x2M2pPNkkKLS0tIFpiRW8rZ1Q1R1RCZGN1ZGs3ek45 - UENaRjJPWFJqUlpzd3dHSC9pdnZ6STQKQaaY28FYUk3O9TTkX9LQTzlrqZVojgxY - M+N6LApfdoioQCmXduDbj18i0eUbECTBXR/uEFEIHbn6AJVD/vx7iw== - -----END AGE ENCRYPTED FILE----- - - recipient: age1jle2auermhswqtehww9gqada8car5aczrx43ztzqf9wtcld0sfmqzaecta - enc: | - -----BEGIN AGE ENCRYPTED FILE----- - YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBRY0lIeE9tWDA3Q21IWk1E - YnlaQUJybFB2bmFpbG1UZ0UyNG16WkRkZlNVCmUySHVBcXpWekpVN3R5dGs5ODY1 - V1ZlUk4zRSs1NkVjY3JSMVVQSXJ1OEkKLS0tIFMzeUNaYVpoNnV3TE1oamEwTEo2 - dnFBa0lDWWZtS1BHdzBoVzNTaGNkSEEKi/W1n7RT8NpTp00SBMwxsUJAPDhumJ/i - V2VnaSNwouD3SswTcoBzqQpBP9XrqzjIYGke90ZODFQbMY9WDQ+O0g== - -----END AGE ENCRYPTED FILE----- - lastmodified: "2024-11-28T03:57:35Z" - mac: ENC[AES256_GCM,data:xjZrlwfWLtZNYfH+KiE2ICt9Jo4nx/LKaEYi/ECN/Od+ZTjety0V6RJ/RfmI6q3K1WMj0sAGc56hCZ0iOn25L8wK6dc14hZVoSwwbIiQ7hTQE5LcK+NbXNmy3r/YC855DHG9kE08eYGHdNcBbckZg3HhkHQ9UYS/Ox/QFFuBa5Q=,iv:N3AW+sr9ET3c/ArXr176haRewYFsfgsNn+hkC0MDJwA=,tag:SCikn+F8btuSBswV+oCdXg==,type:str] - pgp: [] - unencrypted_suffix: _unencrypted - version: 3.9.1 diff --git a/machines/massicot/services.nix b/machines/massicot/services.nix deleted file mode 100644 index a4f0d72..0000000 --- a/machines/massicot/services.nix +++ /dev/null @@ -1,102 +0,0 @@ -{ - config, - pkgs, - lib, - ... -}: -let - kanidm_listen_port = 5324; -in -{ - imports = [ - ./kanidm-provision.nix - ]; - networking.firewall.allowedTCPPorts = [ - 80 - 443 - 2222 - 8448 - ]; - networking.firewall.allowedUDPPorts = [ - 80 - 443 - 8448 - ]; - - custom.monitoring = { - promtail.enable = true; - }; - - custom.prometheus.exporters = { - enable = true; - blackbox = { - enable = true; - }; - node = { - enable = true; - }; - }; - - security.acme = { - acceptTerms = true; - certs."auth.xinyang.life" = { - email = "lixinyang411@gmail.com"; - listenHTTP = "127.0.0.1:1360"; - group = "kanidm"; - }; - }; - - services.kanidm = { - package = pkgs.kanidm.withSecretProvisioning; - enableServer = true; - serverSettings = { - domain = "auth.xinyang.life"; - origin = "https://auth.xinyang.life"; - bindaddress = "[::]:${toString kanidm_listen_port}"; - tls_key = ''${config.security.acme.certs."auth.xinyang.life".directory}/key.pem''; - tls_chain = ''${config.security.acme.certs."auth.xinyang.life".directory}/fullchain.pem''; - online_backup.versions = 7; - # db_path = "/var/lib/kanidm/kanidm.db"; - }; - }; - - users.users.conduit = { - isSystemUser = true; - group = "conduit"; - }; - users.groups.conduit = { }; - - services.gotosocial = { - enable = true; - settings = { - log-level = "debug"; - host = "xinyang.life"; - letsencrypt-enabled = false; - bind-address = "localhost"; - instance-expose-public-timeline = true; - oidc-enabled = true; - oidc-idp-name = "Kanidm"; - oidc-issuer = "https://auth.xinyang.life/oauth2/openid/gts"; - oidc-client-id = "gts"; - oidc-link-existing = true; - storage-local-base-path = "/mnt/storage/gotosocial/storage"; - }; - environmentFile = config.sops.secrets.gts_env.path; - }; - - services.caddy = { - enable = true; - virtualHosts."http://auth.xinyang.life:80".extraConfig = '' - reverse_proxy ${config.security.acme.certs."auth.xinyang.life".listenHTTP} - ''; - virtualHosts."https://auth.xinyang.life".extraConfig = '' - reverse_proxy https://127.0.0.1:${toString kanidm_listen_port} { - header_up Host {upstream_hostport} - header_down Access-Control-Allow-Origin "*" - transport http { - tls_server_name ${config.services.kanidm.serverSettings.domain} - } - } - ''; - }; -} diff --git a/machines/massicot/services/default.nix b/machines/massicot/services/default.nix deleted file mode 100644 index fdf054b..0000000 --- a/machines/massicot/services/default.nix +++ /dev/null @@ -1,5 +0,0 @@ -{ - imports = [ - ./restic.nix - ]; -} diff --git a/machines/massicot/services/restic.nix b/machines/massicot/services/restic.nix deleted file mode 100644 index e8d2501..0000000 --- a/machines/massicot/services/restic.nix +++ /dev/null @@ -1,42 +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" - "/mnt/storage" - ]; - backupPrepareCommand = [ - (sqliteBackup "/var/lib/hedgedoc/db.sqlite" "/backup/hedgedoc" "db.sqlite") - (sqliteBackup "/var/lib/bitwarden_rs/db.sqlite3" "/backup/bitwarden_rs" "db.sqlite3") - (sqliteBackup "/var/lib/gotosocial/database.sqlite" "/backup/gotosocial" "database.sqlite") - (sqliteBackup "/var/lib/kanidm/kanidm.db" "/backup/kanidm" "kanidm.db") - ]; - }; - - services.restic.backups.${config.networking.hostName} = { - extraBackupArgs = [ - "--limit-upload=1024" - ]; - }; -} diff --git a/machines/osmium/default.nix b/machines/osmium/default.nix index 8378b1c..1785582 100644 --- a/machines/osmium/default.nix +++ b/machines/osmium/default.nix @@ -69,7 +69,7 @@ neovim jq iptables - ebtables + nftables tcpdump busybox ethtool @@ -88,15 +88,53 @@ systemd.network = { enable = true; - networks."lan" = { - matchConfig.Name = "enu1"; - networkConfig.DHCP = "no"; - linkConfig.RequiredForOnline = "no"; - }; networks."wan" = { matchConfig.Name = "end0"; networkConfig.DHCP = "yes"; - linkConfig.RequiredForOnline = "yes"; + linkConfig.RequiredForOnline = false; + }; + networks."lan" = { + matchConfig.Name = "enu1"; + networkConfig = { + DHCP = "no"; + DHCPServer = "yes"; + Address = "10.1.1.1/24"; + }; + dhcpServerConfig = { + ServerAddress = "10.1.1.1/24"; + UplinkInterface = "end0"; + EmitDNS = "yes"; + DNS = [ "192.168.1.1" ]; + }; + linkConfig.RequiredForOnline = false; + }; + }; + + networking.firewall.enable = false; + networking.nftables = { + enable = true; + tables = { + filter = { + family = "inet"; + content = '' + chain forward { + iifname { "enu1" } oifname { "end0" } accept comment "Allow trusted LAN to WAN" + iifname { "end0" } oifname { "enu1" } ct state { established, related } accept comment "Allow established back to LANs" + iifname { "enu1" } oifname { "tailscale0" } accept comment "Allow LAN to Tailscale" + } + ''; + }; + + nat = { + family = "ip"; + content = '' + chain postrouting { + type nat hook postrouting priority 100; policy accept; + oifname "end0" masquerade + oifname "tailscale0" masquerade + } + ''; + }; }; }; @@ -105,7 +143,11 @@ configFile = "/var/lib/dae/config.dae"; }; - services.tailscale.enable = true; - + services.tailscale = { + enable = true; + extraSetFlags = [ + "--advertise-routes=10.1.1.0/24" + ]; + }; }; } diff --git a/machines/thorite/default.nix b/machines/thorite/default.nix index f2de662..2ea7cf4 100644 --- a/machines/thorite/default.nix +++ b/machines/thorite/default.nix @@ -37,6 +37,7 @@ commonSettings = { auth.enable = true; + comin.enable = true; }; nixpkgs.system = "x86_64-linux"; diff --git a/machines/thorite/monitoring.nix b/machines/thorite/monitoring.nix index 981fd14..f1ae160 100644 --- a/machines/thorite/monitoring.nix +++ b/machines/thorite/monitoring.nix @@ -12,6 +12,8 @@ let hedgedocDomain grafanaUrl ntfyUrl + internalDomain + transmissionExporterUrl ; removeHttps = s: lib.removePrefix "https://" s; in @@ -58,7 +60,22 @@ in node.enable = true; }; ruleModules = - (mkCaddyRules [ { host = "thorite"; } ]) + [ + { + name = "comin_rules"; + rules = [ + { + alert = "CominBuildFailed"; + expr = "comin_build_info != 1"; + for = "1m"; + labels = { + severity = "critical"; + }; + } + ]; + } + ] + ++ (mkCaddyRules [ { host = "thorite"; } ]) ++ (mkNodeRules [ { host = "thorite"; } ]) ++ (mkBlackboxRules [ { host = "thorite"; } ]); }; @@ -81,7 +98,24 @@ in ]; passwordFile = config.sops.secrets."prometheus/metrics_password".path; in - (mkScrapes [ + [ + { + job_name = "comin"; + scheme = "http"; + static_configs = [ + { + targets = map (host: "${host}.${internalDomain}:4243") [ + "weilite" + "thorite" + "la-00" + "hk-00" + "fra-00" + ]; + } + ]; + } + ] + ++ (mkScrapes [ { name = "immich"; scheme = "http"; @@ -118,9 +152,27 @@ in { name = "loki"; scheme = "http"; - address = "thorite.coho-tet.ts.net"; + address = "thorite.${internalDomain}"; port = 3100; } + { + name = "transmission"; + scheme = "http"; + address = "weilite.${internalDomain}"; + port = 19091; + } + { + name = "sonarr"; + scheme = "http"; + address = "weilite.${internalDomain}"; + port = 21560; + } + { + name = "radarr"; + scheme = "http"; + address = "weilite.${internalDomain}"; + port = 21561; + } ]) ++ (mkCaddyScrapes [ { address = "thorite.coho-tet.ts.net"; } @@ -129,7 +181,6 @@ in ]) ++ (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"; } @@ -139,11 +190,7 @@ in ++ (mkBlackboxScrapes [ { hostAddress = "thorite.coho-tet.ts.net"; - targetAddresses = probeList ++ [ "49.13.13.122:443" ]; - } - { - hostAddress = "massicot.coho-tet.ts.net"; - targetAddresses = probeList ++ [ "45.142.178.32:443" ]; + targetAddresses = probeList; } { hostAddress = "weilite.coho-tet.ts.net"; diff --git a/machines/weilite/default.nix b/machines/weilite/default.nix index 9d8cd04..8846704 100644 --- a/machines/weilite/default.nix +++ b/machines/weilite/default.nix @@ -12,13 +12,36 @@ ./services ]; + options = { + node = lib.mkOption { + type = lib.types.attrs; + default = { }; + }; + }; + config = { - networking.hostName = "weilite"; + networking = { + hostName = "weilite"; + useNetworkd = true; + }; + systemd.network = { + enable = true; + networks = { + "10-wan" = { + matchConfig.MACAddress = "52:54:00:db:23:d0"; + networkConfig.DHCP = "ipv4"; + }; + }; + }; commonSettings = { auth.enable = true; nix = { enable = true; }; + comin.enable = true; + }; + node = { + mediaDir = "/mnt/nixos/media"; }; boot = { @@ -33,25 +56,24 @@ "usb_storage" "sd_mod" ]; - kernelModules = [ "kvm-intel" ]; + kernelModules = [ + "kvm-intel" + ]; + kernelPackages = pkgs.linuxPackages_6_12; }; nixpkgs.config.allowUnfree = true; - environment.systemPackages = [ pkgs.virtiofsd ]; + environment.systemPackages = [ + pkgs.virtiofsd + pkgs.intel-gpu-tools + pkgs.pciutils + ]; sops = { defaultSopsFile = ./secrets.yaml; age.sshKeyPaths = [ "/etc/ssh/ssh_host_ed25519_key" ]; secrets = { - cloudflare_dns_token = { - owner = "caddy"; - mode = "400"; - }; - dnspod_dns_token = { - owner = "caddy"; - mode = "400"; - }; "restic/localpass" = { owner = "restic"; }; @@ -73,13 +95,6 @@ }; systemd.mounts = [ - { - what = "immich"; - where = "/mnt/XinPhotos/immich"; - type = "virtiofs"; - options = "rw,nodev,nosuid"; - wantedBy = [ "immich-server.service" ]; - } { what = "originals"; where = "/mnt/XinPhotos/originals"; @@ -88,21 +103,45 @@ wantedBy = [ "immich-server.service" ]; } { - what = "restic"; - where = "/var/lib/restic"; + what = "nixos"; + where = "/mnt/nixos"; type = "virtiofs"; options = "rw,nodev,nosuid"; + } + { + what = "/mnt/nixos/ocis"; + where = "/var/lib/ocis"; + options = "bind"; + after = [ "mnt-nixos.mount" ]; + wantedBy = [ "ocis.service" ]; + } + { + what = "/mnt/nixos/restic"; + where = "/var/lib/restic"; + options = "bind"; + after = [ "mnt-nixos.mount" ]; wantedBy = [ "restic-rest-server.service" ]; } { - what = "ocis"; - where = "/var/lib/ocis"; - type = "virtiofs"; - options = "rw,nodev,nosuid"; - wantedBy = [ "ocis.service" ]; + what = "/mnt/nixos/immich"; + where = "/var/lib/immich"; + options = "bind"; + after = [ "mnt-nixos.mount" ]; + wantedBy = [ "immich-server.service" ]; } ]; + hardware.graphics = { + enable = true; + extraPackages = with pkgs; [ + intel-media-driver + intel-vaapi-driver + vaapiVdpau + intel-compute-runtime # OpenCL filter support (hardware tonemapping and subtitle burn-in) + intel-media-sdk # QSV up to 11th gen + ]; + }; + services.openssh.ports = [ 22 2222 @@ -128,44 +167,6 @@ # tailscale derper module use nginx for reverse proxy services.nginx.enable = lib.mkForce false; - services.caddy = { - enable = true; - package = pkgs.caddy.withPlugins { - caddyModules = [ - { - repo = "github.com/caddy-dns/cloudflare"; - version = "89f16b99c18ef49c8bb470a82f895bce01cbaece"; - } - { - repo = "github.com/caddy-dns/dnspod"; - version = "1fd4ce87e919f47db5fa029c31ae74b9737a58af"; - } - ]; - vendorHash = "sha256-OhOeU2+JiJyIW9WdCYq98OKckXQZ9Fn5zULz0aLsXMI="; - }; - virtualHosts."derper00.namely.icu:8443".extraConfig = '' - reverse_proxy 127.0.0.1:${toString config.services.tailscale.derper.port} - ''; - virtualHosts."weilite.coho-tet.ts.net:8080".extraConfig = '' - reverse_proxy 127.0.0.1:${toString config.services.immich.port} - ''; - # API Token must be added in systemd environment file - virtualHosts."immich.xinyang.life:8000".extraConfig = '' - reverse_proxy 127.0.0.1:${toString config.services.immich.port} - ''; - globalConfig = '' - acme_dns dnspod {env.DNSPOD_API_TOKEN} - ''; - }; - - networking.firewall.allowedTCPPorts = [ 8000 ]; - - systemd.services.caddy = { - serviceConfig = { - EnvironmentFile = config.sops.secrets.dnspod_dns_token.path; - }; - }; - time.timeZone = "Asia/Shanghai"; fileSystems."/" = { diff --git a/machines/weilite/secrets.yaml b/machines/weilite/secrets.yaml index 0394a80..0fc2813 100644 --- a/machines/weilite/secrets.yaml +++ b/machines/weilite/secrets.yaml @@ -1,9 +1,16 @@ -cloudflare_dns_token: ENC[AES256_GCM,data:m4euSkxxJmiMk9UPyeni/hwpl1W9A4MM0ssg71eOBsX4fFyG39NJeKbNTddW7omBx3gKJtnrRuDdOj5wpg==,iv:eRVzsGwz8hWC42jM+VeSUWCS9Gi8VGSY8Fyh+En0jEI=,tag:NNE8VeNQ8kp9KyziVokyuQ==,type:str] -dnspod_dns_token: ENC[AES256_GCM,data:uZfr3g103amywxh3NMU+AkwuYb61svzyavvQ4rxJijIMIbfPvERrVNcyivoOrFWYXHpPWkhZFdU=,iv:mArVAcebW9i+u26GmQmfmJTsFkR4ZRMIisTqjpMYan8=,tag:Zsmv1Wzfi3+PHigjReToHQ==,type:str] +caddy: + cf_dns_token: ENC[AES256_GCM,data:7PvP3oYMZ3dAeWaJNiuvEweUf3psDhyu90FT6cP0/AIOa0E40sdIRQ==,iv:IIYnZ35xAm9JJa14oHJi+ddI0u7Pgc4MfPLnKT4IlPc=,tag:V1PGZpaVzdN2cLpktbvTnA==,type:str] + dnspod_dns_token: ENC[AES256_GCM,data:ATed7RqLu1u06B61Irhd4SCzjK/Z823ygAgzROsNixZ2rExpB/Xo,iv:L121CGA+iZhn9V6mG2qEu3FI91/s7JO3cVTAwmAeqGw=,tag:l/7MXMZNqgFBwgCCMeZR2A==,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] +transmission: + rpc-password: ENC[AES256_GCM,data:4dumy0hygGOuwU3ANky3xEKRDRBAJWE=,iv:HVV2J+F8HndHZNsMD2YmkWrJOzk5JIapGd0SuQP8VqU=,tag:xqp5pxh5cYYogA4alrmIfg==,type:str] +sonarr: + api-key: ENC[AES256_GCM,data:/CkApTCLQy8TLHGKSM1saacNi9uQDswAjshRSLJk1hg=,iv:PNX4BZLx7krs12lxgORMSarnt0c/ga8yPtoLSzbQ+sY=,tag:V1pp9OCtX5/5fbwLBMGlOQ==,type:str] +radarr: + api-key: ENC[AES256_GCM,data:AeJArngvgmqnxk2g13QjMa6XS893B+3ZdX2K8OqXRQg=,iv:NrQf3yyqRpHMeWQ3bpPH4fUDdo/x2uB6pQCq0ZrFP5c=,tag:Yj2PSy6zRfe8anW0RGuZAQ==,type:str] sops: kms: [] gcp_kms: [] @@ -28,8 +35,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: "2025-02-11T08:45:49Z" + mac: ENC[AES256_GCM,data:iObzkfSxKET1kE8yQbSxffG1qDO95SWfIRSdwbYcwP4mHOrl5sOtlGEjexVaLl7uKa0SMCK6BghbMr4EdLatiOmngsAzr8bxe/GsPZiCze04nr0VbKBgHxKr74gT8d14dwV+Y+np/5fgRZea7zxzJ4YaVfeUOG9PBsa7L6RWbx0=,iv:LMM096xLa5cOiLVTiFO20jBUaK1Uw4aOqsz7eH9u9vc=,tag:C1fPHN9KFbydcy1lRAhGvQ==,type:str] pgp: [] unencrypted_suffix: _unencrypted - version: 3.9.1 + version: 3.9.2 diff --git a/machines/weilite/services/caddy.nix b/machines/weilite/services/caddy.nix new file mode 100644 index 0000000..f93efe6 --- /dev/null +++ b/machines/weilite/services/caddy.nix @@ -0,0 +1,63 @@ +{ config, pkgs, ... }: +{ + sops = { + secrets = { + "caddy/cf_dns_token" = { + owner = "caddy"; + mode = "400"; + }; + "caddy/dnspod_dns_token" = { + owner = "caddy"; + mode = "400"; + }; + }; + templates."caddy.env".content = '' + CF_API_TOKEN=${config.sops.placeholder."caddy/cf_dns_token"} + DNSPOD_API_TOKEN=${config.sops.placeholder."caddy/dnspod_dns_token"} + ''; + }; + + services.caddy = + let + acmeCF = "tls { + dns cloudflare {env.CF_API_TOKEN} + }"; + acmeDnspod = "tls { + dns dnspod {env.DNSPOD_API_TOKEN} + }"; + in + { + enable = true; + package = pkgs.caddy.withPlugins { + plugins = [ + "github.com/caddy-dns/cloudflare@v0.0.0-20240703190432-89f16b99c18e" + "github.com/caddy-dns/dnspod@v0.0.4" + ]; + hash = "sha256-9DZ58u/Y17njwQKvCZNys8DrCoRNsHQSBD2hV2cm8uU="; + }; + virtualHosts."derper00.namely.icu:8443".extraConfig = '' + ${acmeDnspod} + reverse_proxy 127.0.0.1:${toString config.services.tailscale.derper.port} + ''; + # API Token must be added in systemd environment file + virtualHosts."immich.xinyang.life:8000".extraConfig = '' + ${acmeDnspod} + reverse_proxy 127.0.0.1:${toString config.services.immich.port} + ''; + virtualHosts."immich.xiny.li:8443".extraConfig = '' + ${acmeCF} + reverse_proxy 127.0.0.1:${toString config.services.immich.port} + ''; + }; + + networking.firewall.allowedTCPPorts = [ + 8000 + 8443 + ]; + + systemd.services.caddy = { + serviceConfig = { + EnvironmentFile = config.sops.templates."caddy.env".path; + }; + }; +} diff --git a/machines/weilite/services/default.nix b/machines/weilite/services/default.nix index 0a6e4ca..649ca08 100644 --- a/machines/weilite/services/default.nix +++ b/machines/weilite/services/default.nix @@ -1,8 +1,11 @@ { imports = [ + ./caddy.nix ./ocis.nix ./restic.nix ./media-download.nix ./immich.nix + ./jellyfin.nix + ./transmission.nix ]; } diff --git a/machines/weilite/services/immich.nix b/machines/weilite/services/immich.nix index 33a98d3..262f187 100644 --- a/machines/weilite/services/immich.nix +++ b/machines/weilite/services/immich.nix @@ -3,11 +3,14 @@ ... }: let + inherit (config.my-lib.settings) idpUrl; + user = config.systemd.services.immich-server.serviceConfig.User; + immichUrl = "immich.xiny.li:8443"; jsonSettings = { oauth = { enabled = true; - issuerUrl = "https://auth.xinyang.life/oauth2/openid/immich/"; + issuerUrl = "https://${idpUrl}/oauth2/openid/immich/"; clientId = "immich"; clientSecret = config.sops.placeholder."immich/oauth_client_secret"; scope = "openid email profile"; @@ -16,7 +19,7 @@ let buttonText = "Login with Kanidm"; autoLaunch = true; mobileOverrideEnabled = true; - mobileRedirectUri = "https://immich.xinyang.life:8000/api/oauth/mobile-redirect/"; + mobileRedirectUri = "https://${immichUrl}/api/oauth/mobile-redirect/"; }; passwordLogin = { enabled = false; @@ -46,7 +49,6 @@ in services.immich = { enable = true; - mediaLocation = "/mnt/XinPhotos/immich"; host = "127.0.0.1"; port = 3001; openFirewall = true; diff --git a/machines/weilite/services/jellyfin.nix b/machines/weilite/services/jellyfin.nix new file mode 100644 index 0000000..025386b --- /dev/null +++ b/machines/weilite/services/jellyfin.nix @@ -0,0 +1,25 @@ +{ config, pkgs, ... }: +let + cfg = config.services.jellyfin; +in +{ + services.jellyfin.enable = true; + + systemd.services.jellyfin.serviceConfig = { + BindReadOnlyPaths = [ + "/mnt/nixos/media:${cfg.dataDir}/media" + ]; + }; + + environment.systemPackages = with pkgs; [ + jellyfin + jellyfin-web + jellyfin-ffmpeg + ]; + services.caddy.virtualHosts."https://weilite.coho-tet.ts.net:8920".extraConfig = '' + reverse_proxy 127.0.0.1:8096 + ''; + networking.firewall.allowedTCPPorts = [ 8920 ]; # allow on lan + users.users.jellyfin.extraGroups = [ "render" ]; + users.groups.media.members = [ cfg.user ]; +} diff --git a/machines/weilite/services/media-download.nix b/machines/weilite/services/media-download.nix index 6f22744..97c7110 100644 --- a/machines/weilite/services/media-download.nix +++ b/machines/weilite/services/media-download.nix @@ -1,15 +1,16 @@ -{ pkgs, ... }: +{ config, pkgs, ... }: +let + inherit (config.my-lib.settings) + internalDomain + ; +in { + sops.secrets = { + "sonarr/api-key" = { }; + "radarr/api-key" = { }; + }; services.jackett = { enable = true; - package = pkgs.jackett.overrideAttrs { - src = pkgs.fetchFromGitHub { - owner = "jackett"; - repo = "jackett"; - rev = "v0.22.998"; - hash = "sha256-CZvgDWxxIAOTkodgmFNuT3VDW6Ln4Mz+Ki7m91f0BgE="; - }; - }; openFirewall = false; }; @@ -27,4 +28,25 @@ services.radarr = { enable = true; }; + + services.prometheus.exporters.exportarr-sonarr = { + enable = true; + url = "http://127.0.0.1:8989"; + apiKeyFile = config.sops.secrets."sonarr/api-key".path; + listenAddress = "weilite.${internalDomain}"; + port = 21560; + }; + + services.prometheus.exporters.exportarr-radarr = { + enable = true; + url = "http://127.0.0.1:7878"; + apiKeyFile = config.sops.secrets."radarr/api-key".path; + listenAddress = "weilite.${internalDomain}"; + port = 21561; + }; + + users.groups.media.members = [ + config.services.sonarr.user + config.services.radarr.user + ]; } diff --git a/machines/weilite/services/restic.nix b/machines/weilite/services/restic.nix index f62786e..730266c 100644 --- a/machines/weilite/services/restic.nix +++ b/machines/weilite/services/restic.nix @@ -34,7 +34,6 @@ in services.restic.backups = builtins.listToAttrs [ (mkPrune "xin" "calcite") - (mkPrune "xin" "massicot") (mkPrune "xin" "biotite") (mkPrune "xin" "thorite") ]; @@ -42,6 +41,9 @@ in networking.firewall.allowedTCPPorts = [ 8443 ]; services.caddy.virtualHosts."https://backup.xinyang.life:8443".extraConfig = '' + tls { + dns dnspod {env.DNSPOD_API_TOKEN} + } reverse_proxy ${config.services.restic.server.listenAddress} ''; } diff --git a/machines/weilite/services/transmission.nix b/machines/weilite/services/transmission.nix new file mode 100644 index 0000000..58b198c --- /dev/null +++ b/machines/weilite/services/transmission.nix @@ -0,0 +1,98 @@ +{ + config, + pkgs, + lib, + ... +}: +let + cfg = config.services.transmission; + inherit (config.my-lib.settings) transmissionExporterUrl; +in +{ + sops.secrets = { + "transmission/rpc-password" = { }; + }; + + sops.templates."transmission-cred.json" = { + content = builtins.toJSON { + rpc-password = config.sops.placeholder."transmission/rpc-password"; + }; + }; + + sops.templates."transmission-cred.env" = { + content = '' + TRANSMISSION_PASSWORD=${config.sops.placeholder."transmission/rpc-password"} + ''; + }; + + services.transmission = { + enable = true; + package = pkgs.transmission_4; + openPeerPorts = true; + credentialsFile = config.sops.templates."transmission-cred.json".path; + settings = { + download-dir = "/mnt/nixos/media"; + incomplete-dir = "/mnt/nixos/transmission/incomplete"; + alt-speed-down = 40960; + alt-speed-enabled = true; + alt-speed-time-begin = 60; + alt-speed-time-day = 127; + alt-speed-time-enabled = true; + alt-speed-time-end = 420; + alt-speed-up = 4096; + bind-address-ipv4 = "0.0.0.0"; + bind-address-ipv6 = "::"; + download-queue-enabled = true; + download-queue-size = 10; + incomplete-dir-enabled = true; + lpd-enabled = false; + message-level = 4; + peer-congestion-algorithm = ""; + peer-id-ttl-hours = 6; + peer-limit-global = 200; + peer-limit-per-torrent = 50; + peer-port = 51413; + peer-socket-tos = "cs1"; + pex-enabled = true; + preallocation = 1; + prefetch-enabled = true; + queue-stalled-enabled = true; + queue-stalled-minutes = 30; + rename-partial-files = true; + rpc-bind-address = "127.0.0.1"; + rpc-enabled = true; + rpc-authentication-required = true; + rpc-port = 9092; + rpc-username = "xin"; + rpc-whitelist = "127.0.0.1"; + speed-limit-down = 20480; + speed-limit-down-enabled = true; + speed-limit-up = 3072; + speed-limit-up-enabled = true; + start-added-torrents = true; + watch-dir-enabled = false; + }; + }; + services.caddy.virtualHosts."https://weilite.coho-tet.ts.net:9091".extraConfig = '' + reverse_proxy 127.0.0.1:${toString cfg.settings.rpc-port} + ''; + + systemd.services.prometheus-transmission-exporter = { + enable = true; + wantedBy = [ "transmission.service" ]; + environment = { + WEB_ADDR = transmissionExporterUrl; + TRANSMISSION_ADDR = "http://127.0.0.1:${toString cfg.settings.rpc-port}"; + TRANSMISSION_USERNAME = "xin"; + }; + after = [ "tailscaled.service" ]; + wants = [ "tailscaled.service" ]; + serviceConfig = { + ExecStart = "${lib.getExe pkgs.transmission-exporter}"; + EnvironmentFile = config.sops.templates."transmission-cred.env".path; + }; + }; + + networking.firewall.allowedTCPPorts = [ 9091 ]; # allow on lan + users.groups.media.members = [ cfg.user ]; +} diff --git a/modules/home-manager/gui/niri.nix b/modules/home-manager/gui/niri.nix index d26bf93..527e9e6 100644 --- a/modules/home-manager/gui/niri.nix +++ b/modules/home-manager/gui/niri.nix @@ -34,10 +34,6 @@ in }; config = mkIf cfg.enable { - home.packages = with pkgs; [ - cosmic-files - ]; - systemd.user.services.xwayland-satellite = { Install = { WantedBy = [ "graphical-session.target" ]; diff --git a/modules/home-manager/gui/themes.nix b/modules/home-manager/gui/themes.nix index ad0de1c..6278692 100644 --- a/modules/home-manager/gui/themes.nix +++ b/modules/home-manager/gui/themes.nix @@ -13,6 +13,10 @@ name = "Catppuccin-GTK-Dark"; package = pkgs.magnetic-catppuccin-gtk; }; + iconTheme = { + name = "Qogir"; + package = pkgs.qogir-icon-theme; + }; gtk2.configLocation = "${config.xdg.configHome}/gtk-2.0/gtkrc"; }; }; diff --git a/modules/home-manager/gui/waybar.nix b/modules/home-manager/gui/waybar.nix index 3890a00..66b9ecb 100644 --- a/modules/home-manager/gui/waybar.nix +++ b/modules/home-manager/gui/waybar.nix @@ -44,8 +44,6 @@ in modules-right = [ "network#speed" "custom/separator" - "network#if" - "custom/separator" "pulseaudio" "custom/separator" "memory" @@ -121,22 +119,6 @@ in format = " {percentage}%"; }; - "network#if" = { - format = "{ifname}"; - format-disconnected = "󰌙"; - format-ethernet = "󰌘"; - format-linked = "{ifname} (No IP) 󰈁"; - format-wifi = "{icon}"; - format-icons = [ - "󰤯" - "󰤟" - "󰤢" - "󰤥" - "󰤨" - ]; - interval = 10; - }; - "network#speed" = { format = "{ifname}"; format-disconnected = "󰌙"; diff --git a/modules/nixos/common-settings/auth.nix b/modules/nixos/common-settings/auth.nix index 1cd85ec..2fae197 100644 --- a/modules/nixos/common-settings/auth.nix +++ b/modules/nixos/common-settings/auth.nix @@ -11,6 +11,8 @@ let mkEnableOption ; + inherit (config.my-lib.settings) idpUrl; + cfg = config.commonSettings.auth; in { @@ -22,7 +24,7 @@ in services.kanidm = { enableClient = true; clientSettings = { - uri = "https://auth.xinyang.life"; + uri = "https://${idpUrl}"; }; enablePam = true; unixSettings = { @@ -45,11 +47,11 @@ in environment.etc."ssh/auth" = { mode = "0555"; text = '' - #!${pkgs.stdenv.shell} + #!/bin/sh ${pkgs.kanidm}/bin/kanidm_ssh_authorizedkeys $1 ''; }; - users.groups.wheel.members = [ "xin@auth.xinyang.life" ]; + users.groups.wheel.members = [ "xin@${idpUrl}" ]; users.groups.kanidm-ssh-runner = { }; users.users.kanidm-ssh-runner = { isSystemUser = true; diff --git a/modules/nixos/common-settings/comin.nix b/modules/nixos/common-settings/comin.nix new file mode 100644 index 0000000..70a23ee --- /dev/null +++ b/modules/nixos/common-settings/comin.nix @@ -0,0 +1,32 @@ +{ + config, + lib, + ... +}: +let + inherit (lib) + mkEnableOption + mkIf + ; + + cfg = config.commonSettings.comin; +in +{ + options.commonSettings.comin = { + enable = mkEnableOption "auto updater with comin"; + }; + + config = { + services.comin = mkIf cfg.enable { + enable = true; + remotes = [ + { + name = "origin"; + url = "https://github.com/xinyangli/nixos-config.git"; + branches.main.name = "deploy-comin"; + } + ]; + hostname = config.networking.hostName; + }; + }; +} diff --git a/modules/nixos/common-settings/nix-conf.nix b/modules/nixos/common-settings/nix-conf.nix index 1af1419..f6a7684 100644 --- a/modules/nixos/common-settings/nix-conf.nix +++ b/modules/nixos/common-settings/nix-conf.nix @@ -41,6 +41,8 @@ in nix.optimise.automatic = true; + nix.channel.enable = false; + nix.settings = { experimental-features = [ "nix-command" diff --git a/modules/nixos/default.nix b/modules/nixos/default.nix index d2f210d..33929ce 100644 --- a/modules/nixos/default.nix +++ b/modules/nixos/default.nix @@ -2,6 +2,7 @@ imports = [ ./common-settings/auth.nix ./common-settings/autoupgrade.nix + ./common-settings/comin.nix ./common-settings/nix-conf.nix ./common-settings/proxy-server.nix ./common-settings/mainland.nix diff --git a/modules/nixos/monitor/default.nix b/modules/nixos/monitor/default.nix index 71ec05e..5b9d31a 100644 --- a/modules/nixos/monitor/default.nix +++ b/modules/nixos/monitor/default.nix @@ -120,11 +120,11 @@ in 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}} - {{$k}}={{$v}}{{end}} - + {{range .alerts}}{{ if eq .status "resolved" }}✅{{ else }}{{ if eq .status "firing" }}🔥{{end}}{{end}}{{.labels.alertname}} + {{.annotations.summary}} {{end}}''}"; send_resolved = true; + max_alerts = 5; } ]; } @@ -158,7 +158,7 @@ in severity = "critical"; }; annotations = { - summary = "Job {{ $labels.job }} down for 1m."; + summary = "Instance {{ $labels.instance }} of {{ $labels.job }} is down."; }; } ]; diff --git a/modules/nixos/monitor/exporters.nix b/modules/nixos/monitor/exporters.nix index 56750ef..5e75975 100644 --- a/modules/nixos/monitor/exporters.nix +++ b/modules/nixos/monitor/exporters.nix @@ -5,17 +5,41 @@ ... }: let - inherit (lib) mkIf concatStringsSep; + inherit (lib) mkIf getExe; inherit (config.my-lib.settings) prometheusCollectors; cfg = config.custom.prometheus.exporters; in { config = { - systemd.services.tailscaled.after = + systemd.services.tailscaled.before = (lib.optional cfg.node.enable "prometheus-node-exporters.service") ++ (lib.optional cfg.blackbox.enable "prometheus-blackbox-exporters.service") ++ (lib.optional config.services.caddy.enable "caddy.service"); + systemd.services.tailscaled.serviceConfig.ExecStartPost = + pkgs.writers.writePython3 "tailscale-wait-online" + { + flakeIgnore = [ + "E401" # import on one line + "E501" # line length limit + ]; + } + '' + import subprocess, json, time + + for _ in range(30): + status = json.loads( + subprocess.run( + ["${getExe config.services.tailscale.package}", "status", "--peers=false", "--json"], capture_output=True + ).stdout + )["Self"]["Online"] + if status: + exit(0) + time.sleep(1) + + exit(1) + ''; + services.prometheus.exporters.node = mkIf cfg.node.enable { enable = true; enabledCollectors = [ diff --git a/modules/nixos/monitor/grafana.nix b/modules/nixos/monitor/grafana.nix index 9692fb5..7a72603 100644 --- a/modules/nixos/monitor/grafana.nix +++ b/modules/nixos/monitor/grafana.nix @@ -22,9 +22,9 @@ in 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://${idpUrl}/ui/oauth2"; + token_url = "https://${idpUrl}/oauth2/token"; + api_url = "https://${idpUrl}/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..d1197d9 100644 --- a/modules/nixos/monitor/loki.nix +++ b/modules/nixos/monitor/loki.nix @@ -15,6 +15,7 @@ let ; inherit (config.my-lib.settings) alertmanagerPort + internalDomain ; cfg = config.custom.monitoring; lokiPort = 3100; @@ -94,16 +95,17 @@ in rulerFile = pkgs.writeText "ruler.yml" (builtins.toJSON rulerConfig); in mkIf cfg.loki.enable { + systemd.services.loki.serviceConfig.After = "tailscaled.service"; services.loki = { enable = true; configuration = { auth_enabled = false; - server.http_listen_address = "${config.networking.hostName}.coho-tet.ts.net"; + server.http_listen_address = "${config.networking.hostName}.${internalDomain}"; server.http_listen_port = lokiPort; common = { ring = { - instance_addr = "${config.networking.hostName}.coho-tet.ts.net"; + instance_addr = "${config.networking.hostName}.${internalDomain}"; kvstore.store = "inmemory"; }; replication_factor = 1; @@ -160,7 +162,7 @@ in configuration = { server = { - http_listen_address = "${config.networking.hostName}.coho-tet.ts.net"; + http_listen_address = "${config.networking.hostName}.${internalDomain}"; http_listen_port = 28183; grpc_listen_port = 0; }; @@ -169,7 +171,7 @@ in clients = [ { - url = "http://thorite.coho-tet.ts.net:${toString lokiPort}/loki/api/v1/push"; + url = "http://thorite.${internalDomain}:${toString lokiPort}/loki/api/v1/push"; } ]; diff --git a/overlays/add-pkgs.nix b/overlays/add-pkgs.nix index f1b214e..ac76b8e 100644 --- a/overlays/add-pkgs.nix +++ b/overlays/add-pkgs.nix @@ -9,4 +9,6 @@ "idbloader.img" ]; }; + + transmission-exporter = prev.callPackage ./pkgs/transmission-exporter.nix { }; }) diff --git a/overlays/my-lib/prometheus.nix b/overlays/my-lib/prometheus.nix index c79f131..c394e4e 100644 --- a/overlays/my-lib/prometheus.nix +++ b/overlays/my-lib/prometheus.nix @@ -1,6 +1,9 @@ let mkFunction = f: (targets: (map f targets)); mkPort = port: if isNull port then "" else ":${toString port}"; + + # get text before "." in the url + subdomain = url: builtins.elemAt (builtins.elemAt (builtins.split "([a-zA-Z0-9]+)\..*" url) 1) 0; in { mkScrapes = mkFunction ( @@ -129,8 +132,7 @@ in severity = "critical"; }; annotations = { - summary = "Systemd has failed units on {{ $labels.instance }}"; - description = "There are {{ $value }} failed units on {{ $labels.instance }}. Immediate attention required!"; + summary = "{{ $labels.job }} failed on {{ $labels.instance }}."; }; } { @@ -141,7 +143,7 @@ in severity = "warning"; }; annotations = { - summary = "High load average detected on {{ $labels.instance }}"; + summary = "High load average on {{ $labels.instance }}."; description = "The 1-minute load average ({{ $value }}) exceeds 80% the number of CPUs."; }; } @@ -164,7 +166,7 @@ in severity = "warning"; }; annotations = { - summary = "High disk usage on {{ $labels.instance }}"; + summary = "Disk usage exceeeds 85% on {{ $labels.instance }}"; }; } { @@ -177,7 +179,6 @@ in }; 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"; }; } { @@ -188,8 +189,7 @@ in severity = "warning"; }; annotations = { - summary = "High swap usage on {{ $labels.instance }}"; - description = "Swap usage is above 80% for 5 minutes\n Current value: {{ $value }}%"; + summary = "Swap usage above 80% on {{ $labels.instance }}"; }; } { @@ -228,7 +228,7 @@ in ... }: { - job_name = "blackbox(${hostAddress})"; + job_name = "blackbox(${subdomain hostAddress})"; scrape_interval = "1m"; metrics_path = "/probe"; params = { @@ -268,14 +268,14 @@ in inherit name; rules = [ { - alert = "ProbeError"; - expr = "probe_success != 1"; + alert = "ProbeToError"; + expr = "sum by(instance) (probe_success != 1) > 0"; for = "3m"; labels = { severity = "critical"; }; annotations = { - summary = "Probing {{ $labels.instance }} from {{ $labels.from }} failed"; + summary = "Probing {{ $labels.instance }} failed"; }; } { diff --git a/overlays/my-lib/settings.nix b/overlays/my-lib/settings.nix index 46bdb04..649640f 100644 --- a/overlays/my-lib/settings.nix +++ b/overlays/my-lib/settings.nix @@ -1,7 +1,7 @@ { settings = { alertmanagerPort = 9093; - idpUrl = "https://auth.xinyang.life"; + idpUrl = "auth.xiny.li"; gotosocialUrl = "https://gts.xiny.li"; minifluxUrl = "https://rss.xiny.li"; hedgedocDomain = "docs.xiny.li"; @@ -13,8 +13,12 @@ synapseUrl = "https://xiny.li"; synapseDelegateUrl = "https://synapse.xiny.li"; + transmissionExporterUrl = "weilite.coho-tet.ts.net:19091"; + prometheusCollectors = [ "thorite.coho-tet.ts.net" ]; + + internalDomain = "coho-tet.ts.net"; }; } diff --git a/overlays/pkgs/transmission-exporter.nix b/overlays/pkgs/transmission-exporter.nix new file mode 100644 index 0000000..b5e70b8 --- /dev/null +++ b/overlays/pkgs/transmission-exporter.nix @@ -0,0 +1,32 @@ +{ + lib, + fetchFromGitHub, + buildGoModule, +}: +buildGoModule rec { + pname = "transmission-exporter"; + version = "0-unstable-2024-10-09"; + rev = "v${version}"; + + src = fetchFromGitHub { + rev = "a7872aa2975c7a95af680c51198f4a363e226c8f"; + owner = "metalmatze"; + repo = "transmission-exporter"; + sha256 = "sha256-Ky7eCvC1AqHheqGGOGBNKbtVgg4Y8hDG67gCVlpUwZo="; + }; + + vendorHash = "sha256-YhmfrM5iAK0zWcUM7LmbgFnH+k2M/tE+f/QQIQmQlZs="; + + ldflags = [ + "-X github.com/prometheus/common/version.Version=${version}" + "-X github.com/prometheus/common/version.Revision=${rev}" + ]; + + meta = { + description = "Prometheus exporter for Transmission torrent client."; + homepage = "https://github.com/pborzenkov/transmission-exporter"; + mainProgram = "transmission-exporter"; + license = [ lib.licenses.mit ]; + maintainers = [ lib.maintainers.xinyangli ]; + }; +}