From 53d3901e9a5e9980840d28e81e39357f6c9e629f Mon Sep 17 00:00:00 2001 From: Ryan Yin Date: Sun, 24 Mar 2024 22:36:21 +0800 Subject: [PATCH 1/2] feat: dae - arm64 microvm --- flake.lock | 707 +++++++++++++----- flake.nix | 13 +- hosts/12kingdoms-suzu/default.nix | 12 +- hosts/12kingdoms-suzu/microvm-host.nix | 92 +++ hosts/12kingdoms-suzu/microvm.md | 37 + hosts/12kingdoms-suzu/networking.nix | 49 ++ hosts/12kingdoms-suzu/router/README.md | 48 ++ hosts/12kingdoms-suzu/router/config.dae | 320 ++++++++ hosts/12kingdoms-suzu/router/dae.nix | 56 ++ hosts/12kingdoms-suzu/router/default.nix | 3 + hosts/12kingdoms-suzu/router/networking.nix | 184 +++++ outputs/aarch64-linux/src/12kingdoms-suzu.nix | 15 +- vars/networking.nix | 4 + 13 files changed, 1354 insertions(+), 186 deletions(-) create mode 100644 hosts/12kingdoms-suzu/microvm-host.nix create mode 100644 hosts/12kingdoms-suzu/microvm.md create mode 100644 hosts/12kingdoms-suzu/networking.nix create mode 100644 hosts/12kingdoms-suzu/router/README.md create mode 100644 hosts/12kingdoms-suzu/router/config.dae create mode 100644 hosts/12kingdoms-suzu/router/dae.nix create mode 100644 hosts/12kingdoms-suzu/router/default.nix create mode 100644 hosts/12kingdoms-suzu/router/networking.nix diff --git a/flake.lock b/flake.lock index 345a5b87..689ae2e4 100644 --- a/flake.lock +++ b/flake.lock @@ -1,25 +1,50 @@ { "nodes": { "agenix": { + "inputs": { + "agenix": "agenix_2", + "crane": "crane", + "flake-utils": "flake-utils", + "nixpkgs": [ + "nixpkgs" + ], + "rust-overlay": "rust-overlay" + }, + "locked": { + "lastModified": 1709831932, + "narHash": "sha256-WsP8rOFa/SqYNbVtYJ/l2mWWOgyDTJFbITMV8tv0biI=", + "owner": "ryan4yin", + "repo": "ragenix", + "rev": "06de099ef02840ec463419f12de73729d458e1eb", + "type": "github" + }, + "original": { + "owner": "ryan4yin", + "repo": "ragenix", + "type": "github" + } + }, + "agenix_2": { "inputs": { "darwin": "darwin", "home-manager": "home-manager", "nixpkgs": [ + "agenix", "nixpkgs" - ] + ], + "systems": "systems" }, "locked": { - "lastModified": 1703089996, - "narHash": "sha256-ipqShkBmHKC9ft1ZAsA6aeKps32k7+XZSPwfxeHLsAU=", + "lastModified": 1707830867, + "narHash": "sha256-PAdwm5QqdlwIqGrfzzvzZubM+FXtilekQ/FA0cI49/o=", "owner": "ryantm", "repo": "agenix", - "rev": "564595d0ad4be7277e07fa63b5a991b3c645655d", + "rev": "8cb01a0e717311680e0cbca06a76cbceba6f3ed6", "type": "github" }, "original": { "owner": "ryantm", "repo": "agenix", - "rev": "564595d0ad4be7277e07fa63b5a991b3c645655d", "type": "github" } }, @@ -63,9 +88,9 @@ }, "attic": { "inputs": { - "crane": "crane", + "crane": "crane_2", "flake-compat": "flake-compat", - "flake-utils": "flake-utils", + "flake-utils": "flake-utils_2", "nixpkgs": "nixpkgs", "nixpkgs-stable": "nixpkgs-stable" }, @@ -84,6 +109,27 @@ } }, "crane": { + "inputs": { + "nixpkgs": [ + "agenix", + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1711150329, + "narHash": "sha256-Mcejz4bU3a3ZVgGaCk6B2ktk+DIdMN/LzIbKJNzZXPA=", + "owner": "ipetkov", + "repo": "crane", + "rev": "270c7d60d37b769a31bb04d61bc73cc2da1b3f6f", + "type": "github" + }, + "original": { + "owner": "ipetkov", + "repo": "crane", + "type": "github" + } + }, + "crane_2": { "inputs": { "nixpkgs": [ "attic", @@ -104,7 +150,7 @@ "type": "github" } }, - "crane_2": { + "crane_3": { "inputs": { "flake-compat": [ "lanzaboote", @@ -139,22 +185,23 @@ }, "daeuniverse": { "inputs": { + "devshell": "devshell", "flake-parts": "flake-parts_2", - "nixpkgs": "nixpkgs_2", + "nix-eval-jobs": "nix-eval-jobs", + "nixpkgs": "nixpkgs_4", "pnpm2nix": "pnpm2nix", "pre-commit-hooks": "pre-commit-hooks" }, "locked": { - "lastModified": 1709777987, - "narHash": "sha256-rGjM51lS7KumEvJlWGC2ufgBKVCG5DM/3naYWhMv23Q=", + "lastModified": 1711200264, + "narHash": "sha256-0ysbxz9wbRnHWYL2I5101FwDI/sMwdmwQrG+GuInVqY=", "owner": "daeuniverse", "repo": "flake.nix", - "rev": "7b867cfa5a8ee56fc20425f9c09b4feee27d5f76", + "rev": "9e021a7885ea7737337956e4ce8d553ba60bbdd0", "type": "github" }, "original": { "owner": "daeuniverse", - "ref": "exp", "repo": "flake.nix", "type": "github" } @@ -162,16 +209,17 @@ "darwin": { "inputs": { "nixpkgs": [ + "agenix", "agenix", "nixpkgs" ] }, "locked": { - "lastModified": 1673295039, - "narHash": "sha256-AsdYgE8/GPwcelGgrntlijMg4t3hLFJFCRF3tL5WVjA=", + "lastModified": 1700795494, + "narHash": "sha256-gzGLZSiOhf155FW7262kdHo2YDeugp3VuIFb4/GGng0=", "owner": "lnl7", "repo": "nix-darwin", - "rev": "87b9d090ad39b25b2400029c64825fc2a8868943", + "rev": "4b9b83d5a92e8c1fbfd8eb27eda375908c11ec4d", "type": "github" }, "original": { @@ -181,6 +229,25 @@ "type": "github" } }, + "devshell": { + "inputs": { + "flake-utils": "flake-utils_3", + "nixpkgs": "nixpkgs_2" + }, + "locked": { + "lastModified": 1711099426, + "narHash": "sha256-HzpgM/wc3aqpnHJJ2oDqPBkNsqWbW0WfWUO8lKu8nGk=", + "owner": "numtide", + "repo": "devshell", + "rev": "2d45b54ca4a183f2fdcf4b19c895b64fbf620ee8", + "type": "github" + }, + "original": { + "owner": "numtide", + "repo": "devshell", + "type": "github" + } + }, "disko": { "inputs": { "nixpkgs": [ @@ -320,6 +387,28 @@ } }, "flake-parts_3": { + "inputs": { + "nixpkgs-lib": [ + "daeuniverse", + "nix-eval-jobs", + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1701473968, + "narHash": "sha256-YcVE5emp1qQ8ieHUnxt1wCZCC3ZfAS+SRRWZ2TMda7E=", + "owner": "hercules-ci", + "repo": "flake-parts", + "rev": "34fed993f1674c8d06d58b37ce1e0fe5eebcb9f5", + "type": "github" + }, + "original": { + "owner": "hercules-ci", + "repo": "flake-parts", + "type": "github" + } + }, + "flake-parts_4": { "inputs": { "nixpkgs-lib": [ "lanzaboote", @@ -340,7 +429,7 @@ "type": "github" } }, - "flake-parts_4": { + "flake-parts_5": { "inputs": { "nixpkgs-lib": "nixpkgs-lib_2" }, @@ -359,6 +448,42 @@ } }, "flake-utils": { + "inputs": { + "systems": "systems_2" + }, + "locked": { + "lastModified": 1710146030, + "narHash": "sha256-SZ5L6eA7HJ/nmkzGG7/ISclqe6oZdOZTNoesiInkXPQ=", + "owner": "numtide", + "repo": "flake-utils", + "rev": "b1d9ab70662946ef0850d488da1c9019f3a9752a", + "type": "github" + }, + "original": { + "owner": "numtide", + "repo": "flake-utils", + "type": "github" + } + }, + "flake-utils_10": { + "inputs": { + "systems": "systems_11" + }, + "locked": { + "lastModified": 1701680307, + "narHash": "sha256-kAuep2h5ajznlPMD9rnQyffWG8EM/C73lejGofXvdM8=", + "owner": "numtide", + "repo": "flake-utils", + "rev": "4022d587cbbfd70fe950c1e2083a02621806a725", + "type": "github" + }, + "original": { + "owner": "numtide", + "repo": "flake-utils", + "type": "github" + } + }, + "flake-utils_2": { "locked": { "lastModified": 1667395993, "narHash": "sha256-nuEHfE/LcWyuSWnS8t12N1wc105Qtau+/OdUAjtQ0rA=", @@ -373,27 +498,9 @@ "type": "github" } }, - "flake-utils_2": { - "inputs": { - "systems": "systems" - }, - "locked": { - "lastModified": 1685518550, - "narHash": "sha256-o2d0KcvaXzTrPRIo0kOLV0/QXHhDQ5DTi+OxcjO8xqY=", - "owner": "numtide", - "repo": "flake-utils", - "rev": "a1720a10a6cfe8234c0e93907ffe81be440f4cef", - "type": "github" - }, - "original": { - "owner": "numtide", - "repo": "flake-utils", - "type": "github" - } - }, "flake-utils_3": { "inputs": { - "systems": "systems_2" + "systems": "systems_3" }, "locked": { "lastModified": 1701680307, @@ -414,11 +521,11 @@ "systems": "systems_4" }, "locked": { - "lastModified": 1681202837, - "narHash": "sha256-H+Rh19JDwRtpVPAWp64F+rlEtxUWBAQW28eAi3SRSzg=", + "lastModified": 1685518550, + "narHash": "sha256-o2d0KcvaXzTrPRIo0kOLV0/QXHhDQ5DTi+OxcjO8xqY=", "owner": "numtide", "repo": "flake-utils", - "rev": "cfacdce06f30d2b68473a46042957675eebb3401", + "rev": "a1720a10a6cfe8234c0e93907ffe81be440f4cef", "type": "github" }, "original": { @@ -447,7 +554,7 @@ }, "flake-utils_6": { "inputs": { - "systems": "systems_6" + "systems": "systems_7" }, "locked": { "lastModified": 1681202837, @@ -465,7 +572,25 @@ }, "flake-utils_7": { "inputs": { - "systems": "systems_7" + "systems": "systems_8" + }, + "locked": { + "lastModified": 1705309234, + "narHash": "sha256-uNRRNRKmJyCRC/8y1RqBkqWBLM034y4qN7EprSdmgyA=", + "owner": "numtide", + "repo": "flake-utils", + "rev": "1ef2e671c3b0c19053962c07dbda38332dcebf26", + "type": "github" + }, + "original": { + "owner": "numtide", + "repo": "flake-utils", + "type": "github" + } + }, + "flake-utils_8": { + "inputs": { + "systems": "systems_9" }, "locked": { "lastModified": 1701680307, @@ -481,6 +606,24 @@ "type": "github" } }, + "flake-utils_9": { + "inputs": { + "systems": "systems_10" + }, + "locked": { + "lastModified": 1681202837, + "narHash": "sha256-H+Rh19JDwRtpVPAWp64F+rlEtxUWBAQW28eAi3SRSzg=", + "owner": "numtide", + "repo": "flake-utils", + "rev": "cfacdce06f30d2b68473a46042957675eebb3401", + "type": "github" + }, + "original": { + "owner": "numtide", + "repo": "flake-utils", + "type": "github" + } + }, "gitignore": { "inputs": { "nixpkgs": [ @@ -592,16 +735,17 @@ "home-manager": { "inputs": { "nixpkgs": [ + "agenix", "agenix", "nixpkgs" ] }, "locked": { - "lastModified": 1682203081, - "narHash": "sha256-kRL4ejWDhi0zph/FpebFYhzqlOBrk0Pl3dzGEKSAlEw=", + "lastModified": 1703113217, + "narHash": "sha256-7ulcXOk63TIT2lVDSExj7XzFx09LpdSAPtvgtM7yQPE=", "owner": "nix-community", "repo": "home-manager", - "rev": "32d3e39c491e2f91152c84f8ad8b003420eab0a1", + "rev": "3bfaacf46133c037bb356193bd2f1765d9dc82c1", "type": "github" }, "original": { @@ -637,7 +781,7 @@ "nixpkgs": [ "nixpkgs" ], - "systems": "systems_3", + "systems": "systems_6", "wlroots": "wlroots", "xdph": "xdph" }, @@ -698,15 +842,15 @@ }, "lanzaboote": { "inputs": { - "crane": "crane_2", + "crane": "crane_3", "flake-compat": "flake-compat_3", - "flake-parts": "flake-parts_3", - "flake-utils": "flake-utils_4", + "flake-parts": "flake-parts_4", + "flake-utils": "flake-utils_6", "nixpkgs": [ "nixpkgs" ], "pre-commit-hooks-nix": "pre-commit-hooks-nix", - "rust-overlay": "rust-overlay" + "rust-overlay": "rust-overlay_2" }, "locked": { "lastModified": 1682802423, @@ -723,6 +867,28 @@ "type": "github" } }, + "microvm": { + "inputs": { + "flake-utils": "flake-utils_7", + "nixpkgs": [ + "nixpkgs" + ], + "spectrum": "spectrum" + }, + "locked": { + "lastModified": 1711159783, + "narHash": "sha256-nwl2Cygq7NrV9QcebJE/T/vXv7w+zLERD7ygHz0F5g8=", + "owner": "astro", + "repo": "microvm.nix", + "rev": "d31f7c7d3194c51372134832a3a2a256773c161a", + "type": "github" + }, + "original": { + "owner": "astro", + "repo": "microvm.nix", + "type": "github" + } + }, "mysecrets": { "flake": false, "locked": { @@ -760,10 +926,31 @@ "type": "github" } }, + "nix-eval-jobs": { + "inputs": { + "flake-parts": "flake-parts_3", + "nix-github-actions": "nix-github-actions", + "nixpkgs": "nixpkgs_3", + "treefmt-nix": "treefmt-nix" + }, + "locked": { + "lastModified": 1705242886, + "narHash": "sha256-TLj334vRwFtSym3m+NnKcNCnKKPNoTC/TDZL40vmOso=", + "owner": "nix-community", + "repo": "nix-eval-jobs", + "rev": "6b03a93296faf174b97546fd573c8b379f523a8d", + "type": "github" + }, + "original": { + "owner": "nix-community", + "repo": "nix-eval-jobs", + "type": "github" + } + }, "nix-gaming": { "inputs": { - "flake-parts": "flake-parts_4", - "nixpkgs": "nixpkgs_3" + "flake-parts": "flake-parts_5", + "nixpkgs": "nixpkgs_5" }, "locked": { "lastModified": 1707614138, @@ -779,6 +966,28 @@ "type": "github" } }, + "nix-github-actions": { + "inputs": { + "nixpkgs": [ + "daeuniverse", + "nix-eval-jobs", + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1701208414, + "narHash": "sha256-xrQ0FyhwTZK6BwKhahIkUVZhMNk21IEI1nUcWSONtpo=", + "owner": "nix-community", + "repo": "nix-github-actions", + "rev": "93e39cc1a087d65bcf7a132e75a650c44dd2b734", + "type": "github" + }, + "original": { + "owner": "nix-community", + "repo": "nix-github-actions", + "type": "github" + } + }, "nixlib": { "locked": { "lastModified": 1693701915, @@ -870,7 +1079,7 @@ }, "nixos-licheepi4a": { "inputs": { - "nixpkgs": "nixpkgs_4" + "nixpkgs": "nixpkgs_6" }, "locked": { "lastModified": 1709742425, @@ -888,17 +1097,17 @@ }, "nixos-rk3588": { "inputs": { - "flake-utils": "flake-utils_5", + "flake-utils": "flake-utils_8", "nixos-generators": "nixos-generators_2", - "nixpkgs": "nixpkgs_5", + "nixpkgs": "nixpkgs_7", "pre-commit-hooks": "pre-commit-hooks_2" }, "locked": { - "lastModified": 1711256697, - "narHash": "sha256-R/0CBfv0LOUeITUEQp9UgF/jtt6kgp82DjFELSGa1rY=", + "lastModified": 1711336411, + "narHash": "sha256-0JZPbUB6LjcRilXhZdtsVHtb0V9Vy1bmVjVoeQAPJhQ=", "owner": "ryan4yin", "repo": "nixos-rk3588", - "rev": "c6628c5b849adc9c2ddda3767db30e6d29adc222", + "rev": "349f39dcaafeb41250544bcc066db8668a7762ce", "type": "github" }, "original": { @@ -1071,101 +1280,7 @@ "type": "github" } }, - "nixpkgs_2": { - "locked": { - "lastModified": 1706732774, - "narHash": "sha256-hqJlyJk4MRpcItGYMF+3uHe8HvxNETWvlGtLuVpqLU0=", - "owner": "NixOS", - "repo": "nixpkgs", - "rev": "b8b232ae7b8b144397fdb12d20f592e5e7c1a64d", - "type": "github" - }, - "original": { - "owner": "NixOS", - "ref": "nixos-unstable", - "repo": "nixpkgs", - "type": "github" - } - }, - "nixpkgs_3": { - "locked": { - "lastModified": 1707451808, - "narHash": "sha256-UwDBUNHNRsYKFJzyTMVMTF5qS4xeJlWoeyJf+6vvamU=", - "owner": "NixOS", - "repo": "nixpkgs", - "rev": "442d407992384ed9c0e6d352de75b69079904e4e", - "type": "github" - }, - "original": { - "owner": "NixOS", - "ref": "nixpkgs-unstable", - "repo": "nixpkgs", - "type": "github" - } - }, - "nixpkgs_4": { - "locked": { - "lastModified": 1691280485, - "narHash": "sha256-/8Ct9092OC1TTNzHgbcE9ejQdS2QxZYGqrWXEwUxdtQ=", - "owner": "nixos", - "repo": "nixpkgs", - "rev": "240472b7e47a641e9e7675f58b64d3626ca7824d", - "type": "github" - }, - "original": { - "owner": "nixos", - "ref": "nixos-23.05-small", - "repo": "nixpkgs", - "type": "github" - } - }, - "nixpkgs_5": { - "locked": { - "lastModified": 1709309926, - "narHash": "sha256-VZFBtXGVD9LWTecGi6eXrE0hJ/mVB3zGUlHImUs2Qak=", - "owner": "NixOS", - "repo": "nixpkgs", - "rev": "79baff8812a0d68e24a836df0a364c678089e2c7", - "type": "github" - }, - "original": { - "owner": "NixOS", - "ref": "nixos-23.11", - "repo": "nixpkgs", - "type": "github" - } - }, - "nixpkgs_6": { - "locked": { - "lastModified": 1707956935, - "narHash": "sha256-ZL2TrjVsiFNKOYwYQozpbvQSwvtV/3Me7Zwhmdsfyu4=", - "owner": "nixos", - "repo": "nixpkgs", - "rev": "a4d4fe8c5002202493e87ec8dbc91335ff55552c", - "type": "github" - }, - "original": { - "owner": "nixos", - "ref": "nixos-unstable", - "repo": "nixpkgs", - "type": "github" - } - }, - "nixpkgs_7": { - "locked": { - "lastModified": 1701436327, - "narHash": "sha256-tRHbnoNI8SIM5O5xuxOmtSLnswEByzmnQcGGyNRjxsE=", - "rev": "91050ea1e57e50388fa87a3302ba12d188ef723a", - "revCount": 555097, - "type": "tarball", - "url": "https://api.flakehub.com/f/pinned/NixOS/nixpkgs/0.1.555097%2Brev-91050ea1e57e50388fa87a3302ba12d188ef723a/018c3450-2363-7c34-883b-4ba70b1eb7ae/source.tar.gz" - }, - "original": { - "type": "tarball", - "url": "https://flakehub.com/f/NixOS/nixpkgs/0.1.%2A.tar.gz" - } - }, - "nixpkgs_8": { + "nixpkgs_10": { "locked": { "lastModified": 1702921762, "narHash": "sha256-O/rP7gulApQAB47u6szEd8Pn8Biw0d84j5iuP2tcxzY=", @@ -1181,10 +1296,136 @@ "type": "github" } }, + "nixpkgs_2": { + "locked": { + "lastModified": 1704161960, + "narHash": "sha256-QGua89Pmq+FBAro8NriTuoO/wNaUtugt29/qqA8zeeM=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "63143ac2c9186be6d9da6035fa22620018c85932", + "type": "github" + }, + "original": { + "owner": "NixOS", + "ref": "nixpkgs-unstable", + "repo": "nixpkgs", + "type": "github" + } + }, + "nixpkgs_3": { + "locked": { + "lastModified": 1703134684, + "narHash": "sha256-SQmng1EnBFLzS7WSRyPM9HgmZP2kLJcPAz+Ug/nug6o=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "d6863cbcbbb80e71cecfc03356db1cda38919523", + "type": "github" + }, + "original": { + "owner": "NixOS", + "ref": "nixpkgs-unstable", + "repo": "nixpkgs", + "type": "github" + } + }, + "nixpkgs_4": { + "locked": { + "lastModified": 1706732774, + "narHash": "sha256-hqJlyJk4MRpcItGYMF+3uHe8HvxNETWvlGtLuVpqLU0=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "b8b232ae7b8b144397fdb12d20f592e5e7c1a64d", + "type": "github" + }, + "original": { + "owner": "NixOS", + "ref": "nixos-unstable", + "repo": "nixpkgs", + "type": "github" + } + }, + "nixpkgs_5": { + "locked": { + "lastModified": 1707451808, + "narHash": "sha256-UwDBUNHNRsYKFJzyTMVMTF5qS4xeJlWoeyJf+6vvamU=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "442d407992384ed9c0e6d352de75b69079904e4e", + "type": "github" + }, + "original": { + "owner": "NixOS", + "ref": "nixpkgs-unstable", + "repo": "nixpkgs", + "type": "github" + } + }, + "nixpkgs_6": { + "locked": { + "lastModified": 1691280485, + "narHash": "sha256-/8Ct9092OC1TTNzHgbcE9ejQdS2QxZYGqrWXEwUxdtQ=", + "owner": "nixos", + "repo": "nixpkgs", + "rev": "240472b7e47a641e9e7675f58b64d3626ca7824d", + "type": "github" + }, + "original": { + "owner": "nixos", + "ref": "nixos-23.05-small", + "repo": "nixpkgs", + "type": "github" + } + }, + "nixpkgs_7": { + "locked": { + "lastModified": 1709309926, + "narHash": "sha256-VZFBtXGVD9LWTecGi6eXrE0hJ/mVB3zGUlHImUs2Qak=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "79baff8812a0d68e24a836df0a364c678089e2c7", + "type": "github" + }, + "original": { + "owner": "NixOS", + "ref": "nixos-23.11", + "repo": "nixpkgs", + "type": "github" + } + }, + "nixpkgs_8": { + "locked": { + "lastModified": 1707956935, + "narHash": "sha256-ZL2TrjVsiFNKOYwYQozpbvQSwvtV/3Me7Zwhmdsfyu4=", + "owner": "nixos", + "repo": "nixpkgs", + "rev": "a4d4fe8c5002202493e87ec8dbc91335ff55552c", + "type": "github" + }, + "original": { + "owner": "nixos", + "ref": "nixos-unstable", + "repo": "nixpkgs", + "type": "github" + } + }, + "nixpkgs_9": { + "locked": { + "lastModified": 1701436327, + "narHash": "sha256-tRHbnoNI8SIM5O5xuxOmtSLnswEByzmnQcGGyNRjxsE=", + "rev": "91050ea1e57e50388fa87a3302ba12d188ef723a", + "revCount": 555097, + "type": "tarball", + "url": "https://api.flakehub.com/f/pinned/NixOS/nixpkgs/0.1.555097%2Brev-91050ea1e57e50388fa87a3302ba12d188ef723a/018c3450-2363-7c34-883b-4ba70b1eb7ae/source.tar.gz" + }, + "original": { + "type": "tarball", + "url": "https://flakehub.com/f/NixOS/nixpkgs/0.1.%2A.tar.gz" + } + }, "nuenv": { "inputs": { - "nixpkgs": "nixpkgs_7", - "rust-overlay": "rust-overlay_2" + "nixpkgs": "nixpkgs_9", + "rust-overlay": "rust-overlay_3" }, "locked": { "lastModified": 1701856726, @@ -1202,7 +1443,7 @@ }, "nur-ryan4yin": { "inputs": { - "nixpkgs": "nixpkgs_8" + "nixpkgs": "nixpkgs_10" }, "locked": { "lastModified": 1705366605, @@ -1220,7 +1461,7 @@ }, "pnpm2nix": { "inputs": { - "flake-utils": "flake-utils_2", + "flake-utils": "flake-utils_4", "nixpkgs": [ "daeuniverse", "nixpkgs" @@ -1259,7 +1500,7 @@ "pre-commit-hooks": { "inputs": { "flake-compat": "flake-compat_2", - "flake-utils": "flake-utils_3", + "flake-utils": "flake-utils_5", "gitignore": "gitignore", "nixpkgs": [ "daeuniverse", @@ -1348,7 +1589,7 @@ "pre-commit-hooks_3": { "inputs": { "flake-compat": "flake-compat_4", - "flake-utils": "flake-utils_7", + "flake-utils": "flake-utils_10", "gitignore": "gitignore_4", "nixpkgs": [ "nixpkgs" @@ -1383,6 +1624,7 @@ "hyprland": "hyprland", "impermanence": "impermanence", "lanzaboote": "lanzaboote", + "microvm": "microvm", "mysecrets": "mysecrets", "nix-darwin": "nix-darwin", "nix-gaming": "nix-gaming", @@ -1390,7 +1632,7 @@ "nixos-hardware": "nixos-hardware", "nixos-licheepi4a": "nixos-licheepi4a", "nixos-rk3588": "nixos-rk3588", - "nixpkgs": "nixpkgs_6", + "nixpkgs": "nixpkgs_8", "nixpkgs-darwin": "nixpkgs-darwin", "nixpkgs-stable": "nixpkgs-stable_4", "nixpkgs-unstable": "nixpkgs-unstable", @@ -1402,6 +1644,31 @@ } }, "rust-overlay": { + "inputs": { + "flake-utils": [ + "agenix", + "flake-utils" + ], + "nixpkgs": [ + "agenix", + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1711246447, + "narHash": "sha256-g9TOluObcOEKewFo2fR4cn51Y/jSKhRRo4QZckHLop0=", + "owner": "oxalica", + "repo": "rust-overlay", + "rev": "dcc802a6ec4e9cc6a1c8c393327f0c42666f22e4", + "type": "github" + }, + "original": { + "owner": "oxalica", + "repo": "rust-overlay", + "type": "github" + } + }, + "rust-overlay_2": { "inputs": { "flake-utils": [ "lanzaboote", @@ -1426,9 +1693,9 @@ "type": "github" } }, - "rust-overlay_2": { + "rust-overlay_3": { "inputs": { - "flake-utils": "flake-utils_6", + "flake-utils": "flake-utils_9", "nixpkgs": [ "nuenv", "nixpkgs" @@ -1448,6 +1715,22 @@ "type": "github" } }, + "spectrum": { + "flake": false, + "locked": { + "lastModified": 1708358594, + "narHash": "sha256-e71YOotu2FYA67HoC/voJDTFsiPpZNRwmiQb4f94OxQ=", + "ref": "refs/heads/main", + "rev": "6d0e73864d28794cdbd26ab7b37259ab0e1e044c", + "revCount": 614, + "type": "git", + "url": "https://spectrum-os.org/git/spectrum" + }, + "original": { + "type": "git", + "url": "https://spectrum-os.org/git/spectrum" + } + }, "systems": { "locked": { "lastModified": 1681028828, @@ -1463,6 +1746,36 @@ "type": "github" } }, + "systems_10": { + "locked": { + "lastModified": 1681028828, + "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=", + "owner": "nix-systems", + "repo": "default", + "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e", + "type": "github" + }, + "original": { + "owner": "nix-systems", + "repo": "default", + "type": "github" + } + }, + "systems_11": { + "locked": { + "lastModified": 1681028828, + "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=", + "owner": "nix-systems", + "repo": "default", + "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e", + "type": "github" + }, + "original": { + "owner": "nix-systems", + "repo": "default", + "type": "github" + } + }, "systems_2": { "locked": { "lastModified": 1681028828, @@ -1480,16 +1793,16 @@ }, "systems_3": { "locked": { - "lastModified": 1689347949, - "narHash": "sha256-12tWmuL2zgBgZkdoB6qXZsgJEH9LR3oUgpaQq2RbI80=", + "lastModified": 1681028828, + "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=", "owner": "nix-systems", - "repo": "default-linux", - "rev": "31732fcf5e8fea42e59c2488ad31a0e651500f68", + "repo": "default", + "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e", "type": "github" }, "original": { "owner": "nix-systems", - "repo": "default-linux", + "repo": "default", "type": "github" } }, @@ -1525,16 +1838,16 @@ }, "systems_6": { "locked": { - "lastModified": 1681028828, - "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=", + "lastModified": 1689347949, + "narHash": "sha256-12tWmuL2zgBgZkdoB6qXZsgJEH9LR3oUgpaQq2RbI80=", "owner": "nix-systems", - "repo": "default", - "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e", + "repo": "default-linux", + "rev": "31732fcf5e8fea42e59c2488ad31a0e651500f68", "type": "github" }, "original": { "owner": "nix-systems", - "repo": "default", + "repo": "default-linux", "type": "github" } }, @@ -1553,6 +1866,58 @@ "type": "github" } }, + "systems_8": { + "locked": { + "lastModified": 1681028828, + "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=", + "owner": "nix-systems", + "repo": "default", + "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e", + "type": "github" + }, + "original": { + "owner": "nix-systems", + "repo": "default", + "type": "github" + } + }, + "systems_9": { + "locked": { + "lastModified": 1681028828, + "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=", + "owner": "nix-systems", + "repo": "default", + "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e", + "type": "github" + }, + "original": { + "owner": "nix-systems", + "repo": "default", + "type": "github" + } + }, + "treefmt-nix": { + "inputs": { + "nixpkgs": [ + "daeuniverse", + "nix-eval-jobs", + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1702979157, + "narHash": "sha256-RnFBbLbpqtn4AoJGXKevQMCGhra4h6G2MPcuTSZZQ+g=", + "owner": "numtide", + "repo": "treefmt-nix", + "rev": "2961375283668d867e64129c22af532de8e77734", + "type": "github" + }, + "original": { + "owner": "numtide", + "repo": "treefmt-nix", + "type": "github" + } + }, "wallpapers": { "flake": false, "locked": { diff --git a/flake.nix b/flake.nix index 4a369681..37a5cdf4 100644 --- a/flake.nix +++ b/flake.nix @@ -87,9 +87,9 @@ # secrets management agenix = { # lock with git commit at 0.15.0 - url = "github:ryantm/agenix/564595d0ad4be7277e07fa63b5a991b3c645655d"; + # url = "github:ryantm/agenix/564595d0ad4be7277e07fa63b5a991b3c645655d"; # replaced with a type-safe reimplementation to get a better error message and less bugs. - # url = "github:ryan4yin/ragenix"; + url = "github:ryan4yin/ragenix"; inputs.nixpkgs.follows = "nixpkgs"; }; @@ -108,8 +108,8 @@ nuenv.url = "github:DeterminateSystems/nuenv"; - # daeuniverse.url = "github:daeuniverse/flake.nix/unstable"; - daeuniverse.url = "github:daeuniverse/flake.nix/exp"; + daeuniverse.url = "github:daeuniverse/flake.nix"; + # daeuniverse.url = "github:daeuniverse/flake.nix/exp"; attic.url = "github:zhaofengli/attic"; @@ -118,6 +118,11 @@ inputs.nixpkgs.follows = "nixpkgs"; }; + microvm = { + url = "github:astro/microvm.nix"; + inputs.nixpkgs.follows = "nixpkgs"; + }; + ######################## Some non-flake repositories ######################################### # AstroNvim is an aesthetic and feature-rich neovim config. diff --git a/hosts/12kingdoms-suzu/default.nix b/hosts/12kingdoms-suzu/default.nix index 618d4dc7..5068e029 100644 --- a/hosts/12kingdoms-suzu/default.nix +++ b/hosts/12kingdoms-suzu/default.nix @@ -8,6 +8,8 @@ # # Suzu - Orange Pi 5 Plus, RK3588 + 16GB RAM # +# https://github.com/astro/microvm.nix +# ############################################################# let hostName = "suzu"; # Define your hostname. @@ -19,14 +21,12 @@ in { ./hardware-configuration.nix ./disko-fs.nix ./impermanence.nix + + ./networking.nix + ./microvm-host.nix ]; - networking = { - inherit hostName; - inherit (myvars.networking) defaultGateway nameservers; - inherit (myvars.networking.hostsInterface.${hostName}) interfaces; - networkmanager.enable = false; - }; + networking = {inherit hostName;}; # This value determines the NixOS release from which the default # settings for stateful data, like file locations and database versions diff --git a/hosts/12kingdoms-suzu/microvm-host.nix b/hosts/12kingdoms-suzu/microvm-host.nix new file mode 100644 index 00000000..233615ab --- /dev/null +++ b/hosts/12kingdoms-suzu/microvm-host.nix @@ -0,0 +1,92 @@ +{ + myvars, + mylib, + daeuniverse, + agenix, + microvm, + mysecrets, + nuenv, + ... +}: { + imports = [ + # Include the microvm host module + microvm.nixosModules.host + ]; + + microvm.vms = { + suzi = { + autostart = true; + restartIfChanged = true; + + specialArgs = {inherit myvars mylib daeuniverse agenix mysecrets nuenv;}; + + config = { + imports = [ + ./router + ../../secrets/nixos.nix + ../../modules/nixos/base/ssh.nix + ../../modules/nixos/base/user-group.nix + ../../modules/base.nix + ]; + + modules.secrets.server.network.enable = true; + + microvm = { + mem = 1024; # RAM allocation in MB + vcpu = 1; # Number of Virtual CPU cores + + interfaces = [ + { + type = "tap"; + id = "vm-suzi"; # should be prefixed with "vm-" + mac = "02:00:00:00:00:01"; + } + ]; + + # Block device images for persistent storage + # microvm use tmpfs for root(/), so everything else + # is ephemeral and will be lost on reboot. + # + # you can check this by running `df -Th` & `lsblk` in the VM. + volumes = [ + { + mountPoint = "/var"; + image = "var.img"; + size = 512; + } + { + mountPoint = "/etc"; + image = "etc.img"; + size = 50; + } + ]; + + # shares can not be set to `neededForBoot = true;` + # so if you try to use a share in boot script(such as system.activationScripts), it will fail! + shares = [ + { + # It is highly recommended to share the host's nix-store + # with the VMs to prevent building huge images. + # a host's /nix/store will be picked up so that no + # squashfs/erofs will be built for it. + # + # by this way, /nix/store is readonly in the VM, + # and thus the VM can't run any command that modifies + # the store. such as nix build, nix shell, etc... + # if you want to run nix commands in the VM, see + # https://github.com/astro/microvm.nix/blob/main/doc/src/shares.md#writable-nixstore-overlay + tag = "ro-store"; # Unique virtiofs daemon tag + proto = "virtiofs"; # virtiofs is faster than 9p + source = "/nix/store"; + mountPoint = "/nix/.ro-store"; + } + ]; + + hypervisor = "qemu"; + # Control socket for the Hypervisor so that a MicroVM can be shutdown cleanly + socket = "control.socket"; + }; + }; + }; + }; +} diff --git a/hosts/12kingdoms-suzu/microvm.md b/hosts/12kingdoms-suzu/microvm.md new file mode 100644 index 00000000..b13beffe --- /dev/null +++ b/hosts/12kingdoms-suzu/microvm.md @@ -0,0 +1,37 @@ +# microvm.nix + +## Commands + +> https://github.com/astro/microvm.nix/blob/main/doc/src/microvm-command.md + +```bash +# list vm +microvm -l + +# update vm +microvm -u my-microvm + + +# show logs of a vm +journalctl -u microvm@my-microvm -n 50 + +# stop vm +systemctl stop microvm@$NAME + +# remove vm +rm -rf /var/lib/microvms/$NAME + +# Run a MicroVM in foreground(for testing) +# You have to stop the vm before running this command! +microvm -r my-microvm + +# Stop a MicroVM that is running in foreground +## 1. run `sudo shutdown -h now` in the vm +## 2. run `systemctl stop microvm@my-microvm` in the host +``` + +## FAQ + +### 1. enter the vm without ssh + +[Enter running machine as systemd service](https://github.com/astro/microvm.nix/issues/123) diff --git a/hosts/12kingdoms-suzu/networking.nix b/hosts/12kingdoms-suzu/networking.nix new file mode 100644 index 00000000..6ec55d1a --- /dev/null +++ b/hosts/12kingdoms-suzu/networking.nix @@ -0,0 +1,49 @@ +{myvars, ...}: let + hostName = "suzu"; + inherit (myvars.networking) defaultGateway nameservers; + inherit (myvars.networking.hostsAddr.${hostName}) iface ipv4; + + ipv4WithMask = "${ipv4}/24"; +in { + boot = { + kernel = { + sysctl = { + # forward network packets that are not destined for the interface on which they were received + "net.ipv4.conf.all.forwarding" = true; + "net.ipv6.conf.all.forwarding" = true; + }; + }; + }; + + networking.useNetworkd = true; + systemd.network.enable = true; + + # A bridge to link all VM's TAP interfaces into local network. + # https://github.com/astro/microvm.nix/blob/main/doc/src/simple-network.md + systemd.network.networks."10-lan" = { + # match on the main interface and all VM interfaces + matchConfig.Name = [iface "vm-*"]; + networkConfig = { + Bridge = "br0"; + }; + }; + + systemd.network.netdevs."br0" = { + netdevConfig = { + Name = "br0"; + Kind = "bridge"; + }; + }; + + # Add ipv4 address to the bridge. + systemd.network.networks."10-lan-bridge" = { + matchConfig.Name = "br0"; + networkConfig = { + Address = [ipv4WithMask]; + Gateway = defaultGateway; + DNS = nameservers; + IPv6AcceptRA = true; + }; + linkConfig.RequiredForOnline = "routable"; + }; +} diff --git a/hosts/12kingdoms-suzu/router/README.md b/hosts/12kingdoms-suzu/router/README.md new file mode 100644 index 00000000..bf35766b --- /dev/null +++ b/hosts/12kingdoms-suzu/router/README.md @@ -0,0 +1,48 @@ +# Dae - NixOS Router + +A router(IPv4 only) with a transparent proxy to bypass the G|F|W. + +NOTE: dae do not provides a http/socks5 proxy server, so a v2ray server is running on +[idols_kana](../idols_kana/proxy.nix) to provides a http/socks5 proxy service. + +## Troubleshooting + +### Can not access the global internet + +1. Check whether the subscription url is accessible. + - If not, then you need to get a new subscription url and update the `dae`'s configuration. +1. Check the `dae` service's log by `journalctl -u dae -n 1000`. + +### DNS cannot be resolved + +1. `sudo systemctl stop dae`, then try to resolve the domain name again. + - If it works, the problem is caused by `dae` service. + - check dae's log by `journalctl -u dae -n 1000` +1. DNS & DHCP is provided by `dnsmasq` service, check the configuration of `dnsmasq`. + +### DHCP cannot be obtained + +1. `ss -tunlp`, check if `dnsmasq` is running and listening on udp port 67. +1. `journalctl -u dnsmasq -n 1000` to check the log of `dnsmasq`. +1. Request a new IP address by disconnect and reconnect one of your devices' wifi. +1. `nix shell nixpkgs#dhcpdump` and then `sudo dhcpdump -i br-lan`, check if the DHCP request is + received by `dnsmasq`. + 1. The server listens on UDP port number 67, and the client listens on UDP port number 68. + 1. DHCP operations fall into four phases: + 1. Server **discovery**: The DHCP client broadcasts a DHCPDISCOVER message on the network + subnet using the destination address 255.255.255.255 (limited broadcast) or the specific + subnet broadcast address (directed broadcast). + 1. IP lease **offer**: When a DHCP server receives a DHCPDISCOVER message from a client, which + is an IP address lease request, the DHCP server reserves an IP address for the client and + makes a lease offer by sending a DHCPOFFER message to the client. + 1. IP lease **request**: In response to the DHCP offer, the client replies with a DHCPREQUEST + message, broadcast to the server,[a] requesting the offered address. + 1. IP lease **acknowledgement**: When the DHCP server receives the DHCPREQUEST message from + the client, it sends a DHCPACK packet to the client, which includes the lease duration and + any other configuration information that the client might have requested. + 1. So if you see only `DISCOVER` messages, the dhsmasq is not working properly. + +## References + +- +- diff --git a/hosts/12kingdoms-suzu/router/config.dae b/hosts/12kingdoms-suzu/router/config.dae new file mode 100644 index 00000000..ed30a66d --- /dev/null +++ b/hosts/12kingdoms-suzu/router/config.dae @@ -0,0 +1,320 @@ +# https://github.com/daeuniverse/dae/discussions/81 +# https://github.com/daeuniverse/dae/blob/main/example.dae + +# load all dae files placed in ./config.d/ +include { + config.d/*.dae +} +global { + ##### Software options. + + # tproxy port to listen on. It is NOT a HTTP/SOCKS port, and is just used by eBPF program. + # In normal case, you do not need to use it. + tproxy_port: 12345 + + # Set it true to protect tproxy port from unsolicited traffic. Set it false to allow users to use self-managed + # iptables tproxy rules. + tproxy_port_protect: true + + # If not zero, traffic sent from dae will be set SO_MARK. It is useful to avoid traffic loop with iptables tproxy + # rules. + so_mark_from_dae: 1 + + # Log level: error, warn, info, debug, trace. + log_level: info + + # Disable waiting for network before pulling subscriptions. + disable_waiting_network: false + + + ##### Interface and kernel options. + + # The LAN interface to bind. Use it if you want to proxy LAN. + # Multiple interfaces split by ",". + lan_interface: br-lan + + # The WAN interface to bind. Use it if you want to proxy localhost. + # Multiple interfaces split by ",". Use "auto" to auto detect. + # + # Disable this to avoid problems with the proxy server that prevent the subscription link from being updated + # wan_interface: auto + + # Automatically configure Linux kernel parameters like ip_forward and send_redirects. Check out + # https://github.com/daeuniverse/dae/blob/main/docs/en/user-guide/kernel-parameters.md to see what will dae do. + auto_config_kernel_parameter: false + + ##### Node connectivity check. + + # Host of URL should have both IPv4 and IPv6 if you have double stack in local. + # First is URL, others are IP addresses if given. + # Considering traffic consumption, it is recommended to choose a site with anycast IP and less response. + #tcp_check_url: 'http://cp.cloudflare.com' + tcp_check_url: 'http://cp.cloudflare.com,1.1.1.1,2606:4700:4700::1111' + + # The HTTP request method to `tcp_check_url`. Use 'HEAD' by default because some server implementations bypass + # accounting for this kind of traffic. + tcp_check_http_method: HEAD + + # This DNS will be used to check UDP connectivity of nodes. And if dns_upstream below contains tcp, it also be used to check + # TCP DNS connectivity of nodes. + # First is URL, others are IP addresses if given. + # This DNS should have both IPv4 and IPv6 if you have double stack in local. + #udp_check_dns: 'dns.google.com:53' + udp_check_dns: 'dns.google.com:53,8.8.8.8,2001:4860:4860::8888' + + check_interval: 30s + + # Group will switch node only when new_latency <= old_latency - tolerance. + check_tolerance: 50ms + + + ##### Connecting options. + + # Optional values of dial_mode are: + # 1. "ip". Dial proxy using the IP from DNS directly. This allows your ipv4, ipv6 to choose the optimal path + # respectively, and makes the IP version requested by the application meet expectations. For example, if you + # use curl -4 ip.sb, you will request IPv4 via proxy and get a IPv4 echo. And curl -6 ip.sb will request IPv6. + # This may solve some weird full-cone problem if your are be your node support that. Sniffing will be disabled + # in this mode. + # 2. "domain". Dial proxy using the domain from sniffing. This will relieve DNS pollution problem to a great extent + # if have impure DNS environment. Generally, this mode brings faster proxy response time because proxy will + # re-resolve the domain in remote, thus get better IP result to connect. This policy does not impact routing. + # That is to say, domain rewrite will be after traffic split of routing and dae will not re-route it. + # 3. "domain+". Based on domain mode but do not check the reality of sniffed domain. It is useful for users whose + # DNS requests do not go through dae but want faster proxy response time. Notice that, if DNS requests do not + # go through dae, dae cannot split traffic by domain. + # 4. "domain++". Based on domain+ mode but force to re-route traffic using sniffed domain to partially recover + # domain based traffic split ability. It doesn't work for direct traffic and consumes more CPU resources. + dial_mode: domain + + # Allow insecure TLS certificates. It is not recommended to turn it on unless you have to. + allow_insecure: false + + # Timeout to waiting for first data sending for sniffing. It is always 0 if dial_mode is ip. Set it higher is useful + # in high latency LAN network. + sniffing_timeout: 100ms + + # TLS implementation. tls is to use Go's crypto/tls. utls is to use uTLS, which can imitate browser's Client Hello. + tls_implementation: tls + + # The Client Hello ID for uTLS to imitate. This takes effect only if tls_implementation is utls. + # See more: https://github.com/daeuniverse/dae/blob/331fa23c16/component/outbound/transport/tls/utls.go#L17 + utls_imitate: chrome_auto +} + +# See https://github.com/daeuniverse/dae/blob/main/docs/en/configuration/dns.md for full examples. +dns { + # For example, if ipversion_prefer is 4 and the domain name has both type A and type AAAA records, the dae will only + # respond to type A queries and response empty answer to type AAAA queries. + ipversion_prefer: 4 + + # Give a fixed ttl for domains. Zero means that dae will request to upstream every time and not cache DNS results + # for these domains. + #fixed_domain_ttl { + # ddns.example.org: 10 + # test.example.org: 3600 + #} + + upstream { + # Value can be scheme://host:port, where the scheme can be tcp/udp/tcp+udp. + # If host is a domain and has both IPv4 and IPv6 record, dae will automatically choose + # IPv4 or IPv6 to use according to group policy (such as min latency policy). + # Please make sure DNS traffic will go through and be forwarded by dae, which is REQUIRED for domain routing. + # If dial_mode is "ip", the upstream DNS answer SHOULD NOT be polluted, so domestic public DNS is not recommended. + + alidns: 'udp://223.5.5.5:53' + googledns: 'tcp+udp://8.8.8.8:53' + } + routing { + # According to the request of dns query, decide to use which DNS upstream. + # Match rules from top to bottom. + request { + # Lookup China mainland domains using alidns, otherwise googledns. + qname(geosite:cn) -> alidns + # fallback is also called default. + fallback: googledns + + # other custom rules + qname(full:analytics.google.com) -> googledns # do not block google analytics(console) + qname(regex: '.+\.nixos.org$') -> googledns + qname(geosite:category-ads) -> reject + qname(geosite:category-ads-all) -> reject + qtype(aaaa) -> reject + qname(regex: '.+\.linkedin$') -> googledns + } + + # According to the response of dns query, decide to accept or re-lookup using another DNS upstream. + # Match rules from top to bottom. + response { + # Trusted upstream. Always accept its result. + upstream(googledns) -> accept + + # Possibly polluted(domain resolved to a private ip), re-lookup using googledns. + ip(geoip:private) && !qname(geosite:cn) -> googledns + + fallback: accept + } + } +} + +# Node group (outbound). +group { + proxy { + filter: name(keyword: 'Hong Kong') + filter: name(keyword: '香港') + filter: name(keyword: 'Singapore') + filter: name(keyword: '新加坡') + # Filter nodes and give a fixed latency offset to archive latency-based failover. + # In this example, there is bigger possibility to choose US node even if original latency of US node is higher. + filter: name(keyword: 'USA') [add_latency: -500ms] + filter: name(keyword: '美国') [add_latency: -500ms] + filter: name(keyword: 'UK') [add_latency: -300ms] + # filter: name(keyword: '英国') [add_latency: -300ms] + # filter: name(keyword: 'Japan') [add_latency: 300ms] + # filter: name(keyword: '日本') [add_latency: 300ms] + + # Other filters: + # Filter nodes from the global node pool defined by the subscription and node section above. + # filter: subtag(regex: '^my_', another_sub) && !name(keyword: 'ExpireAt:') + # Filter nodes from the global node pool defined by tag. + # filter: name('node_a','node_b') + + # Select the node with min average of the last 10 latencies from the group for every connection. + policy: min_avg10 + # Other policies: + # random - Randomly select a node from the group for every connection. + # fixed(0) - Select the first node from the group for every connection. + # min - Select the node with min last latency from the group for every connection. + # min_moving_avg - Select the node with min moving average of latencies from the group for every connection. + } + + media { + filter: name(keyword: 'Hong Kong') + filter: name(keyword: '香港') + filter: name(keyword: 'Singapore') + filter: name(keyword: '新加坡') + filter: name(keyword: 'USA') [add_latency: -500ms] + filter: name(keyword: '美国') [add_latency: -500ms] + filter: name(keyword: 'UK') [add_latency: -300ms] + filter: name(keyword: '英国') [add_latency: -300ms] + filter: name(keyword: 'Japan') [add_latency: 300ms] + filter: name(keyword: '日本') [add_latency: 300ms] + + policy: min_avg10 + } + + ssh-proxy { + filter: name(keyword: 'UK') + filter: name(keyword: '英国') + policy: min_avg10 + } + + sg { + filter: name(keyword: 'Singapore') + filter: name(keyword: '新加坡') + policy: min_avg10 + } + + usa { + filter: name(keyword: 'USA') + filter: name(keyword: '美国') + policy: min_avg10 + } +} + +# See https://github.com/daeuniverse/dae/blob/main/docs/en/configuration/routing.md for full examples. +# Pname has the highest priority, so should be placed in the front. +# Priority of other rules is the same as the order of the rules defined in this file. +routing { + ### Preset rules. + + # Network managers in localhost should be direct to + # avoid false negative network connectivity check when binding to WAN. + pname(NetworkManager) -> direct + pname(systemd-networkd) -> direct + + # Put it in the front to prevent broadcast, multicast and other packets that should be sent to the LAN from being + # forwarded by the proxy. + # "dip" means destination IP. + dip(224.0.0.0/3, 'ff00::/8') -> direct + + # This line allows you to access private addresses directly instead of via your proxy. If you really want to access + # private addresses in your proxy host network, modify the below line. + dip(geoip:private) -> direct + + # --- Core rules ---# + + # Disable HTTP3(QUIC) because it usually consumes too much cpu/mem resources. + l4proto(udp) && dport(443) -> block + + # Direct access to all Chinese mainland-related IP addresses + dip(geoip:cn) -> direct + domain(geosite:cn) -> direct + + # Block ads + domain(full:analytics.google.com) -> proxy # do not block google analytics(console) + domain(geosite:category-ads) -> block + domain(geosite:category-ads-all) -> block + + # DNS + dip(8.8.8.8, 8.8.4.4) -> proxy + dip(223.5.5.5, 223.6.6.6) -> direct + domain(full:dns.alidns.com) -> direct + domain(full:dns.googledns.com) -> proxy + domain(full:dns.opendns.com) -> proxy + + # --- Rules for other commonly used sites ---# + + # SSH - tcp port 22 is blocked by many proxy servers. + dport(22) && !dip(geoip:cn) && !domain(geosite:cn) -> ssh-proxy + + ### OpenAI + domain(geosite:openai) -> sg + domain(regex:'.+\.openai$') -> sg + + ### Media + domain(geosite:netflix) -> media + + ### Proxy + domain(suffix: linkedin.com) -> proxy + domain(keyword:'linkedin') -> proxy + domain(regex:'.+\.linkedin\.com$') -> proxy + domain(regex:'.+\.quay\.io$') -> proxy + domain(regex:'.+\.notion\.so$') -> proxy + domain(regex:'.+\.amazon\.com$') -> proxy + domain(regex:'.+\.oracle\.com$') -> proxy + domain(regex:'.+\.docker\.com$') -> proxy + domain(regex:'.+\.kubernetes\.io$') -> proxy + domain(regex:'.+\.nixos\.org$') -> proxy + + domain(geosite:microsoft) -> proxy + domain(geosite:linkedin) -> proxy + domain(geosite:twitter) -> proxy + domain(geosite:telegram) -> proxy + domain(geosite:google) -> proxy + domain(geosite:apple) -> proxy + domain(geosite:category-container) -> proxy + domain(geosite:category-dev) -> proxy + domain(geosite:google-scholar) -> proxy + domain(geosite:category-scholar-!cn) -> proxy + + ### Direct + domain(regex:'.+\.edu\.cn$') -> direct + domain(keyword:'baidu') -> direct + domain(keyword:'bilibili') -> direct + domain(keyword:'taobao') -> direct + domain(keyword:'alibabadns') -> direct + domain(keyword:'alicdn') -> direct + domain(keyword:'tbcache') -> direct + domain(keyword:'zhihu') -> direct + domain(keyword:'douyu') -> direct + domain(geosite:cloudflare-cn) -> direct + + # --- Fallback rules ---# + + # Access all other foreign sites + domain(geosite:geolocation-!cn) -> proxy + !dip(geoip:cn) -> proxy + + fallback: direct +} diff --git a/hosts/12kingdoms-suzu/router/dae.nix b/hosts/12kingdoms-suzu/router/dae.nix new file mode 100644 index 00000000..0f468f95 --- /dev/null +++ b/hosts/12kingdoms-suzu/router/dae.nix @@ -0,0 +1,56 @@ +{ + config, + pkgs, + daeuniverse, + ... +}: +# https://github.com/daeuniverse/flake.nix +let + daeConfigPath = "/etc/dae/config.dae"; + subscriptionConfigPath = "/etc/dae/config.d/subscription.dae"; +in { + imports = [ + daeuniverse.nixosModules.dae + ]; + + # dae - eBPF-based Linux high-performance transparent proxy. + services.dae = { + enable = true; + package = daeuniverse.packages.${pkgs.system}.dae; + disableTxChecksumIpGeneric = false; + configFile = daeConfigPath; + assets = with pkgs; [v2ray-geoip v2ray-domain-list-community]; + # alternatively, specify assets dir + # assetsPath = "/etc/dae"; + openFirewall = { + enable = true; + port = 12345; + }; + }; + + # dae supports two types of subscriptions: base64 encoded proxies, and sip008. + # subscription can be a url return the subscription, or a file path that contains the subscription. + # + # Nix decrypt and merge my dae's base config and subscription config here. + # the subscription config is something like: + # ``` + # subscription { + # 'https://www.example.com/subscription/link' + # 'https://example.com/no_tag_link' + # } + # node { + # # Support socks5, http, https, ss, ssr, vmess, vless, trojan, trojan-go, tuic, juicity + # node_a: 'trojan://' + # node_b: 'trojan://' + # node_c: 'vless://' + # node_d: 'vless://' + # node_e: 'vmess://' + # node_f: 'tuic://' + # node_h: 'juicity://' + # } + # ``` + system.activationScripts.installDaeConfig = '' + install -Dm 600 ${./config.dae} ${daeConfigPath} + install -Dm 600 ${config.age.secrets."dae-subscription.dae".path} ${subscriptionConfigPath} + ''; +} diff --git a/hosts/12kingdoms-suzu/router/default.nix b/hosts/12kingdoms-suzu/router/default.nix new file mode 100644 index 00000000..eeb48a40 --- /dev/null +++ b/hosts/12kingdoms-suzu/router/default.nix @@ -0,0 +1,3 @@ +{mylib, ...}: { + imports = mylib.scanPaths ./.; +} diff --git a/hosts/12kingdoms-suzu/router/networking.nix b/hosts/12kingdoms-suzu/router/networking.nix new file mode 100644 index 00000000..afdcd4c4 --- /dev/null +++ b/hosts/12kingdoms-suzu/router/networking.nix @@ -0,0 +1,184 @@ +{ + lib, + myvars, + ... +}: let + hostName = "suzi"; + inherit (myvars.networking) mainGateway nameservers; + inherit (myvars.networking.hostsAddr.${hostName}) ipv4; + + ipv4WithMask = "${ipv4}/24"; + dhcpRange = { + start = "192.168.5.5"; + end = "192.168.5.99"; + }; +in { + # https://github.com/ghostbuster91/blogposts/blob/main/router2023-part2/main.md + boot = { + kernel = { + # https://github.com/daeuniverse/dae/blob/main/docs/en/user-guide/kernel-parameters.md + sysctl = { + # forward network packets that are not destined for the interface on which they were received + "net.ipv4.conf.all.forwarding" = true; + "net.ipv6.conf.all.forwarding" = true; + "net.ipv4.conf.br-lan.rp_filter" = 1; + "net.ipv4.conf.br-lan.send_redirects" = 0; + }; + }; + }; + + # Docker uses iptables internally to setup NAT for containers. + # This module disables the ip_tables kernel module, which is required for nftables to work. + # So make sure to disable docker here. + virtualisation.docker.enable = lib.mkForce false; + networking = { + useNetworkd = true; + + useDHCP = false; + networkmanager.enable = false; + wireless.enable = false; # Enables wireless support via wpa_supplicant. + # No local firewall. + nat.enable = false; + firewall.enable = false; + + # https://github.com/NixOS/nixpkgs/blob/nixos-23.11/nixos/modules/services/networking/nftables.nix + nftables = { + enable = true; + # Check the applied rules with `nft -a list ruleset`. + # Since this is a internal bypass router, we don't need to do NAT & can forward all traffic. + ruleset = '' + # Check out https://wiki.nftables.org/ for better documentation. + # Table for both IPv4 and IPv6. + table inet filter { + chain input { + type filter hook input priority 0; + + # accept any localhost traffic + iifname lo accept + + # accept any lan traffic + iifname br-lan accept + + # count and drop any other traffic + counter drop + } + + # Allow all outgoing connections. + chain output { + type filter hook output priority 0; + accept + } + + # Allow all forwarding all traffic. + chain forward { + type filter hook forward priority 0; + accept + } + } + ''; + }; + }; + + # https://nixos.wiki/wiki/Systemd-networkd + systemd.network = { + netdevs = { + # Create the bridge interface + "20-br-lan" = { + netdevConfig = { + Kind = "bridge"; + Name = "br-lan"; + }; + }; + }; + # This is a bypass router, so we do not need a wan interface here. + networks = { + "30-lan0" = { + # match the interface by type + matchConfig.Type = "ether"; + # Connect to the bridge + networkConfig = { + Bridge = "br-lan"; + ConfigureWithoutCarrier = true; + }; + linkConfig.RequiredForOnline = "enslaved"; + }; + # Configure the bridge device we just created + "40-br-lan" = { + matchConfig.Name = "br-lan"; + address = [ + # configure addresses including subnet mask + ipv4WithMask # forwards all traffic to the gateway except for the router address itself + ]; + routes = [ + # forward all traffic to the main gateway + {routeConfig.Gateway = mainGateway;} + ]; + bridgeConfig = {}; + linkConfig.RequiredForOnline = "routable"; + }; + }; + }; + + # resolved is conflict with dnsmasq + services.resolved.enable = false; + services.dnsmasq = { + enable = true; + # resolve local queries (add 127.0.0.1 to /etc/resolv.conf) + resolveLocalQueries = true; # may be conflict with dae, disable this. + alwaysKeepRunning = true; + # https://thekelleys.org.uk/gitweb/?p=dnsmasq.git;a=tree + settings = { + # upstream DNS servers + server = nameservers; + # forces dnsmasq to try each query with each server strictly + # in the order they appear in the config. + strict-order = true; + + # Never forward plain names (without a dot or domain part) + domain-needed = true; + # Never forward addresses in the non-routed address spaces(e.g. private IP). + bogus-priv = true; + # don't needlessly read /etc/resolv.conf which only contains the localhost addresses of dnsmasq itself. + no-resolv = true; + + # Cache dns queries. + cache-size = 1000; + + dhcp-range = ["${dhcpRange.start},${dhcpRange.end},24h"]; + interface = "br-lan"; + dhcp-sequential-ip = true; + dhcp-option = [ + # Override the default route supplied by dnsmasq, which assumes the + # router is the same machine as the one running dnsmasq. + "option:router,${ipv4}" + "option:dns-server,${ipv4}" + ]; + + # local domains + local = "/lan/"; + domain = "lan"; + expand-hosts = true; + + # don't use /etc/hosts + no-hosts = true; + address = [ + # "/surfer.lan/192.168.10.1" + ]; + }; + }; + + # monitoring with prometheus + # https://github.com/NixOS/nixpkgs/blob/nixos-23.11/nixos/modules/services/monitoring/prometheus/exporters/dnsmasq.nix + services.prometheus.exporters.dnsmasq = { + enable = true; + listenAddress = "0.0.0.0"; + port = 9153; + openFirewall = false; + leasesPath = "/var/lib/dnsmasq/dnsmasq.leases"; + }; + + # The service irqbalance is useful as it assigns certain IRQ calls to specific CPUs instead of + # letting the first CPU core to handle everything. + # This is supposed to increase performance by hitting CPU cache more often. + services.irqbalance.enable = false; +} diff --git a/outputs/aarch64-linux/src/12kingdoms-suzu.nix b/outputs/aarch64-linux/src/12kingdoms-suzu.nix index 2c1c2658..9d0c6d00 100644 --- a/outputs/aarch64-linux/src/12kingdoms-suzu.nix +++ b/outputs/aarch64-linux/src/12kingdoms-suzu.nix @@ -16,11 +16,16 @@ ssh-user = "root"; modules = { - nixos-modules = map mylib.relativeToRoot [ - "modules/nixos/server/server-aarch64.nix" - # host specific modules - "hosts/12kingdoms-${name}" - ]; + nixos-modules = + (map mylib.relativeToRoot [ + "secrets/nixos.nix" + "modules/nixos/server/server-aarch64.nix" + # host specific modules + "hosts/12kingdoms-${name}" + ]) + ++ [ + {modules.secrets.server.network.enable = true;} + ]; }; inherit (inputs) nixos-rk3588; diff --git a/vars/networking.nix b/vars/networking.nix index e8d6144e..7fa1b325 100644 --- a/vars/networking.nix +++ b/vars/networking.nix @@ -74,6 +74,10 @@ iface = "enP4p65s0"; ipv4 = "192.168.5.179"; }; + suzi = { + iface = "eth1"; + ipv4 = "192.168.5.178"; + }; # ============================================ # Kubernetes Clusters From 50783093c583fc5a03c52173183e5ca9babb52e0 Mon Sep 17 00:00:00 2001 From: Ryan Yin Date: Tue, 26 Mar 2024 00:39:48 +0800 Subject: [PATCH 2/2] fix: rekey secrets for microvm - suzi --- flake.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/flake.lock b/flake.lock index 689ae2e4..8218ee64 100644 --- a/flake.lock +++ b/flake.lock @@ -892,10 +892,10 @@ "mysecrets": { "flake": false, "locked": { - "lastModified": 1709488959, - "narHash": "sha256-7KULeEF0rob7pDc2OKVW1Iz7bTQIFYUrnwZcowWajW0=", + "lastModified": 1711384638, + "narHash": "sha256-1XyAHel88+uqA6yzT2/mwgfxYt4JfJKmnI5OI93vDYg=", "ref": "refs/heads/main", - "rev": "d23c2f47f0395155cfe64b49c9a858aa7f4bfbd0", + "rev": "691dce5db5077c4f668468434cc422f93e7834c5", "shallow": true, "type": "git", "url": "ssh://git@github.com/ryan4yin/nix-secrets.git"