forked from penal-colony/nixos-vps
Compare commits
10 commits
1c76661538
...
db959e9fd4
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
db959e9fd4 | ||
| aa670604b5 | |||
| 49ffe471a3 | |||
| b505d2a327 | |||
| 43bc670bf4 | |||
| adb8ddb611 | |||
| 5d177a0d5c | |||
| f31ec2ce65 | |||
| b0b0989d36 | |||
| 6155b36279 |
7 changed files with 186 additions and 19 deletions
|
|
@ -90,12 +90,14 @@
|
|||
|
||||
nix.settings.experimental-features = [ "nix-command" "flakes" ];
|
||||
|
||||
# === SearXNG ===
|
||||
myModules.searxng = {
|
||||
# === Websurfx (replaces SearXNG) ===
|
||||
myModules.websurfx = {
|
||||
enable = true;
|
||||
port = 8888;
|
||||
domain = "search.ashisgreat.xyz"; # Change to your domain
|
||||
instanceName = "Ashie Search";
|
||||
domain = "search.ashisgreat.xyz";
|
||||
threads = 8;
|
||||
theme = "simple";
|
||||
colorscheme = "catppuccin-mocha";
|
||||
};
|
||||
|
||||
# === Nginx Reverse Proxy ===
|
||||
|
|
|
|||
|
|
@ -96,6 +96,16 @@ in
|
|||
querylog_enabled = true;
|
||||
querylog_file_enabled = true;
|
||||
statistics_enabled = true;
|
||||
rewrites = [
|
||||
{
|
||||
domain = "*.ashisgreat.xyz";
|
||||
answer = "100.64.0.3";
|
||||
}
|
||||
{
|
||||
domain = "ashisgreat.xyz";
|
||||
answer = "100.64.0.3";
|
||||
}
|
||||
];
|
||||
};
|
||||
|
||||
tls = {
|
||||
|
|
@ -175,15 +185,10 @@ in
|
|||
iptables -t nat -D PREROUTING -i tailscale0 -p tcp --dport 53 -j REDIRECT --to-ports 5353 || true
|
||||
'';
|
||||
|
||||
# Nginx configuration (kept to satisfy ACME challenges for DoT certificates)
|
||||
services.nginx.virtualHosts."${cfg.domain}" = {
|
||||
enableACME = true;
|
||||
forceSSL = true;
|
||||
|
||||
# Block all paths (no DoH or UI exposed via Nginx)
|
||||
locations."/" = {
|
||||
return = "404";
|
||||
};
|
||||
# Nginx reverse proxy for AdGuard Home Web UI and DoH
|
||||
myModules.nginx.domains."${cfg.domain}" = {
|
||||
port = cfg.port;
|
||||
contentSecurityPolicy = null; # AdGuard Home handles its own CSP
|
||||
};
|
||||
|
||||
# Ensure nginx user can access ACME certs
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@
|
|||
./podman.nix
|
||||
./nginx.nix
|
||||
./searxng.nix
|
||||
./websurfx.nix
|
||||
./openclaw-podman.nix
|
||||
./vaultwarden.nix
|
||||
./crowdsec.nix
|
||||
|
|
|
|||
|
|
@ -74,6 +74,12 @@ in
|
|||
description = "Content-Security-Policy header value. Set to null to omit.";
|
||||
};
|
||||
|
||||
internalOnly = lib.mkOption {
|
||||
type = lib.types.bool;
|
||||
default = false;
|
||||
description = "Restrict access to Tailscale network and localhost only";
|
||||
};
|
||||
|
||||
rateLimit = {
|
||||
enable = lib.mkOption {
|
||||
type = lib.types.nullOr lib.types.bool;
|
||||
|
|
@ -156,6 +162,12 @@ in
|
|||
|
||||
# Security headers applied per-vhost
|
||||
extraConfig = ''
|
||||
${lib.optionalString opts.internalOnly ''
|
||||
# Restrict access to Tailscale network
|
||||
allow 100.64.0.0/10;
|
||||
allow 127.0.0.0/8;
|
||||
deny all;
|
||||
''}
|
||||
# Strict Transport Security — 6 months, include subdomains, preload-ready
|
||||
add_header Strict-Transport-Security "max-age=15768000; includeSubDomains; preload" always;
|
||||
|
||||
|
|
|
|||
|
|
@ -28,10 +28,6 @@
|
|||
}
|
||||
},
|
||||
"tools": {
|
||||
"github": {
|
||||
"enabled": true,
|
||||
"token": "${GITHUB_TOKEN}"
|
||||
},
|
||||
"elevated": { "enabled": true },
|
||||
"exec": { "security": "full", "ask": "off" },
|
||||
"web": {
|
||||
|
|
|
|||
|
|
@ -39,6 +39,11 @@ in
|
|||
# Enable podman
|
||||
myModules.podman.enable = true;
|
||||
|
||||
# Create directory for OpenClaw data
|
||||
systemd.tmpfiles.rules = [
|
||||
"d /var/lib/openclaw 0755 1000 1000 -" # Assuming node user is uid 1000
|
||||
];
|
||||
|
||||
# OpenClaw container (bridge network — isolated from host services)
|
||||
virtualisation.oci-containers.containers."openclaw" = {
|
||||
image = "ghcr.io/openclaw/openclaw:latest";
|
||||
|
|
@ -47,9 +52,17 @@ in
|
|||
config.sops.templates."openclaw.env".path
|
||||
];
|
||||
volumes = [
|
||||
"${./openclaw-config.json}:/home/node/.openclaw/openclaw.json:ro"
|
||||
"openclaw-data:/home/node/.openclaw"
|
||||
"/var/lib/openclaw:/home/node/.openclaw"
|
||||
];
|
||||
};
|
||||
|
||||
# Copy the declarative config before starting the container
|
||||
# This allows OpenClaw to safely write/rename the file at runtime without EBUSY errors
|
||||
systemd.services."podman-openclaw".preStart = lib.mkBefore ''
|
||||
mkdir -p /var/lib/openclaw
|
||||
cp -f ${./openclaw-config.json} /var/lib/openclaw/openclaw.json
|
||||
chown -R 1000:1000 /var/lib/openclaw
|
||||
chmod -R u+rwX /var/lib/openclaw
|
||||
'';
|
||||
};
|
||||
}
|
||||
|
|
|
|||
138
modules/websurfx.nix
Normal file
138
modules/websurfx.nix
Normal file
|
|
@ -0,0 +1,138 @@
|
|||
# Websurfx Module (Podman)
|
||||
# Provides: Fast, privacy-focused meta-search engine written in Rust
|
||||
#
|
||||
# Usage:
|
||||
# myModules.websurfx = {
|
||||
# enable = true;
|
||||
# port = 8080;
|
||||
# domain = "search.example.com";
|
||||
# };
|
||||
|
||||
{
|
||||
config,
|
||||
lib,
|
||||
pkgs,
|
||||
...
|
||||
}:
|
||||
|
||||
let
|
||||
cfg = config.myModules.websurfx;
|
||||
in
|
||||
{
|
||||
options.myModules.websurfx = {
|
||||
enable = lib.mkEnableOption "Websurfx meta-search engine";
|
||||
|
||||
port = lib.mkOption {
|
||||
type = lib.types.port;
|
||||
default = 8080;
|
||||
description = "Port to expose Websurfx on localhost";
|
||||
};
|
||||
|
||||
domain = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
example = "search.example.com";
|
||||
description = "Public domain name for Websurfx";
|
||||
};
|
||||
|
||||
threads = lib.mkOption {
|
||||
type = lib.types.int;
|
||||
default = 8;
|
||||
description = "Number of threads for the app to use";
|
||||
};
|
||||
|
||||
theme = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
default = "simple";
|
||||
description = "Default theme (simple, dark, etc.)";
|
||||
};
|
||||
|
||||
colorscheme = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
default = "catppuccin-mocha";
|
||||
description = "Color scheme (catppuccin-mocha, dracula, monokai, nord, etc.)";
|
||||
};
|
||||
};
|
||||
|
||||
config = lib.mkIf cfg.enable {
|
||||
# Ensure Podman is enabled
|
||||
myModules.podman.enable = true;
|
||||
|
||||
# Create bridge network
|
||||
systemd.services.create-websurfx-network = {
|
||||
description = "Create Websurfx podman network";
|
||||
after = [ "network-online.target" ];
|
||||
requires = [ "network-online.target" ];
|
||||
serviceConfig = {
|
||||
Type = "oneshot";
|
||||
RemainAfterExit = true;
|
||||
};
|
||||
path = [ pkgs.podman ];
|
||||
script = ''
|
||||
if ! podman network exists websurfx-net 2>/dev/null; then
|
||||
podman network create websurfx-net --subnet 10.89.3.0/24
|
||||
fi
|
||||
'';
|
||||
};
|
||||
|
||||
# Config file for Websurfx
|
||||
environment.etc."xdg/websurfx/config.lua".text = ''
|
||||
-- ### General ###
|
||||
logging = true
|
||||
debug = false
|
||||
threads = ${toString cfg.threads}
|
||||
|
||||
-- ### Server ###
|
||||
port = "8080"
|
||||
binding_ip = "0.0.0.0"
|
||||
production_use = true
|
||||
|
||||
-- ### Search ###
|
||||
rate_limiter = {
|
||||
number_of_requests = 20,
|
||||
time_limit = 60,
|
||||
}
|
||||
|
||||
-- ### Cache ###
|
||||
redis_url = "redis://redis:6379"
|
||||
|
||||
-- ### UI ###
|
||||
style = {
|
||||
theme = "${cfg.theme}",
|
||||
colorscheme = "${cfg.colorscheme}",
|
||||
}
|
||||
'';
|
||||
|
||||
# Allow list and block list files (empty by default)
|
||||
environment.etc."xdg/websurfx/allowlist.txt".text = "";
|
||||
environment.etc."xdg/websurfx/blocklist.txt".text = "";
|
||||
|
||||
# Redis Container (Cache)
|
||||
virtualisation.oci-containers.containers."websurfx-redis" = {
|
||||
image = "docker.io/redis:alpine";
|
||||
cmd = [ "redis-server" "--save" "" "--appendonly" "no" ];
|
||||
extraOptions = [
|
||||
"--network=websurfx-net"
|
||||
"--network-alias=redis"
|
||||
];
|
||||
};
|
||||
|
||||
# Websurfx Container
|
||||
virtualisation.oci-containers.containers."websurfx" = {
|
||||
image = "docker.io/neonmmd/websurfx:latest";
|
||||
ports = [ "127.0.0.1:${toString cfg.port}:8080" ];
|
||||
extraOptions = [
|
||||
"--network=websurfx-net"
|
||||
"--network-alias=websurfx"
|
||||
"--cap-drop=ALL"
|
||||
"--dns=9.9.9.9"
|
||||
"--dns=1.1.1.1"
|
||||
];
|
||||
volumes = [
|
||||
"/etc/xdg/websurfx/config.lua:/etc/xdg/websurfx/config.lua:ro"
|
||||
"/etc/xdg/websurfx/allowlist.txt:/etc/xdg/websurfx/allowlist.txt:ro"
|
||||
"/etc/xdg/websurfx/blocklist.txt:/etc/xdg/websurfx/blocklist.txt:ro"
|
||||
];
|
||||
dependsOn = [ "websurfx-redis" ];
|
||||
};
|
||||
};
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue