Compare commits

...

3 commits

Author SHA1 Message Date
Leon Schwarzäugl
5e378178f2
chore: remove generated deploy files
Some checks are pending
Build and Deploy / build (push) Waiting to run
Build and Deploy / deploy (push) Blocked by required conditions
2025-12-31 04:03:28 +01:00
Leon Schwarzäugl
cd1a23845f
feat: add new deploy pipeline 2025-12-31 03:14:50 +01:00
Leon Schwarzäugl
c39cbed1cf
feat[server]: first working microvm 2025-12-24 14:48:27 +01:00
44 changed files with 2789 additions and 35387 deletions

57
.github/workflows/build-and-deploy.yml vendored Normal file
View file

@ -0,0 +1,57 @@
name: Build and Deploy
on:
push:
branches:
- feat/router # or master, depending on your default branch
workflow_dispatch: # allows manual trigger
permissions:
contents: read
pages: write
id-token: write
concurrency:
group: "pages"
cancel-in-progress: false
jobs:
build:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Install Emacs
run: |
sudo apt-get update
sudo apt-get install -y emacs-nox elpa-htmlize
- name: Export Org to HTML
run: |
emacs --batch \
--eval "(require 'org)" \
--eval "(setq org-confirm-babel-evaluate nil
org-html-validation-link nil
org-export-with-broken-links 'mark)" \
--visit=SwarselSystems.org \
--funcall org-html-export-to-html
- name: Setup Pages
uses: actions/configure-pages@v4
- name: Upload artifact
uses: actions/upload-pages-artifact@v3
with:
path: '.'
deploy:
environment:
name: github-pages
url: ${{ steps.deployment.outputs.page_url }}
runs-on: ubuntu-latest
needs: build
steps:
- name: Deploy to GitHub Pages
id: deployment
uses: actions/deploy-pages@v4

2
.gitignore vendored
View file

@ -7,3 +7,5 @@ result
*.bak *.bak
.pre-commit-config.yaml .pre-commit-config.yaml
.direnv .direnv
/index.html
/style.css

File diff suppressed because it is too large Load diff

117
flake.lock generated
View file

@ -156,6 +156,27 @@
"type": "github" "type": "github"
} }
}, },
"dependencyDagOfSubmodule": {
"inputs": {
"nixpkgs": [
"nixos-nftables-firewall",
"nixpkgs"
]
},
"locked": {
"lastModified": 1656615370,
"narHash": "sha256-IZDqz1aSySoqf1qtVQg+oJMHfC4IlT55Zoa7EkjvPug=",
"owner": "thelegy",
"repo": "nix-dependencyDagOfSubmodule",
"rev": "98eb563d80b35acafbfc1abb9ccee569c1efb19c",
"type": "github"
},
"original": {
"owner": "thelegy",
"repo": "nix-dependencyDagOfSubmodule",
"type": "github"
}
},
"devshell": { "devshell": {
"inputs": { "inputs": {
"nixpkgs": "nixpkgs" "nixpkgs": "nixpkgs"
@ -1508,6 +1529,25 @@
"type": "github" "type": "github"
} }
}, },
"nixos-nftables-firewall": {
"inputs": {
"dependencyDagOfSubmodule": "dependencyDagOfSubmodule",
"nixpkgs": "nixpkgs_17"
},
"locked": {
"lastModified": 1715521768,
"narHash": "sha256-BQkkBqDemoPRd2a4G94I9w9fNE0IxWtVsQ9SalnNqCQ=",
"owner": "thelegy",
"repo": "nixos-nftables-firewall",
"rev": "2c5a19966b4dfc5ca92df7eb250c68f90be653c8",
"type": "github"
},
"original": {
"owner": "thelegy",
"repo": "nixos-nftables-firewall",
"type": "github"
}
},
"nixos-stable": { "nixos-stable": {
"locked": { "locked": {
"lastModified": 1749237914, "lastModified": 1749237914,
@ -1885,15 +1925,15 @@
}, },
"nixpkgs_17": { "nixpkgs_17": {
"locked": { "locked": {
"lastModified": 1763835633, "lastModified": 1692638711,
"narHash": "sha256-HzxeGVID5MChuCPESuC0dlQL1/scDKu+MmzoVBJxulM=", "narHash": "sha256-J0LgSFgJVGCC1+j5R2QndadWI1oumusg6hCtYAzLID4=",
"owner": "nixos", "owner": "nixos",
"repo": "nixpkgs", "repo": "nixpkgs",
"rev": "050e09e091117c3d7328c7b2b7b577492c43c134", "rev": "91a22f76cd1716f9d0149e8a5c68424bb691de15",
"type": "github" "type": "github"
}, },
"original": { "original": {
"owner": "nixos", "owner": "NixOS",
"ref": "nixos-unstable", "ref": "nixos-unstable",
"repo": "nixpkgs", "repo": "nixpkgs",
"type": "github" "type": "github"
@ -1901,11 +1941,11 @@
}, },
"nixpkgs_18": { "nixpkgs_18": {
"locked": { "locked": {
"lastModified": 1720957393, "lastModified": 1763835633,
"narHash": "sha256-oedh2RwpjEa+TNxhg5Je9Ch6d3W1NKi7DbRO1ziHemA=", "narHash": "sha256-HzxeGVID5MChuCPESuC0dlQL1/scDKu+MmzoVBJxulM=",
"owner": "nixos", "owner": "nixos",
"repo": "nixpkgs", "repo": "nixpkgs",
"rev": "693bc46d169f5af9c992095736e82c3488bf7dbb", "rev": "050e09e091117c3d7328c7b2b7b577492c43c134",
"type": "github" "type": "github"
}, },
"original": { "original": {
@ -1917,11 +1957,11 @@
}, },
"nixpkgs_19": { "nixpkgs_19": {
"locked": { "locked": {
"lastModified": 1763835633, "lastModified": 1720957393,
"narHash": "sha256-HzxeGVID5MChuCPESuC0dlQL1/scDKu+MmzoVBJxulM=", "narHash": "sha256-oedh2RwpjEa+TNxhg5Je9Ch6d3W1NKi7DbRO1ziHemA=",
"owner": "nixos", "owner": "nixos",
"repo": "nixpkgs", "repo": "nixpkgs",
"rev": "050e09e091117c3d7328c7b2b7b577492c43c134", "rev": "693bc46d169f5af9c992095736e82c3488bf7dbb",
"type": "github" "type": "github"
}, },
"original": { "original": {
@ -1948,6 +1988,22 @@
} }
}, },
"nixpkgs_20": { "nixpkgs_20": {
"locked": {
"lastModified": 1763835633,
"narHash": "sha256-HzxeGVID5MChuCPESuC0dlQL1/scDKu+MmzoVBJxulM=",
"owner": "nixos",
"repo": "nixpkgs",
"rev": "050e09e091117c3d7328c7b2b7b577492c43c134",
"type": "github"
},
"original": {
"owner": "nixos",
"ref": "nixos-unstable",
"repo": "nixpkgs",
"type": "github"
}
},
"nixpkgs_21": {
"locked": { "locked": {
"lastModified": 1763934636, "lastModified": 1763934636,
"narHash": "sha256-9glbI7f1uU+yzQCq5LwLgdZqx6svOhZWkd4JRY265fc=", "narHash": "sha256-9glbI7f1uU+yzQCq5LwLgdZqx6svOhZWkd4JRY265fc=",
@ -1963,7 +2019,7 @@
"type": "github" "type": "github"
} }
}, },
"nixpkgs_21": { "nixpkgs_22": {
"locked": { "locked": {
"lastModified": 1763553727, "lastModified": 1763553727,
"narHash": "sha256-4aRqRkYHplWk0mrtoF5i3Uo73E3niOWiUZU8kmPm9hQ=", "narHash": "sha256-4aRqRkYHplWk0mrtoF5i3Uo73E3niOWiUZU8kmPm9hQ=",
@ -1979,7 +2035,7 @@
"type": "github" "type": "github"
} }
}, },
"nixpkgs_22": { "nixpkgs_23": {
"locked": { "locked": {
"lastModified": 1764445028, "lastModified": 1764445028,
"narHash": "sha256-ik6H/0Zl+qHYDKTXFPpzuVHSZE+uvVz2XQuQd1IVXzo=", "narHash": "sha256-ik6H/0Zl+qHYDKTXFPpzuVHSZE+uvVz2XQuQd1IVXzo=",
@ -1995,7 +2051,7 @@
"type": "github" "type": "github"
} }
}, },
"nixpkgs_23": { "nixpkgs_24": {
"locked": { "locked": {
"lastModified": 1763966396, "lastModified": 1763966396,
"narHash": "sha256-6eeL1YPcY1MV3DDStIDIdy/zZCDKgHdkCmsrLJFiZf0=", "narHash": "sha256-6eeL1YPcY1MV3DDStIDIdy/zZCDKgHdkCmsrLJFiZf0=",
@ -2011,7 +2067,7 @@
"type": "github" "type": "github"
} }
}, },
"nixpkgs_24": { "nixpkgs_25": {
"locked": { "locked": {
"lastModified": 1762977756, "lastModified": 1762977756,
"narHash": "sha256-4PqRErxfe+2toFJFgcRKZ0UI9NSIOJa+7RXVtBhy4KE=", "narHash": "sha256-4PqRErxfe+2toFJFgcRKZ0UI9NSIOJa+7RXVtBhy4KE=",
@ -2027,7 +2083,7 @@
"type": "github" "type": "github"
} }
}, },
"nixpkgs_25": { "nixpkgs_26": {
"locked": { "locked": {
"lastModified": 1763966396, "lastModified": 1763966396,
"narHash": "sha256-6eeL1YPcY1MV3DDStIDIdy/zZCDKgHdkCmsrLJFiZf0=", "narHash": "sha256-6eeL1YPcY1MV3DDStIDIdy/zZCDKgHdkCmsrLJFiZf0=",
@ -2043,7 +2099,7 @@
"type": "github" "type": "github"
} }
}, },
"nixpkgs_26": { "nixpkgs_27": {
"locked": { "locked": {
"lastModified": 1761236834, "lastModified": 1761236834,
"narHash": "sha256-+pthv6hrL5VLW2UqPdISGuLiUZ6SnAXdd2DdUE+fV2Q=", "narHash": "sha256-+pthv6hrL5VLW2UqPdISGuLiUZ6SnAXdd2DdUE+fV2Q=",
@ -2059,7 +2115,7 @@
"type": "github" "type": "github"
} }
}, },
"nixpkgs_27": { "nixpkgs_28": {
"locked": { "locked": {
"lastModified": 1751274312, "lastModified": 1751274312,
"narHash": "sha256-/bVBlRpECLVzjV19t5KMdMFWSwKLtb5RyXdjz3LJT+g=", "narHash": "sha256-/bVBlRpECLVzjV19t5KMdMFWSwKLtb5RyXdjz3LJT+g=",
@ -2075,7 +2131,7 @@
"type": "github" "type": "github"
} }
}, },
"nixpkgs_28": { "nixpkgs_29": {
"locked": { "locked": {
"lastModified": 1754800730, "lastModified": 1754800730,
"narHash": "sha256-HfVZCXic9XLBgybP0318ym3cDnGwBs/+H5MgxFVYF4I=", "narHash": "sha256-HfVZCXic9XLBgybP0318ym3cDnGwBs/+H5MgxFVYF4I=",
@ -2298,7 +2354,7 @@
"nswitch-rcm-nix": { "nswitch-rcm-nix": {
"inputs": { "inputs": {
"flake-parts": "flake-parts_3", "flake-parts": "flake-parts_3",
"nixpkgs": "nixpkgs_18" "nixpkgs": "nixpkgs_19"
}, },
"locked": { "locked": {
"lastModified": 1721304043, "lastModified": 1721304043,
@ -2317,7 +2373,7 @@
"nur": { "nur": {
"inputs": { "inputs": {
"flake-parts": "flake-parts_4", "flake-parts": "flake-parts_4",
"nixpkgs": "nixpkgs_19" "nixpkgs": "nixpkgs_20"
}, },
"locked": { "locked": {
"lastModified": 1763996502, "lastModified": 1763996502,
@ -2549,7 +2605,7 @@
"inputs": { "inputs": {
"flake-compat": "flake-compat_7", "flake-compat": "flake-compat_7",
"gitignore": "gitignore_4", "gitignore": "gitignore_4",
"nixpkgs": "nixpkgs_20" "nixpkgs": "nixpkgs_21"
}, },
"locked": { "locked": {
"lastModified": 1763988335, "lastModified": 1763988335,
@ -2589,7 +2645,8 @@
"nixos-generators": "nixos-generators", "nixos-generators": "nixos-generators",
"nixos-hardware": "nixos-hardware", "nixos-hardware": "nixos-hardware",
"nixos-images": "nixos-images", "nixos-images": "nixos-images",
"nixpkgs": "nixpkgs_17", "nixos-nftables-firewall": "nixos-nftables-firewall",
"nixpkgs": "nixpkgs_18",
"nixpkgs-dev": "nixpkgs-dev", "nixpkgs-dev": "nixpkgs-dev",
"nixpkgs-kernel": "nixpkgs-kernel", "nixpkgs-kernel": "nixpkgs-kernel",
"nixpkgs-stable": "nixpkgs-stable_3", "nixpkgs-stable": "nixpkgs-stable_3",
@ -2724,7 +2781,7 @@
"blobs": "blobs", "blobs": "blobs",
"flake-compat": "flake-compat_8", "flake-compat": "flake-compat_8",
"git-hooks": "git-hooks", "git-hooks": "git-hooks",
"nixpkgs": "nixpkgs_21" "nixpkgs": "nixpkgs_22"
}, },
"locked": { "locked": {
"lastModified": 1763564778, "lastModified": 1763564778,
@ -2760,7 +2817,7 @@
}, },
"sops": { "sops": {
"inputs": { "inputs": {
"nixpkgs": "nixpkgs_22" "nixpkgs": "nixpkgs_23"
}, },
"locked": { "locked": {
"lastModified": 1764483358, "lastModified": 1764483358,
@ -2794,7 +2851,7 @@
}, },
"spicetify-nix": { "spicetify-nix": {
"inputs": { "inputs": {
"nixpkgs": "nixpkgs_23", "nixpkgs": "nixpkgs_24",
"systems": "systems_5" "systems": "systems_5"
}, },
"locked": { "locked": {
@ -2898,7 +2955,7 @@
"firefox-gnome-theme": "firefox-gnome-theme", "firefox-gnome-theme": "firefox-gnome-theme",
"flake-parts": "flake-parts_5", "flake-parts": "flake-parts_5",
"gnome-shell": "gnome-shell", "gnome-shell": "gnome-shell",
"nixpkgs": "nixpkgs_24", "nixpkgs": "nixpkgs_25",
"nur": "nur_2", "nur": "nur_2",
"systems": "systems_6", "systems": "systems_6",
"tinted-foot": "tinted-foot", "tinted-foot": "tinted-foot",
@ -2924,7 +2981,7 @@
"swarsel-nix": { "swarsel-nix": {
"inputs": { "inputs": {
"flake-parts": "flake-parts_6", "flake-parts": "flake-parts_6",
"nixpkgs": "nixpkgs_25", "nixpkgs": "nixpkgs_26",
"systems": "systems_7" "systems": "systems_7"
}, },
"locked": { "locked": {
@ -3175,7 +3232,7 @@
}, },
"treefmt-nix": { "treefmt-nix": {
"inputs": { "inputs": {
"nixpkgs": "nixpkgs_26" "nixpkgs": "nixpkgs_27"
}, },
"locked": { "locked": {
"lastModified": 1762938485, "lastModified": 1762938485,
@ -3193,7 +3250,7 @@
}, },
"vbc-nix": { "vbc-nix": {
"inputs": { "inputs": {
"nixpkgs": "nixpkgs_27", "nixpkgs": "nixpkgs_28",
"systems": "systems_9" "systems": "systems_9"
}, },
"locked": { "locked": {
@ -3271,7 +3328,7 @@
"inputs": { "inputs": {
"crane": "crane_3", "crane": "crane_3",
"flake-utils": "flake-utils_8", "flake-utils": "flake-utils_8",
"nixpkgs": "nixpkgs_28", "nixpkgs": "nixpkgs_29",
"rust-overlay": "rust-overlay_3" "rust-overlay": "rust-overlay_3"
}, },
"locked": { "locked": {

View file

@ -74,6 +74,7 @@
dns.url = "github:kirelagin/dns.nix"; dns.url = "github:kirelagin/dns.nix";
nix-minecraft.url = "github:Infinidoge/nix-minecraft"; nix-minecraft.url = "github:Infinidoge/nix-minecraft";
simple-nixos-mailserver.url = "gitlab:simple-nixos-mailserver/nixos-mailserver/master"; simple-nixos-mailserver.url = "gitlab:simple-nixos-mailserver/nixos-mailserver/master";
nixos-nftables-firewall.url = "github:thelegy/nixos-nftables-firewall";
}; };
outputs = outputs =

View file

@ -1,4 +1,4 @@
{ self, lib, minimal, ... }: { self, config, lib, minimal, confLib, ... }:
{ {
imports = [ imports = [
@ -6,6 +6,7 @@
./disk-config.nix ./disk-config.nix
"${self}/modules/nixos/optional/systemd-networkd-server.nix" "${self}/modules/nixos/optional/systemd-networkd-server.nix"
"${self}/modules/nixos/optional/systemd-networkd-vlan.nix"
]; ];
topology.self = { topology.self = {
@ -31,6 +32,7 @@
rootDisk = "/dev/sda"; rootDisk = "/dev/sda";
swapSize = "8G"; swapSize = "8G";
networkKernelModules = [ "igb" ]; networkKernelModules = [ "igb" ];
withMicroVMs = true;
server = { server = {
wireguard.interfaces = { wireguard.interfaces = {
wgHome = { wgHome = {
@ -47,7 +49,7 @@
swarselprofiles = { swarselprofiles = {
server = true; server = true;
router = false; router = true;
}; };
swarselmodules = { swarselmodules = {
@ -56,4 +58,9 @@
}; };
}; };
guests = lib.mkIf (!minimal && config.swarselsystems.withMicroVMs) (
{ }
// confLib.mkMicrovm "adguardhome"
);
} }

View file

@ -0,0 +1,23 @@
{ self, lib, minimal, ... }:
{
imports = [
"${self}/profiles/nixos/microvm"
"${self}/modules/nixos"
];
swarselsystems = {
isMicroVM = true;
};
} // lib.optionalAttrs (!minimal) {
microvm = {
mem = 1024 * 1;
vcpu = 1;
};
swarselprofiles = {
microvm = true;
};
}

View file

@ -1,5 +1,5 @@
{ {
"data": "ENC[AES256_GCM,data:mi/EbLHjvOmJyK30E719clNAN/hq6FCS1ld0pLG4ahuuDkOfgbUr0vPEmhlxoIrkmD3HNkDufTlFsWezZ9s6OiZKS1ASRSPI96Js43BwVLotub1/YJaV0JMFNVoKTo9ag/5soaAbta0GNq0wExIjBNaVExCmNOs3puXCod4nOI9qmcn/ytx+98+3iZk8p87NTauX5W3jb87QjMqucWaEWxo4DLerkLI54baEMKJUULYRO4/BJ102pFq1twOVNm7v4R8FLbjknNL0A5T2ymmAJqOSpRLApcFJjSda6JkVoMV380a7Wa9cawLF/9xHRJn2K5R5uRx7JTLxL2VuW1olYMSrImO/d08277ZHymxeV07nJCyO/Y/0aR36P5YxJrUwNwKe31oR2RSm3Ns7u/DoC3gymYzbBLlBYMfocl34lL4EkK56W2qiGAfuEf6v/kXqS9X6si+rGDEaXkuS/0UEtsP7AxsUpRYHWngk/DGOUTzKXPkMsNv6IbxHSK4wpA1Xka93r13DrKTzcaoXOqEe+K9GWiJsJl0zAM4UEmYcXF7sh7WzYeeY3D1RT7nt4I0AHaPkt7PKsdo/DR3xQPUluQ553vVUe2rAMokqRVHHzM5OuGwng5iLb3u0fZaD,iv:bmp/x16E/gRXCDqcg5sUt+DRFCRsHIO0/01nr+uFR7Y=,tag:wFw8Efid68B88gTkAbCzuw==,type:str]", "data": "ENC[AES256_GCM,data:jaTRcoqOd3SNxwmzAcsqWyuvhYO0YipQPH2K2SM5OxhWWlUHTWQXqXmuAy0+efNnZlC8xqUWIoU//XXzUq/b7Lhi9bv9WyP7aHLOQNLFZ50Rt3b7yidFA/mxcRo2ZuGUR9mGoP8e1VtiQVVuzZQbJWqTCKtxb8s1f35aZx6NjaqeBFogfhHPwsVPL0lWdaxW2aYj/iwWb65xaxhcXa5mWpYgzfvuTXCkABFhrPxYG+NZpCyG7lt8MWpJ3yYWE0OEr/1Fe0TNfBjp7cih1wvMGIBj9uZRoJWkVwn6T+nldf52WpHCRZCdLhsjXCzM5T0g6Jj1HHatiISYZY3KLVAYKj63nSS3GkHk+BfoiAnJROcE2Aak0w7Op2csbNrNz807kU0x1A3ccbc50PKOGPFAh3JaJJUc0K+pGaIZ+FJhpIT8UyfQ7/YA7CDIvQObI9X7idsWPeuU3YN8VifgsGPznLWHyIgaUW7QmUtH1+KJdO0lo68C13FFnzEoMUroxMoUdS9Bvo1ncC9cITOr3Iuvb9nWQyg+wemyTJ5AOIx7dBh81PxMBYJ3JOTmxiO8LZapyqSbNhcbpo/3Q3s8J2DhIzgR2Ty7EI2tFxoGbzvpzBpWf/c7/rWWO67YDCfmB618w31Phes0/TTK2gxjviH917Q=,iv:M+S2woApVJAglQmvr0X1ZNvezNNl/nvxKjADWWXLiGY=,tag:CT4zP0qyJtbWCBJqqS7F5w==,type:str]",
"sops": { "sops": {
"age": [ "age": [
{ {
@ -7,8 +7,8 @@
"enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBXc3VHa0p2MVdIdHRrbEVi\ndUwxMXA3cFpDODA0Z0MyUC9aemF4U2RXeUhrCmZjSDBLZ0twRk5rZG16blorQVVZ\nRE5SNE51bGlhYTVqcThFUVIvTWxwOW8KLS0tIEVHZ3Z6VVZHK2FUQWZQNVlOTkpL\nYUpNUSsyQllQL0lUa0FaODZiSjBDSk0KSJHdYoiOuma7YFjLpssAgw8BfBo5tl+o\nRvNt9rsXUlXEwMlcmYpkgUlsSAJnus+uE9AdBSvTyFRb9Wo696YFRg==\n-----END AGE ENCRYPTED FILE-----\n" "enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBXc3VHa0p2MVdIdHRrbEVi\ndUwxMXA3cFpDODA0Z0MyUC9aemF4U2RXeUhrCmZjSDBLZ0twRk5rZG16blorQVVZ\nRE5SNE51bGlhYTVqcThFUVIvTWxwOW8KLS0tIEVHZ3Z6VVZHK2FUQWZQNVlOTkpL\nYUpNUSsyQllQL0lUa0FaODZiSjBDSk0KSJHdYoiOuma7YFjLpssAgw8BfBo5tl+o\nRvNt9rsXUlXEwMlcmYpkgUlsSAJnus+uE9AdBSvTyFRb9Wo696YFRg==\n-----END AGE ENCRYPTED FILE-----\n"
} }
], ],
"lastmodified": "2025-12-22T09:31:39Z", "lastmodified": "2025-12-23T09:27:50Z",
"mac": "ENC[AES256_GCM,data:rOOL5gRTILzOnIU7LveEAI3HeLkf16wTZL4toxBqDiReWwXllCeUaFJ+n5awehit44LL1HrFVgZ/uUsnJBpF6WciPjXTKeRZsazhEKEuBhvcfJzvDQvj/ls5QsEXr/xuDmVaLNM7s7QCok+iefSS4Cu9IHhrmmdo1GyIw6gvNP0=,iv:pDnLtzMbGWR0PnIshenuNNvHIglvNFD+DJuUOapWGQI=,tag:9azzi8367Nq0Z0yGW8H5sg==,type:str]", "mac": "ENC[AES256_GCM,data:fuYSElvGFbFIdkQaTwNuXqaXxMuOmpT8moN9m/Yl+6u3e0sU9AMJLK95Azl0xffjScc79PAPXitILrK7gUwUdo4PvTpQo14IoSCzIQ4lcJFlrWXgn9dPFrc97iooMtBMk4hWmTzYL1mHkT/ab7NP3aE7j81N4HJcYwZqzVkdXaI=,iv:hpkTsdwJ+N/NVHEM5LdXC1iwZXT77OwZ+fM9mu3l3Bc=,tag:dxv4T9x9q8g8m5Imcurnag==,type:str]",
"pgp": [ "pgp": [
{ {
"created_at": "2025-12-15T22:09:23Z", "created_at": "2025-12-15T22:09:23Z",

View file

@ -38,6 +38,7 @@ kanidm-grafana: ENC[AES256_GCM,data:61PEA1fBcaRy8+x0dn9WrH9P0D+NOkbeZw==,iv:kbR3
kanidm-nextcloud: ENC[AES256_GCM,data:9FjsOzBos18ouHBeuzrzHIpCDowFt0Aktw==,iv:iqUQUsWsO5N+KZqHyqNxMxSija/yPrrrAqvz4b1NG1M=,tag:/WC3wg/eYXV3hLJPRVWLog==,type:str] kanidm-nextcloud: ENC[AES256_GCM,data:9FjsOzBos18ouHBeuzrzHIpCDowFt0Aktw==,iv:iqUQUsWsO5N+KZqHyqNxMxSija/yPrrrAqvz4b1NG1M=,tag:/WC3wg/eYXV3hLJPRVWLog==,type:str]
kanidm-oauth2-proxy: ENC[AES256_GCM,data:DQ5tj7N+P1b8vFnF+MGhaUBvbVQoE4sVhQ==,iv:Xy4bdi8fSFuFHsQKgZ3PswFFYsqtiAeqeSRam1k/H0E=,tag:9W4LRPPYtDOrSpxRDK/7sg==,type:str] kanidm-oauth2-proxy: ENC[AES256_GCM,data:DQ5tj7N+P1b8vFnF+MGhaUBvbVQoE4sVhQ==,iv:Xy4bdi8fSFuFHsQKgZ3PswFFYsqtiAeqeSRam1k/H0E=,tag:9W4LRPPYtDOrSpxRDK/7sg==,type:str]
kanidm-freshrss: ENC[AES256_GCM,data:4y0X3sSOfs5pKNCmZGJhxlAKH7GD1UACdw==,iv:LuQQCfOpsTqglwQvohHMFpNGaOjoZ8PKDgG50qBP02k=,tag:Z5mVYP/9nToerQ1qui1eWQ==,type:str] kanidm-freshrss: ENC[AES256_GCM,data:4y0X3sSOfs5pKNCmZGJhxlAKH7GD1UACdw==,iv:LuQQCfOpsTqglwQvohHMFpNGaOjoZ8PKDgG50qBP02k=,tag:Z5mVYP/9nToerQ1qui1eWQ==,type:str]
kanidm-firezone: ENC[AES256_GCM,data:hQWySw7EZZN2AT7rM4R2go8DAGYHph32tQ==,iv:vASPrP7qM1G5c4tC1aaAbCigglXt4keThMYOJdRYhOg=,tag:f5jevrQtiHAQTbMY07iIrQ==,type:str]
#ENC[AES256_GCM,data:M9U+Mr1cAhlt7NpW,iv:LY19BZEwDdQD1Nhbmgdt9/9VNJjcTkOGP7SwEDE3Xwk=,tag:TlYrhu5dBj1D+Qd72r7Ofg==,type:comment] #ENC[AES256_GCM,data:M9U+Mr1cAhlt7NpW,iv:LY19BZEwDdQD1Nhbmgdt9/9VNJjcTkOGP7SwEDE3Xwk=,tag:TlYrhu5dBj1D+Qd72r7Ofg==,type:comment]
firefly-iii-app-key: ENC[AES256_GCM,data:hzgl8eRL0irNRP5TO7G1rNtNM7fXCkmbcaX4QoTsM0xA1rgyKwiy6a4lYDjoXZyOMy5p,iv:q5eepIELwIecyQ56A6THUOu+rebK3irKVYb7/gNHlU8=,tag:+M/KTX1JzPzXeK4TRzW42w==,type:str] firefly-iii-app-key: ENC[AES256_GCM,data:hzgl8eRL0irNRP5TO7G1rNtNM7fXCkmbcaX4QoTsM0xA1rgyKwiy6a4lYDjoXZyOMy5p,iv:q5eepIELwIecyQ56A6THUOu+rebK3irKVYb7/gNHlU8=,tag:+M/KTX1JzPzXeK4TRzW42w==,type:str]
#ENC[AES256_GCM,data:mBlfyJvQyrhTnpkJ,iv:hHnTCsHfzCgKuBO82JjNbjYYjWV8e7+0VRkbTGw+WRE=,tag:7Dp77Q2VjWJM5LydvpbJnQ==,type:comment] #ENC[AES256_GCM,data:mBlfyJvQyrhTnpkJ,iv:hHnTCsHfzCgKuBO82JjNbjYYjWV8e7+0VRkbTGw+WRE=,tag:7Dp77Q2VjWJM5LydvpbJnQ==,type:comment]
@ -69,8 +70,8 @@ sops:
c0lDa2EvQkUwM1ZIc1ppY1REZnlPKzQKJRXSl8SYQwzgPw+twNAFy3y+S2r7JwS0 c0lDa2EvQkUwM1ZIc1ppY1REZnlPKzQKJRXSl8SYQwzgPw+twNAFy3y+S2r7JwS0
xESNBdFS4Ntg9gXENRBzCaGmoOJfiFtGditBlvWUwbDYwLdn/y3kIQ== xESNBdFS4Ntg9gXENRBzCaGmoOJfiFtGditBlvWUwbDYwLdn/y3kIQ==
-----END AGE ENCRYPTED FILE----- -----END AGE ENCRYPTED FILE-----
lastmodified: "2025-12-04T12:35:41Z" lastmodified: "2025-12-24T13:09:23Z"
mac: ENC[AES256_GCM,data:0Ps8slUmB7A+2vvCa44pOIVs+ehzczFyVUYh8vledsEW3odgm5LemmilspSw3xmf4V3cTl0h7mgGvLHJhpaZpI4nS4W4Cz3CrN6v3eu8ELRorVHUIDPIJNfzaCeRlat+oujGCWAuMbaEyXYj40PtXq9pSaYSluxDiPQu+QwKRaA=,iv:Rb1RcTJThoWO76vfDcyYlF3VnrDkN12frVdcQhRTLzQ=,tag:Mu5IgH541rXP3rlP1XlJrA==,type:str] mac: ENC[AES256_GCM,data:BNaX6zXAxEzarm0+X5qDIIOOfLoUFIlhhLN7QATzHIYoujZaJCGFWlM/+k9cnnIcGak22b0hwydjCF+opgH2bbau8P4NFPbWGxJHVry1Nu+EyB+Qb4QnVZZDWMcDxEMChR5eZvLAFC/K2f6oLtJeL2kGtedb079jhwpJt9nr87s=,iv:90SerUCkSoBqDYH4J6SV7cRXwGeinW44NxhSnfJ0r2k=,tag:8VnRp2oAuctwp7Nk3U7OWw==,type:str]
pgp: pgp:
- created_at: "2025-12-02T14:59:44Z" - created_at: "2025-12-02T14:59:44Z"
enc: |- enc: |-

34683
index.html

File diff suppressed because it is too large Load diff

View file

@ -1,3 +1,4 @@
# @ future me: dont panic, this file is not read in by readNix
{ lib, ... }: { lib, ... }:
let let
importNames = lib.swarselsystems.readNix "modules/home"; importNames = lib.swarselsystems.readNix "modules/home";

View file

@ -1,4 +1,4 @@
{ self, lib, config, vars, ... }: { self, lib, config, vars, withHomeManager, ... }:
{ {
options.swarselmodules.stylix = lib.mkEnableOption "stylix config"; options.swarselmodules.stylix = lib.mkEnableOption "stylix config";
config = { config = {
@ -12,6 +12,7 @@
image = config.swarselsystems.wallpaper; image = config.swarselsystems.wallpaper;
} }
vars.stylix); vars.stylix);
} // lib.optionalAttrs withHomeManager {
home-manager.users."${config.swarselsystems.mainUser}" = { home-manager.users."${config.swarselsystems.mainUser}" = {
stylix = { stylix = {
targets = vars.stylixHomeTargets; targets = vars.stylixHomeTargets;

View file

@ -1,19 +1,20 @@
{ lib, config, pkgs, ... }: { lib, config, pkgs, withHomeManager, ... }:
let let
inherit (config.swarselsystems) mainUser; inherit (config.swarselsystems) mainUser;
in in
{ {
options.swarselmodules.sway = lib.mkEnableOption "sway config"; options.swarselmodules.sway = lib.mkEnableOption "sway config";
config = lib.mkIf config.swarselmodules.sway { config = lib.mkIf config.swarselmodules.sway
programs.sway = { {
enable = true; programs.sway = {
package = pkgs.swayfx; enable = true;
wrapperFeatures = { package = pkgs.swayfx;
base = true; wrapperFeatures = {
gtk = true; base = true;
gtk = true;
};
}; };
} // lib.optionalAttrs withHomeManager {
inherit (config.home-manager.users.${mainUser}.wayland.windowManager.sway) extraSessionCommands; inherit (config.home-manager.users.${mainUser}.wayland.windowManager.sway) extraSessionCommands;
};
}; };
} }

View file

@ -138,6 +138,10 @@ in
type = types.nullOr types.str; type = types.nullOr types.str;
default = null; default = null;
}; };
isHome = mkOption {
type = types.bool;
default = false;
};
}; };
}) })
); );
@ -188,6 +192,9 @@ in
wanAddress6 = mkOption { wanAddress6 = mkOption {
type = types.nullOr types.net.ipv6; type = types.nullOr types.net.ipv6;
}; };
isHome = mkOption {
type = types.bool;
};
}; };
} }
); );

View file

@ -1,45 +1,47 @@
{ self, lib, config, globals, ... }: { self, lib, config, globals, withHomeManager, ... }:
let let
inherit (config.swarselsystems) mainUser homeDir; inherit (config.swarselsystems) mainUser homeDir;
inherit (config.repo.secrets.common.emacs) radicaleUser; inherit (config.repo.secrets.common.emacs) radicaleUser;
modules = config.home-manager.users.${mainUser}.swarselmodules;
certsSopsFile = self + /secrets/repo/certs.yaml; certsSopsFile = self + /secrets/repo/certs.yaml;
in in
{ {
config = lib.mkIf config.swarselsystems.withHomeManager { config = { } // lib.optionalAttrs withHomeManager {
sops = { sops =
secrets = (lib.optionalAttrs modules.mail let
{ modules = config.home-manager.users.${mainUser}.swarselmodules;
in
{
secrets = (lib.optionalAttrs modules.mail {
address1-token = { owner = mainUser; }; address1-token = { owner = mainUser; };
address2-token = { owner = mainUser; }; address2-token = { owner = mainUser; };
address3-token = { owner = mainUser; }; address3-token = { owner = mainUser; };
address4-token = { owner = mainUser; }; address4-token = { owner = mainUser; };
}) // (lib.optionalAttrs modules.waybar { }) // (lib.optionalAttrs modules.waybar {
github-notifications-token = { owner = mainUser; }; github-notifications-token = { owner = mainUser; };
}) // (lib.optionalAttrs modules.emacs { }) // (lib.optionalAttrs modules.emacs {
fever-pw = { path = "${homeDir}/.emacs.d/.fever"; owner = mainUser; }; fever-pw = { path = "${homeDir}/.emacs.d/.fever"; owner = mainUser; };
}) // (lib.optionalAttrs modules.zsh { }) // (lib.optionalAttrs modules.zsh {
croc-password = { owner = mainUser; }; croc-password = { owner = mainUser; };
github-nixpkgs-review-token = { owner = mainUser; }; github-nixpkgs-review-token = { owner = mainUser; };
}) // (lib.optionalAttrs modules.emacs { }) // (lib.optionalAttrs modules.emacs {
emacs-radicale-pw = { owner = mainUser; }; emacs-radicale-pw = { owner = mainUser; };
github-forge-token = { owner = mainUser; }; github-forge-token = { owner = mainUser; };
}) // (lib.optionalAttrs (modules ? optional-work) { }) // (lib.optionalAttrs (modules ? optional-work) {
harica-root-ca = { sopsFile = certsSopsFile; path = "${homeDir}/.aws/certs/harica-root.pem"; owner = mainUser; }; harica-root-ca = { sopsFile = certsSopsFile; path = "${homeDir}/.aws/certs/harica-root.pem"; owner = mainUser; };
}) // (lib.optionalAttrs modules.anki { }) // (lib.optionalAttrs modules.anki {
anki-user = { owner = mainUser; }; anki-user = { owner = mainUser; };
anki-pw = { owner = mainUser; }; anki-pw = { owner = mainUser; };
}); });
templates = { templates = {
authinfo = lib.mkIf modules.emacs { authinfo = lib.mkIf modules.emacs {
path = "${homeDir}/.emacs.d/.authinfo"; path = "${homeDir}/.emacs.d/.authinfo";
content = '' content = ''
machine ${globals.services.radicale.domain} login ${radicaleUser} password ${config.sops.placeholder.emacs-radicale-pw} machine ${globals.services.radicale.domain} login ${radicaleUser} password ${config.sops.placeholder.emacs-radicale-pw}
''; '';
owner = mainUser; owner = mainUser;
};
}; };
}; };
};
}; };
} }

View file

@ -1,8 +1,8 @@
{ self, inputs, config, lib, homeLib, outputs, globals, nodes, minimal, configName, arch, type, ... }: { self, inputs, config, lib, homeLib, outputs, globals, nodes, minimal, configName, arch, type, withHomeManager, ... }:
{ {
options.swarselmodules.home-manager = lib.mkEnableOption "home-manager"; options.swarselmodules.home-manager = lib.mkEnableOption "home-manager";
config = lib.mkIf config.swarselmodules.home-manager { config = lib.mkIf config.swarselmodules.home-manager {
home-manager = lib.mkIf config.swarselsystems.withHomeManager { home-manager = lib.mkIf withHomeManager {
useGlobalPkgs = true; useGlobalPkgs = true;
useUserPackages = true; useUserPackages = true;
verbose = true; verbose = true;

View file

@ -1,4 +1,4 @@
{ self, lib, pkgs, config, outputs, inputs, minimal, globals, ... }: { self, lib, pkgs, config, outputs, inputs, minimal, globals, withHomeManager, ... }:
let let
inherit (config.swarselsystems) mainUser; inherit (config.swarselsystems) mainUser;
inherit (config.repo.secrets.common) atticPublicKey; inherit (config.repo.secrets.common) atticPublicKey;
@ -122,18 +122,19 @@ in
nixpkgs = { nixpkgs = {
overlays = [ overlays = [
outputs.overlays.default outputs.overlays.default
] ++ lib.optionals withHomeManager [
(final: prev: (final: prev:
let let
additions = final: _: import "${self}/pkgs/config" { additions = final: _: import "${self}/pkgs/config" {
inherit self config lib; inherit self config lib;
pkgs = final; pkgs = final;
homeConfig = config.home-manager.users.${config.swarselsystems.mainUser}; homeConfig = config.home-manager.users.${config.swarselsystems.mainUser} or { };
}; };
in in
additions final prev additions final prev
) )
]; ];
config = { config = lib.mkIf (!config.swarselsystems.isMicroVM) {
allowUnfree = true; allowUnfree = true;
}; };
}; };

View file

@ -16,7 +16,7 @@
description = "Leon S"; description = "Leon S";
password = lib.mkIf (minimal || config.swarselsystems.isPublic) "setup"; password = lib.mkIf (minimal || config.swarselsystems.isPublic) "setup";
hashedPasswordFile = lib.mkIf (!minimal && !config.swarselsystems.isPublic) config.sops.secrets.main-user-hashed-pw.path; hashedPasswordFile = lib.mkIf (!minimal && !config.swarselsystems.isPublic) config.sops.secrets.main-user-hashed-pw.path;
extraGroups = [ "wheel" ] ++ lib.optionals (!minimal) [ "networkmanager" "syncthing" "docker" "lp" "audio" "video" "vboxusers" "libvirtd" "scanner" ]; extraGroups = [ "wheel" ] ++ lib.optionals (!minimal && !config.swarselsystems.isMicroVM) [ "networkmanager" "syncthing" "docker" "lp" "audio" "video" "vboxusers" "libvirtd" "scanner" ];
packages = with pkgs; [ ]; packages = with pkgs; [ ];
}; };
}; };

View file

@ -1,4 +1,4 @@
{ self, lib, config, outputs, globals, ... }: { self, lib, config, outputs, globals, withHomeManager, ... }:
let let
macUser = globals.user.work; macUser = globals.user.work;
in in
@ -7,20 +7,22 @@ in
]; ];
options.swarselmodules.optional.darwin = lib.mkEnableOption "optional darwin settings"; options.swarselmodules.optional.darwin = lib.mkEnableOption "optional darwin settings";
config = lib.mkIf config.swarselmodules.optional.darwin { config = lib.mkIf config.swarselmodules.optional.darwin
nix.settings.experimental-features = "nix-command flakes"; {
nixpkgs = { nix.settings.experimental-features = "nix-command flakes";
hostPlatform = "x86_64-darwin"; nixpkgs = {
overlays = [ outputs.overlays.default ]; hostPlatform = "x86_64-darwin";
config = { overlays = [ outputs.overlays.default ];
allowUnfree = true; config = {
allowUnfree = true;
};
}; };
};
system.stateVersion = 4;
} // lib.optionalAttrs withHomeManager {
home-manager.users."${macUser}".imports = [ home-manager.users."${macUser}".imports = [
"${self}/modules/home/darwin" "${self}/modules/home/darwin"
]; ];
system.stateVersion = 4;
}; };
} }

View file

@ -1,3 +1,4 @@
# @ future me: dont panic, optionals and darwin are not read in by readNix
{ lib, ... }: { lib, ... }:
let let
importNames = lib.swarselsystems.readNix "modules/nixos"; importNames = lib.swarselsystems.readNix "modules/nixos";

View file

@ -1,3 +1,4 @@
# @ future me: dont panic, this file is not read in by readNix
{ lib, ... }: { lib, ... }:
let let
importNames = lib.swarselsystems.readNix "modules/nixos/optional"; importNames = lib.swarselsystems.readNix "modules/nixos/optional";

View file

@ -1,12 +1,7 @@
{ self, config, ... }: { self, lib, config, withHomeManager, ... }:
{ {
config = { config = {
home-manager.users."${config.swarselsystems.mainUser}" = {
imports = [
"${self}/modules/home/optional/framework.nix"
];
};
services = { services = {
fwupd = { fwupd = {
@ -29,5 +24,11 @@
defaultStrategy = "lazy"; defaultStrategy = "lazy";
}; };
}; };
} // lib.optionalAttrs withHomeManager {
home-manager.users."${config.swarselsystems.mainUser}" = {
imports = [
"${self}/modules/home/optional/framework.nix"
];
};
}; };
} }

View file

@ -1,13 +1,7 @@
{ self, pkgs, config, ... }: { self, lib, pkgs, config, withHomeManager, ... }:
{ {
config = { config = {
home-manager.users."${config.swarselsystems.mainUser}" = {
imports = [
"${self}/modules/home/optional/gaming.nix"
];
};
programs.steam = { programs.steam = {
enable = true; enable = true;
package = pkgs.steam; package = pkgs.steam;
@ -41,6 +35,12 @@
# ]; # ];
# }; # };
# }; # };
} // lib.optionalAttrs withHomeManager {
home-manager.users."${config.swarselsystems.mainUser}" = {
imports = [
"${self}/modules/home/optional/gaming.nix"
];
};
}; };
} }

View file

@ -1,9 +1,28 @@
_: { self, inputs, ... }:
{ {
# imports = [ imports = [
# inputs.microvm.nixosModules.microvm inputs.disko.nixosModules.disko
# ]; inputs.home-manager.nixosModules.home-manager
inputs.impermanence.nixosModules.impermanence
inputs.lanzaboote.nixosModules.lanzaboote
inputs.microvm.nixosModules.host
inputs.microvm.nixosModules.microvm
inputs.nix-index-database.nixosModules.nix-index
inputs.nix-minecraft.nixosModules.minecraft-servers
inputs.nix-topology.nixosModules.default
inputs.nswitch-rcm-nix.nixosModules.nswitch-rcm
inputs.simple-nixos-mailserver.nixosModules.default
inputs.sops.nixosModules.sops
inputs.stylix.nixosModules.stylix
inputs.swarsel-nix.nixosModules.default
inputs.nixos-nftables-firewall.nixosModules.default
config = (inputs.nixos-extra-modules + "/modules/interface-naming.nix")
{ };
"${self}/modules/shared/meta.nix"
];
config = {
system.stateVersion = "23.05";
};
} }

View file

@ -0,0 +1,116 @@
{ lib, config, globals, ... }:
{
systemd.network = {
wait-online.anyInterface = true;
netdevs = {
"10-veth" = {
netdevConfig = {
Kind = "veth";
Name = "veth-br";
};
peerConfig = {
Name = "veth-int";
};
};
"20-br" = {
netdevConfig = {
Kind = "bridge";
Name = "br";
};
};
} // lib.flip lib.concatMapAttrs globals.networks.home-lan.vlans (
vlanName: vlanCfg: {
"30-vlan-${vlanName}" = {
netdevConfig = {
Kind = "vlan";
Name = "vlan-${vlanName}";
};
vlanConfig.Id = vlanCfg.id;
};
"40-me-${vlanName}" = {
netdevConfig = {
Name = "me-${vlanName}";
Kind = "macvlan";
};
extraConfig = ''
[MACVLAN]
Mode=bridge
'';
};
}
);
networks = {
"40-br" = {
matchConfig.Name = "br";
bridgeConfig = { };
linkConfig = {
ActivationPolicy = "always-up";
RequiredForOnline = "no";
};
networkConfig = {
ConfigureWithoutCarrier = true;
LinkLocalAddressing = "no";
};
};
"15-veth-br" = {
matchConfig.Name = "veth-br";
linkConfig = {
RequiredForOnline = "no";
};
networkConfig = {
Bridge = "br";
};
};
"15-veth-int" = {
matchConfig.Name = "veth-int";
linkConfig = {
ActivationPolicy = "always-up";
RequiredForOnline = "no";
};
networkConfig = {
ConfigureWithoutCarrier = true;
LinkLocalAddressing = "no";
};
vlan = map (name: "vlan-${name}") (builtins.attrNames globals.networks.home-lan.vlans);
};
"90-macvtap-ignore" = {
matchConfig.Kind = "macvtap";
linkConfig.ActivationPolicy = "manual";
linkConfig.Unmanaged = "yes";
};
} // lib.flip lib.concatMapAttrs globals.networks.home-lan.vlans (
vlanName: vlanCfg: {
"30-vlan-${vlanName}" = {
matchConfig.Name = "vlan-${vlanName}";
networkConfig.LinkLocalAddressing = "no";
networkConfig.MACVLAN = "me-${vlanName}";
linkConfig.RequiredForOnline = "no";
};
"40-me-${vlanName}" = {
address = [
vlanCfg.hosts.${config.node.name}.cidrv4
vlanCfg.hosts.${config.node.name}.cidrv6
];
matchConfig.Name = "me-${vlanName}";
networkConfig = {
IPv4Forwarding = "yes";
IPv6PrivacyExtensions = "yes";
IPv6SendRA = true;
IPv6AcceptRA = false;
};
ipv6Prefixes = [
{ Prefix = vlanCfg.cidrv6; }
];
linkConfig.RequiredForOnline = "routable";
};
}
);
};
}

View file

@ -1,6 +1,6 @@
{ self, config, ... }: { self, config, withHomeManager, ... }:
{ {
config = { config = { } // lib.optionalAttrs withHomeManager {
home-manager.users."${config.swarselsystems.mainUser}" = { home-manager.users."${config.swarselsystems.mainUser}" = {
imports = [ imports = [

View file

@ -1,4 +1,4 @@
{ self, lib, pkgs, config, ... }: { self, lib, pkgs, config, withHomeManager, ... }:
let let
inherit (config.swarselsystems) mainUser homeDir; inherit (config.swarselsystems) mainUser homeDir;
iwd = config.networking.networkmanager.wifi.backend == "iwd"; iwd = config.networking.networkmanager.wifi.backend == "iwd";
@ -18,12 +18,6 @@ in
}; };
config = { config = {
home-manager.users."${config.swarselsystems.mainUser}" = {
imports = [
"${self}/modules/home/optional/work.nix"
];
};
sops = sops =
let let
secretNames = [ secretNames = [
@ -198,7 +192,7 @@ in
openssh = { openssh = {
enable = true; enable = true;
extraConfig = '' extraConfig = ''
''; '';
}; };
syncthing = { syncthing = {
@ -236,6 +230,13 @@ in
# ]; # ];
# }; # };
# }; # };
} // lib.optionalAttrs withHomeManager {
home-manager.users."${config.swarselsystems.mainUser}" = {
imports = [
"${self}/modules/home/optional/work.nix"
];
};
}; };
} }

View file

@ -0,0 +1,76 @@
{ lib, config, globals, confLib, ... }:
let
inherit (confLib.gen { name = "kea"; dir = "/var/lib/private/kea"; }) serviceName serviceDir;
in
{
options = {
swarselmodules.server.${serviceName} = lib.mkEnableOption "enable ${serviceName} on server";
};
config = lib.mkIf config.swarselmodules.server.${serviceName} {
environment.persistence."/persist".directories = lib.mkIf config.swarselsystems.isImpermanence [
{ directory = serviceDir; mode = "0700"; }
];
services.kea.dhcp4 = {
enable = true;
settings = {
lease-database = {
name = "/var/lib/kea/dhcp4.leases";
persist = true;
type = "memfile";
};
valid-lifetime = 86400;
renew-timer = 3600;
interfaces-config = {
# XXX: BUG: why does this bind other macvtaps?
interfaces = map (name: "me-${name}") (builtins.attrNames globals.networks.home-lan.vlans);
service-sockets-max-retries = -1;
};
subnet4 = lib.flip lib.mapAttrsToList globals.networks.home-lan.vlans (
vlanName: vlanCfg: {
inherit (vlanCfg) id;
interface = "me-${vlanName}";
subnet = vlanCfg.cidrv4;
pools = [
{
pool = "${lib.net.cidr.host 20 vlanCfg.cidrv4} - ${lib.net.cidr.host (-6) vlanCfg.cidrv4}";
}
];
option-data =
[
{
name = "routers";
data = vlanCfg.hosts.hintbooth.ipv4; # FIXME: how to advertise v6 address also?
}
];
# Advertise DNS server for VLANS that have internet access
# ++
# lib.optional
# (lib.elem vlanName [
# "services"
# "home"
# "devices"
# "guests"
# ])
# {
# name = "domain-name-servers";
# data = globals.networks.home-lan.vlans.services.hosts.hintbooth-adguardhome.ipv4;
# };
reservations = lib.concatLists (
lib.forEach (builtins.attrValues vlanCfg.hosts) (
hostCfg:
lib.optional (hostCfg.mac != null) {
hw-address = hostCfg.mac;
ip-address = hostCfg.ipv4;
}
)
);
}
);
};
};
};
}

View file

@ -0,0 +1,74 @@
{ lib, config, confLib, ... }:
let
inherit (confLib.gen { name = "nftables"; }) serviceName;
in
{
options = {
swarselmodules.${serviceName} = lib.mkEnableOption "enable ${serviceName} on server";
};
config = lib.mkIf config.swarselmodules.${serviceName} {
networking.nftables = {
stopRuleset = lib.mkDefault ''
table inet filter {
chain input {
type filter hook input priority filter; policy drop;
ct state invalid drop
ct state {established, related} accept
iifname lo accept
meta l4proto ipv6-icmp accept
meta l4proto icmp accept
ip protocol igmp accept
tcp dport ${toString (lib.head config.services.openssh.ports)} accept
}
chain forward {
type filter hook forward priority filter; policy drop;
}
chain output {
type filter hook output priority filter; policy accept;
}
}
'';
firewall = {
enable = true;
localZoneName = "local";
snippets = {
nnf-common.enable = false;
nnf-conntrack.enable = true;
nnf-drop.enable = true;
nnf-loopback.enable = true;
nnf-ssh.enable = true;
};
rules.untrusted-to-local = {
from = [ "untrusted" ];
to = [ "local" ];
inherit (config.networking.firewall)
allowedTCPPorts
allowedTCPPortRanges
allowedUDPPorts
allowedUDPPortRanges
;
};
rules.icmp-and-igmp = {
after = [
"ct"
"ssh"
];
from = "all";
to = [ "local" ];
extraLines = [
"meta l4proto ipv6-icmp accept"
"meta l4proto icmp accept"
"ip protocol igmp accept"
];
};
};
};
};
}

View file

@ -1,4 +1,4 @@
{ lib, config, pkgs, ... }: { lib, config, pkgs, withHomeManager, ... }:
{ {
options.swarselmodules.server.packages = lib.mkEnableOption "enable packages on server"; options.swarselmodules.server.packages = lib.mkEnableOption "enable packages on server";
config = lib.mkIf config.swarselmodules.server.packages { config = lib.mkIf config.swarselmodules.server.packages {
@ -14,6 +14,7 @@
tmux tmux
busybox busybox
swarsel-deploy swarsel-deploy
] ++ lib.optionals withHomeManager [
swarsel-gens swarsel-gens
swarsel-switch swarsel-switch
]; ];

View file

@ -1,56 +1,142 @@
{ lib, config, ... }: { lib, config, globals, ... }:
let let
serviceName = "router"; serviceName = "router";
in in
{ {
options.swarselmodules.server.${serviceName} = lib.mkEnableOption "enable ${serviceName} on server"; options.swarselmodules.server.${serviceName} = lib.mkEnableOption "enable ${serviceName} on server";
config = lib.mkIf config.swarselmodules.server.${serviceName} { config = lib.mkIf config.swarselmodules.server.${serviceName}
{
services.avahi.reflector = true;
systemd.network = { networking.nftables = {
wait-online.anyInterface = true; firewall = {
networks = { zones = {
"30-lan0" = { untrusted.interfaces = [ "lan" ];
matchConfig.Name = "lan0"; wgHome.interfaces = [ "wgHome" ];
linkConfig.RequiredForOnline = "enslaved"; adguardhome.ipv4Addresses = [ globals.networks.home-lan.vlans.services.hosts.hintbooth-adguardhome.ipv4 ];
networkConfig = { adguardhome.ipv6Addresses = [ globals.networks.home-lan.vlans.services.hosts.hintbooth-adguardhome.ipv6 ];
ConfigureWithoutCarrier = true; }
// lib.flip lib.concatMapAttrs globals.networks.home-lan.vlans (
vlanName: _: {
"vlan-${vlanName}".interfaces = [ "me-${vlanName}" ];
}
);
rules = {
masquerade-internet = {
from = map (name: "vlan-${name}") (builtins.attrNames globals.networks.home-lan.vlans);
to = [ "untrusted" ];
# masquerade = true; NOTE: custom rule below for ip4 + ip6
late = true; # Only accept after any rejects have been processed
verdict = "accept";
};
# Allow access to the AdGuardHome DNS server from any VLAN that has internet access
access-adguardhome-dns = {
from = map (name: "vlan-${name}") (builtins.attrNames globals.networks.home-lan.vlans);
to = [ "adguardhome" ];
verdict = "accept";
};
# Allow devices in the home VLAN to talk to any of the services or home devices.
access-services = {
from = [ "vlan-home" ];
to = [
"vlan-services"
"vlan-devices"
];
late = true;
verdict = "accept";
};
# Allow the services VLAN to talk to our wireguard server
services-to-local = {
from = [ "vlan-services" ];
to = [ "local" ];
allowedUDPPorts = [ 52829 ];
};
# Forward traffic between wireguard participants
forward-proxy-home-vpn-traffic = {
from = [ "wgHome" ];
to = [ "wgHome" ];
verdict = "accept";
};
}; };
}; };
"30-lan1" = {
matchConfig.Name = "lan1"; chains.postrouting = {
linkConfig.RequiredForOnline = "enslaved"; masquerade-internet = {
networkConfig = { after = [ "hook" ];
ConfigureWithoutCarrier = true; late = true;
rules =
lib.forEach
(map (name: "vlan-${name}") (builtins.attrNames globals.networks.home-lan.vlans))
(
zone:
lib.concatStringsSep " " [
"meta protocol { ip, ip6 }"
(lib.head config.networking.nftables.firewall.zones.${zone}.ingressExpression)
(lib.head config.networking.nftables.firewall.zones.untrusted.egressExpression)
"masquerade random"
]
);
}; };
}; };
"30-lan2" = {
matchConfig.Name = "lan2";
linkConfig.RequiredForOnline = "enslaved";
networkConfig = {
ConfigureWithoutCarrier = true;
};
};
"30-lan3" = {
matchConfig.Name = "lan3";
linkConfig.RequiredForOnline = "enslaved";
networkConfig = {
ConfigureWithoutCarrier = true;
};
};
"10-wan" = {
matchConfig.Name = "wan";
networkConfig = {
# start a DHCP Client for IPv4 Addressing/Routing
DHCP = "ipv4";
DNSOverTLS = true;
DNSSEC = true;
IPv6PrivacyExtensions = false;
IPForward = true;
};
# make routing on this interface a dependency for network-online.target
linkConfig.RequiredForOnline = "routable";
};
}; };
boot.kernel.sysctl = {
"net.ipv4.ip_forward" = 1;
"net.ipv4.conf.all.forwarding" = true;
"net.ipv6.conf.all.forwarding" = true;
};
systemd.network = {
wait-online.anyInterface = true;
networks = {
"30-lan1" = {
matchConfig.MACAddress = config.repo.secrets.local.networking.networks.lan1.mac;
linkConfig.RequiredForOnline = "enslaved";
networkConfig = {
Bridge = "br";
ConfigureWithoutCarrier = true;
};
};
"30-lan2" = {
matchConfig.MACAddress = config.repo.secrets.local.networking.networks.lan2.mac;
linkConfig.RequiredForOnline = "enslaved";
networkConfig = {
Bridge = "br";
ConfigureWithoutCarrier = true;
};
};
"30-lan3" = {
matchConfig.MACAddress = config.repo.secrets.local.networking.networks.lan3.mac;
linkConfig.RequiredForOnline = "enslaved";
networkConfig = {
Bridge = "br";
ConfigureWithoutCarrier = true;
};
};
"30-lan4" = {
matchConfig.MACAddress = config.repo.secrets.local.networking.networks.lan4.mac;
linkConfig.RequiredForOnline = "enslaved";
networkConfig = {
Bridge = "br";
ConfigureWithoutCarrier = true;
};
};
"30-lan5" = {
matchConfig.MACAddress = config.repo.secrets.local.networking.networks.lan5.mac;
linkConfig.RequiredForOnline = "enslaved";
networkConfig = {
Bridge = "br";
ConfigureWithoutCarrier = true;
};
};
};
};
}; };
};
} }

View file

@ -22,16 +22,18 @@ in
} }
config.swarselsystems.shellAliases; config.swarselsystems.shellAliases;
nixpkgs.config.permittedInsecurePackages = [ nixpkgs.config = lib.mkIf (!config.swarselsystems.isMicroVM) {
# matrix perittedInsecurePackages = [
"olm-3.2.16" # matrix
# sonarr "olm-3.2.16"
"aspnetcore-runtime-wrapped-6.0.36" # sonarr
"aspnetcore-runtime-6.0.36" "aspnetcore-runtime-wrapped-6.0.36"
"dotnet-sdk-wrapped-6.0.428" "aspnetcore-runtime-6.0.36"
"dotnet-sdk-6.0.428" "dotnet-sdk-wrapped-6.0.428"
# "dotnet-sdk-6.0.428"
"SDL_ttf-2.0.11" #
]; "SDL_ttf-2.0.11"
];
};
}; };
} }

View file

@ -1,4 +1,4 @@
{ self, lib, config, ... }: { self, lib, config, withHomeManager, ... }:
{ {
options.swarselmodules.server.ssh = lib.mkEnableOption "enable ssh on server"; options.swarselmodules.server.ssh = lib.mkEnableOption "enable ssh on server";
config = lib.mkIf config.swarselmodules.server.ssh { config = lib.mkIf config.swarselmodules.server.ssh {
@ -21,16 +21,18 @@
} }
]; ];
}; };
users.users."${config.swarselsystems.mainUser}".openssh.authorizedKeys.keyFiles = [ users.users = {
(self + /secrets/public/ssh/yubikey.pub) "${config.swarselsystems.mainUser}".openssh.authorizedKeys.keyFiles = lib.mkIf withHomeManager [
(self + /secrets/public/ssh/magicant.pub) (self + /secrets/public/ssh/yubikey.pub)
# (lib.mkIf config.swarselsystems.isBastionTarget (self + /secrets/public/ssh/jump.pub)) (self + /secrets/public/ssh/magicant.pub)
]; # (lib.mkIf config.swarselsystems.isBastionTarget (self + /secrets/public/ssh/jump.pub))
users.users.root.openssh.authorizedKeys.keyFiles = [ ];
(self + /secrets/public/ssh/yubikey.pub) root.openssh.authorizedKeys.keyFiles = [
(self + /secrets/public/ssh/magicant.pub) (self + /secrets/public/ssh/yubikey.pub)
# (lib.mkIf config.swarselsystems.isBastionTarget (self + /secrets/public/ssh/jump.pub)) (self + /secrets/public/ssh/magicant.pub)
]; # (lib.mkIf config.swarselsystems.isBastionTarget (self + /secrets/public/ssh/jump.pub))
];
};
security.sudo.extraConfig = '' security.sudo.extraConfig = ''
Defaults env_keep+=SSH_AUTH_SOCK Defaults env_keep+=SSH_AUTH_SOCK
''; '';

View file

@ -1,4 +1,4 @@
{ config, lib, globals, nixosConfig ? null, ... }: { self, config, lib, globals, inputs, outputs, minimal, nixosConfig ? null, ... }:
{ {
_module.args = { _module.args = {
confLib = rec { confLib = rec {
@ -36,6 +36,44 @@
proxyAddress4 = globals.hosts.${proxy}.wanAddress4 or null; proxyAddress4 = globals.hosts.${proxy}.wanAddress4 or null;
proxyAddress6 = globals.hosts.${proxy}.wanAddress6 or null; proxyAddress6 = globals.hosts.${proxy}.wanAddress6 or null;
}; };
mkMicrovm =
if config.swarselsystems.withMicroVMs then
(guestName: {
${guestName} = {
backend = "microvm";
autostart = true;
modules = [
(config.node.configDir + /guests/${guestName}.nix)
{
node.secretsDir = config.node.configDir + /secrets/${guestName};
node.configDir = config.node.configDir + /guests/${guestName};
networking.nftables.firewall = {
zones.untrusted.interfaces = lib.mkIf
(
lib.length config.guests.${guestName}.networking.links == 1
)
config.guests.${guestName}.networking.links;
};
}
"${self}/modules/nixos/optional/microvm-guest.nix"
];
microvm = {
system = config.node.arch;
baseMac = config.repo.secrets.local.networking.networks.lan.mac;
interfaces.vlan-services = { };
};
extraSpecialArgs = {
inherit (outputs) nodes;
inherit (inputs.self.pkgs.${config.node.arch}) lib;
inherit inputs outputs minimal;
inherit (inputs) self;
withHomeManager = false;
globals = outputs.globals.${config.node.arch};
};
};
}) else (_: { _ = { }; });
}; };
}; };
} }

View file

@ -7,6 +7,11 @@
type = lib.types.path; type = lib.types.path;
default = ./.; default = ./.;
}; };
configDir = lib.mkOption {
description = "Path to the base directory for this node.";
type = lib.types.path;
default = ./.;
};
name = lib.mkOption { name = lib.mkOption {
type = lib.types.str; type = lib.types.str;
}; };

View file

@ -21,9 +21,9 @@
type = lib.types.bool; type = lib.types.bool;
default = config.swarselsystems.isLaptop; default = config.swarselsystems.isLaptop;
}; };
withHomeManager = lib.mkOption { isMicroVM = lib.mkOption {
type = lib.types.bool; type = lib.types.bool;
default = true; default = false;
}; };
isSwap = lib.mkOption { isSwap = lib.mkOption {
type = lib.types.bool; type = lib.types.bool;

View file

@ -14,6 +14,8 @@
inherit (config) nodes; inherit (config) nodes;
globals = config.globals.${arch}; globals = config.globals.${arch};
type = "nixos"; type = "nixos";
withHomeManager = true;
extraModules = [ "${self}/modules/nixos/common/globals.nix" ];
}; };
modules = [ modules = [
inputs.disko.nixosModules.disko inputs.disko.nixosModules.disko
@ -30,6 +32,7 @@
inputs.sops.nixosModules.sops inputs.sops.nixosModules.sops
inputs.stylix.nixosModules.stylix inputs.stylix.nixosModules.stylix
inputs.swarsel-nix.nixosModules.default inputs.swarsel-nix.nixosModules.default
inputs.nixos-nftables-firewall.nixosModules.default
(inputs.nixos-extra-modules + "/modules/guests") (inputs.nixos-extra-modules + "/modules/guests")
(inputs.nixos-extra-modules + "/modules/interface-naming.nix") (inputs.nixos-extra-modules + "/modules/interface-naming.nix")
"${self}/hosts/nixos/${arch}/${configName}" "${self}/hosts/nixos/${arch}/${configName}"
@ -47,6 +50,7 @@
arch = lib.mkForce arch; arch = lib.mkForce arch;
type = lib.mkForce "nixos"; type = lib.mkForce "nixos";
secretsDir = ../hosts/nixos/${arch}/${configName}/secrets; secretsDir = ../hosts/nixos/${arch}/${configName}/secrets;
configDir = ../hosts/nixos/${arch}/${configName};
lockFromBootstrapping = lib.mkIf (!minimal) (lib.swarselsystems.mkStrong true); lockFromBootstrapping = lib.mkIf (!minimal) (lib.swarselsystems.mkStrong true);
}; };
@ -70,6 +74,7 @@
specialArgs = { specialArgs = {
inherit inputs lib outputs self minimal configName; inherit inputs lib outputs self minimal configName;
inherit (config) nodes; inherit (config) nodes;
withHomeManager = true;
globals = config.globals.${arch}; globals = config.globals.${arch};
}; };
modules = [ modules = [
@ -181,7 +186,7 @@
guestConfigurations = lib.flip lib.concatMapAttrs config.nixosConfigurations ( guestConfigurations = lib.flip lib.concatMapAttrs config.nixosConfigurations (
_: node: _: node:
lib.flip lib.mapAttrs' (node.config.microvm.vms or { }) ( lib.flip lib.mapAttrs' (node.config.guests or { }) (
guestName: guestDef: guestName: guestDef:
lib.nameValuePair guestDef.nodeName node.config.microvm.vms.${guestName}.config lib.nameValuePair guestDef.nodeName node.config.microvm.vms.${guestName}.config
) )

View file

@ -1,4 +1,4 @@
{ self, homeConfig, lib, pkgs, config, ... }: { self, lib, pkgs, config, homeConfig, ... }:
let let
mkPackages = names: pkgs: builtins.listToAttrs (map mkPackages = names: pkgs: builtins.listToAttrs (map
(name: { (name: {

View file

@ -43,6 +43,7 @@
lowBattery = lib.mkForce true; lowBattery = lib.mkForce true;
lanzaboote = lib.mkForce true; lanzaboote = lib.mkForce true;
autologin = lib.mkForce true; autologin = lib.mkForce true;
nftables = lib.mkDefault true;
}; };
}; };

View file

@ -14,6 +14,7 @@
btrfs = lib.mkDefault true; btrfs = lib.mkDefault true;
sops = lib.mkDefault true; sops = lib.mkDefault true;
boot = lib.mkDefault true; boot = lib.mkDefault true;
nftables = lib.mkDefault true;
server = { server = {
general = lib.mkDefault true; general = lib.mkDefault true;
network = lib.mkDefault true; network = lib.mkDefault true;

View file

@ -0,0 +1,27 @@
{ lib, config, ... }:
{
options.swarselprofiles.microvm = lib.mkEnableOption "is this a server";
config = lib.mkIf config.swarselprofiles.microvm {
swarselsystems = {
isLinux = true;
isNixos = true;
};
swarselmodules = {
general = lib.mkDefault true;
pii = lib.mkDefault true;
xserver = lib.mkDefault true;
time = lib.mkDefault true;
users = lib.mkDefault true;
impermanence = lib.mkDefault true;
btrfs = lib.mkDefault true;
sops = lib.mkDefault true;
nftables = lib.mkDefault true;
server = {
general = lib.mkDefault true;
packages = lib.mkDefault true;
ssh = lib.mkDefault true;
};
};
};
}

View file

@ -18,6 +18,7 @@
autologin = lib.mkDefault true; autologin = lib.mkDefault true;
boot = lib.mkDefault true; boot = lib.mkDefault true;
btrfs = lib.mkDefault true; btrfs = lib.mkDefault true;
nftables = lib.mkDefault true;
server = { server = {
ssh = lib.mkDefault true; ssh = lib.mkDefault true;

View file

@ -26,6 +26,7 @@
lowBattery = lib.mkDefault false; lowBattery = lib.mkDefault false;
network = lib.mkDefault true; network = lib.mkDefault true;
networkDevices = lib.mkDefault true; networkDevices = lib.mkDefault true;
nftables = lib.mkDefault true;
nix-ld = lib.mkDefault true; nix-ld = lib.mkDefault true;
nvd = lib.mkDefault true; nvd = lib.mkDefault true;
packages = lib.mkDefault true; packages = lib.mkDefault true;

View file

@ -3,8 +3,10 @@
options.swarselprofiles.router = lib.mkEnableOption "enable the router profile"; options.swarselprofiles.router = lib.mkEnableOption "enable the router profile";
config = lib.mkIf config.swarselprofiles.router { config = lib.mkIf config.swarselprofiles.router {
swarselmodules = { swarselmodules = {
nftables = lib.mkDefault true;
server = { server = {
router = lib.mkDefault true; router = lib.mkDefault true;
kea = lib.mkDefault true;
}; };
}; };
}; };