From 649893358ccdaad4e4ce56a6767909c0240b5394 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Felix=20Schr=C3=B6ter?= <dev@felschr.com> Date: Fri, 6 Jun 2025 15:24:48 +0200 Subject: [PATCH 01/12] chore(flake): update inputs --- flake.lock | 42 +++++++++++++++++++++--------------------- hosts/flake-module.nix | 2 +- 2 files changed, 22 insertions(+), 22 deletions(-) diff --git a/flake.lock b/flake.lock index 12682b8..b85ef07 100644 --- a/flake.lock +++ b/flake.lock @@ -72,11 +72,11 @@ ] }, "locked": { - "lastModified": 1727447169, - "narHash": "sha256-3KyjMPUKHkiWhwR91J1YchF6zb6gvckCAY1jOE+ne0U=", + "lastModified": 1749105467, + "narHash": "sha256-hXh76y/wDl15almBcqvjryB50B0BaiXJKk20f314RoE=", "owner": "serokell", "repo": "deploy-rs", - "rev": "aa07eb05537d4cd025e2310397a6adcedfe72c76", + "rev": "6bc76b872374845ba9d645a2f012b764fecd765f", "type": "github" }, "original": { @@ -129,11 +129,11 @@ }, "locked": { "dir": "pkgs/firefox-addons", - "lastModified": 1749009805, - "narHash": "sha256-eRv4m89aPJvIAX9mZQcJM+l3sYG+OJvcLsiHvAvXalg=", + "lastModified": 1749143092, + "narHash": "sha256-IrVT37SUU8/B3X53rwEzDrx3djGLIfa8tmsyqVJxpR4=", "owner": "rycee", "repo": "nur-expressions", - "rev": "622c38d004cdded682d9a5ab7323181dc6efb0c1", + "rev": "d62d10f250ca6a37cbbe05a35a0e1e7ae3b4b5c2", "type": "gitlab" }, "original": { @@ -146,11 +146,11 @@ "flake-compat": { "flake": false, "locked": { - "lastModified": 1696426674, - "narHash": "sha256-kvjfFW7WAETZlt09AgDn1MrtKzP7t90Vf7vypd3OL1U=", + "lastModified": 1733328505, + "narHash": "sha256-NeCCThCEP3eCl2l/+27kNNK7QrwZB1IJCrXfrbv5oqU=", "owner": "edolstra", "repo": "flake-compat", - "rev": "0f9255e01c2351cc7d116c072cb317785dd33b33", + "rev": "ff81ac966bb2cae68946d5ed5fc4994f96d0ffec", "type": "github" }, "original": { @@ -299,11 +299,11 @@ ] }, "locked": { - "lastModified": 1748665073, - "narHash": "sha256-RMhjnPKWtCoIIHiuR9QKD7xfsKb3agxzMfJY8V9MOew=", + "lastModified": 1749154018, + "narHash": "sha256-gjN3j7joRvT3a8Zgcylnd4NFsnXeDBumqiu4HmY1RIg=", "owner": "nix-community", "repo": "home-manager", - "rev": "282e1e029cb6ab4811114fc85110613d72771dea", + "rev": "7aae0ee71a17b19708b93b3ed448a1a0952bf111", "type": "github" }, "original": { @@ -353,11 +353,11 @@ }, "nixos-hardware": { "locked": { - "lastModified": 1748942041, - "narHash": "sha256-HEu2gTct7nY0tAPRgBtqYepallryBKR1U8B4v2zEEqA=", + "lastModified": 1749195551, + "narHash": "sha256-W5GKQHgunda/OP9sbKENBZhMBDNu2QahoIPwnsF6CeM=", "owner": "NixOS", "repo": "nixos-hardware", - "rev": "fc7c4714125cfaa19b048e8aaf86b9c53e04d853", + "rev": "4602f7e1d3f197b3cb540d5accf5669121629628", "type": "github" }, "original": { @@ -368,11 +368,11 @@ }, "nixpkgs": { "locked": { - "lastModified": 1749024892, - "narHash": "sha256-OGcDEz60TXQC+gVz5sdtgGJdKVYr6rwdzQKuZAJQpCA=", + "lastModified": 1749086602, + "narHash": "sha256-DJcgJMekoxVesl9kKjfLPix2Nbr42i7cpEHJiTnBUwU=", "owner": "NixOS", "repo": "nixpkgs", - "rev": "8f1b52b04f2cb6e5ead50bd28d76528a2f0380ef", + "rev": "4792576cb003c994bd7cc1edada3129def20b27d", "type": "github" }, "original": { @@ -423,11 +423,11 @@ "systems": "systems_3" }, "locked": { - "lastModified": 1749025503, - "narHash": "sha256-Me3mk/wLz4msOQAASCaf2+mQizje1Q37rgNfExJse6M=", + "lastModified": 1749198233, + "narHash": "sha256-5YEDpGF46A5pnHX52ALqmFMlAB1orI0SnZhI6LQiw9w=", "owner": "astro", "repo": "nix-openwrt-imagebuilder", - "rev": "1b157ee2f34fc67f365a62c5a4fca63ba86040c6", + "rev": "7eb902386112129be892e06cd5a51ffdfeb2517e", "type": "github" }, "original": { diff --git a/hosts/flake-module.nix b/hosts/flake-module.nix index c963958..8b5bc1c 100644 --- a/hosts/flake-module.nix +++ b/hosts/flake-module.nix @@ -35,7 +35,7 @@ ( { pkgs, ... }: { - environment.systemPackages = [ inputs.deploy-rs.defaultPackage.x86_64-linux ]; + environment.systemPackages = [ inputs.deploy-rs.packages.x86_64-linux.default ]; } ) ]; From 80808acdd86ef37fbdce3aa9baff7f80608f220a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Felix=20Schr=C3=B6ter?= <dev@felschr.com> Date: Fri, 6 Jun 2025 15:27:16 +0200 Subject: [PATCH 02/12] refactor(home): adjust nixpkgs config --- home/base.nix | 5 +++++ home/felschr-server.nix | 1 + home/felschr-work.nix | 1 + home/felschr.nix | 1 + home/flake-module.nix | 16 ++++++---------- home/{modules => }/nixpkgs.nix | 0 6 files changed, 14 insertions(+), 10 deletions(-) create mode 100644 home/base.nix rename home/{modules => }/nixpkgs.nix (100%) diff --git a/home/base.nix b/home/base.nix new file mode 100644 index 0000000..3a1b576 --- /dev/null +++ b/home/base.nix @@ -0,0 +1,5 @@ +_: + +{ + imports = [ ./nixpkgs.nix ]; +} diff --git a/home/felschr-server.nix b/home/felschr-server.nix index 82c0de5..71414f5 100644 --- a/home/felschr-server.nix +++ b/home/felschr-server.nix @@ -7,6 +7,7 @@ { imports = [ + ./base.nix ./shell ./editors/lsp.nix ./editors/helix diff --git a/home/felschr-work.nix b/home/felschr-work.nix index 73e4003..ce4cb8f 100644 --- a/home/felschr-work.nix +++ b/home/felschr-work.nix @@ -3,6 +3,7 @@ with pkgs; { imports = [ + ./base.nix ./shell ./tailscale.nix ./editors diff --git a/home/felschr.nix b/home/felschr.nix index b0e32b0..95c4076 100644 --- a/home/felschr.nix +++ b/home/felschr.nix @@ -2,6 +2,7 @@ { imports = [ + ./base.nix ./shell ./tailscale.nix ./editors diff --git a/home/flake-module.nix b/home/flake-module.nix index f6b54ac..caee67c 100644 --- a/home/flake-module.nix +++ b/home/flake-module.nix @@ -16,15 +16,12 @@ let pkgs = self.pkgsFor system; extraSpecialArgs = { inherit inputs; }; - modules = - (with self.homeModules; [ nixpkgs ]) - ++ [ - { - home.username = user; - home.homeDirectory = "/home/${user}"; - } - ] - ++ modules; + modules = [ + { + home.username = user; + home.homeDirectory = "/home/${user}"; + } + ] ++ modules; }; in { @@ -32,7 +29,6 @@ in flake = { homeModules = { - nixpkgs = import ./modules/nixpkgs.nix; git = import ./modules/git.nix; firefox = import ./modules/firefox/firefox.nix; tor-browser = import ./modules/firefox/tor-browser.nix; diff --git a/home/modules/nixpkgs.nix b/home/nixpkgs.nix similarity index 100% rename from home/modules/nixpkgs.nix rename to home/nixpkgs.nix From 56ef4fdf119612ab24446658e89137875cd6eade Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Felix=20Schr=C3=B6ter?= <dev@felschr.com> Date: Fri, 6 Jun 2025 15:30:30 +0200 Subject: [PATCH 03/12] feat(desktop): configure compose key via xkb --- desktop/x11.nix | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/desktop/x11.nix b/desktop/x11.nix index 252b536..e571bc5 100644 --- a/desktop/x11.nix +++ b/desktop/x11.nix @@ -1,8 +1,16 @@ -{ config, pkgs, ... }: +{ + config, + pkgs, + lib, + ... +}: { # Enable the X11 windowing system. services.xserver.enable = true; services.xserver.xkb.layout = "gb"; - services.xserver.xkb.options = "eurosign:e"; + services.xserver.xkb.options = lib.concatStringsSep "," [ + "eurosign:e" + "compose:ralt" + ]; } From 1e7bdad3091fb2bfc44b015e11b1025584f3a9d5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Felix=20Schr=C3=B6ter?= <dev@felschr.com> Date: Fri, 6 Jun 2025 15:33:05 +0200 Subject: [PATCH 04/12] docs(secrets): fix instructions for new host key --- secrets/secrets.nix | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/secrets/secrets.nix b/secrets/secrets.nix index a906a73..eb46594 100644 --- a/secrets/secrets.nix +++ b/secrets/secrets.nix @@ -3,7 +3,7 @@ let felschr = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIGbQpMo1JOGk59Rzl6pVoOcMHOoqezph+aIlEXZP4rBu"; users = [ felschr ]; - # `ssh-keygen -t ed25519 -N "" -f /etc/secrets/initrd/ssh_host_ed25519_key` + # `ssh-keygen -t ed25519 -N "" -f /etc/ssh/ssh_host_ed25519_key` home-pc = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIBFTQvIcSdhEKl/Kq+pcS/cPCyyZ1ygj+djfuaXzaRMx"; home-server = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAILO+OLPr8zdOMYyKtm98AFJai7zbaxw7JhVWgOwu7K3C"; cmdframe = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIAMcPrg69IqmH3V+7lgoXif/J6z4/aEi7w7p5jRn/lkp"; From 5953733aebbff1a1e3db0f38d59e88fd2bd37f4a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Felix=20Schr=C3=B6ter?= <dev@felschr.com> Date: Fri, 6 Jun 2025 15:45:24 +0200 Subject: [PATCH 05/12] feat(networking): add tools --- system/networking.nix | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/system/networking.nix b/system/networking.nix index 38dcc07..e136a77 100644 --- a/system/networking.nix +++ b/system/networking.nix @@ -1,4 +1,9 @@ -{ config, lib, ... }: +{ + config, + pkgs, + lib, + ... +}: let isAdguardHost = config.services.adguardhome.enable; @@ -83,4 +88,12 @@ in # mDNS already handled by systemd-resolved services.avahi.enable = false; + + programs.mtr.enable = true; + programs.mosh.enable = true; + + environment.systemPackages = with pkgs; [ + dig + wireguard-tools + ]; } From a63e02af0fadbbce48a1475de8159ae72931cc70 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Felix=20Schr=C3=B6ter?= <dev@felschr.com> Date: Fri, 6 Jun 2025 15:47:14 +0200 Subject: [PATCH 06/12] fix(networking): fix IPv4 CIDR --- system/networking.nix | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/system/networking.nix b/system/networking.nix index e136a77..0c35c5c 100644 --- a/system/networking.nix +++ b/system/networking.nix @@ -15,7 +15,7 @@ let lan = rec { IPv4Prefix = "192.168.1"; - IPv4CIDR = "${IPv4Prefix}.1/24"; + IPv4CIDR = "${IPv4Prefix}.0/24"; IPv6ULAPrefix = "fd1c:ca95:d74d"; IPv6ULACIDR = "${IPv6ULAPrefix}::/48"; }; From a1675da8bf7bc729d6b2c251bb3a44bc0536e88e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Felix=20Schr=C3=B6ter?= <dev@felschr.com> Date: Fri, 6 Jun 2025 15:47:55 +0200 Subject: [PATCH 07/12] feat(nix): switch to lix --- system/nix.nix | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/system/nix.nix b/system/nix.nix index 3a8a7f5..c2616d7 100644 --- a/system/nix.nix +++ b/system/nix.nix @@ -1,4 +1,9 @@ -{ inputs, config, ... }: +{ + inputs, + config, + pkgs, + ... +}: let inherit (inputs.self.outputs) nixConfig; @@ -6,6 +11,8 @@ in { nixpkgs.config.allowUnfree = true; + nix.package = pkgs.lix; + nix.gc = { automatic = true; dates = "04:00"; From 45c4b8a3f35badcff6e4e496f1f8d0faa928f68c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Felix=20Schr=C3=B6ter?= <dev@felschr.com> Date: Fri, 6 Jun 2025 15:55:56 +0200 Subject: [PATCH 08/12] feat(hosts): add disko config for home-pc & home-server --- hardware/home-pc.nix | 36 ------------------ hardware/lattepanda.nix | 37 ------------------ hosts/flake-module.nix | 4 ++ hosts/home-pc/default.nix | 1 + hosts/home-pc/disk-config.nix | 62 +++++++++++++++++++++++++++++++ hosts/home-server/default.nix | 1 + hosts/home-server/disk-config.nix | 62 +++++++++++++++++++++++++++++++ 7 files changed, 130 insertions(+), 73 deletions(-) create mode 100644 hosts/home-pc/disk-config.nix create mode 100644 hosts/home-server/disk-config.nix diff --git a/hardware/home-pc.nix b/hardware/home-pc.nix index d8aab7a..9c7f0e8 100644 --- a/hardware/home-pc.nix +++ b/hardware/home-pc.nix @@ -22,42 +22,6 @@ boot.kernelModules = [ "kvm-amd" ]; boot.extraModulePackages = [ ]; - fileSystems."/" = { - device = "/dev/disk/by-uuid/5830e9b3-260b-451c-bfee-2028c64c6199"; - fsType = "btrfs"; - options = [ - "subvol=@" - "compress-force=zstd:1" - "noatime" - ]; - }; - - boot.initrd.luks.devices."enc".device = "/dev/disk/by-uuid/1dd848b6-cd7f-4959-8500-a03ffdaeae66"; - - fileSystems."/home" = { - device = "/dev/disk/by-uuid/5830e9b3-260b-451c-bfee-2028c64c6199"; - fsType = "btrfs"; - options = [ - "subvol=@home" - "compress-force=zstd:1" - "noatime" - ]; - }; - - fileSystems."/.snapshots" = { - device = "/dev/disk/by-uuid/5830e9b3-260b-451c-bfee-2028c64c6199"; - fsType = "btrfs"; - options = [ - "subvol=@snapshots" - "compress-force=zstd:1" - "noatime" - ]; - }; - - fileSystems."/boot" = { - device = "/dev/disk/by-uuid/17B2-42C2"; - fsType = "vfat"; - }; hardware.cpu.amd.updateMicrocode = lib.mkDefault config.hardware.enableRedistributableFirmware; } diff --git a/hardware/lattepanda.nix b/hardware/lattepanda.nix index 0239167..626774a 100644 --- a/hardware/lattepanda.nix +++ b/hardware/lattepanda.nix @@ -16,43 +16,6 @@ boot.kernelParams = [ "i915.enable_guc=3" ]; boot.extraModulePackages = [ ]; - fileSystems."/" = { - device = "/dev/disk/by-uuid/70f03d67-e248-42f6-a204-c02e4f180531"; - fsType = "btrfs"; - options = [ - "subvol=@" - "compress-force=zstd:1" - "noatime" - ]; - }; - - boot.initrd.luks.devices."enc".device = "/dev/disk/by-uuid/d3b12d0e-7e8e-4130-9a8f-680abcdc9682"; - - fileSystems."/home" = { - device = "/dev/disk/by-uuid/70f03d67-e248-42f6-a204-c02e4f180531"; - fsType = "btrfs"; - options = [ - "subvol=@home" - "compress-force=zstd:1" - "noatime" - ]; - }; - - fileSystems."/.snapshots" = { - device = "/dev/disk/by-uuid/70f03d67-e248-42f6-a204-c02e4f180531"; - fsType = "btrfs"; - options = [ - "subvol=@snapshots" - "compress-force=zstd:1" - "noatime" - ]; - }; - - fileSystems."/boot" = { - device = "/dev/disk/by-uuid/95FC-D4E5"; - fsType = "vfat"; - }; - powerManagement.cpuFreqGovernor = lib.mkDefault "powersave"; hardware.cpu.intel.updateMicrocode = lib.mkDefault config.hardware.enableRedistributableFirmware; } diff --git a/hosts/flake-module.nix b/hosts/flake-module.nix index 8b5bc1c..02aa847 100644 --- a/hosts/flake-module.nix +++ b/hosts/flake-module.nix @@ -2,12 +2,15 @@ { flake = { diskoConfigurations = { + home-pc = import ./home-pc/disk-config.nix; + home-server = import ./home-server/disk-config.nix; cmdframe = import ./cmdframe/disk-config.nix; }; nixosConfigurations = { home-pc = inputs.nixpkgs.lib.nixosSystem { system = "x86_64-linux"; modules = [ + inputs.disko.nixosModules.disko inputs.nixpkgs.nixosModules.notDetected inputs.nixos-hardware.nixosModules.common-pc inputs.nixos-hardware.nixosModules.common-pc-ssd @@ -46,6 +49,7 @@ home-server = inputs.nixpkgs.lib.nixosSystem { system = "x86_64-linux"; modules = [ + inputs.disko.nixosModules.disko inputs.nixpkgs.nixosModules.notDetected inputs.nixos-hardware.nixosModules.common-pc inputs.nixos-hardware.nixosModules.common-pc-ssd diff --git a/hosts/home-pc/default.nix b/hosts/home-pc/default.nix index 5e32deb..0cbba48 100644 --- a/hosts/home-pc/default.nix +++ b/hosts/home-pc/default.nix @@ -2,6 +2,7 @@ { imports = [ + ./disk-config.nix ../../hardware/base.nix ../../hardware/bluetooth.nix ../../hardware/xbox.nix diff --git a/hosts/home-pc/disk-config.nix b/hosts/home-pc/disk-config.nix new file mode 100644 index 0000000..82ad757 --- /dev/null +++ b/hosts/home-pc/disk-config.nix @@ -0,0 +1,62 @@ +{ + disko.devices = { + disk = { + main = { + type = "disk"; + device = "/dev/nvme0n1"; + content = { + type = "gpt"; + partitions = { + ESP = { + size = "512M"; + type = "EF00"; + content = { + type = "filesystem"; + format = "vfat"; + mountpoint = "/boot"; + mountOptions = [ "umask=0077" ]; + }; + }; + luks = { + size = "100%"; + content = { + type = "luks"; + name = "enc"; + settings = { + allowDiscards = true; + }; + content = { + type = "btrfs"; + extraArgs = [ "-f" ]; + subvolumes = { + "@" = { + mountpoint = "/"; + mountOptions = [ + "compress-force=zstd:1" + "noatime" + ]; + }; + "@home" = { + mountpoint = "/home"; + mountOptions = [ + "compress-force=zstd:1" + "noatime" + ]; + }; + "@snapshots" = { + mountpoint = "/.snapshots"; + mountOptions = [ + "compress-force=zstd:1" + "noatime" + ]; + }; + }; + }; + }; + }; + }; + }; + }; + }; + }; +} diff --git a/hosts/home-server/default.nix b/hosts/home-server/default.nix index 0a8c4bd..931d571 100644 --- a/hosts/home-server/default.nix +++ b/hosts/home-server/default.nix @@ -18,6 +18,7 @@ let in { imports = [ + ./disk-config.nix ../../hardware/base.nix ../../desktop/x11.nix ../../system/server.nix diff --git a/hosts/home-server/disk-config.nix b/hosts/home-server/disk-config.nix new file mode 100644 index 0000000..82ad757 --- /dev/null +++ b/hosts/home-server/disk-config.nix @@ -0,0 +1,62 @@ +{ + disko.devices = { + disk = { + main = { + type = "disk"; + device = "/dev/nvme0n1"; + content = { + type = "gpt"; + partitions = { + ESP = { + size = "512M"; + type = "EF00"; + content = { + type = "filesystem"; + format = "vfat"; + mountpoint = "/boot"; + mountOptions = [ "umask=0077" ]; + }; + }; + luks = { + size = "100%"; + content = { + type = "luks"; + name = "enc"; + settings = { + allowDiscards = true; + }; + content = { + type = "btrfs"; + extraArgs = [ "-f" ]; + subvolumes = { + "@" = { + mountpoint = "/"; + mountOptions = [ + "compress-force=zstd:1" + "noatime" + ]; + }; + "@home" = { + mountpoint = "/home"; + mountOptions = [ + "compress-force=zstd:1" + "noatime" + ]; + }; + "@snapshots" = { + mountpoint = "/.snapshots"; + mountOptions = [ + "compress-force=zstd:1" + "noatime" + ]; + }; + }; + }; + }; + }; + }; + }; + }; + }; + }; +} From 1ef2364f31d1c9bbf39cdc4463f31dba2729f9ec Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Felix=20Schr=C3=B6ter?= <dev@felschr.com> Date: Fri, 6 Jun 2025 16:01:52 +0200 Subject: [PATCH 09/12] feat(home): add cosmic module --- home/desktop/cosmic.nix | 32 +++++++ home/desktop/default.nix | 1 + home/flake-module.nix | 1 + home/modules/cosmic/default.nix | 53 +++++++++++ home/modules/cosmic/ron.nix | 129 +++++++++++++++++++++++++++ home/modules/cosmic/settings.nix | 108 +++++++++++++++++++++++ home/modules/cosmic/types.nix | 145 +++++++++++++++++++++++++++++++ 7 files changed, 469 insertions(+) create mode 100644 home/desktop/cosmic.nix create mode 100644 home/modules/cosmic/default.nix create mode 100644 home/modules/cosmic/ron.nix create mode 100644 home/modules/cosmic/settings.nix create mode 100644 home/modules/cosmic/types.nix diff --git a/home/desktop/cosmic.nix b/home/desktop/cosmic.nix new file mode 100644 index 0000000..3337b21 --- /dev/null +++ b/home/desktop/cosmic.nix @@ -0,0 +1,32 @@ +_: + +{ + imports = [ ../modules/cosmic ]; + + programs.cosmic = { + enable = true; + settings = { + "com.system76.CosmicTk".v1 = { + icon_theme = "Cosmic"; + }; + "com.system76.CosmicFiles".v1 = { + tab.show_hidden = true; + favorites = [ + "Home" + "Documents" + "Downloads" + "Music" + "Pictures" + "Videos" + ''Path("/home/felschr/dev")'' + ''Path("/home/felschr/dev/work")'' + ''Path("/home/felschr/dev/mscs")'' + ''Path("/home/felschr/Documents/CU Boulder MSCS")'' + ]; + }; + "com.system76.CosmicAppletAudio".v1 = { + show_media_controls_in_top_panel = true; + }; + }; + }; +} diff --git a/home/desktop/default.nix b/home/desktop/default.nix index b5d0adb..ee28be4 100644 --- a/home/desktop/default.nix +++ b/home/desktop/default.nix @@ -4,6 +4,7 @@ imports = [ ./gtk.nix ./gnome.nix + ./cosmic.nix ./mimeapps.nix ]; } diff --git a/home/flake-module.nix b/home/flake-module.nix index caee67c..2849f00 100644 --- a/home/flake-module.nix +++ b/home/flake-module.nix @@ -33,6 +33,7 @@ in firefox = import ./modules/firefox/firefox.nix; tor-browser = import ./modules/firefox/tor-browser.nix; mullvad-browser = import ./modules/firefox/mullvad-browser.nix; + cosmic = import ./modules/cosmic; # users felschr = import ./felschr.nix; diff --git a/home/modules/cosmic/default.nix b/home/modules/cosmic/default.nix new file mode 100644 index 0000000..7a5cc08 --- /dev/null +++ b/home/modules/cosmic/default.nix @@ -0,0 +1,53 @@ +{ config, lib, ... }: + +# Based on: +# https://github.com/tristanbeedell/home-manager/tree/efa4d272f6c2b14d4a3b67b0b1e4b38ae46e5588/modules/programs/cosmic + +let + cfg = config.programs.cosmic; + + ron = import ./ron.nix { inherit lib; }; +in +{ + imports = [ ./settings.nix ]; + + options.programs.cosmic = { + enable = lib.mkEnableOption "COSMIC Desktop"; + settings = lib.mkOption { + default = { }; + type = lib.types.submodule { + freeformType = lib.types.submodule { + freeformType = lib.types.attrsOf lib.types.anything; + }; + }; + description = '' + An attrset of explicit settings for COSMIC apps, using their full config path. + ''; + example = lib.literalExpression '' + { + "com.system76.CosmicPanel.Dock".v1 = { + opacity = 0.8; + }; + }; + ''; + }; + }; + + config = lib.mkIf cfg.enable { + xdg.configFile = lib.concatMapAttrs ( + component: + lib.concatMapAttrs ( + version: + lib.concatMapAttrs ( + option: value: + lib.optionalAttrs (value != null) { + "cosmic/${component}/${version}/${option}" = { + enable = true; + text = ron.serialise value; + }; + } + ) + ) + ) cfg.settings; + }; +} diff --git a/home/modules/cosmic/ron.nix b/home/modules/cosmic/ron.nix new file mode 100644 index 0000000..3727ea9 --- /dev/null +++ b/home/modules/cosmic/ron.nix @@ -0,0 +1,129 @@ +{ lib }: +let + inherit (lib) + filterAttrs + concatStrings + concatStringsSep + mapAttrsToList + concatLists + foldlAttrs + boolToString + ; + inherit (builtins) typeOf toString stringLength; + + # list -> array + array = a: "[${concatStringsSep "," (map serialise a)}]"; + + # attrset -> hashmap + _assoc = a: mapAttrsToList (name: val: "${name}: ${val},") a; + assoc = a: '' + { + ${concatStringsSep "\n " (concatLists (map _assoc a))} + } + ''; + + stringArray = a: array (map toQuotedString a); + + tuple = a: "(${concatStringsSep "," (map serialise a)})"; + enum = + s: + if isNull s.value then + s.name + else + concatStrings [ + s.name + "(" + (serialise s.value) + ")" + ]; + + option = + value: + if isNull value then + "None" + else + enum { + name = "Some"; + inherit value; + }; + + # attrset -> struct + _struct_kv = + k: v: + if v == null then + "" + else + (concatStringsSep ": " [ + k + (serialise v) + ]); + _struct_concat = + s: + foldlAttrs ( + acc: k: v: + if stringLength acc > 0 then + concatStringsSep ", " [ + acc + (_struct_kv k v) + ] + else + _struct_kv k v + ) "" s; + _struct_filt = s: _struct_concat (filterAttrs (k: v: v != null) s); + struct = s: "(${_struct_filt s})"; + + toQuotedString = s: ''"${toString s}"''; + + # this is an enum, but use string interp to make sure it's put in the nix store + path = p: ''Path("${p}")''; + + # attrset for best-effort serialisation of nix types + # currently, no way to differentiate between enums and structs + serialisers = { + int = toString; + float = toString; + bool = boolToString; + # can't assume quoted string, sometimes it's a Rust enum + string = toString; + path = path; + null = _: "None"; + set = struct; + list = array; + }; + + serialise = v: serialisers.${typeOf v} v; + +in +{ + inherit + array + assoc + tuple + stringArray + serialise + option + path + struct + toQuotedString + enum + ; + + # some handy wrapper types, to reduce transformation effort in modules producing Ron + types = { + # string type, but implicitly wraps in quote marks for usage in Ron + str = (lib.types.coercedTo lib.types.str toQuotedString lib.types.str) // { + description = "string"; + }; + + # takes a (non submodule) type, and implicitly wraps in Rust Option<> type + option = + type: + let + wantedType = lib.types.nullOr (type); + in + (lib.types.coercedTo (wantedType) (option) lib.types.str) + // { + description = wantedType.description; + }; + }; +} diff --git a/home/modules/cosmic/settings.nix b/home/modules/cosmic/settings.nix new file mode 100644 index 0000000..8a8a101 --- /dev/null +++ b/home/modules/cosmic/settings.nix @@ -0,0 +1,108 @@ +{ lib, ... }: + +# Known definitions for settings options + +let + inherit (lib) types; + ron = import ./ron.nix { inherit lib; }; + cosmic = { + types = import ./types.nix { inherit lib ron; }; + }; +in +{ + options.programs.cosmic.settings = { + # https://github.com/pop-os/libcosmic/blob/1fce5df160f595d1b1e5a8e2bb2a24775419f82d/src/config/mod.rs#L85 + "com.system76.CosmicTk".v1 = { + apply_theme_global = lib.mkOption { + type = types.nullOr types.bool; + default = null; + description = "Apply the theme to other toolkits."; + }; + show_minimize = lib.mkOption { + type = types.nullOr types.bool; + default = null; + description = "Show minimize button in window header."; + }; + show_maximize = lib.mkOption { + type = types.nullOr types.bool; + default = null; + description = "Show maximize button in window header."; + }; + icon_theme = lib.mkOption { + type = types.nullOr ron.types.str; + default = null; + description = "Preferred icon theme."; + }; + header_size = lib.mkOption { + type = types.nullOr cosmic.types.density; + default = null; + description = "Density of CSD/SSD header bars."; + }; + interface_density = lib.mkOption { + type = types.nullOr cosmic.types.density; + default = null; + description = "Interface density."; + }; + interface_font = lib.mkOption { + type = types.nullOr cosmic.types.font_config; + default = null; + description = "Interface font family"; + }; + monospace_font = lib.mkOption { + type = types.nullOr cosmic.types.font_config; + default = null; + description = "Mono font family"; + }; + }; + + # https://github.com/pop-os/cosmic-files/blob/1a5a4501ee501b3155295cbfccc1c992b5ec9c01/src/config.rs#L106 + "com.system76.CosmicFiles".v1 = { + app_theme = lib.mkOption { + type = types.nullOr cosmic.types.theme; + default = null; + description = ""; + }; + desktop = lib.mkOption { + type = types.nullOr cosmic.types.files_desktop; + default = null; + description = ""; + }; + favorites = lib.mkOption { + type = types.nullOr cosmic.types.files_favorites; + default = null; + description = ""; + }; + show_details = lib.mkOption { + type = types.nullOr types.bool; + default = null; + description = ""; + }; + tab = lib.mkOption { + type = types.nullOr cosmic.types.files_tab_config; + default = null; + description = ""; + }; + type_to_search = lib.mkOption { + type = types.nullOr ( + types.enum [ + "Recursive" + "EnterPath" + ] + ); + default = null; + description = ""; + }; + }; + + # https://github.com/pop-os/cosmic-applets/blob/b4b465712218be8d26b6772a382d19f4c3ff97f8/cosmic-applet-audio/src/config.rs#L9 + "com.system76.CosmicAppletAudio".v1 = { + show_media_controls_in_top_panel = lib.mkOption { + type = types.nullOr types.bool; + default = null; + description = ""; + }; + }; + + # ... + }; +} diff --git a/home/modules/cosmic/types.nix b/home/modules/cosmic/types.nix new file mode 100644 index 0000000..9ad749a --- /dev/null +++ b/home/modules/cosmic/types.nix @@ -0,0 +1,145 @@ +{ lib, ron }: + +let + inherit (lib) types; +in +lib.fix (self: { + theme = types.enum [ + "Dark" + "Light" + "System" + ]; + density = types.enum [ + "Compact" + "Spacious" + "Standard" + ]; + weight = types.enum [ + "Thin" + "ExtraLight" + "Light" + "Normal" + "Medium" + "Semibold" + "Bold" + "ExtraBold" + "Black" + ]; + stretch = types.enum [ + "UltraCondensed" + "ExtraCondensed" + "Condensed" + "SemiCondensed" + "Normal" + "SemiExpanded" + "Expanded" + "ExtraExpanded" + "UltraExpanded" + ]; + style = types.enum [ + "Normal" + "Italic" + "Oblique" + ]; + + # libcosmic + font_config = types.submodule { + options = { + family = lib.mkOption { + type = ron.types.str; + default = null; + }; + weight = lib.mkOption { + type = types.nullOr self.weight; + default = null; + }; + stretch = lib.mkOption { + type = types.nullOr self.stretch; + default = null; + }; + style = lib.mkOption { + type = types.nullOr self.style; + default = null; + }; + }; + }; + + # Files + files_desktop = types.submodule { + options = { + grid_spacing = lib.mkOption { + type = types.nullOr types.int; + default = null; + }; + icon_size = lib.mkOption { + type = types.nullOr types.int; + default = null; + }; + show_content = lib.mkOption { + type = types.nullOr types.bool; + default = null; + }; + show_mounted_drives = lib.mkOption { + type = types.nullOr types.bool; + default = null; + }; + show_trash = lib.mkOption { + type = types.nullOr types.bool; + default = null; + }; + }; + }; + files_favorites = types.listOf ( + types.oneOf [ + (types.enum [ + "Home" + "Documents" + "Downloads" + "Music" + "Pictures" + "Videos" + ]) + (lib.types.strMatching ''^Path\(".*"\)$'') + ] + ); + files_view = types.enum [ + "Grid" + "List" + ]; + files_icon_sizes = types.submodule { + options = { + list = lib.mkOption { + type = types.nullOr types.int; + default = null; + }; + grid = lib.mkOption { + type = types.nullOr types.int; + default = null; + }; + }; + }; + files_tab_config = types.submodule { + options = { + view = lib.mkOption { + type = types.nullOr self.files_view; + default = null; + }; + folders_first = lib.mkOption { + type = types.nullOr types.bool; + default = null; + }; + show_hidden = lib.mkOption { + type = types.nullOr types.bool; + default = null; + }; + icon_sizes = lib.mkOption { + type = types.nullOr self.files_icon_sizes; + default = null; + }; + single_click = lib.mkOption { + type = types.nullOr types.bool; + default = null; + }; + }; + }; +}) From 318eb4a682eda9b1e4946211110b42332d75ec55 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Felix=20Schr=C3=B6ter?= <dev@felschr.com> Date: Fri, 6 Jun 2025 16:41:08 +0200 Subject: [PATCH 10/12] feat(modules): add nginx-authelia --- flake.nix | 1 + modules/nginx-authelia.nix | 145 +++++++++++++++++++++++++++++++++++++ services/authelia.nix | 6 ++ 3 files changed, 152 insertions(+) create mode 100644 modules/nginx-authelia.nix diff --git a/flake.nix b/flake.nix index 53ca564..cf2c29e 100644 --- a/flake.nix +++ b/flake.nix @@ -104,6 +104,7 @@ rec { flakeDefaults = import ./modules/flakeDefaults.nix; systemdNotify = import ./modules/systemdNotify.nix; inadyn = import ./modules/inadyn.nix; + nginx-authelia = import ./modules/nginx-authelia.nix; }; }; perSystem = diff --git a/modules/nginx-authelia.nix b/modules/nginx-authelia.nix new file mode 100644 index 0000000..c6662dc --- /dev/null +++ b/modules/nginx-authelia.nix @@ -0,0 +1,145 @@ +{ config, lib, ... }: + +let + cfg = config.services.nginx-authelia; + vhostOptionsAuth = + { config, ... }: + { + options = { + enableAutheliaAuth = lib.mkEnableOption "Enable authelia auth"; + }; + config = lib.mkIf config.enableAutheliaAuth { + locations."/authelia".extraConfig = '' + set $upstream_authelia http://${cfg.host}:${toString cfg.port}/api/verify; + + ## Essential Proxy Configuration + internal; + proxy_pass $upstream_authelia; + + ## Headers + ## The headers starting with X-* are required. + proxy_set_header X-Original-URL $scheme://$http_host$request_uri; + proxy_set_header X-Original-Method $request_method; + proxy_set_header X-Forwarded-Method $request_method; + proxy_set_header X-Forwarded-Proto $scheme; + proxy_set_header X-Forwarded-Host $http_host; + proxy_set_header X-Forwarded-Uri $request_uri; + proxy_set_header X-Forwarded-For $remote_addr; + proxy_set_header Content-Length ""; + proxy_set_header Connection ""; + + ## Basic Proxy Configuration + proxy_pass_request_body off; + proxy_next_upstream error timeout invalid_header http_500 http_502 http_503; # Timeout if the real server is dead + proxy_redirect http:// $scheme://; + proxy_http_version 1.1; + proxy_cache_bypass $cookie_session; + proxy_no_cache $cookie_session; + proxy_buffers 4 32k; + client_body_buffer_size 128k; + + ## Advanced Proxy Configuration + send_timeout 5m; + proxy_read_timeout 240; + proxy_send_timeout 240; + proxy_connect_timeout 240; + ''; + locations."/".extraConfig = '' + ## Send a subrequest to Authelia to verify if the user is authenticated and has permission to access the resource. + auth_request /authelia; + + ## Set the $target_url variable based on the original request. + + ## Requires nginx http_set_misc module. + set_escape_uri $target_url $scheme://$http_host$request_uri; + + ## Save the upstream response headers from Authelia to variables. + auth_request_set $user $upstream_http_remote_user; + auth_request_set $groups $upstream_http_remote_groups; + auth_request_set $name $upstream_http_remote_name; + auth_request_set $email $upstream_http_remote_email; + + ## Inject the response headers from the variables into the request made to the backend. + proxy_set_header Remote-User $user; + proxy_set_header Remote-Groups $groups; + proxy_set_header Remote-Name $name; + proxy_set_header Remote-Email $email; + + ## If the subreqest returns 200 pass to the backend, if the subrequest returns 401 redirect to the portal. + error_page 401 =302 https://auth.zx.dev/?rd=$target_url; + ''; + }; + }; + + vhostOptionsProxy = + { config, ... }: + { + options = { + useAutheliaProxyConf = lib.mkEnableOption "Use recommended authelia proxy configuration"; + }; + config = lib.mkIf config.useAutheliaProxyConf { + locations."/".extraConfig = '' + ## Headers + proxy_set_header Host $host; + proxy_set_header X-Original-URL $scheme://$http_host$request_uri; + proxy_set_header X-Forwarded-Proto $scheme; + proxy_set_header X-Forwarded-Host $http_host; + proxy_set_header X-Forwarded-Uri $request_uri; + proxy_set_header X-Forwarded-Ssl on; + proxy_set_header X-Forwarded-For $remote_addr; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header Connection ""; + + ## Basic Proxy Configuration + client_body_buffer_size 128k; + proxy_next_upstream error timeout invalid_header http_500 http_502 http_503; ## Timeout if the real server is dead. + proxy_redirect http:// $scheme://; + proxy_http_version 1.1; + proxy_cache_bypass $cookie_session; + proxy_no_cache $cookie_session; + proxy_buffers 64 256k; + + ## Trusted Proxies Configuration + ## Please read the following documentation before configuring this: + ## https://www.authelia.com/integration/proxies/nginx/#trusted-proxies + # set_real_ip_from 10.0.0.0/8; + # set_real_ip_from 172.16.0.0/12; + # set_real_ip_from 192.168.0.0/16; + # set_real_ip_from fc00::/7; + real_ip_header X-Forwarded-For; + real_ip_recursive on; + + ## Advanced Proxy Configuration + send_timeout 5m; + proxy_read_timeout 360; + proxy_send_timeout 360; + proxy_connect_timeout 360; + ''; + }; + }; +in +{ + options = { + services.nginx-authelia = { + host = lib.mkOption { + type = lib.types.str; + default = "localhost"; + }; + port = lib.mkOption { + type = lib.types.int; + default = 9091; + }; + }; + + services.nginx.virtualHosts = lib.mkOption { + type = lib.types.attrsOf ( + lib.types.submodule [ + vhostOptionsAuth + vhostOptionsProxy + ] + ); + }; + }; + + config = { }; +} diff --git a/services/authelia.nix b/services/authelia.nix index 011bfb1..6209d9f 100644 --- a/services/authelia.nix +++ b/services/authelia.nix @@ -63,6 +63,8 @@ let smtpAccount = config.programs.msmtp.accounts.default; in { + imports = [ ../modules/nginx-authelia.nix ]; + age.secrets.authelia-jwt = { file = ../secrets/authelia/jwt.age; owner = cfg.user; @@ -208,6 +210,10 @@ in "lldap.service" ]; + services.nginx-authelia = { + inherit port; + }; + services.postgresql = { enable = true; ensureDatabases = [ cfg.user ]; From 5bc625a88360d8b99e13e40da1bbeb9fbe5d6b40 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Felix=20Schr=C3=B6ter?= <dev@felschr.com> Date: Fri, 6 Jun 2025 16:41:50 +0200 Subject: [PATCH 11/12] feat(adguardhome): enable nginx authelia auth --- services/adguardhome.nix | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/services/adguardhome.nix b/services/adguardhome.nix index b92c593..4bbf1ad 100644 --- a/services/adguardhome.nix +++ b/services/adguardhome.nix @@ -37,9 +37,6 @@ in certificate_path = "${config.security.acme.certs."${host}".directory}/fullchain.pem"; private_key_path = "${config.security.acme.certs."${host}".directory}/key.pem"; }; - # HINT: users needs to be set up manually: - # https://github.com/AdguardTeam/AdGuardHome/wiki/Configuration#password-reset - # users = [ { name = "felschr"; } ]; querylog = { enabled = true; interval = "24h"; @@ -104,6 +101,7 @@ in services.nginx = { virtualHosts."${host}" = { + enableAutheliaAuth = true; enableACME = true; forceSSL = true; http3 = true; From 7db7982b41e62d427d9a7bc461ff978b1e23f3ca Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Felix=20Schr=C3=B6ter?= <dev@felschr.com> Date: Fri, 6 Jun 2025 16:53:06 +0200 Subject: [PATCH 12/12] refactor: move NixOS hardware configs from hardware/ to hosts/<host>/ --- hosts/flake-module.nix | 4 ++-- hardware/home-pc.nix => hosts/home-pc/hardware.nix | 1 - hardware/lattepanda.nix => hosts/home-server/hardware.nix | 0 3 files changed, 2 insertions(+), 3 deletions(-) rename hardware/home-pc.nix => hosts/home-pc/hardware.nix (99%) rename hardware/lattepanda.nix => hosts/home-server/hardware.nix (100%) diff --git a/hosts/flake-module.nix b/hosts/flake-module.nix index 02aa847..a762134 100644 --- a/hosts/flake-module.nix +++ b/hosts/flake-module.nix @@ -17,7 +17,7 @@ inputs.nixos-hardware.nixosModules.common-cpu-amd-pstate inputs.nixos-hardware.nixosModules.common-gpu-amd (self.lib.createSystemModule "home-pc" { - hardwareConfig = ../hardware/home-pc.nix; + hardwareConfig = ../hosts/home-pc/hardware.nix; config = ../hosts/home-pc/default.nix; }) self.lib.createMediaGroup @@ -57,7 +57,7 @@ inputs.nixos-hardware.nixosModules.common-gpu-intel-kaby-lake inputs.matrix-appservices.nixosModule (self.lib.createSystemModule "home-server" { - hardwareConfig = ../hardware/lattepanda.nix; + hardwareConfig = ../hosts/home-server/hardware.nix; config = ../hosts/home-server/default.nix; }) self.lib.createMediaGroup diff --git a/hardware/home-pc.nix b/hosts/home-pc/hardware.nix similarity index 99% rename from hardware/home-pc.nix rename to hosts/home-pc/hardware.nix index 9c7f0e8..3704143 100644 --- a/hardware/home-pc.nix +++ b/hosts/home-pc/hardware.nix @@ -22,6 +22,5 @@ boot.kernelModules = [ "kvm-amd" ]; boot.extraModulePackages = [ ]; - hardware.cpu.amd.updateMicrocode = lib.mkDefault config.hardware.enableRedistributableFirmware; } diff --git a/hardware/lattepanda.nix b/hosts/home-server/hardware.nix similarity index 100% rename from hardware/lattepanda.nix rename to hosts/home-server/hardware.nix