aboutsummaryrefslogtreecommitdiff
path: root/modules
diff options
context:
space:
mode:
authorCollin Williams <96917990+bluedragon1221@users.noreply.github.com>2026-01-18 08:10:20 -0600
committerCollin Williams <96917990+bluedragon1221@users.noreply.github.com>2026-01-18 08:10:20 -0600
commitd6c4bd6d87d31a2c688fb2fcfdb0cb15d8f9163d (patch)
tree07f85b8fac540f7625f90b10ee500a1bc8116ac3 /modules
parented2550a41c8429a1d2fe897deb878717c2ebc3d1 (diff)
parent43af7f28b28021932b318964a953463d8dd79372 (diff)
Merge branch 'main' into wg
Diffstat (limited to 'modules')
-rw-r--r--modules/boot/nixos/default.nix50
-rw-r--r--modules/boot/options.nix9
-rw-r--r--modules/desktop/hjem/programs/firefox.nix2
-rw-r--r--modules/desktop/hjem/wm/fuzzel.nix40
-rw-r--r--modules/desktop/nixos/fonts.nix3
-rw-r--r--modules/desktop/nixos/greeters/greetd.nix28
-rw-r--r--modules/desktop/options.nix132
-rw-r--r--modules/nix/nixos/default.nix10
-rw-r--r--modules/options.nix3
-rw-r--r--modules/secrets/options.nix10
-rw-r--r--modules/services/nixos/audio.nix5
-rw-r--r--modules/services/nixos/bluetooth.nix12
-rw-r--r--modules/services/nixos/networking/default.nix18
-rw-r--r--modules/services/nixos/networking/networkd.nix7
-rw-r--r--modules/services/nixos/networking/resolved.nix17
-rw-r--r--modules/services/nixos/selfhost/adguard.nix12
-rw-r--r--modules/services/nixos/selfhost/default.nix1
-rw-r--r--modules/services/nixos/selfhost/forgejo.nix15
-rw-r--r--modules/services/nixos/selfhost/headscale.nix75
-rw-r--r--modules/services/nixos/ssh.nix14
-rw-r--r--modules/services/nixos/tailscale.nix12
-rw-r--r--modules/services/options.nix80
-rw-r--r--modules/terminal/hjem/programs/tmux.nix4
-rw-r--r--modules/terminal/options.nix10
-rw-r--r--modules/user/nixos/default.nix3
-rw-r--r--modules/user/options.nix2
26 files changed, 404 insertions, 170 deletions
diff --git a/modules/boot/nixos/default.nix b/modules/boot/nixos/default.nix
index 026226b..49cca5e 100644
--- a/modules/boot/nixos/default.nix
+++ b/modules/boot/nixos/default.nix
@@ -26,6 +26,37 @@ in {
efi.canTouchEfiVariables = true;
timeout = cfg.timeout; # hold space to show boot menu
};
+
+ # from hardened.nix
+ blacklistedKernelModules = [
+ # Obscure network protocols
+ "ax25"
+ "netrom"
+ "rose"
+
+ # Old or rare or insufficiently audited filesystems
+ "adfs"
+ "affs"
+ "bfs"
+ "befs"
+ "cramfs"
+ "efs"
+ # "erofs" # necessary for system.etc.overlay
+ "exofs"
+ "freevxfs"
+ "f2fs"
+ "hfs"
+ "hpfs"
+ "jfs"
+ "minix"
+ "nilfs2"
+ "ntfs"
+ "omfs"
+ "qnx4"
+ "qnx6"
+ "sysv"
+ "ufs"
+ ];
}
// (lib.optionalAttrs cfg.secureBoot.enable {
lanzaboote = {
@@ -34,14 +65,17 @@ in {
};
});
- system.etc.overlay.enable = true;
+ system.etc.overlay = {
+ enable = true;
+ mutable = true; # would love this to be false, but we're not there yet
+ };
system.nixos-init.enable = true;
- environment.systemPackages =
- (
- if cfg.secureBoot.enable
- then [pkgs.sbctl]
- else []
- )
- ++ [pkgs.efibootmgr];
+ # store journald logs in memory
+ services.journald.extraConfig = ''
+ Storage=volatile
+ RuntimeMaxUse=100M
+ '';
+
+ environment.systemPackages = [pkgs.efibootmgr] ++ lib.optional cfg.secureBoot.enable pkgs.sbctl;
}
diff --git a/modules/boot/options.nix b/modules/boot/options.nix
index 2f670f9..9e85570 100644
--- a/modules/boot/options.nix
+++ b/modules/boot/options.nix
@@ -1,9 +1,11 @@
{
+ my-lib,
config,
lib,
...
}: let
- inherit (lib) mkOption mkEnableOption types;
+ inherit (lib) mkOption mkEnableOption;
+ inherit (my-lib.options {inherit lib config;}) mkThemeOption;
in {
options = {
collinux.boot = {
@@ -15,10 +17,7 @@ in {
};
plymouth = {
enable = mkEnableOption "plymouth bootsplash";
- theme = mkOption {
- type = types.enum ["catppuccin" "adwaita"];
- default = config.collinux.theme;
- };
+ theme = mkThemeOption "plymouth";
};
secureBoot.enable = mkEnableOption "lanzaboote";
};
diff --git a/modules/desktop/hjem/programs/firefox.nix b/modules/desktop/hjem/programs/firefox.nix
index b5ea433..2078e3c 100644
--- a/modules/desktop/hjem/programs/firefox.nix
+++ b/modules/desktop/hjem/programs/firefox.nix
@@ -27,6 +27,8 @@ in
};
};
+ ".mozilla/firefox/collin/user.js".source = "${inputs.betterfox}/user.js";
+
".mozilla/firefox/collin/chrome/userChrome.css".text = mkCssHacks (
# (lib.optional (cfg.theme == "adwaita") "window_control_placeholder_support") ++
[
diff --git a/modules/desktop/hjem/wm/fuzzel.nix b/modules/desktop/hjem/wm/fuzzel.nix
index 7d61255..f9a9edb 100644
--- a/modules/desktop/hjem/wm/fuzzel.nix
+++ b/modules/desktop/hjem/wm/fuzzel.nix
@@ -8,34 +8,38 @@
settings = {
main = {
- prompt = "";
- dpi-aware = false;
+ prompt = builtins.fromJSON ''"\u200B"''; # https://discourse.nixos.org/t/how-can-i-put-an-nonprintable-character-in-a-nix-expression/47750/7
- font = "Iosevka Nerd Font";
- line-height = 25;
+ font = "Iosevka Nerd Font:size=9";
+ use-bold = true;
+ line-height = 16;
lines = 10;
- width = 30;
+ width = 20;
- horizontal-pad = 8;
- vertical-pad = 8;
+ anchor = "bottom-right";
+
+ horizontal-pad = 0;
+ vertical-pad = 0;
};
border = {
radius = 0;
width = 3;
};
- colors = with config.collinux.palette; {
- background = "${base00}99";
- border = "ffffff00";
- input = base05;
- match = base13;
- placeholder = base03;
- text = base01;
- prompt = base01;
+ colors = with config.collinux.palette; let
+ transparent = "#ffffff00";
+ in {
+ background = transparent;
+ border = transparent;
+ input = transparent;
+ match = "#${base13}ff";
+ placeholder = "#${base03}ff";
+ text = "#${base04}ff";
+ prompt = "#${base05}ff";
- selection = "${base01}5a";
- selection-match = base13;
- selection-text = base05;
+ selection = transparent;
+ selection-match = "#${base13}ff";
+ selection-text = "#${base05}ff";
};
};
in
diff --git a/modules/desktop/nixos/fonts.nix b/modules/desktop/nixos/fonts.nix
index 3f10d92..5ac17ec 100644
--- a/modules/desktop/nixos/fonts.nix
+++ b/modules/desktop/nixos/fonts.nix
@@ -1,8 +1,7 @@
{pkgs, ...}: {
fonts = {
enableDefaultPackages = false;
- # fontDir.enable = true;
fontconfig.enable = true;
- packages = [pkgs.nerd-fonts.iosevka pkgs.ibm-plex]; # for terminal (blackbox or foot)
+ packages = [pkgs.nerd-fonts.iosevka pkgs.ibm-plex]; # for terminal (blackbox or foot or ghostty)
};
}
diff --git a/modules/desktop/nixos/greeters/greetd.nix b/modules/desktop/nixos/greeters/greetd.nix
index b612c86..02af31f 100644
--- a/modules/desktop/nixos/greeters/greetd.nix
+++ b/modules/desktop/nixos/greeters/greetd.nix
@@ -1,19 +1,35 @@
{
+ pkgs,
config,
lib,
...
}: let
cfg = config.collinux.desktop.greetd;
+
+ session =
+ if cfg.cosmic-greeter.enable
+ then {
+ command = "${pkgs.cosmic-greeter}/bin/cosmic-greeter-start";
+ user = config.collinux.user.name;
+ }
+ else if cfg.autologin.enable
+ then {
+ user = config.collinux.user.name;
+ command = with config.collinux.desktop;
+ if (wm.sway.enable && !gnome.enable && !wm.niri.enable)
+ then lib.getExe pkgs.sway
+ else if (wm.niri.enable && !gnome.enable && !wm.sway.enable)
+ then "${pkgs.niri}/bin/niri-session"
+ else null;
+ }
+ else {};
in
lib.mkIf cfg.enable {
services.greetd = {
enable = true;
- settings = rec {
- initial_session = {
- command = cfg.command;
- user = config.collinux.user.name;
- };
- default_session = initial_session;
+ settings = {
+ initial_session = session;
+ default_session = session;
};
};
}
diff --git a/modules/desktop/options.nix b/modules/desktop/options.nix
index 1067d0b..a4ba38d 100644
--- a/modules/desktop/options.nix
+++ b/modules/desktop/options.nix
@@ -6,7 +6,7 @@
...
}: let
inherit (lib) mkOption mkEnableOption types;
- inherit (my-lib.options {inherit lib config;}) mkProgramOption;
+ inherit (my-lib.options {inherit lib config;}) mkProgramOption mkThemeOption;
in {
options = {
collinux.desktop = {
@@ -17,21 +17,13 @@ in {
wallpaper_cmd = mkOption {
type = types.str;
default = "${lib.getExe pkgs.wbg} -s ${config.collinux.desktop.wallpaper}";
+ internal = true;
};
greetd = {
enable = mkEnableOption "greetd greeter";
- command = mkOption {
- type = lib.types.str;
- default = let
- cfg = config.collinux.desktop;
- in
- if (cfg.wm.sway.enable && !cfg.gnome.enable && !cfg.wm.niri.enable)
- then lib.getExe pkgs.sway
- else if (cfg.wm.niri.enable && !cfg.gnome.enable && !cfg.wm.sway.enable)
- then "${pkgs.niri}/bin/niri-session"
- else null;
- };
+ autologin.enable = mkEnableOption "autologin";
+ cosmic-greeter.enable = mkEnableOption "cosmic-greeter";
};
gdm.enable = mkEnableOption "gdm display manager";
@@ -40,7 +32,6 @@ in {
niri.enable = mkEnableOption "niri";
components = {
- # waybar = mkProgramOption "waybar";
dunst = mkProgramOption "dunst";
fuzzel = mkProgramOption "fuzzel";
};
@@ -49,54 +40,67 @@ in {
gtk = {
enable = mkEnableOption "gtk theming";
- theme = mkOption {
- type = types.enum ["catppuccin" "adwaita" "kanagawa"];
- default = config.collinux.theme;
- };
- cursor_data = {
- package = mkOption {
- type = lib.types.package;
- default =
- if (config.collinux.desktop.gtk.theme == "catppuccin")
- then pkgs.catppuccin-cursors.mochaDark
- else if (config.collinux.desktop.gtk.theme == "adwaita")
- then pkgs.vanilla-dmz
- else null;
- };
- name = mkOption {
- type = lib.types.str;
- default =
- if (config.collinux.desktop.gtk.theme == "catppuccin")
- then "catppuccin-mocha-dark-cursors"
- else if (config.collinux.desktop.gtk.theme == "adwaita")
- then "Vanilla-DMZ"
- else null;
+ theme = mkThemeOption "gtk";
+
+ cursor_data = mkOption {
+ internal = true;
+ type = lib.types.submodule {
+ options = {
+ package = mkOption {
+ internal = true;
+ type = lib.types.package;
+ };
+ name = mkOption {
+ internal = true;
+ type = lib.types.str;
+ };
+ };
};
+ default =
+ if config.collinux.desktop.gtk.theme == "catppuccin"
+ then {
+ name = "catppuccin-mocha-dark-cursors";
+ package = pkgs.catppuccin-cursors.mochaDark;
+ }
+ else if config.collinux.gtk.theme == "adwaita"
+ then {
+ name = "Vanilla-DMZ";
+ package = pkgs.vanilla-dmz;
+ }
+ else null;
};
- theme_data = {
- package = mkOption {
- type = lib.types.package;
- default =
- if (config.collinux.desktop.gtk.theme == "catppuccin")
- then
- (pkgs.catppuccin-gtk.override {
- variant = "mocha";
- accents = ["blue"];
- size = "standard";
- })
- else if (config.collinux.desktop.gtk.theme == "adwaita")
- then pkgs.adw-gtk3
- else "";
- };
- name = mkOption {
- type = lib.types.str;
- default =
- if (config.collinux.desktop.gtk.theme == "catppuccin")
- then "catppuccin-mocha-blue-standard"
- else if (config.collinux.desktop.gtk.theme == "adwaita")
- then "adw-gtk3"
- else "";
+
+ theme_data = mkOption {
+ internal = true;
+ type = lib.types.submodule {
+ options = {
+ package = mkOption {
+ internal = true;
+ type = lib.types.package;
+ };
+ name = mkOption {
+ internal = true;
+ type = lib.types.str;
+ };
+ };
};
+
+ default =
+ if config.collinux.desktop.gtk.theme == "catppuccin"
+ then {
+ package = pkgs.catppuccin-gtk.override {
+ variant = "mocha";
+ accents = ["blue"];
+ size = "standard";
+ };
+ name = "catppuccin-mocha-blue-standard";
+ }
+ else if config.collinux.desktop.gtk.theme == "adwaita"
+ then {
+ package = pkgs.adw-gtk3;
+ name = "adw-gtk3";
+ }
+ else null;
};
};
@@ -106,11 +110,9 @@ in {
profileName = mkOption {
type = types.str;
default = config.collinux.user.name;
+ internal = true;
};
- theme = mkOption {
- type = types.enum ["none" "catppuccin" "adwaita" "kanagawa"];
- default = config.collinux.theme;
- };
+ theme = mkThemeOption "firefox";
extensions.zotero.enable = mkOption {
description = "install Zotero Connector for Firefox";
default = config.collinux.desktop.programs.research.enable;
@@ -122,7 +124,7 @@ in {
ghostty.enable = mkEnableOption "ghostty";
alacritty.enable = mkEnableOption "alacritty";
- research.enable = mkEnableOption "zathura, Xournal++, Zotero, Zotero Connector";
+ research.enable = mkEnableOption "zathura, Xournal++, Zotero";
};
};
};
@@ -133,6 +135,10 @@ in {
assertion = with config.collinux.desktop; !(gdm.enable && greetd.enable);
message = "Can't enable gdm and greetd at the same time";
}
+ {
+ assertion = with config.collinux.desktop.greetd; enable && !(autologin.enable && cosmic-greeter.enable);
+ message = "Can't use autologin and cosmic-greeter at the same time";
+ }
];
};
}
diff --git a/modules/nix/nixos/default.nix b/modules/nix/nixos/default.nix
index 7116371..c817859 100644
--- a/modules/nix/nixos/default.nix
+++ b/modules/nix/nixos/default.nix
@@ -1,12 +1,9 @@
{
- inputs,
config,
pkgs,
...
}: {
nix = {
- # package = inputs.determinate.packages.${pkgs.system}.default;
-
gc.automatic = false; # use nh cleaner instead
# Make builds run with low priority so my system stays responsive
@@ -27,9 +24,12 @@
programs.nh = {
enable = true;
- flake = "/home/collin/nixos";
+ flake = "/home/${config.collinux.user.name}/nixos";
clean.enable = true;
};
- hjem.users."${config.collinux.user.name}".packages = [pkgs.cached-nix-shell];
+ environment.systemPackages = [pkgs.cached-nix-shell];
+
+ nixpkgs.hostPlatform = "x86_64-linux";
+ system.stateVersion = "25.05";
}
diff --git a/modules/options.nix b/modules/options.nix
index 65de32e..8ecf1d7 100644
--- a/modules/options.nix
+++ b/modules/options.nix
@@ -7,15 +7,18 @@
in {
options = {
collinux.theme = mkOption {
+ description = "System-wide theme";
type = types.enum ["catppuccin" "adwaita" "kanagawa"];
};
collinux.palette = let
colorOption = lib.mkOption {
type = lib.types.strMatching "^([0-9a-fA-F]{6}|[0-9a-fA-F]{3})$";
+ internal = true;
};
in
lib.mkOption {
+ internal = true;
type = lib.types.submodule {
options = {
base00 = colorOption;
diff --git a/modules/secrets/options.nix b/modules/secrets/options.nix
index de15f50..fa53d6f 100644
--- a/modules/secrets/options.nix
+++ b/modules/secrets/options.nix
@@ -3,25 +3,33 @@
in {
options = {
collinux.secrets = lib.mkOption {
+ description = "Atribute set of secrets";
type = lib.types.attrsOf (
lib.types.submodule ({config, ...}: {
options = {
name = mkOption {
type = lib.types.str;
default = config._module.args.name;
+ internal = true;
+ };
+ file = mkOption {
+ description = "Name of the file in the /run/secrets.d";
+ type = lib.types.path;
};
- file = mkOption {type = lib.types.path;};
mode = mkOption {
+ description = "Permissions mode of the decrypted secret in a format understood by chmod";
type = lib.types.str;
default = "0400";
};
owner = mkOption {
+ description = "Owner of the decrypted secret file";
type = lib.types.str;
default = "0";
};
path = mkOption {
type = lib.types.str;
default = "/run/secrets.d/${config.name}";
+ description = "Path where the decrypted secret is installed";
};
};
})
diff --git a/modules/services/nixos/audio.nix b/modules/services/nixos/audio.nix
index 93f8289..8f2f23e 100644
--- a/modules/services/nixos/audio.nix
+++ b/modules/services/nixos/audio.nix
@@ -12,9 +12,10 @@ in
enable = true;
wireplumber.enable = true;
alsa.enable = true;
-
- pulse.enable = cfg.pulse.enable;
+ pulse.enable = false;
};
+ boot.blacklistedKernelModules = ["snd_seq_dummy"]; # remove extraneous alsa midi devices
+
environment.systemPackages = [pkgs.pwvucontrol];
}
diff --git a/modules/services/nixos/bluetooth.nix b/modules/services/nixos/bluetooth.nix
index a86b5b3..bdcaa00 100644
--- a/modules/services/nixos/bluetooth.nix
+++ b/modules/services/nixos/bluetooth.nix
@@ -12,6 +12,18 @@ in
powerOnBoot = true;
};
+ # hardening (down to 2.1 OK)
+ systemd.services."bluetooth".serviceConfig = {
+ IPAddressDeny = "any";
+ ProtectHostname = true;
+ ProtectKernelTunables = lib.mkForce true;
+ ProtectKernelLogs = true;
+ ProtectKernelModules = lib.mkForce true;
+ RestrictAddressFamilies = ["AF_UNIX" "AF_BLUETOOTH"];
+ ProtectClock = true;
+ ProcSubset = "pid";
+ };
+
environment.systemPackages = [
(lib.mkIf cfg.blueman.enable pkgs.blueman)
(lib.mkIf cfg.bluetuith.enable pkgs.bluetuith)
diff --git a/modules/services/nixos/networking/default.nix b/modules/services/nixos/networking/default.nix
index 2667849..9fa56da 100644
--- a/modules/services/nixos/networking/default.nix
+++ b/modules/services/nixos/networking/default.nix
@@ -3,24 +3,8 @@
./iwd.nix
./networkmanager.nix
./networkd.nix
+ ./resolved.nix
];
networking.firewall.enable = true;
-
- # DNS
- services.resolved = {
- enable = true;
- dnsovertls = "opportunistic";
- fallbackDns = [
- "9.9.9.9#dns.quad9.net"
- "149.112.112.112#dns.quad9.net"
- ];
-
- # disable extra stuff
- llmnr = "false";
- extraConfig = "MulticastDNS=no";
- };
- networking.resolvconf.enable = false;
-
- systemd.network.wait-online.enable = false;
}
diff --git a/modules/services/nixos/networking/networkd.nix b/modules/services/nixos/networking/networkd.nix
index 9a11129..920b93f 100644
--- a/modules/services/nixos/networking/networkd.nix
+++ b/modules/services/nixos/networking/networkd.nix
@@ -25,6 +25,13 @@ in
systemd.network = {
enable = true;
+
+ wait-online = {
+ enable = true;
+ ignoredInterfaces = ["docker0"];
+ anyInterface = true;
+ };
+
networks."11-static-lan" = {
name = "wl*";
diff --git a/modules/services/nixos/networking/resolved.nix b/modules/services/nixos/networking/resolved.nix
new file mode 100644
index 0000000..b552095
--- /dev/null
+++ b/modules/services/nixos/networking/resolved.nix
@@ -0,0 +1,17 @@
+{
+ networking.resolvconf.enable = false;
+
+ services.resolved = {
+ enable = true;
+ dnsovertls = "opportunistic";
+ dnssec = "allow-downgrade";
+ fallbackDns = [
+ "9.9.9.9#dns.quad9.net"
+ "149.112.112.112#dns.quad9.net"
+ ];
+
+ # disable extra stuff
+ llmnr = "false";
+ extraConfig = "MulticastDNS=no";
+ };
+}
diff --git a/modules/services/nixos/selfhost/adguard.nix b/modules/services/nixos/selfhost/adguard.nix
index c5e93ee..69fb8a4 100644
--- a/modules/services/nixos/selfhost/adguard.nix
+++ b/modules/services/nixos/selfhost/adguard.nix
@@ -32,16 +32,16 @@ in
DNSStubListener=no
'';
- services.caddy = lib.mkIf config.collinux.services.selfhost.caddy.enable {
+ services.tailscale.extraSetFlags = lib.optional config.collinux.services.networking.tailscale.enable "--accept-dns=false"; # would create an infinite loop of dns lookups
+
+ services.caddy = lib.mkIf cfg.caddy.enable {
virtualHosts.${cfg.root_url}.extraConfig = ''
${
- if config.collinux.services.networking.tailscale.enable
- then "bind tailscale/adguard"
+ if cfg.caddy.bind_tailscale
+ then "bind tailscale/${cfg.service_name}"
else ""
}
- reverse_proxy localhost:${toString cfg.port}
+ reverse_proxy ${cfg.bind_host}:${toString cfg.port}
'';
};
-
- services.tailscale.extraSetFlags = lib.optional config.collinux.services.networking.tailscale.enable "--accept-dns=false"; # would create an infinite loop of dns lookups
}
diff --git a/modules/services/nixos/selfhost/default.nix b/modules/services/nixos/selfhost/default.nix
index 876586d..de1078b 100644
--- a/modules/services/nixos/selfhost/default.nix
+++ b/modules/services/nixos/selfhost/default.nix
@@ -2,6 +2,7 @@
imports = [
./adguard.nix
./forgejo.nix
+ ./headscale.nix
./caddy.nix
];
}
diff --git a/modules/services/nixos/selfhost/forgejo.nix b/modules/services/nixos/selfhost/forgejo.nix
index b1a6095..4571dca 100644
--- a/modules/services/nixos/selfhost/forgejo.nix
+++ b/modules/services/nixos/selfhost/forgejo.nix
@@ -8,7 +8,7 @@ in
lib.mkIf cfg.enable {
services.forgejo = {
enable = true;
- database.type = "postgres";
+ database.type = "sqlite3";
settings = {
server = {
DOMAIN = "localhost";
@@ -36,14 +36,19 @@ in
};
};
- services.caddy = lib.mkIf config.collinux.services.selfhost.caddy.enable {
+ systemd.services."forgejo" = lib.mkIf config.collinux.services.networking.networkd.enable {
+ after = lib.mkAfter ["network-online.target"];
+ wants = lib.mkAfter ["network-online.target"];
+ };
+
+ services.caddy = lib.mkIf cfg.caddy.enable {
virtualHosts.${cfg.root_url}.extraConfig = ''
${
- if config.collinux.services.networking.tailscale.enable
- then "bind tailscale/forgejo"
+ if cfg.caddy.bind_tailscale
+ then "bind tailscale/${cfg.service_name}"
else ""
}
- reverse_proxy localhost:${toString cfg.port}
+ reverse_proxy ${cfg.bind_host}:${toString cfg.port}
'';
};
}
diff --git a/modules/services/nixos/selfhost/headscale.nix b/modules/services/nixos/selfhost/headscale.nix
new file mode 100644
index 0000000..2bdcca1
--- /dev/null
+++ b/modules/services/nixos/selfhost/headscale.nix
@@ -0,0 +1,75 @@
+{
+ config,
+ pkgs,
+ lib,
+ ...
+}: let
+ cfg = config.collinux.services.selfhost.headscale;
+
+ acl_file = (pkgs.formats.json {}).generate "acl.json" {
+ ssh = [
+ {
+ src = ["collin@"];
+ dst = ["collin@"];
+ users = ["autogroup:nonroot" "root"];
+ action = "accept";
+ }
+ ];
+ };
+in
+ lib.mkIf cfg.enable {
+ services.headscale = {
+ enable = true;
+ address = cfg.bind_host;
+ port = cfg.port;
+ settings = {
+ server_url = "https://${cfg.root_url}";
+
+ database.type = "sqlite";
+
+ dns = {
+ magic_dns = true;
+ base_domain = "collinux.tailnet";
+ override_local_dns = true;
+ nameservers.global = ["9.9.9.9" "149.112.112.112" "2620:fe::fe" "2620:fe::9"];
+ };
+
+ policy.path = "${acl_file}";
+
+ prefixes = {
+ "v4" = "100.100.0.0/16";
+ allocation = "random";
+ };
+
+ # leave tls for caddy to worry about
+ tls_cert_path = null;
+ tls_key_path = null;
+
+ logtail.enabled = false;
+ };
+ };
+
+ # make sure headscale can start before tailscale
+ systemd.services."headscale" = lib.mkIf config.collinux.services.networking.tailscale.enable {
+ after = lib.mkForce ["network.target"];
+ before = lib.mkForce ["headscale.target"];
+ wants = lib.mkForce ["network.target" "headscale.target"];
+ };
+
+ systemd.targets."headscale" = {
+ description = "Target represents headscale is running. started by headscale.service";
+ };
+
+ environment.systemPackages = [pkgs.headscale];
+
+ services.caddy = lib.mkIf cfg.caddy.enable {
+ virtualHosts.${cfg.root_url}.extraConfig = ''
+ ${
+ if cfg.caddy.bind_tailscale
+ then "bind tailscale/${cfg.service_name}"
+ else ""
+ }
+ reverse_proxy ${cfg.bind_host}:${toString cfg.port}
+ '';
+ };
+ }
diff --git a/modules/services/nixos/ssh.nix b/modules/services/nixos/ssh.nix
index 2867d10..cfe7883 100644
--- a/modules/services/nixos/ssh.nix
+++ b/modules/services/nixos/ssh.nix
@@ -8,18 +8,32 @@ in {
config = lib.mkIf cfg.enable {
services.openssh = {
enable = true;
+ openFirewall = false;
hostKeys = [
{
path = "/etc/ssh/ssh_host_ed25519_key";
type = "ed25519";
}
];
+
+ listenAddresses = [
+ {
+ addr = cfg.bind_host;
+ port = 22;
+ }
+ ];
+
settings = {
PermitRootLogin = "prohibit-password";
PasswordAuthentication = false;
};
};
+ systemd.services."openssh" = lib.mkIf config.collinux.services.networking.networkd.enable {
+ after = lib.mkAfter ["network-online.target"];
+ wants = lib.mkAfter ["network-online.target"];
+ };
+
services.tailscale.extraSetFlags = lib.optional config.services.tailscale.enable "--ssh=true";
};
}
diff --git a/modules/services/nixos/tailscale.nix b/modules/services/nixos/tailscale.nix
index f39fc27..50e35d3 100644
--- a/modules/services/nixos/tailscale.nix
+++ b/modules/services/nixos/tailscale.nix
@@ -18,5 +18,17 @@ in
allowedUDPPorts = [config.services.tailscale.port];
};
+ # don't start tailscale until after headscale starts
+ systemd.services."tailscaled" =
+ if config.collinux.services.selfhost.headscale.enable
+ then {
+ wants = lib.mkForce ["network.target" "headscale.target"];
+ after = lib.mkForce ["network.target" "headscale.target"];
+ }
+ else {
+ wants = lib.mkForce ["network.target"];
+ after = lib.mkForce ["network.target"];
+ };
+
environment.systemPackages = [pkgs.tailscale];
}
diff --git a/modules/services/options.nix b/modules/services/options.nix
index e87ecb3..085895e 100644
--- a/modules/services/options.nix
+++ b/modules/services/options.nix
@@ -17,27 +17,48 @@ in {
networkmanager.enable = mkEnableOption "heavier wifi daemon";
networkd = {
- enable = mkEnableOption "set static IP (systemd-networkd)";
- ssid = mkOption {type = lib.types.str;};
- pskFile = mkOption {type = lib.types.str;};
+ enable = mkEnableOption "use systemd-networkd";
+ ssid = mkOption {
+ description = "SSID for this network";
+ type = lib.types.str;
+ };
+ pskFile = mkOption {
+ description = "Absolute path to a file containing the pre-shared key for this network";
+ type = lib.types.str;
+ example = "/run/secrets.d/wifi-psk";
+ };
static = lib.mkOption {
+ description = "Set a static IP address for this device on this network. Set to null to use DHCP";
type = lib.types.nullOr (lib.types.submodule {
options = {
- ip = mkOption {type = ip_addr_cidr;};
- gateway = mkOption {type = ip_addr;};
+ ip = mkOption {
+ description = "IP address";
+ type = ip_addr_cidr;
+ };
+ gateway = mkOption {
+ description = "default gateway";
+ type = ip_addr;
+ };
};
});
default = null;
};
};
+
tailscale.enable = mkEnableOption "tailscale";
- sshd.enable = mkEnableOption "OpenSSH server";
- };
- audio = {
- enable = mkEnableOption "pipewire + wireplumber";
- pulse.enable = mkEnableOption "pipewire-pulse";
+ sshd = {
+ enable = mkEnableOption "OpenSSH server";
+ bind_host = mkOption {
+ description = "The IP address on which OpenSSH will listen for incomming connections. The default, `0.0.0.0`, means 'all interfaces'";
+ type = ip_addr;
+ default = "0.0.0.0";
+ };
+ };
};
+
+ audio.enable = mkEnableOption "pipewire and wireplumber";
+
bluetooth = {
enable = mkEnableOption "bluetooth";
blueman.enable = mkEnableOption "graphical bluetooth manager";
@@ -48,27 +69,33 @@ in {
selfhostOptions = {
service_name,
default_port ? null,
- ...
}: {
- enable = mkEnableOption "";
+ enable = mkEnableOption "${service_name} selfhosted service";
+
+ service_name = mkOption {
+ type = lib.types.str;
+ internal = true;
+ };
+
bind_host = mkOption {
+ description = "The IP address on which ${service_name} will listen for incoming connections. The default, `0.0.0.0`, means 'all interfaces'";
type = ip_addr;
- default =
- if config.collinux.services.networking.tailscale.enable
- then "100.69.160.89"
- else "0.0.0.0";
+ default = "0.0.0.0";
};
port = mkOption {
+ description = "The port on which ${service_name} will listen for incomming connections";
type = lib.types.port;
default = default_port;
};
root_url = mkOption {
- type = lib.types.str;
- default =
- if config.collinux.services.networking.tailscale.enable
- then "https://${service_name}.tail7cca06.ts.net"
- else null;
+ description = "The final url that this service will be hosted on. Required for caddy, otherwise optional";
+ type = lib.types.nullOr lib.types.str;
+ };
+
+ caddy = {
+ enable = mkEnableOption "Automatically create caddy configurations for this service";
+ bind_tailscale = mkEnableOption "Bind the service to ${service_name}.{tailnet}";
};
};
in {
@@ -76,14 +103,23 @@ in {
service_name = "adguard";
default_port = 8001;
};
+
forgejo = selfhostOptions {
service_name = "forgejo";
default_port = 8010;
};
+
+ headscale = selfhostOptions {
+ service_name = "headscale";
+ default_port = 8080;
+ };
+
caddy = {
enable = mkEnableOption "caddy https server";
envFile = mkOption {
+ description = "Absolute path to file that contains environment variables for caddy operations";
type = lib.types.str;
+ example = "/run/secrets.d/caddy-env";
};
};
};
@@ -94,7 +130,7 @@ in {
assertions = [
{
assertion = with config.collinux.services.networking; (iwd.enable && !networkmanager.enable && !networkd.enable) || (!iwd.enable && networkmanager.enable && !networkd.enable) || (!iwd.enable && !networkmanager.enable && networkd.enable);
- message = "only one networking method (iwd, networkmanager, static) can be active";
+ message = "only one networking method (iwd, networkmanager, networkd) can be active";
}
{
assertion = with config.collinux.services.networking; !(wireguard.enable && tailscale.enable);
diff --git a/modules/terminal/hjem/programs/tmux.nix b/modules/terminal/hjem/programs/tmux.nix
index 8525569..2c87212 100644
--- a/modules/terminal/hjem/programs/tmux.nix
+++ b/modules/terminal/hjem/programs/tmux.nix
@@ -16,8 +16,8 @@ in {
enable = true;
theme = {
- bg = config.collinux.palette.base01;
- bg_dark = config.collinux.palette.base00;
+ bg = "#${config.collinux.palette.base00}";
+ bg_dark = "#${config.collinux.palette.base01}";
};
keys.leader = [
diff --git a/modules/terminal/options.nix b/modules/terminal/options.nix
index 25e0eb4..8207be3 100644
--- a/modules/terminal/options.nix
+++ b/modules/terminal/options.nix
@@ -6,7 +6,7 @@
...
}: let
inherit (lib) mkOption mkEnableOption types;
- inherit (my-lib.options {inherit lib config;}) mkProgramOption;
+ inherit (my-lib.options {inherit lib config;}) mkProgramOption mkThemeOption;
in {
options = {
collinux.terminal = {
@@ -37,10 +37,11 @@ in {
git = {
enable = mkEnableOption "git";
userName = mkOption {
+ description = "Public name uses for git";
type = types.str;
- default = config.collinux.user.name;
};
userEmail = mkOption {
+ description = "Public email used for git";
type = types.str;
};
installKey = mkEnableOption "automatically install github authentication key";
@@ -48,10 +49,7 @@ in {
helix = {
enable = mkEnableOption "helix text editor";
- theme = mkOption {
- type = lib.types.enum ["catppuccin" "adwaita" "kanagawa"];
- default = config.collinux.theme;
- };
+ theme = mkThemeOption "helix";
hardMode = mkOption {
type = types.bool;
description = "Disable arrow keys and mouse";
diff --git a/modules/user/nixos/default.nix b/modules/user/nixos/default.nix
index b14e52d..0b0ae41 100644
--- a/modules/user/nixos/default.nix
+++ b/modules/user/nixos/default.nix
@@ -1,13 +1,12 @@
{
config,
- hostname,
lib,
...
}: let
cfg = config.collinux.user;
in {
users = {
- mutableUsers = true;
+ mutableUsers = true; # system passwords stored mutably
users."${cfg.name}" = {
isNormalUser = true;
diff --git a/modules/user/options.nix b/modules/user/options.nix
index 1024494..d805bf9 100644
--- a/modules/user/options.nix
+++ b/modules/user/options.nix
@@ -4,9 +4,11 @@ in {
options = {
collinux.user = {
name = mkOption {
+ description = "Name for the sole user of this system";
type = types.str;
};
isAdmin = mkOption {
+ description = "Whether this user is an admin";
type = types.bool;
default = true;
};