commit df1ea7ce328451e66ba008ab1a94b37afe4c0e9c Author: Lucy Date: Thu Sep 25 13:51:04 2025 +0200 init diff --git a/README.md b/README.md new file mode 100644 index 0000000..0677e16 --- /dev/null +++ b/README.md @@ -0,0 +1,136 @@ +# BaseOS + +**BaseOS** is a NixOS flake designed specifically for life and work at the **c-base Space**. + +--- + +## Features + +- **c-base Wi-Fi**: + - `c-base-crew` → Members network (EAP/PEAP/MSCHAPv2), requires ISRG Root X1 certificate. + - `c-base-public` → Guest network, open, no certificate needed. +- **Freifunk Berlin**: `berlin.freifunk.net`, open community Wi-Fi. +- **ISRG Root X1 Certificate** as a package (`pkgs.byName.is.isrg-root-x1`) only used for crew Wi-Fi. + + +--- + +## Project Structure + +``` +flake.nix +cbase-wifi.nix +pkgs/ +└── by-name/ + └── is/ + └── isrg-root-x1/ + └── default.nix +README.md +``` + +--- + +## Usage as a Nix Flake + +Here is a fully working example to include in your `flake.nix` or `nixosConfigurations`: + +```nix +{ + description = "BaseOS flake for c-base space"; + + inputs = { + nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable"; + baseos.url = "https://code.c-base.org/lucy/baseos"; + }; + + outputs = { self, nixpkgs, baseos }: let + system = "x86_64-linux"; + pkgs = import nixpkgs { inherit system; }; + in + { + nixosConfigurations.cbase-client = pkgs.lib.nixosSystem { + inherit system; + modules = [ + baseos.nixosModules.cbase-wifi.${system} + { + boot.loader.systemd-boot.enable = true; + boot.loader.efi.canTouchEfiVariables = true; + networking.hostName = "cbase-client"; + + # Enable c-base Wi-Fi + networking.wireless.c-base = { + crew = true; # Member network + usePublic = true; # Guest network (only if crew enabled) + useFreifunk = true; # Berlin Freifunk + credentialsFile = "/run/secrets/cbase-credentials"; + }; + + system.stateVersion = "24.05"; + } + ]; + }; + + devShells.${system}.default = pkgs.mkShell { + buildInputs = with pkgs; [ + nixos-rebuild + git + nixpkgs-fmt + statix + deadnix + ]; + }; + + packages.${system}.isrg-root-x1 = baseos.packages.${system}.isrg-root-x1; + }; +} +``` + +--- + +### Wi-Fi Connection Priorities + +- `c-base-crew` → 20 +- `c-base-public` → 10 +- `berlin.freifunk.net` → 5 + +--- + +### Development + +Enter the dev shell: + +```bash +nix develop +``` + +Run formatter: + +```bash +nix build .#formatter +``` + +Run formatting checks: + +```bash +nix build .#checks +``` + +--- + +### Certificate + +Use the certificate only for the crew network: + +```nix +pkgs.byName.is.isrg-root-x1 +``` + +--- + +### Target Audience + +**BaseOS** is for anyone who: +- Is a member of the c-base Space. +- Wants a reproducible NixOS environment for Wi-Fi, certificates, and dev tools. +- Wants to use the flake as a base for other c-base projects. + diff --git a/flake.lock b/flake.lock new file mode 100644 index 0000000..bda2242 --- /dev/null +++ b/flake.lock @@ -0,0 +1,62 @@ +{ + "nodes": { + "nixpkgs": { + "locked": { + "lastModified": 1758427187, + "narHash": "sha256-pHpxZ/IyCwoTQPtFIAG2QaxuSm8jWzrzBGjwQZIttJc=", + "owner": "nixos", + "repo": "nixpkgs", + "rev": "554be6495561ff07b6c724047bdd7e0716aa7b46", + "type": "github" + }, + "original": { + "owner": "nixos", + "ref": "nixos-unstable", + "repo": "nixpkgs", + "type": "github" + } + }, + "nixpkgs_2": { + "locked": { + "lastModified": 1754340878, + "narHash": "sha256-lgmUyVQL9tSnvvIvBp7x1euhkkCho7n3TMzgjdvgPoU=", + "owner": "nixos", + "repo": "nixpkgs", + "rev": "cab778239e705082fe97bb4990e0d24c50924c04", + "type": "github" + }, + "original": { + "owner": "nixos", + "ref": "nixpkgs-unstable", + "repo": "nixpkgs", + "type": "github" + } + }, + "root": { + "inputs": { + "nixpkgs": "nixpkgs", + "treefmt-nix": "treefmt-nix" + } + }, + "treefmt-nix": { + "inputs": { + "nixpkgs": "nixpkgs_2" + }, + "locked": { + "lastModified": 1758728421, + "narHash": "sha256-ySNJ008muQAds2JemiyrWYbwbG+V7S5wg3ZVKGHSFu8=", + "owner": "numtide", + "repo": "treefmt-nix", + "rev": "5eda4ee8121f97b218f7cc73f5172098d458f1d1", + "type": "github" + }, + "original": { + "owner": "numtide", + "repo": "treefmt-nix", + "type": "github" + } + } + }, + "root": "root", + "version": 7 +} diff --git a/flake.nix b/flake.nix new file mode 100644 index 0000000..52e5448 --- /dev/null +++ b/flake.nix @@ -0,0 +1,67 @@ +{ + description = "c-base WiFi + Dev Tools flake"; + + inputs = { + nixpkgs.url = "github:nixos/nixpkgs?ref=nixos-unstable"; + treefmt-nix.url = "github:numtide/treefmt-nix"; + }; + + outputs = + { + self, + nixpkgs, + treefmt-nix, + }: + let + systemList = [ + "x86_64-linux" + "aarch64-linux" + ]; + + # Helper: map a function over all systems + eachSystem = + f: + nixpkgs.lib.genAttrs systemList ( + system: + let + pkgs = import nixpkgs { inherit system; }; + in + f pkgs system + ); + + # ISRG Root X1 Certificate package per system + isrgRootX1 = eachSystem (pkgs: system: pkgs.callPackage ./pkgs/by-name/is/isrg-root-x1 { }); + in + { + # Packages per system + packages = eachSystem ( + pkgs: system: { + isrg-root-x1 = isrgRootX1.${system}; + } + ); + + # NixOS Modules per system + nixosModules = eachSystem ( + pkgs: system: + import ./nixos-modules/wifi.nix { + inherit pkgs; + isrgRootX1Cert = isrgRootX1.${system}; + } + ); + + # Dev Shells per system + devShells = eachSystem ( + pkgs: system: { + default = pkgs.mkShell { + buildInputs = with pkgs; [ + nixos-rebuild + git + nixpkgs-fmt + statix + deadnix + ]; + }; + } + ); + }; +} diff --git a/nixos-modules/wifi.nix b/nixos-modules/wifi.nix new file mode 100644 index 0000000..d76c22c --- /dev/null +++ b/nixos-modules/wifi.nix @@ -0,0 +1,136 @@ +{ + config, + lib, + isrgRootX1Cert, + ... +}: + +with lib; + +let + cfg = config.networking.wireless.c-base; +in +{ + options.networking.wireless.c-base = { + crew = mkEnableOption "c-base-crew WLAN access" // { + default = false; + }; + usePublic = mkOption { + type = types.bool; + default = false; + description = "Enable c-base-public WLAN access (guests)"; + }; + useFreifunk = mkOption { + type = types.bool; + default = false; + description = "Enable berlin.freifunk.net WLAN access"; + }; + credentialsFile = mkOption { + type = types.nullOr types.path; + default = null; + description = '' + Path to file containing credentials for crew only: + USERNAME=your-username + PASSWORD=your-password + ''; + }; + }; + + config = mkMerge [ + { + assertions = [ + { + assertion = !(cfg.useFreifunk && cfg.usePublic); + message = "useFreifunk and usePublic cannot both be enabled"; + } + { + assertion = !cfg.crew || (cfg.credentialsFile != null); + message = "credentialsFile must be set when crew is enabled"; + } + ]; + } + + (mkIf cfg.crew { + networking.networkmanager = { + enable = true; + ensureProfiles = { + environmentFiles = [ cfg.credentialsFile ]; + profiles = { + "c-base-crew" = { + connection = { + id = "c-base-crew"; + type = "wifi"; + autoconnect = true; + autoconnect-priority = 20; + }; + wifi = { + ssid = "c-base-crew"; + mode = "infrastructure"; + }; + wifi-security = { + key-mgmt = "wpa-eap"; + }; + "802-1x" = { + eap = "peap"; + identity = "$USERNAME"; + password = "$PASSWORD"; + phase2-auth = "mschapv2"; + ca-cert = "${isrgRootX1Cert}"; + domain-suffix-match = "radius.cbrp3.c-base.org"; + }; + ipv4.method = "auto"; + ipv6.method = "auto"; + }; + }; + }; + }; + security.pki.certificateFiles = [ isrgRootX1Cert ]; + }) + + (mkIf cfg.usePublic { + networking.networkmanager.enable = true; + networking.networkmanager.ensureProfiles.profiles = { + "c-base-public" = { + connection = { + id = "c-base-public"; + type = "wifi"; + autoconnect = true; + autoconnect-priority = 10; + }; + wifi = { + ssid = "c-base-public"; + mode = "infrastructure"; + }; + wifi-security = { + key-mgmt = "none"; + }; + ipv4.method = "auto"; + ipv6.method = "auto"; + }; + }; + }) + + (mkIf cfg.useFreifunk { + networking.networkmanager.enable = true; + networking.networkmanager.ensureProfiles.profiles = { + "berlin-freifunk" = { + connection = { + id = "berlin.freifunk.net"; + type = "wifi"; + autoconnect = true; + autoconnect-priority = 5; + }; + wifi = { + ssid = "berlin.freifunk.net"; + mode = "infrastructure"; + }; + wifi-security = { + key-mgmt = "none"; + }; + ipv4.method = "auto"; + ipv6.method = "auto"; + }; + }; + }) + ]; +} diff --git a/tools/treefmt.nix b/tools/treefmt.nix new file mode 100644 index 0000000..d5ea330 --- /dev/null +++ b/tools/treefmt.nix @@ -0,0 +1,5 @@ +# treefmt.nix +{ pkgs, ... }: +{ + projectRootFile = "flake.nix"; +}