From 35af4bab99da94845ebd6e9b2efae6a544d39b35 Mon Sep 17 00:00:00 2001 From: Collin Williams <96917990+bluedragon1221@users.noreply.github.com> Date: Fri, 22 May 2026 10:23:58 -0500 Subject: LOTS OF TEMP STUFF --- modules/desktop/hjem/programs/firefox.nix | 8 +- modules/desktop/hjem/programs/foot.nix | 3 +- modules/desktop/hjem/wm/sway.nix | 9 +- modules/desktop/nixos/fonts.nix | 2 +- modules/desktop/nixos/programs/firefox.nix | 19 +-- modules/desktop/options.nix | 12 +- modules/nix/nixos/default.nix | 4 +- modules/services/nixos/default.nix | 5 +- modules/services/nixos/ganyupload/AGENTS.md | 65 ++++++++ modules/services/nixos/ganyupload/main.go | 212 +++++++++++++++++++++++++- modules/services/nixos/jta/main.go | 30 +++- modules/services/nixos/minecraft.nix | 12 +- modules/services/nixos/ngircd.nix | 8 +- modules/services/nixos/openssh.nix | 31 ++-- modules/services/nixos/polaris.nix | 26 ---- modules/services/options.nix | 94 +++++------- modules/system/nixos/networking/tailscale.nix | 33 ---- modules/system/options.nix | 2 - modules/terminal/hjem/programs/broot.nix | 7 +- modules/terminal/hjem/programs/git.nix | 9 +- modules/terminal/hjem/programs/tmux.nix | 46 +++--- 21 files changed, 418 insertions(+), 219 deletions(-) create mode 100644 modules/services/nixos/ganyupload/AGENTS.md delete mode 100644 modules/services/nixos/polaris.nix delete mode 100644 modules/system/nixos/networking/tailscale.nix (limited to 'modules') diff --git a/modules/desktop/hjem/programs/firefox.nix b/modules/desktop/hjem/programs/firefox.nix index cf9c532..6198afb 100644 --- a/modules/desktop/hjem/programs/firefox.nix +++ b/modules/desktop/hjem/programs/firefox.nix @@ -1,5 +1,4 @@ { - pkgs, lib, config, inputs, @@ -44,18 +43,13 @@ in "${profileDir}/chrome/userChrome.css".text = mkCssHacks [ # Tabs - ( - if cfg.theme == "catppuccin" - then "hide_tabs_with_one_tab" - else "hide_tabs_with_one_tab_w_window_controls" - ) + "hide_tabs_with_one_tab" "tabs_on_bottom_v2" "tab_close_button_always_on_hover" "tabs_fill_available_width" # Icons! "iconized_main_menu" - # "iconized_menubar_items" "iconized_places_context_menu" "iconized_tabs_context_menu" "icon_only_context_menu_text_controls" diff --git a/modules/desktop/hjem/programs/foot.nix b/modules/desktop/hjem/programs/foot.nix index d10db24..a28a269 100644 --- a/modules/desktop/hjem/programs/foot.nix +++ b/modules/desktop/hjem/programs/foot.nix @@ -9,8 +9,7 @@ settings = { main = { font = "Iosevka Nerd Font:size=12"; - # shell = "${pkgs.fish}/bin/fish"; - shell = "${pkgs.fish}/bin/fish -c 'br'"; + shell = "fish -c '${pkgs.broot}/bin/broot'"; }; # key-bindings.spawn-terminal = "Control+Return"; diff --git a/modules/desktop/hjem/wm/sway.nix b/modules/desktop/hjem/wm/sway.nix index 441670b..33ea869 100644 --- a/modules/desktop/hjem/wm/sway.nix +++ b/modules/desktop/hjem/wm/sway.nix @@ -35,12 +35,15 @@ pkgs.sway ]; text = '' - selection=$(printf '%s\n' logout suspend reboot shutdown | fuzzel --dmenu --prompt "power: ") + selection=$(printf '%s\n' logout hibernate suspend reboot shutdown | fuzzel --dmenu --prompt "power: ") case "$selection" in logout) swaymsg exit ;; + hibernate) + systemctl hibernate + ;; suspend) systemctl suspend ;; @@ -61,6 +64,8 @@ ${pkgs.dbus}/bin/dbus-update-activation-environment --systemd WAYLAND_DISPLAY DISPLAY SWAYSOCK XDG_CURRENT_DESKTOP GTK_USE_PORTAL NIXOS_OZONE_WL MOZ_ENABLE_WAYLAND } + seat seat0 xcursor_theme ${config.collinux.desktop.gtk.cursor_data.name} + # target title bg text indicator border client.focused #${base07} #${base00} #${base05} #${base06} #${base13} client.focused_inactive #${base03} #${base00} #${base05} #${base06} #${base03} @@ -107,8 +112,8 @@ Mod4+Return exec foot Mod4+Space exec fuzzel - Mod4+Escape exec '${powerMenu}/bin/power-menu' Mod4+b exec firefox + Mod4+Escape exec '${powerMenu}/bin/power-menu' Mod4+k exec '${batteryNotify}/bin/battery-notify' Mod4+w exec '${pkgs.iwmenu}/bin/iwmenu -l fuzzel -i font -s 2' Mod4+e exec '${pkgs.bzmenu}/bin/bzmenu -l fuzzel -i font -s 2' diff --git a/modules/desktop/nixos/fonts.nix b/modules/desktop/nixos/fonts.nix index 5ac17ec..d2e8ba9 100644 --- a/modules/desktop/nixos/fonts.nix +++ b/modules/desktop/nixos/fonts.nix @@ -2,6 +2,6 @@ fonts = { enableDefaultPackages = false; fontconfig.enable = true; - packages = [pkgs.nerd-fonts.iosevka pkgs.ibm-plex]; # for terminal (blackbox or foot or ghostty) + packages = [pkgs.nerd-fonts.iosevka pkgs.ibm-plex pkgs.liberation_ttf]; # for terminal (blackbox or foot or ghostty) }; } diff --git a/modules/desktop/nixos/programs/firefox.nix b/modules/desktop/nixos/programs/firefox.nix index 61e7b7d..9e2b8ca 100644 --- a/modules/desktop/nixos/programs/firefox.nix +++ b/modules/desktop/nixos/programs/firefox.nix @@ -25,6 +25,8 @@ in NewTabPage = false; + SearchEngines.Default = "DuckDuckGo"; + Preferences = let opt = Value: { inherit Value; @@ -32,12 +34,9 @@ in }; in { "toolkit.legacyUserProfileCustomizations.stylesheets" = opt true; - "browser.tabs.inTitlebar" = opt ( - if cfg.theme == "catppuccin" - then 0 - else 1 - ); + "browser.tabs.inTitlebar" = opt 0; "browser.tabs.hoverPreview.enabled" = opt 0; + "browser.profiles.enabled" = opt false; "browser.theme.content-theme" = opt 0; "browser.theme.toolbar-theme" = opt 0; @@ -99,7 +98,6 @@ in "datareporting.policy.dataSubmissionPolicyBypassNotification" = opt true; "browser.startup.homepage" = opt "about:blank"; - "cookiebanners.ui.desktop.enabled" = opt false; "browser.compactmode.show" = opt true; "browser.uidensity" = opt 1; @@ -107,9 +105,6 @@ in # get that AI out of my browser "browser.ml.chat.enabled" = opt false; "browser.ml.enable" = opt false; - - # use system pki certificates - "security.enterprise_roots.enabled" = opt true; }; ExtensionSettings = let @@ -130,10 +125,10 @@ in // (lib.optionalAttrs (cfg.theme == "adwaita") { "{f1128560-8b23-46c1-aa6f-fb3e79f23cf3}" = ext "gnome-adwaita-gtk4-dark"; }) - // (lib.optionalAttrs (cfg.extensions.zotero.enable) { - "zotero@chnm.gmu.edu" = { + // (lib.optionalAttrs (cfg.extensions.foxyproxy.enable) { + "foxyproxy@eric.h.jung" = { installation_mode = "force_installed"; - install_url = "https://download.zotero.org/connector/firefox/release/Zotero_Connector-5.0.181.xpi"; + install_url = "https://addons.mozilla.org/firefox/downloads/latest/foxyproxy-standard/latest.xpi"; }; }); }; diff --git a/modules/desktop/options.nix b/modules/desktop/options.nix index 3e20643..9a601fe 100644 --- a/modules/desktop/options.nix +++ b/modules/desktop/options.nix @@ -133,16 +133,8 @@ in { programs = { firefox = { enable = mkEnableOption "firefox"; - profileName = mkOption { - type = types.str; - default = config.collinux.user.name; - internal = true; - }; theme = mkThemeOption "firefox"; - extensions.zotero.enable = mkOption { - description = "install Zotero Connector for Firefox"; - default = config.collinux.desktop.programs.research.enable; - }; + extensions.foxyproxy.enable = mkEnableOption "install FoxyProxy extension"; }; foot = mkProgramOption "foot"; @@ -150,7 +142,7 @@ in { ghostty.enable = mkEnableOption "ghostty"; alacritty.enable = mkEnableOption "alacritty"; - research.enable = mkEnableOption "zathura, Xournal++, Zotero"; + research.enable = mkEnableOption "zathura, Xournal++"; }; }; }; diff --git a/modules/nix/nixos/default.nix b/modules/nix/nixos/default.nix index f39f368..3d76e36 100644 --- a/modules/nix/nixos/default.nix +++ b/modules/nix/nixos/default.nix @@ -10,8 +10,6 @@ ]; 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 @@ -43,5 +41,5 @@ environment.systemPackages = [pkgs.cached-nix-shell]; nixpkgs.hostPlatform = "x86_64-linux"; - system.stateVersion = "25.05"; + system.stateVersion = "25.11"; } diff --git a/modules/services/nixos/default.nix b/modules/services/nixos/default.nix index c3652b5..13cdcf4 100644 --- a/modules/services/nixos/default.nix +++ b/modules/services/nixos/default.nix @@ -6,11 +6,10 @@ ./forgejo.nix ./goaccess.nix ./btopweb.nix - ./cgit - ./jta ./ganyupload - ./polaris.nix + + ./jta ./agate.nix ./minecraft.nix ./ngircd.nix diff --git a/modules/services/nixos/ganyupload/AGENTS.md b/modules/services/nixos/ganyupload/AGENTS.md new file mode 100644 index 0000000..c4d9192 --- /dev/null +++ b/modules/services/nixos/ganyupload/AGENTS.md @@ -0,0 +1,65 @@ +# Ganyupload - Agent Instructions + +## Quick Context +- Simple Go file upload service using standard `net/http`. +- Single `main.go`, two Nix files (`default.nix`, `pkg.nix`), one README. +- Embedded README is served on GET /. +- Used as a NixOS module: `collinux.services.ganyupload` enables it, configures port and upload directory via systemd environment. + +## How to Build and Test + +### Build +```bash +nix build +``` + +Alternatively, from the repo root: +```bash +nix build .#nixosConfigurations..config.system.build.toplevel +``` + +### Test +No dedicated test file. Verify locally by running with environment variables: +```bash +PORT=8080 UPLOAD_DIR=/tmp/upload go run main.go +``` + +Then test uploads: +```bash +curl -X PUT --data-binary @file.txt http://localhost:8080/file.txt +curl http://localhost:8080/ # Read embedded README +``` + +## Code Style + +**Go:** +- Keep `main.go` clean; use `gofmt -w .`. +- Match existing error handling (early return, `log.Printf` for warnings, `log.Fatalf` for fatal errors). +- Path traversal prevention is critical; do not weaken `filepath.Clean` + `..` prefix checks. + +**Nix:** +- Follow `/home/collin/nixos/AGENTS.md` conventions (2-space indent, common arg pattern, `lib.mkIf` for gating). +- `default.nix` imports `mkCaddyCfg.nix` to integrate with Caddy reverse proxy; do not remove that import. + +## Key Implementation Notes + +1. **Embedded README:** The README file is embedded at compile time using `//go:embed README`. If you update README, rebuild to reflect changes. +2. **Environment Variables:** + - `UPLOAD_DIR`: Defaults to `.`, overridden by systemd service to `/media/ganyupload`. + - `PORT`: Defaults to `8080`, set by systemd to the configured `cfg.port`. +3. **NixOS Integration:** The service runs as user/group `ganyupload` with home `/var/lib/ganyupload`. Ensure the service has write permission to `UPLOAD_DIR`. +4. **Caddy Integration:** `default.nix` imports `mkCaddyCfg.nix` to configure Caddy as a reverse proxy. Changes to hostname or port must be reflected in both Nix config and the Caddy rule. + +## Common Tasks + +- **Update Go code:** Edit `main.go`, test locally, then nix build to verify. +- **Change upload directory or port:** Update `default.nix` (systemd environment or `cfg.port`). +- **Update README:** Edit README file, then rebuild (`nix build`) so the embedded version updates. +- **Debug NixOS module:** Check `/etc/systemd/system/ganyupload.service` for actual service config after rebuild. + +## Validation + +After changes: +1. Run `nix build` from this directory or `nix build .#nixosConfigurations..config.system.build.toplevel` from repo root. +2. If applicable, test via `PORT=8080 UPLOAD_DIR=/tmp go run main.go`. +3. Verify no Nix lint issues (use repo-level `yo test` or `nix run nixpkgs#alejandra -- .` for formatting). diff --git a/modules/services/nixos/ganyupload/main.go b/modules/services/nixos/ganyupload/main.go index 6aa219e..75852c2 100644 --- a/modules/services/nixos/ganyupload/main.go +++ b/modules/services/nixos/ganyupload/main.go @@ -2,11 +2,14 @@ package main import ( _ "embed" + "fmt" + "html" "io" "log" "net/http" "os" "path/filepath" + "sort" "strings" ) @@ -15,6 +18,42 @@ var readme string var uploadDir = "." +// cleanPath safely cleans and validates a path to prevent traversal attacks +func cleanPath(filename string) (string, error) { + // Remove leading slash + filename = strings.TrimPrefix(filename, "/") + if filename == "" { + return "", nil + } + + // Clean the path + filename = filepath.Clean(filename) + + // Reject if it tries to go up + if strings.HasPrefix(filename, "..") || strings.Contains(filename, "/../") { + return "", fmt.Errorf("invalid filename: path traversal not allowed") + } + + return filename, nil +} + +// isPathSafe checks that the resolved fullPath stays within uploadDir +func isPathSafe(uploadDir, fullPath string) bool { + // Resolve both paths to absolute to catch symlink attacks + absUploadDir, err := filepath.Abs(uploadDir) + if err != nil { + return false + } + absFullPath, err := filepath.Abs(fullPath) + if err != nil { + return false + } + + // Ensure the resolved path starts with uploadDir + return strings.HasPrefix(absFullPath, absUploadDir+string(filepath.Separator)) || + absFullPath == absUploadDir +} + func handleRoot(w http.ResponseWriter, r *http.Request) { if r.Method != http.MethodGet { http.Error(w, "method not allowed", http.StatusMethodNotAllowed) @@ -32,27 +71,37 @@ func handleUpload(w http.ResponseWriter, r *http.Request) { return } + // Handle GET requests for downloads and directory listing + if r.Method == http.MethodGet { + handleDownload(w, r) + return + } + if r.Method != http.MethodPut { http.Error(w, "method not allowed", http.StatusMethodNotAllowed) return } // Extract filename from URL path, preventing path traversal - filename := strings.TrimPrefix(r.URL.Path, "/") - if filename == "" { - http.Error(w, "filename required", http.StatusBadRequest) + filename, err := cleanPath(r.URL.Path) + if err != nil { + http.Error(w, err.Error(), http.StatusBadRequest) return } - // Prevent path traversal - filename = filepath.Clean(filename) - if strings.HasPrefix(filename, "..") { - http.Error(w, "invalid filename", http.StatusBadRequest) + if filename == "" { + http.Error(w, "filename required", http.StatusBadRequest) return } fullPath := filepath.Join(uploadDir, filename) + // Verify the path is safe + if !isPathSafe(uploadDir, fullPath) { + http.Error(w, "invalid path", http.StatusBadRequest) + return + } + // Ensure the directory exists dir := filepath.Dir(fullPath) if err := os.MkdirAll(dir, 0755); err != nil { @@ -85,6 +134,155 @@ func handleUpload(w http.ResponseWriter, r *http.Request) { log.Printf("uploaded %s (%d bytes)", filename, written) } +func handleDownload(w http.ResponseWriter, r *http.Request) { + // Extract filename from URL path + filename, err := cleanPath(r.URL.Path) + if err != nil { + http.Error(w, err.Error(), http.StatusBadRequest) + return + } + + fullPath := filepath.Join(uploadDir, filename) + + // Verify the path is safe + if !isPathSafe(uploadDir, fullPath) { + http.Error(w, "invalid path", http.StatusBadRequest) + return + } + + fileInfo, err := os.Stat(fullPath) + if err != nil { + if os.IsNotExist(err) { + http.Error(w, "not found", http.StatusNotFound) + } else { + log.Printf("failed to stat: %v", err) + http.Error(w, "internal server error", http.StatusInternalServerError) + } + return + } + + // If it's a directory, list its contents + if fileInfo.IsDir() { + handleDirList(w, r, uploadDir, filename, fullPath) + return + } + + // Serve the file + http.ServeFile(w, r, fullPath) +} + +func handleDirList(w http.ResponseWriter, r *http.Request, uploadDir, relPath, fullPath string) { + entries, err := os.ReadDir(fullPath) + if err != nil { + log.Printf("failed to read directory: %v", err) + http.Error(w, "internal server error", http.StatusInternalServerError) + return + } + + // Sort entries by name + sort.Slice(entries, func(i, j int) bool { + return entries[i].Name() < entries[j].Name() + }) + + // Build breadcrumb navigation + pathParts := strings.Split(strings.Trim(relPath, "/"), "/") + if relPath == "" { + pathParts = []string{} + } + + w.Header().Set("Content-Type", "text/html; charset=utf-8") + w.WriteHeader(http.StatusOK) + + fmt.Fprintf(w, ` + + + + + Directory: %s + + + +

Directory: %s

+`, html.EscapeString(relPath), html.EscapeString(relPath)) + + // Breadcrumb navigation + fmt.Fprint(w, ` `) + + // Directory listing + fmt.Fprint(w, ` +`) + for _, entry := range entries { + name := entry.Name() + safeName := html.EscapeString(name) + + if entry.IsDir() { + // For directories, add trailing slash to the link + linkPath := relPath + "/" + name + if relPath == "" { + linkPath = "/" + name + } + linkPath = strings.TrimPrefix(linkPath, "/") + fmt.Fprintf(w, ` +`, html.EscapeString(linkPath), safeName) + } else { + info, _ := entry.Info() + linkPath := relPath + "/" + name + if relPath == "" { + linkPath = "/" + name + } + linkPath = strings.TrimPrefix(linkPath, "/") + size := formatSize(info.Size()) + fmt.Fprintf(w, ` +`, html.EscapeString(linkPath), safeName, size) + } + } + fmt.Fprint(w, `
%s/-
%s%s
+ + +`) +} + +func formatSize(bytes int64) string { + const ( + KB = 1024 + MB = KB * 1024 + GB = MB * 1024 + ) + + switch { + case bytes < KB: + return fmt.Sprintf("%d B", bytes) + case bytes < MB: + return fmt.Sprintf("%.1f KB", float64(bytes)/KB) + case bytes < GB: + return fmt.Sprintf("%.1f MB", float64(bytes)/MB) + default: + return fmt.Sprintf("%.1f GB", float64(bytes)/GB) + } +} + func main() { if envUploadDir := os.Getenv("UPLOAD_DIR"); envUploadDir != "" { uploadDir = envUploadDir diff --git a/modules/services/nixos/jta/main.go b/modules/services/nixos/jta/main.go index 1390d7f..e7b5a0f 100644 --- a/modules/services/nixos/jta/main.go +++ b/modules/services/nixos/jta/main.go @@ -36,19 +36,35 @@ var pageTmpl = template.Must(template.New("md_template.html").Parse(mdTemplate)) const authCookieName = "jta_auth" -func isAuthenticated(r *http.Request) bool { +func isAuthenticated(w http.ResponseWriter, r *http.Request) bool { expectedHash := strings.TrimSpace(os.Getenv("AUTH_PASSWORD_HASH")) if expectedHash == "" { return false } - cookie, err := r.Cookie(authCookieName) - if err != nil { - return false + // Try cookie first + if cookie, err := r.Cookie(authCookieName); err == nil { + providedHash := strings.TrimSpace(cookie.Value) + if providedHash != "" && strings.EqualFold(providedHash, expectedHash) { + return true + } + } + + // Fallback to URL parameter + paramHash := strings.TrimSpace(r.URL.Query().Get(authCookieName)) + if paramHash != "" && strings.EqualFold(paramHash, expectedHash) { + http.SetCookie(w, &http.Cookie{ + Name: authCookieName, + Value: paramHash, + Path: "/", + HttpOnly: true, // Security: Protects against XSS cookie theft + Secure: false, // Set to true if you are hosting over HTTPS + SameSite: http.SameSiteLaxMode, // Prevents CSRF vulnerabilities + }) + return true } - providedHash := strings.TrimSpace(cookie.Value) - return strings.EqualFold(providedHash, expectedHash) + return false } func serveMarkdown(w http.ResponseWriter, r *http.Request) { @@ -101,7 +117,7 @@ func main() { return } - if !isAuthenticated(r) { + if !isAuthenticated(w, r) { http.Error(w, "unauthorized", http.StatusUnauthorized) return } diff --git a/modules/services/nixos/minecraft.nix b/modules/services/nixos/minecraft.nix index 1b8b047..7e12a61 100644 --- a/modules/services/nixos/minecraft.nix +++ b/modules/services/nixos/minecraft.nix @@ -6,7 +6,7 @@ cfg = config.collinux.services.minecraft; in lib.mkIf cfg.enable { - networking.firewall.allowedUDPPorts = lib.optional (cfg.listenAddr == "0.0.0.0") cfg.port; + networking.firewall.allowedUDPPorts = lib.optional cfg.public cfg.port; virtualisation.oci-containers.containers."Minecraft" = { environment = { @@ -15,14 +15,20 @@ in SERVER_NAME = "YServer"; TZ = config.time.timeZone; - VERSION = "1.26.3.1"; + VERSION = "1.26.20.5"; CONTENT_LOG_FILE_ENABLED = "false"; ALLOW_CHEATS = "false"; DIFFICULTY = "1"; }; image = "itzg/minecraft-bedrock-server"; - ports = ["${cfg.listenAddr}:${toString cfg.port}:19132/udp"]; + ports = [ + "${ + if cfg.public + then "0.0.0.0" + else "127.0.0.1" + }:${toString cfg.port}:19132/udp" + ]; volumes = ["/var/lib/minecraft/:/data"]; extraOptions = ["--no-healthcheck"]; diff --git a/modules/services/nixos/ngircd.nix b/modules/services/nixos/ngircd.nix index d06a497..ac93f06 100644 --- a/modules/services/nixos/ngircd.nix +++ b/modules/services/nixos/ngircd.nix @@ -6,7 +6,7 @@ cfg = config.collinux.services.ngircd; in lib.mkIf cfg.enable { - networking.firewall.allowedTCPPorts = [cfg.port]; + networking.firewall.allowedTCPPorts = lib.optional cfg.public cfg.port; services.ngircd = { enable = true; @@ -16,7 +16,11 @@ in Info = Ganymede IRC Chat AdminInfo1 = Collin - Listen = 0.0.0.0 + Listen = ${ + if cfg.public + then "0.0.0.0" + else "127.0.0.1" + } Ports = ${toString cfg.port} [Channel] diff --git a/modules/services/nixos/openssh.nix b/modules/services/nixos/openssh.nix index 1ce1abc..98f8b87 100644 --- a/modules/services/nixos/openssh.nix +++ b/modules/services/nixos/openssh.nix @@ -6,15 +6,9 @@ ... }: let cfg = config.collinux.services.sshd; - - authorizedKeys = - hosts - |> builtins.mapAttrs (_: data: data.user_pubkey or null) - |> builtins.attrValues - |> builtins.filter (x: x != null); in { config = lib.mkIf cfg.enable { - networking.firewall.allowedTCPPorts = [cfg.port]; + networking.firewall.allowedTCPPorts = lib.optional cfg.public cfg.port; services.openssh = { enable = true; @@ -29,7 +23,10 @@ in { listenAddresses = [ { - addr = cfg.listenAddr; + addr = + if cfg.public + then "0.0.0.0" + else "127.0.0.1"; port = cfg.port; } ]; @@ -46,7 +43,7 @@ in { extraConfig = lib.concatStringsSep "\n" [ "Match LocalPort ${toString cfg.port}" ( - if cfg.otp + if cfg.conf.otp then '' ChallengeResponseAuthentication yes PubkeyAuthentication yes @@ -58,11 +55,11 @@ in { AuthenticationMethods publickey '' ) - (lib.optionalString cfg.rootLogin "PermitRootLogin yes") + (lib.optionalString cfg.conf.rootLogin "PermitRootLogin yes") ]; }; - security.pam.services = lib.optionalAttrs cfg.otp { + security.pam.services = lib.optionalAttrs cfg.conf.otp { login.googleAuthenticator.enable = true; sshd.text = '' @@ -78,8 +75,16 @@ in { ''; }; - users.users.${config.collinux.user.name}.openssh.authorizedKeys.keys = authorizedKeys; - users.users."root".openssh.authorizedKeys.keys = lib.mkIf cfg.rootLogin authorizedKeys; + users.users = let + k.openssh.authorizedKeys.keys = + hosts + |> builtins.mapAttrs (_: data: data.user_pubkey or null) + |> builtins.attrValues + |> builtins.filter (x: x != null); + in { + ${config.collinux.user.name} = k; + "root" = lib.mkIf cfg.conf.rootLogin k; + }; systemd.services."openssh" = { after = lib.mkAfter ["network-online.target"]; diff --git a/modules/services/nixos/polaris.nix b/modules/services/nixos/polaris.nix deleted file mode 100644 index 89f5ef3..0000000 --- a/modules/services/nixos/polaris.nix +++ /dev/null @@ -1,26 +0,0 @@ -{ - lib, - config, - ... -}: let - cfg = config.collinux.services.polaris; -in { - imports = [ - (import ./mkCaddyCfg.nix cfg) - ]; - - config = lib.mkIf cfg.enable { - services.polaris = { - enable = true; - port = cfg.port; - settings = { - mount_dirs = [ - { - name = "Ganymede Library"; - source = "/media/library/music"; - } - ]; - }; - }; - }; -} diff --git a/modules/services/options.nix b/modules/services/options.nix index 8918781..1888f5b 100644 --- a/modules/services/options.nix +++ b/modules/services/options.nix @@ -55,70 +55,73 @@ in { options.collinux.services = { sshd = { enable = mkEnableOption "OpenSSH server"; - port = mkOption { description = "Port to run on"; type = lib.types.port; + default = 22; }; + public = mkEnableOption "whether to make this service accessable over the internet"; - listenAddr = mkOption { - description = "Address to listen on"; - type = lib.types.str; - default = "127.0.0.1"; + conf = { + otp = mkEnableOption "Whether to require TOTP (Google Authenticator) 2fa codes to login"; + rootLogin = mkEnableOption "Whether to allow root login"; + }; + }; + minecraft = { + enable = mkEnableOption "Minecraft bedrock server"; + port = mkOption { + description = "port to run on"; + type = lib.types.port; + default = 19132; + }; + + public = mkEnableOption "whether to make this service accessable over the internet"; + }; + ngircd = { + enable = mkEnableOption "ncircd IRC server"; + port = mkOption { + type = lib.types.port; + default = 6667; }; - otp = mkEnableOption "Whether to require TOTP (Google Authenticator) 2fa codes"; - rootLogin = mkEnableOption "Whether to allow root login"; + public = mkEnableOption "whether to make this service accessable over the internet"; + }; + agate = { + enable = mkEnableOption "Agate Gemini Protocol Server"; + publicUrl = mkOption { + description = "domain to run this gemini server on"; + type = lib.types.str; + }; }; + jta = webserviceOptions { + service_name = "jta"; + default_port = 8072; + }; + ganyupload = webserviceOptions { + service_name = "ganyupload"; + default_port = 8073; + }; forgejo = webserviceOptions { service_name = "forgejo"; default_port = 8010; }; - btopweb = webserviceOptions { service_name = "btopweb"; default_port = 8017; }; - goaccess = webserviceOptions { service_name = "goaccess"; reverse_proxy = false; }; - cgit = webserviceOptions { service_name = "cgit"; reverse_proxy = false; }; - - agate = { - enable = mkEnableOption "Agate Gemini Protocol Server"; - publicUrl = mkOption { - description = "domain to run this gemini server on"; - type = lib.types.str; - }; - }; - - polaris = webserviceOptions { - service_name = "polaris"; - default_port = 8079; - }; - qbittorrent = webserviceOptions { service_name = "qbittorrent"; default_port = 8076; }; - - jta = webserviceOptions { - service_name = "jta"; - default_port = 8072; - }; - - ganyupload = webserviceOptions { - service_name = "ganyupload"; - default_port = 8073; - }; - copyparty = (webserviceOptions { service_name = "copyparty"; @@ -146,27 +149,6 @@ in { }; }; - ngircd = { - enable = mkEnableOption "ncircd IRC server"; - port = mkOption { - type = lib.types.port; - default = 6667; - }; - }; - - minecraft = { - enable = mkEnableOption "Minecraft bedrock server"; - listenAddr = mkOption { - description = "Address to listen on"; - type = ipAddr; - default = "127.0.0.1"; - }; - port = mkOption { - type = lib.types.port; - default = 19132; - }; - }; - caddy = { enable = mkEnableOption "caddy https server"; envFile = mkOption { diff --git a/modules/system/nixos/networking/tailscale.nix b/modules/system/nixos/networking/tailscale.nix deleted file mode 100644 index 552ec8b..0000000 --- a/modules/system/nixos/networking/tailscale.nix +++ /dev/null @@ -1,33 +0,0 @@ -{ - config, - pkgs, - lib, - ... -}: let - cfg = config.collinux.system.network.tailscale; -in - lib.mkIf cfg.enable { - services.tailscale = { - enable = true; - useRoutingFeatures = "both"; - }; - - networking.firewall = { - trustedInterfaces = ["tailscale0"]; - allowedUDPPorts = [config.services.tailscale.port]; - }; - - systemd.services."tailscaled" = - if config.collinux.services.selfhost.headscale.enable - then { - # don't start tailscale until after headscale starts - 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/system/options.nix b/modules/system/options.nix index 8126b6a..a6db575 100644 --- a/modules/system/options.nix +++ b/modules/system/options.nix @@ -64,8 +64,6 @@ in { }; dynamic = lib.mkEnableOption "Enable dynamically joining wireless networks with iwd"; }; - - tailscale.enable = mkEnableOption "tailscale"; }; audio.enable = mkEnableOption "pipewire and wireplumber"; diff --git a/modules/terminal/hjem/programs/broot.nix b/modules/terminal/hjem/programs/broot.nix index 59f16aa..cd425bd 100644 --- a/modules/terminal/hjem/programs/broot.nix +++ b/modules/terminal/hjem/programs/broot.nix @@ -7,9 +7,10 @@ cfg = config.collinux.terminal.programs.broot; conf = { - imports = [ - "skins/catppuccin-mocha.hjson" - ]; + imports = + if config.collinux.theme == "catppuccin" + then ["skins/catppuccin-mocha.hjson"] + else ["skins/dark-gruvbox.hjson"]; default_flags = "-g"; icon_theme = "nerdfont"; diff --git a/modules/terminal/hjem/programs/git.nix b/modules/terminal/hjem/programs/git.nix index 918381c..85db4ab 100644 --- a/modules/terminal/hjem/programs/git.nix +++ b/modules/terminal/hjem/programs/git.nix @@ -8,15 +8,16 @@ git_config = lib.mkMerge [ { + user = { + email = cfg.userEmail; + name = cfg.userName; + }; alias = { stage = "add"; unstage = "restore --staged"; }; init.defaultBranch = "main"; - user = { - email = cfg.userEmail; - name = cfg.userName; - }; + push.autoSetupRemote = true; } (lib.mkIf cfg.installKey { # commit signing diff --git a/modules/terminal/hjem/programs/tmux.nix b/modules/terminal/hjem/programs/tmux.nix index 2c87212..2d7155e 100644 --- a/modules/terminal/hjem/programs/tmux.nix +++ b/modules/terminal/hjem/programs/tmux.nix @@ -7,30 +7,30 @@ }: let cfg = config.collinux.terminal.programs.tmux; in { - imports = [ - inputs.tmux-tsunami.hjemModules.tsunami - ]; + # imports = [ + # inputs.tmux-tsunami.hjemModules.tsunami + # ]; - config = lib.mkIf cfg.enable { - tsunami = { - enable = true; + # config = lib.mkIf cfg.enable { + # tsunami = { + # enable = true; - theme = { - bg = "#${config.collinux.palette.base00}"; - bg_dark = "#${config.collinux.palette.base01}"; - }; + # theme = { + # bg = "#${config.collinux.palette.base00}"; + # bg_dark = "#${config.collinux.palette.base01}"; + # }; - keys.leader = [ - { - name = "Lazygit"; - key = "C-g"; - exec = "display-popup -E -w 80% -h 80% -x C -y C -d '#{?@default-path,#{@default-path},#{pane_current_path}}' ${lib.getExe pkgs.lazygit}"; - } - ]; - confs."main" = '' - set -g mouse on - set-window-option -g mode-keys vi - ''; - }; - }; + # keys.leader = [ + # { + # name = "Lazygit"; + # key = "C-g"; + # exec = "display-popup -E -w 80% -h 80% -x C -y C -d '#{?@default-path,#{@default-path},#{pane_current_path}}' ${lib.getExe pkgs.lazygit}"; + # } + # ]; + # confs."main" = '' + # set -g mouse on + # set-window-option -g mode-keys vi + # ''; + # }; + # }; } -- cgit v1.3.1