aboutsummaryrefslogtreecommitdiff
path: root/modules
diff options
context:
space:
mode:
authorCollin Williams <96917990+bluedragon1221@users.noreply.github.com>2026-05-22 10:23:58 -0500
committerCollin Williams <96917990+bluedragon1221@users.noreply.github.com>2026-05-22 10:24:06 -0500
commit35af4bab99da94845ebd6e9b2efae6a544d39b35 (patch)
tree47c6f76b47f1012932729c9f693316df1512197a /modules
parent2e0c6ccbbc76cc36e92128aea44e4bdd4e5c3d0a (diff)
LOTS OF TEMP STUFF
Diffstat (limited to 'modules')
-rw-r--r--modules/desktop/hjem/programs/firefox.nix8
-rw-r--r--modules/desktop/hjem/programs/foot.nix3
-rw-r--r--modules/desktop/hjem/wm/sway.nix9
-rw-r--r--modules/desktop/nixos/fonts.nix2
-rw-r--r--modules/desktop/nixos/programs/firefox.nix19
-rw-r--r--modules/desktop/options.nix12
-rw-r--r--modules/nix/nixos/default.nix4
-rw-r--r--modules/services/nixos/default.nix5
-rw-r--r--modules/services/nixos/ganyupload/AGENTS.md65
-rw-r--r--modules/services/nixos/ganyupload/main.go212
-rw-r--r--modules/services/nixos/jta/main.go30
-rw-r--r--modules/services/nixos/minecraft.nix12
-rw-r--r--modules/services/nixos/ngircd.nix8
-rw-r--r--modules/services/nixos/openssh.nix31
-rw-r--r--modules/services/nixos/polaris.nix26
-rw-r--r--modules/services/options.nix94
-rw-r--r--modules/system/nixos/networking/tailscale.nix33
-rw-r--r--modules/system/options.nix2
-rw-r--r--modules/terminal/hjem/programs/broot.nix7
-rw-r--r--modules/terminal/hjem/programs/git.nix9
-rw-r--r--modules/terminal/hjem/programs/tmux.nix46
21 files changed, 418 insertions, 219 deletions
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.<hostname>.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.<hostname>.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, `<!DOCTYPE html>
+<html>
+<head>
+ <meta charset="UTF-8">
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
+ <title>Directory: %s</title>
+ <style>
+ body { font-family: monospace; margin: 2rem; }
+ h1 { margin-bottom: 0.5rem; }
+ .breadcrumb { margin-bottom: 2rem; font-size: 0.9rem; }
+ .breadcrumb a { text-decoration: none; color: #0066cc; }
+ .breadcrumb a:hover { text-decoration: underline; }
+ table { border-collapse: collapse; width: 100%%; }
+ td { padding: 0.5rem; border-bottom: 1px solid #ccc; }
+ td:first-child { text-align: left; }
+ td:last-child { text-align: right; color: #666; }
+ a { text-decoration: none; color: #0066cc; }
+ a:hover { text-decoration: underline; }
+ .directory { color: #0066cc; font-weight: bold; }
+ </style>
+</head>
+<body>
+ <h1>Directory: %s</h1>
+`, html.EscapeString(relPath), html.EscapeString(relPath))
+
+ // Breadcrumb navigation
+ fmt.Fprint(w, ` <div class="breadcrumb">`)
+ fmt.Fprintf(w, `<a href="/">home</a>`)
+ if len(pathParts) > 0 {
+ accumulated := ""
+ for _, part := range pathParts {
+ accumulated = accumulated + "/" + part
+ fmt.Fprintf(w, ` / <a href="%s">%s</a>`, html.EscapeString(accumulated), html.EscapeString(part))
+ }
+ }
+ fmt.Fprint(w, `</div>`)
+
+ // Directory listing
+ fmt.Fprint(w, ` <table>
+`)
+ 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, ` <tr><td><a href="/%s" class="directory">%s/</a></td><td>-</td></tr>
+`, 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, ` <tr><td><a href="/%s">%s</a></td><td>%s</td></tr>
+`, html.EscapeString(linkPath), safeName, size)
+ }
+ }
+ fmt.Fprint(w, ` </table>
+</body>
+</html>
+`)
+}
+
+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
+ # '';
+ # };
+ # };
}