411 lines
12 KiB
Nix
411 lines
12 KiB
Nix
{ pkgs, ... }:
|
|
|
|
{
|
|
imports = [ ./common.nix ];
|
|
|
|
networking.hostName = "axiomania";
|
|
|
|
# ============================================================================
|
|
# Firewall
|
|
# ============================================================================
|
|
networking.firewall = {
|
|
allowedTCPPorts = [ 22 80 443 2222 ];
|
|
allowedUDPPorts = [ 51820 ]; # Wireguard
|
|
checkReversePath = "loose"; # Required for WireGuard NAT
|
|
};
|
|
|
|
# ============================================================================
|
|
# Forgejo
|
|
# ============================================================================
|
|
services.forgejo = {
|
|
enable = true;
|
|
database.type = "sqlite3";
|
|
settings = {
|
|
DEFAULT.APP_NAME = "Axiomania Git";
|
|
|
|
server = {
|
|
DOMAIN = "git.axiomania.org";
|
|
ROOT_URL = "https://git.axiomania.org/";
|
|
HTTP_ADDR = "127.0.0.1";
|
|
HTTP_PORT = 3000;
|
|
SSH_DOMAIN = "git.axiomania.org";
|
|
SSH_PORT = 2222;
|
|
START_SSH_SERVER = true;
|
|
};
|
|
|
|
service = {
|
|
DISABLE_REGISTRATION = true;
|
|
DEFAULT_KEEP_EMAIL_PRIVATE = true;
|
|
};
|
|
|
|
repository = {
|
|
DEFAULT_PRIVATE = "private";
|
|
};
|
|
|
|
api = {
|
|
ENABLE_SWAGGER = false;
|
|
};
|
|
|
|
session = {
|
|
COOKIE_SECURE = true;
|
|
};
|
|
|
|
actions = {
|
|
ENABLED = true;
|
|
};
|
|
};
|
|
};
|
|
|
|
# ============================================================================
|
|
# Forgejo Actions Runner
|
|
# ============================================================================
|
|
# Requires a registration token from Forgejo.
|
|
# Generate one: ssh root@178.104.15.221, then:
|
|
# forgejo-runner register (follow prompts)
|
|
# Or via Forgejo web UI: Site Administration > Runners > Create Runner
|
|
# Then put the token in /var/lib/forgejo-runner/token
|
|
services.gitea-actions-runner.instances.default = {
|
|
enable = true;
|
|
name = "axiomania";
|
|
url = "https://git.axiomania.org";
|
|
tokenFile = "/var/lib/forgejo-runner/token";
|
|
labels = [ "native:host" ];
|
|
hostPackages = with pkgs; [
|
|
bash
|
|
coreutils
|
|
curl
|
|
gawk
|
|
git
|
|
gnused
|
|
nodejs
|
|
nix
|
|
];
|
|
};
|
|
|
|
# ============================================================================
|
|
# Vaultwarden (Bitwarden-compatible password manager)
|
|
# ============================================================================
|
|
services.vaultwarden = {
|
|
enable = true;
|
|
config = {
|
|
DOMAIN = "https://vault.axiomania.org";
|
|
SIGNUPS_ALLOWED = false;
|
|
ROCKET_ADDRESS = "127.0.0.1";
|
|
ROCKET_PORT = 8222;
|
|
};
|
|
};
|
|
|
|
# ============================================================================
|
|
# Navidrome (music streaming)
|
|
# ============================================================================
|
|
services.navidrome = {
|
|
enable = true;
|
|
settings = {
|
|
Address = "127.0.0.1";
|
|
Port = 4533;
|
|
MusicFolder = "/var/lib/navidrome/music";
|
|
};
|
|
};
|
|
|
|
# ============================================================================
|
|
# Syncthing (file sync)
|
|
# ============================================================================
|
|
services.syncthing = {
|
|
enable = true;
|
|
openDefaultPorts = true;
|
|
dataDir = "/var/lib/syncthing";
|
|
settings.gui.insecureSkipHostcheck = true;
|
|
};
|
|
|
|
# ============================================================================
|
|
# Attic (Nix binary cache)
|
|
# ============================================================================
|
|
# Requires a secret generated on the server:
|
|
# openssl genrsa -traditional 4096 | base64 -w0 > /var/lib/atticd/token-secret
|
|
# echo "ATTIC_SERVER_TOKEN_RS256_SECRET_BASE64=$(cat /var/lib/atticd/token-secret)" > /etc/atticd.env
|
|
services.atticd = {
|
|
enable = true;
|
|
environmentFile = "/etc/atticd.env";
|
|
settings = {
|
|
listen = "[::]:8080";
|
|
storage = {
|
|
type = "local";
|
|
path = "/var/lib/atticd/storage";
|
|
};
|
|
garbage-collection = {
|
|
default-retention-period = "3 months";
|
|
};
|
|
chunking = {
|
|
nar-size-threshold = 65536;
|
|
min-size = 16384;
|
|
avg-size = 65536;
|
|
max-size = 262144;
|
|
};
|
|
};
|
|
};
|
|
|
|
# ============================================================================
|
|
# Kavita (ebook library)
|
|
# ============================================================================
|
|
# Generate token on the server:
|
|
# openssl rand -hex 128 > /var/lib/kavita/token-key
|
|
services.kavita = {
|
|
enable = true;
|
|
settings.Port = 5000;
|
|
tokenKeyFile = "/var/lib/kavita/token-key";
|
|
};
|
|
|
|
# ============================================================================
|
|
# Audiobookshelf
|
|
# ============================================================================
|
|
services.audiobookshelf = {
|
|
enable = true;
|
|
port = 8234;
|
|
host = "127.0.0.1";
|
|
};
|
|
|
|
# ============================================================================
|
|
# Paperless-ngx (document management)
|
|
# ============================================================================
|
|
services.paperless = {
|
|
enable = true;
|
|
port = 28981;
|
|
address = "127.0.0.1";
|
|
domain = "docs.axiomania.org";
|
|
};
|
|
|
|
# ============================================================================
|
|
# Adguard Home (DNS ad blocker)
|
|
# ============================================================================
|
|
# Use as DNS server via Wireguard: set DNS = 10.100.0.1 in client config
|
|
services.adguardhome = {
|
|
enable = true;
|
|
port = 3300;
|
|
host = "127.0.0.1";
|
|
};
|
|
|
|
# ============================================================================
|
|
# SearXNG (private search engine)
|
|
# ============================================================================
|
|
# Generate secret on the server:
|
|
# echo "SEARX_SECRET=$(openssl rand -hex 32)" > /etc/searx/secrets.env
|
|
services.searx = {
|
|
enable = true;
|
|
redisCreateLocally = true;
|
|
settings = {
|
|
server = {
|
|
bind_address = "127.0.0.1";
|
|
port = 8888;
|
|
secret_key = "$SEARX_SECRET";
|
|
};
|
|
};
|
|
environmentFile = "/etc/searx/secrets.env";
|
|
};
|
|
|
|
# ============================================================================
|
|
# Homepage (services dashboard)
|
|
# ============================================================================
|
|
services.homepage-dashboard = {
|
|
enable = true;
|
|
listenPort = 8082;
|
|
allowedHosts = "home.axiomania.org";
|
|
};
|
|
|
|
# ============================================================================
|
|
# Matrix Conduit (encrypted messaging)
|
|
# ============================================================================
|
|
services.matrix-conduit = {
|
|
enable = true;
|
|
settings.global = {
|
|
server_name = "axiomania.org";
|
|
port = 6167;
|
|
address = "127.0.0.1";
|
|
allow_registration = false;
|
|
};
|
|
};
|
|
|
|
# ============================================================================
|
|
# Gokapi (file sharing) — disabled due to CVEs in stable
|
|
# ============================================================================
|
|
# services.gokapi = {
|
|
# enable = true;
|
|
# environment = {
|
|
# GOKAPI_PORT = 53842;
|
|
# };
|
|
# };
|
|
|
|
# ============================================================================
|
|
# Wireguard VPN
|
|
# ============================================================================
|
|
# Generate keys on the server:
|
|
# wg genkey | tee /etc/wireguard/private.key | wg pubkey > /etc/wireguard/public.key
|
|
networking.wireguard.interfaces.wg0 = {
|
|
ips = [ "10.100.0.1/24" ];
|
|
listenPort = 51820;
|
|
privateKeyFile = "/etc/wireguard/private.key";
|
|
peers = [
|
|
{
|
|
# Minisforum V3 SE (local NixOS machine)
|
|
publicKey = "rEsHqzJVnv9AoOIEVTrdEF3x4G6rWxXqHLXTzAx88gc=";
|
|
allowedIPs = [ "10.100.0.2/32" ];
|
|
}
|
|
{
|
|
# Pixel 5
|
|
publicKey = "jP+rYdc8qKdNY4l3PDFmGiOA31SnJRgcmQIVu6AJ9EM=";
|
|
allowedIPs = [ "10.100.0.3/32" ];
|
|
}
|
|
];
|
|
};
|
|
|
|
# NAT for Wireguard clients to access the internet
|
|
networking.nat = {
|
|
enable = true;
|
|
externalInterface = "enp1s0";
|
|
internalInterfaces = [ "wg0" ];
|
|
};
|
|
|
|
# ============================================================================
|
|
# Nginx reverse proxy + ACME
|
|
# ============================================================================
|
|
services.nginx = {
|
|
enable = true;
|
|
recommendedProxySettings = true;
|
|
recommendedTlsSettings = true;
|
|
recommendedOptimisation = true;
|
|
recommendedGzipSettings = true;
|
|
|
|
# ── Public services ──
|
|
virtualHosts."git.axiomania.org" = {
|
|
enableACME = true;
|
|
forceSSL = true;
|
|
locations."/" = {
|
|
proxyPass = "http://127.0.0.1:3000";
|
|
proxyWebsockets = true;
|
|
};
|
|
};
|
|
|
|
virtualHosts."matrix.axiomania.org" = {
|
|
enableACME = true;
|
|
forceSSL = true;
|
|
locations."/" = {
|
|
proxyPass = "http://127.0.0.1:6167";
|
|
proxyWebsockets = true;
|
|
};
|
|
};
|
|
|
|
virtualHosts."cache.axiomania.org" = {
|
|
enableACME = true;
|
|
forceSSL = true;
|
|
locations."/" = {
|
|
proxyPass = "http://[::1]:8080";
|
|
proxyWebsockets = true;
|
|
extraConfig = "client_max_body_size 0;";
|
|
};
|
|
};
|
|
|
|
# ── VPN-only services (WireGuard clients only) ──
|
|
virtualHosts."vault.axiomania.org" = {
|
|
enableACME = true;
|
|
forceSSL = true;
|
|
locations."/" = {
|
|
proxyPass = "http://127.0.0.1:8222";
|
|
proxyWebsockets = true;
|
|
extraConfig = "allow 10.100.0.0/24; allow 127.0.0.1; deny all;";
|
|
};
|
|
};
|
|
|
|
virtualHosts."music.axiomania.org" = {
|
|
enableACME = true;
|
|
forceSSL = true;
|
|
locations."/" = {
|
|
proxyPass = "http://127.0.0.1:4533";
|
|
proxyWebsockets = true;
|
|
extraConfig = "allow 10.100.0.0/24; allow 127.0.0.1; deny all;";
|
|
};
|
|
};
|
|
|
|
virtualHosts."sync.axiomania.org" = {
|
|
enableACME = true;
|
|
forceSSL = true;
|
|
locations."/" = {
|
|
proxyPass = "http://127.0.0.1:8384";
|
|
proxyWebsockets = true;
|
|
extraConfig = "allow 10.100.0.0/24; allow 127.0.0.1; deny all;";
|
|
};
|
|
};
|
|
|
|
virtualHosts."books.axiomania.org" = {
|
|
enableACME = true;
|
|
forceSSL = true;
|
|
locations."/" = {
|
|
proxyPass = "http://127.0.0.1:5000";
|
|
proxyWebsockets = true;
|
|
extraConfig = "allow 10.100.0.0/24; allow 127.0.0.1; deny all;";
|
|
};
|
|
};
|
|
|
|
virtualHosts."audio.axiomania.org" = {
|
|
enableACME = true;
|
|
forceSSL = true;
|
|
locations."/" = {
|
|
proxyPass = "http://127.0.0.1:8234";
|
|
proxyWebsockets = true;
|
|
extraConfig = "allow 10.100.0.0/24; allow 127.0.0.1; deny all;";
|
|
};
|
|
};
|
|
|
|
virtualHosts."docs.axiomania.org" = {
|
|
enableACME = true;
|
|
forceSSL = true;
|
|
locations."/" = {
|
|
proxyPass = "http://127.0.0.1:28981";
|
|
proxyWebsockets = true;
|
|
extraConfig = "allow 10.100.0.0/24; allow 127.0.0.1; deny all;";
|
|
};
|
|
};
|
|
|
|
virtualHosts."search.axiomania.org" = {
|
|
enableACME = true;
|
|
forceSSL = true;
|
|
locations."/" = {
|
|
proxyPass = "http://127.0.0.1:8888";
|
|
proxyWebsockets = true;
|
|
extraConfig = "allow 10.100.0.0/24; allow 127.0.0.1; deny all;";
|
|
};
|
|
};
|
|
|
|
virtualHosts."home.axiomania.org" = {
|
|
enableACME = true;
|
|
forceSSL = true;
|
|
locations."/" = {
|
|
proxyPass = "http://127.0.0.1:8082";
|
|
proxyWebsockets = true;
|
|
extraConfig = "allow 10.100.0.0/24; allow 127.0.0.1; deny all;";
|
|
};
|
|
};
|
|
|
|
# virtualHosts."share.axiomania.org" = {
|
|
# enableACME = true;
|
|
# forceSSL = true;
|
|
# locations."/" = {
|
|
# proxyPass = "http://127.0.0.1:53842";
|
|
# proxyWebsockets = true;
|
|
# };
|
|
# };
|
|
};
|
|
|
|
security.acme = {
|
|
acceptTerms = true;
|
|
defaults.email = "gamma.kinematics@gmail.com";
|
|
};
|
|
|
|
# ============================================================================
|
|
# Packages
|
|
# ============================================================================
|
|
environment.systemPackages = with pkgs; [
|
|
git
|
|
vim
|
|
htop
|
|
wireguard-tools
|
|
];
|
|
}
|