Compare commits

...
7 Commits
Author SHA1 Message Date
hektor 78c7388192 fix(wol): generalize 'wol-*' scripts
check / lint (push) Successful in 16s
2026-10-25 17:26:07 +01:00
hektor 81093e2b69 fix(browser): use 'browser' group for KeePassXC browser credentials
check / lint (push) Successful in 15s
2026-10-25 16:45:00 +01:00
hektor 74a11e0e63 fix(3d): modularize 3D module
check / lint (push) Successful in 15s
2026-10-25 16:44:16 +01:00
hektor f77dea3e42 fix(ssh): further harden SSH
check / lint (push) Successful in 15s
2026-10-25 14:18:40 +01:00
hektor 0776c9a63e fix(backups): improve reliability
check / lint (push) Successful in 19s
2026-10-25 13:46:12 +01:00
hektor 82109a74ff fix(ai-tools): bump 'ccline' 2026-10-25 13:44:08 +01:00
hektor 9ad228fd0e fix(ai-tools): use 'rtk' from 'nixpkgs' 2026-10-25 13:44:08 +01:00
12 changed files with 107 additions and 75 deletions

No files matched your search

+1 -4
View File
@@ -19,10 +19,7 @@
xdg.userDirs.createDirectories = false; xdg.userDirs.createDirectories = false;
xdg.userDirs.download = "${config.home.homeDirectory}/dl"; xdg.userDirs.download = "${config.home.homeDirectory}/dl";
modules."3d" = { modules."3d".printing.enable = true;
printing.enable = true;
modeling.enable = true;
};
ai-tools = { ai-tools = {
claude-code.enable = true; claude-code.enable = true;
codex.enable = true; codex.enable = true;
+12 -1
View File
@@ -6,7 +6,18 @@
enable = lib.mkEnableOption "3D printing tools"; enable = lib.mkEnableOption "3D printing tools";
}; };
modeling = { modeling = {
enable = lib.mkEnableOption "3D modeling tools"; blender = {
enable = lib.mkOption {
default = false;
type = lib.types.bool;
};
};
openscad = {
enable = lib.mkOption {
default = false;
type = lib.types.bool;
};
};
}; };
}; };
+6 -2
View File
@@ -6,9 +6,13 @@
}: }:
{ {
config = lib.mkIf config.modules."3d".modeling.enable { config = {
home.packages = with pkgs; [ home.packages =
with pkgs;
lib.optionals config.modules."3d".modeling.blender.enable [
blender blender
]
++ lib.optionals config.modules."3d".modeling.openscad.enable [
openscad-lsp openscad-lsp
openscad-unstable openscad-unstable
]; ];
+16 -35
View File
@@ -6,52 +6,33 @@
}: }:
let let
cfg = config.ai-tools.claude-code; cfg = config.ai-tools.claude-code;
rtk-version = "0.18.1";
in in
{ {
config = lib.mkIf cfg.enable { config = lib.mkIf cfg.enable {
programs.claude-code.enable = true; programs.claude-code.enable = true;
home.packages = with pkgs; [ home.packages = with pkgs; [
(stdenv.mkDerivation { (rustPlatform.buildRustPackage (finalAttrs: {
name = "ccline"; pname = "ccometixline";
src = fetchurl { version = "2.0.1";
url = "https://github.com/Haleclipse/CCometixLine/releases/download/v1.0.8/ccline-linux-x64.tar.gz"; src = fetchFromGitHub {
hash = "sha256-Joe3Dd6uSMGi66QT6xr2oY/Tz8rA5RuKa6ckBVJIzI0="; owner = "Haleclipse";
repo = "CCometixLine";
tag = "v${finalAttrs.version}";
hash = "sha256-tzEo+8M86C6EdN31rDVqt8+SCYqeEXRCVFsbtbW41XY=";
}; };
unpackPhase = "tar xzf $src"; cargoHash = "sha256-dTsuyklpaiYqp5Rq1Q7YUBrmQUH42ve2UY+MwUqF7Ek=";
installPhase = '' checkFlags = [ "--skip=git::tests::detects_repositories_without_spawning_git" ];
mkdir -p $out/bin postInstall = "mv $out/bin/ccometixline $out/bin/ccline";
cp ccline $out/bin/
chmod +x $out/bin/ccline
'';
meta = { meta = {
description = "CCometixLine Linux x64 CLI (Claude Code statusline)"; description = "CCometixLine (ccline) - Claude Code statusline tool";
homepage = "https://github.com/Haleclipse/CCometixLine"; homepage = "https://github.com/Haleclipse/CCometixLine";
license = lib.licenses.mit; license = lib.licenses.mit;
platforms = [ "x86_64-linux" ]; mainProgram = "ccline";
platforms = lib.platforms.unix;
}; };
}) }))
(stdenv.mkDerivation { rtk
name = "rtk-${rtk-version}";
version = rtk-version;
src = fetchurl {
url = "https://github.com/rtk-ai/rtk/releases/download/v${rtk-version}/rtk-x86_64-unknown-linux-gnu.tar.gz";
hash = "sha256-XoTia5K8b00OzcKYCufwx8ApkAS31DxUCpGSU0jFs2Q=";
};
unpackPhase = "tar xzf $src";
installPhase = ''
mkdir -p $out/bin
cp rtk $out/bin/
chmod +x $out/bin/rtk
'';
meta = {
description = "RTK - AI coding tool enhancer";
homepage = "https://www.rtk-ai.app";
license = lib.licenses.mit;
platforms = [ "x86_64-linux" ];
};
})
mcp-nixos mcp-nixos
]; ];
}; };
+4
View File
@@ -53,6 +53,10 @@ in
}; };
policies = { policies = {
DefaultDownloadDirectory = "\${home}/dl"; DefaultDownloadDirectory = "\${home}/dl";
"3rdparty".Extensions."keepassxc-browser@keepassxc.org".settings = {
defaultGroup = "browser";
defaultPasskeyGroup = "browser";
};
ExtensionSettings = { ExtensionSettings = {
"jid1-ZAdIEUB7XOzOJw@jetpack" = { "jid1-ZAdIEUB7XOzOJw@jetpack" = {
default_area = "navbar"; default_area = "navbar";
+1 -5
View File
@@ -8,7 +8,6 @@
let let
meta = import ./meta.nix; meta = import ./meta.nix;
wolInterfaces = import ./wol-interfaces.nix;
in in
{ {
imports = [ imports = [
@@ -88,10 +87,7 @@ in
}; };
tailscale.enable = true; tailscale.enable = true;
taskwarrior.enable = true; taskwarrior.enable = true;
wol = { wol.interfaces.eno1.macAddress = "02:68:b3:29:da:98";
enable = true;
interfaces.eno1 = { inherit (wolInterfaces.eno1) macAddress; };
};
zfs.enable = true; zfs.enable = true;
disko.devices = { disko.devices = {
-3
View File
@@ -1,3 +0,0 @@
{
eno1.macAddress = "02:68:b3:29:da:98";
}
+1 -10
View File
@@ -71,6 +71,7 @@ in
}; };
}; };
taskwarrior.enable = true; taskwarrior.enable = true;
wol.wakes = [ "andromache" ];
zfs.enable = true; zfs.enable = true;
secrets.nixSigningKey.enable = true; secrets.nixSigningKey.enable = true;
@@ -82,16 +83,6 @@ in
hardware.cpu.intel.updateMicrocode = true; hardware.cpu.intel.updateMicrocode = true;
environment.systemPackages = [
(pkgs.writeShellApplication {
name = "wol-andromache";
runtimeInputs = [ pkgs.wakeonlan ];
text = ''
wakeonlan ${(import ../andromache/wol-interfaces.nix).eno1.macAddress}
'';
})
];
networking = { networking = {
hostId = "5f0bde3c"; hostId = "5f0bde3c";
useDHCP = false; useDHCP = false;
+1
View File
@@ -16,6 +16,7 @@ in
ssh.enable = true; ssh.enable = true;
tailscale.enable = true; tailscale.enable = true;
wol.wakes = [ "andromache" ];
boot = { boot = {
kernelParams = [ kernelParams = [
+12
View File
@@ -21,6 +21,11 @@ in
type = lib.types.listOf lib.types.str; type = lib.types.listOf lib.types.str;
default = [ "/home" ]; default = [ "/home" ];
}; };
inhibitsSleep = lib.mkOption {
type = lib.types.bool;
default = config.host.role != "laptop";
};
}; };
config = lib.mkIf cfg.enable { config = lib.mkIf cfg.enable {
@@ -53,6 +58,7 @@ in
Persistent = true; Persistent = true;
}; };
initialize = true; initialize = true;
inherit (cfg) inhibitsSleep;
extraBackupArgs = [ "--one-file-system" ]; extraBackupArgs = [ "--one-file-system" ];
pruneOpts = [ pruneOpts = [
"--keep-daily 7" "--keep-daily 7"
@@ -62,5 +68,11 @@ in
]; ];
environmentFile = config.sops.templates."restic/b2-env-${host}".path; environmentFile = config.sops.templates."restic/b2-env-${host}".path;
}; };
systemd.services.restic-backups-home = {
unitConfig = {
RequiresMountsFor = cfg.paths;
};
};
}; };
} }
+15 -1
View File
@@ -17,7 +17,8 @@ in
config = { config = {
networking.firewall.allowedTCPPorts = lib.mkIf config.ssh.enable [ 22 ]; networking.firewall.allowedTCPPorts = lib.mkIf config.ssh.enable [ 22 ];
services.openssh.settings = optionalAttrs cfg.harden { services.openssh = {
settings = optionalAttrs cfg.harden {
PermitRootLogin = "no"; PermitRootLogin = "no";
PasswordAuthentication = false; PasswordAuthentication = false;
AuthenticationMethods = "publickey"; AuthenticationMethods = "publickey";
@@ -29,6 +30,19 @@ in
PermitTunnel = false; PermitTunnel = false;
MaxAuthTries = 3; MaxAuthTries = 3;
LoginGraceTime = "1m"; LoginGraceTime = "1m";
ClientAliveInterval = 300;
ClientAliveCountMax = 2;
TCPKeepAlive = false;
MaxSessions = 4;
LogLevel = "VERBOSE";
AllowUsers = [ config.host.username ];
};
hostKeys = mkIf cfg.harden [
{
type = "ed25519";
path = "/etc/ssh/ssh_host_ed25519_key";
}
];
}; };
}; };
} }
+38 -14
View File
@@ -1,33 +1,57 @@
{ lib, config, ... }: {
lib,
config,
outputs,
paths,
myUtils,
pkgs,
...
}:
let let
inherit (lib) mkEnableOption mkOption types; hosts = myUtils.dirNames paths.hosts;
interfaces = host: outputs.nixosConfigurations.${host}.config.wol.interfaces;
in in
{ {
options.wol = { options.wol = {
enable = mkEnableOption "Wake-on-LAN configuration"; wakes = lib.mkOption {
type = lib.types.listOf (lib.types.enum hosts);
interfaces = mkOption {
type = types.attrsOf (
types.submodule {
options = {
macAddress = mkOption {
type = types.str;
example = "02:68:b3:29:da:98";
}; };
interfaces = lib.mkOption {
type = lib.types.attrsOf (
lib.types.submodule {
options = {
macAddress = lib.mkOption { type = lib.types.str; };
}; };
} }
); );
default = { };
}; };
}; };
config = lib.mkIf config.wol.enable { config = {
assertions = map (host: {
assertion = interfaces host != { };
message = "cannot set up wake-on-lan for '${host}' as it declares no 'wol.interfaces'.";
}) config.wol.wakes;
networking.interfaces = lib.mapAttrs (_: iface: { networking.interfaces = lib.mapAttrs (_: iface: {
wakeOnLan.enable = true; wakeOnLan.enable = true;
inherit (iface) macAddress; inherit (iface) macAddress;
}) config.wol.interfaces; }) config.wol.interfaces;
# networking.firewall.allowedUDPPorts = [ 9 ]; environment.systemPackages = map (
host:
let
macAddresses = lib.mapAttrsToList (_: interface: interface.macAddress) (interfaces host);
in
pkgs.writeShellApplication {
name = "wol-${host}";
runtimeInputs = [ pkgs.wakeonlan ];
text = ''
wakeonlan ${lib.escapeShellArgs macAddresses}
'';
}
) config.wol.wakes;
}; };
} }