From 95f86e629a073e3a8c473e2acd5f8b648413c68b Mon Sep 17 00:00:00 2001 From: Tim Keller Date: Tue, 19 Aug 2025 21:26:36 -0500 Subject: move web services to services and expose web socket for searxng --- modules/root/cgit.nix | 126 -------------------------------------- modules/root/default.nix | 4 -- modules/root/gitea.nix | 60 ------------------ modules/root/searxng.nix | 109 --------------------------------- modules/root/services/cgit.nix | 126 ++++++++++++++++++++++++++++++++++++++ modules/root/services/gitea.nix | 60 ++++++++++++++++++ modules/root/services/searxng.nix | 119 +++++++++++++++++++++++++++++++++++ 7 files changed, 305 insertions(+), 299 deletions(-) delete mode 100644 modules/root/cgit.nix delete mode 100644 modules/root/gitea.nix delete mode 100644 modules/root/searxng.nix create mode 100644 modules/root/services/cgit.nix create mode 100644 modules/root/services/gitea.nix create mode 100644 modules/root/services/searxng.nix (limited to 'modules/root') diff --git a/modules/root/cgit.nix b/modules/root/cgit.nix deleted file mode 100644 index 366c1f8..0000000 --- a/modules/root/cgit.nix +++ /dev/null @@ -1,126 +0,0 @@ -{ lib, pkgs, config, userDetails, ... }: -let - cfg = config.cgit; -in { - options = { - cgit = { - enable = lib.mkEnableOption "enables cgit service"; - hostAddress = lib.mkOption { - type = lib.types.str; - description = "hostAddress for the container"; - default = "10.0.1.1"; - }; - localAddress = lib.mkOption { - type = lib.types.str; - description = "localAddress for the container"; - default = "10.0.1.2"; - }; - rootTitle = lib.mkOption { - type = lib.types.str; - description = "cgit site title"; - default = ""; - }; - rootDesc = lib.mkOption { - type = lib.types.str; - description = "cgit site description"; - default = ""; - }; - extraConfig = lib.mkOption { - type = lib.types.str; - description = "cgitrc lines inserted verbatim at the end"; - default = ""; - }; - }; - }; - - config = lib.mkIf cfg.enable { - # Configure cgit container - containers.cgit = { - autoStart = true; - privateNetwork = true; - hostAddress = cfg.hostAddress; - localAddress = cfg.localAddress; - - specialArgs = { - authorizedKeys = userDetails.sshPublicKeys; - cgitrc = with cfg; { - inherit rootTitle; - inherit rootDesc; - inherit extraConfig; - }; - }; - - config = { lib, config, authorizedKeys, cgitrc, ... }: { - # Create git user for ssh access - users.users.git = { - isNormalUser = true; - home = "/srv/git"; # Serve from git user's home to allow cloning git@cgit:repo - group = "git"; - createHome = true; - homeMode = "750"; # Allow read permissions for group members - shell = pkgs.bash; - openssh.authorizedKeys.keys = authorizedKeys; - }; - users.groups.git.members = [ "lighttpd" ]; # Create the git group and add lighttpd user as a member so /srv/git can be served by cgit - - # Enable git - programs.git.enable = true; - - # Enable ssh service - services.openssh.enable = true; - - # Enable cgit service - services.lighttpd.enable = true; - services.lighttpd.cgit = { - enable = true; - #subdir = ""; # FIXME this does not work for some reason - configText = '' - # Based on joseluisq/alpine-cgit - root-title=${cgitrc.rootTitle} - root-desc=${cgitrc.rootDesc} - - source-filter=${pkgs.cgit}/lib/cgit/filters/syntax-highlighting.py - about-filter=${pkgs.cgit}/lib/cgit/filters/about-formatting.sh - - readme=:README.md - readme=:README.html - readme=:README.txt - readme=:README - readme=:INSTALL.md - readme=:INSTALL.html - readme=:INSTALL.txt - readme=:INSTALL - - # Cache - #cache-root=/var/cache/cgit - #cache-size=2000 - - enable-index-links=1 - enable-index-owner=0 - enable-remote-branches=1 - enable-log-filecount=1 - enable-log-linecount=1 - enable-git-config=1 - snapshots=tar.xz zip - - robots=noindex, nofollow - - virtual-root=/cgit - section-from-path=0 - max-repo-count=100 - scan-path=/srv/git - - # extra config - ${cgitrc.extraConfig} - ''; - }; - - # Networking, etc. - networking.firewall.allowedTCPPorts = [ 80 22 ]; - networking.hostName = "cgit"; - - system.stateVersion = "25.05"; - }; - }; - }; -} diff --git a/modules/root/default.nix b/modules/root/default.nix index 5d62584..7f647b5 100644 --- a/modules/root/default.nix +++ b/modules/root/default.nix @@ -4,7 +4,6 @@ ./autologin.nix ./bluetooth.nix ./bootloader.nix - ./cgit.nix ./doas.nix ./firewall.nix ./fonts.nix @@ -17,7 +16,6 @@ ./pipewire.nix ./powerkeys.nix ./printing.nix - ./searxng.nix ./secrets.nix ./ssh.nix ./suspend.nix @@ -31,7 +29,6 @@ autologin.enable = lib.mkDefault true; avahi.enable = lib.mkDefault true; bluetooth.enable = lib.mkDefault false; - cgit.enable = lib.mkDefault false; doas.enable = lib.mkDefault true; fonts.enable = lib.mkDefault true; nas = { @@ -50,7 +47,6 @@ printing.enable = lib.mkDefault true; tlp.enable = lib.mkDefault true; scanning.enable = lib.mkDefault true; - searxng.enable = lib.mkDefault false; suspend.enable = lib.mkDefault true; wifi.enable = lib.mkDefault true; xserver.enable = lib.mkDefault true; diff --git a/modules/root/gitea.nix b/modules/root/gitea.nix deleted file mode 100644 index 32c56db..0000000 --- a/modules/root/gitea.nix +++ /dev/null @@ -1,60 +0,0 @@ -{ lib, pkgs, config, userDetails, ... }: -let - cfg = config.gitea; -in { - options = { - gitea = { - enable = lib.mkEnableOption "enables gitea service"; - hostAddress = lib.mkOption { - type = lib.types.str; - description = "hostAddress for the container"; - default = "10.0.1.1"; - }; - localAddress = lib.mkOption { - type = lib.types.str; - description = "localAddress for the container"; - default = "10.0.1.3"; - }; - }; - }; - - config = lib.mkIf cfg.enable { - containers.gitea = { - autoStart = true; - privateNetwork = true; - hostAddress = cfg.hostAddress; - localAddress = cfg.localAddress; - - config = { lib, config, ... }: { - # Enable gitea service - services.gitea = { - enable = true; - user = "git"; # So ssh cloning uses git@gitea - settings = { - server = { - HTTP_PORT = 3000; # Can't set as 80 without root permissions, use 3000 instead - }; - }; - }; - - # Networking, etc. - # Redirect 80 to 3000 - networking.nftables = { - enable = true; - ruleset = '' - table ip nat { - chain prerouting { - type nat hook prerouting priority 0; - tcp dport 80 redirect to :3000 - } - } - ''; - }; - networking.firewall.allowedTCPPorts = [ 3000 80 22 ]; # Still need to forward 3000 for nftables rule to work - networking.hostName = "gitea"; - - system.stateVersion = "25.05"; - }; - }; - }; -} diff --git a/modules/root/searxng.nix b/modules/root/searxng.nix deleted file mode 100644 index 9f59314..0000000 --- a/modules/root/searxng.nix +++ /dev/null @@ -1,109 +0,0 @@ -{ pkgs, lib, config, ... }: let - environmentFile = "/run/searx/searxng.env"; - generateEnvironmentFile = '' - umask 077 - echo "SEARXNG_SECRET=$(head -c 56 /dev/urandom | base64)" > ${environmentFile} - ls /run/searx - ''; -in { - options = { - searxng.enable = lib.mkEnableOption "enables searxng service"; - }; - - config = lib.mkIf config.searxng.enable { - # Generate secret key - systemd.services.searx-environment-file = { - description = "Generate environment file with secret key for searx"; - wantedBy = [ "searx-init.service" ]; - partOf = [ "searx-init.service" ]; - before = [ "searx-init.service" ]; - serviceConfig = { - Type = "oneshot"; - RemainAfterExit = true; - User = "searx"; - RuntimeDirectory = "searx"; - RuntimeDirectoryMode = "750"; - ConditionPathExists = "!${environmentFile}"; - }; - script = generateEnvironmentFile; - }; - - # Configure searxng - services.searx = { - enable = true; - redisCreateLocally = true; - package = pkgs.searxng; - inherit environmentFile; # Provides secret key - - settings = { - general = { - instance_name = "TJK Search"; - donation_url = "https://tjkeller.xyz"; - enable_metrics = false; - }; - - # Search engine settings - search = { - safe_search = 2; # Strict - autocomplete = ""; - default_lang = "en-US"; - }; - - preferences.lock = [ "safesearch" ]; # Lock safe_search at strict - - # https://docs.searxng.org/admin/plugins.html - enabled_plugins = [ - "Tor check plugin" - "Tracker URL remover" - "Basic Calculator" - "Unit converter plugin" - "Hash plugin" - "Self Information" - "Open Access DOI rewrite" - "Hostnames plugin" - ]; - - hostnames.replace = { - "(.*\.)?youtube\.com$" = "piped.tjkeller.xyz"; - "(.*\.)?youtu\.be$" = "piped.tjkeller.xyz"; - "(.*\.)?reddit\.com$" = "old.reddit.com"; - }; - - # Enable / disabled search engines from default list - engines = lib.mapAttrsToList (name: value: { inherit name; disabled = !value; }) { - # Images - "artic" = false; - "deviantart" = false; - "flickr" = false; - "library of congress" = false; - "openverse" = false; - "pinterest" = false; - "public domain image archive" = false; - "unsplash" = false; - "wallhaven" = false; - "wikicommons.images" = false; - - # Videos - "bitchute" = true; - "dailymotion" = false; - "piped" = false; - "rumble" = true; - "sepiasearch" = false; - "vimeo" = false; - "wikicommons.videos" = false; - - # Music - "piped.music" = false; - - # Files - "1337x" = true; - "annas archive" = true; - "library genesis" = true; - - # Apps - "fdroid" = true; - }; - }; - }; - }; -} diff --git a/modules/root/services/cgit.nix b/modules/root/services/cgit.nix new file mode 100644 index 0000000..366c1f8 --- /dev/null +++ b/modules/root/services/cgit.nix @@ -0,0 +1,126 @@ +{ lib, pkgs, config, userDetails, ... }: +let + cfg = config.cgit; +in { + options = { + cgit = { + enable = lib.mkEnableOption "enables cgit service"; + hostAddress = lib.mkOption { + type = lib.types.str; + description = "hostAddress for the container"; + default = "10.0.1.1"; + }; + localAddress = lib.mkOption { + type = lib.types.str; + description = "localAddress for the container"; + default = "10.0.1.2"; + }; + rootTitle = lib.mkOption { + type = lib.types.str; + description = "cgit site title"; + default = ""; + }; + rootDesc = lib.mkOption { + type = lib.types.str; + description = "cgit site description"; + default = ""; + }; + extraConfig = lib.mkOption { + type = lib.types.str; + description = "cgitrc lines inserted verbatim at the end"; + default = ""; + }; + }; + }; + + config = lib.mkIf cfg.enable { + # Configure cgit container + containers.cgit = { + autoStart = true; + privateNetwork = true; + hostAddress = cfg.hostAddress; + localAddress = cfg.localAddress; + + specialArgs = { + authorizedKeys = userDetails.sshPublicKeys; + cgitrc = with cfg; { + inherit rootTitle; + inherit rootDesc; + inherit extraConfig; + }; + }; + + config = { lib, config, authorizedKeys, cgitrc, ... }: { + # Create git user for ssh access + users.users.git = { + isNormalUser = true; + home = "/srv/git"; # Serve from git user's home to allow cloning git@cgit:repo + group = "git"; + createHome = true; + homeMode = "750"; # Allow read permissions for group members + shell = pkgs.bash; + openssh.authorizedKeys.keys = authorizedKeys; + }; + users.groups.git.members = [ "lighttpd" ]; # Create the git group and add lighttpd user as a member so /srv/git can be served by cgit + + # Enable git + programs.git.enable = true; + + # Enable ssh service + services.openssh.enable = true; + + # Enable cgit service + services.lighttpd.enable = true; + services.lighttpd.cgit = { + enable = true; + #subdir = ""; # FIXME this does not work for some reason + configText = '' + # Based on joseluisq/alpine-cgit + root-title=${cgitrc.rootTitle} + root-desc=${cgitrc.rootDesc} + + source-filter=${pkgs.cgit}/lib/cgit/filters/syntax-highlighting.py + about-filter=${pkgs.cgit}/lib/cgit/filters/about-formatting.sh + + readme=:README.md + readme=:README.html + readme=:README.txt + readme=:README + readme=:INSTALL.md + readme=:INSTALL.html + readme=:INSTALL.txt + readme=:INSTALL + + # Cache + #cache-root=/var/cache/cgit + #cache-size=2000 + + enable-index-links=1 + enable-index-owner=0 + enable-remote-branches=1 + enable-log-filecount=1 + enable-log-linecount=1 + enable-git-config=1 + snapshots=tar.xz zip + + robots=noindex, nofollow + + virtual-root=/cgit + section-from-path=0 + max-repo-count=100 + scan-path=/srv/git + + # extra config + ${cgitrc.extraConfig} + ''; + }; + + # Networking, etc. + networking.firewall.allowedTCPPorts = [ 80 22 ]; + networking.hostName = "cgit"; + + system.stateVersion = "25.05"; + }; + }; + }; +} diff --git a/modules/root/services/gitea.nix b/modules/root/services/gitea.nix new file mode 100644 index 0000000..32c56db --- /dev/null +++ b/modules/root/services/gitea.nix @@ -0,0 +1,60 @@ +{ lib, pkgs, config, userDetails, ... }: +let + cfg = config.gitea; +in { + options = { + gitea = { + enable = lib.mkEnableOption "enables gitea service"; + hostAddress = lib.mkOption { + type = lib.types.str; + description = "hostAddress for the container"; + default = "10.0.1.1"; + }; + localAddress = lib.mkOption { + type = lib.types.str; + description = "localAddress for the container"; + default = "10.0.1.3"; + }; + }; + }; + + config = lib.mkIf cfg.enable { + containers.gitea = { + autoStart = true; + privateNetwork = true; + hostAddress = cfg.hostAddress; + localAddress = cfg.localAddress; + + config = { lib, config, ... }: { + # Enable gitea service + services.gitea = { + enable = true; + user = "git"; # So ssh cloning uses git@gitea + settings = { + server = { + HTTP_PORT = 3000; # Can't set as 80 without root permissions, use 3000 instead + }; + }; + }; + + # Networking, etc. + # Redirect 80 to 3000 + networking.nftables = { + enable = true; + ruleset = '' + table ip nat { + chain prerouting { + type nat hook prerouting priority 0; + tcp dport 80 redirect to :3000 + } + } + ''; + }; + networking.firewall.allowedTCPPorts = [ 3000 80 22 ]; # Still need to forward 3000 for nftables rule to work + networking.hostName = "gitea"; + + system.stateVersion = "25.05"; + }; + }; + }; +} diff --git a/modules/root/services/searxng.nix b/modules/root/services/searxng.nix new file mode 100644 index 0000000..8ed632e --- /dev/null +++ b/modules/root/services/searxng.nix @@ -0,0 +1,119 @@ +{ pkgs, lib, config, ... }: let + environmentFile = "/run/searx/searxng.env"; + generateEnvironmentFile = '' + umask 077 + echo "SEARXNG_SECRET=$(head -c 56 /dev/urandom | base64)" > ${environmentFile} + ls /run/searx + ''; +in { + options = { + searxng.enable = lib.mkEnableOption "enables searxng service"; + searxng.uwsgi.enable = lib.mkEnableOption "enables searxng uwsgi"; + }; + + config = lib.mkIf config.searxng.enable { + # Generate secret key + systemd.services.searx-environment-file = { + description = "Generate environment file with secret key for searx"; + wantedBy = [ "searx-init.service" ]; + partOf = [ "searx-init.service" ]; + before = [ "searx-init.service" ]; + serviceConfig = { + Type = "oneshot"; + RemainAfterExit = true; + User = "searx"; + RuntimeDirectory = "searx"; + RuntimeDirectoryMode = "750"; + ConditionPathExists = "!${environmentFile}"; + }; + script = generateEnvironmentFile; + }; + + # Configure searxng + services.searx = { + enable = true; + redisCreateLocally = true; + package = pkgs.searxng; + inherit environmentFile; # Provides secret key + + # UWSGI configuration + runInUwsgi = config.searxng.uwsgi.enable; + + uwsgiConfig = { + socket = "/run/searx/searx.sock"; + http = ":8888"; + chmod-socket = "660"; + }; + + settings = { + general = { + instance_name = "TJK Search"; + donation_url = "https://tjkeller.xyz"; + enable_metrics = false; + }; + + # Search engine settings + search = { + safe_search = 2; # Strict + autocomplete = ""; + default_lang = "en-US"; + }; + + preferences.lock = [ "safesearch" ]; # Lock safe_search at strict + + # https://docs.searxng.org/admin/plugins.html + enabled_plugins = [ + "Tor check plugin" + "Tracker URL remover" + "Basic Calculator" + "Unit converter plugin" + "Hash plugin" + "Self Information" + "Open Access DOI rewrite" + "Hostnames plugin" + ]; + + hostnames.replace = { + "(.*\.)?youtube\.com$" = "piped.tjkeller.xyz"; + "(.*\.)?youtu\.be$" = "piped.tjkeller.xyz"; + "(.*\.)?reddit\.com$" = "old.reddit.com"; + }; + + # Enable / disabled search engines from default list + engines = lib.mapAttrsToList (name: value: { inherit name; disabled = !value; }) { + # Images + "artic" = false; + "deviantart" = false; + "flickr" = false; + "library of congress" = false; + "openverse" = false; + "pinterest" = false; + "public domain image archive" = false; + "unsplash" = false; + "wallhaven" = false; + "wikicommons.images" = false; + + # Videos + "bitchute" = true; + "dailymotion" = false; + "piped" = false; + "rumble" = true; + "sepiasearch" = false; + "vimeo" = false; + "wikicommons.videos" = false; + + # Music + "piped.music" = false; + + # Files + "1337x" = true; + "annas archive" = true; + "library genesis" = true; + + # Apps + "fdroid" = true; + }; + }; + }; + }; +} -- cgit v1.2.3