mirror of
https://github.com/itme-brain/nixos.git
synced 2026-05-08 06:50:11 -04:00
init
This commit is contained in:
commit
864c69fe61
147 changed files with 11233 additions and 0 deletions
163
system/machines/server/modules/nginx/default.nix
Normal file
163
system/machines/server/modules/nginx/default.nix
Normal file
|
|
@ -0,0 +1,163 @@
|
|||
{ pkgs, lib, config, ... }:
|
||||
|
||||
with lib;
|
||||
let
|
||||
cfg = config.modules.system.nginx;
|
||||
domain = "ramos.codes";
|
||||
privateAccessRules = concatMapStringsSep "\n" (cidr: "allow ${cidr};") cfg.privateAllowCidrs + "\ndeny all;";
|
||||
|
||||
in
|
||||
{
|
||||
options.modules.system.nginx = {
|
||||
enable = mkEnableOption "Nginx Reverse Proxy";
|
||||
|
||||
privateAllowCidrs = mkOption {
|
||||
type = types.listOf types.str;
|
||||
default = [
|
||||
"192.168.0.0/24"
|
||||
"10.8.0.0/24"
|
||||
];
|
||||
description = ''
|
||||
CIDR ranges allowed to access private vhosts (LAN + WireGuard).
|
||||
'';
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
config = mkIf cfg.enable {
|
||||
networking.firewall.allowedTCPPorts = [ 80 443 ];
|
||||
|
||||
systemd.services.nginx.serviceConfig.LimitNOFILE = 65536;
|
||||
|
||||
environment.etc."fail2ban/filter.d/nginx-404.conf".text = ''
|
||||
[Definition]
|
||||
failregex = ^<HOST> - .+ "(GET|POST|HEAD|PUT|DELETE|PATCH) .+ HTTP/[0-9.]+" 404
|
||||
ignoreregex =
|
||||
'';
|
||||
|
||||
environment.etc."fail2ban/filter.d/nginx-401.conf".text = ''
|
||||
[Definition]
|
||||
failregex = ^<HOST> - .+ "(GET|POST|HEAD|PUT|DELETE|PATCH) .+ HTTP/[0-9.]+" 401
|
||||
ignoreregex =
|
||||
'';
|
||||
|
||||
services.fail2ban.jails.nginx-404 = ''
|
||||
enabled = true
|
||||
filter = nginx-404
|
||||
logpath = /var/log/nginx/access.log
|
||||
maxretry = 10
|
||||
findtime = 10m
|
||||
bantime = 24h
|
||||
'';
|
||||
|
||||
services.fail2ban.jails.nginx-401 = ''
|
||||
enabled = true
|
||||
filter = nginx-401
|
||||
logpath = /var/log/nginx/access.log
|
||||
maxretry = 5
|
||||
findtime = 10m
|
||||
bantime = 24h
|
||||
'';
|
||||
|
||||
security.acme = {
|
||||
acceptTerms = true;
|
||||
defaults.email = config.user.email;
|
||||
|
||||
certs."${domain}" = {
|
||||
domain = "*.${domain}";
|
||||
dnsProvider = "namecheap";
|
||||
environmentFile = "/var/lib/acme/namecheap.env";
|
||||
group = "nginx";
|
||||
};
|
||||
};
|
||||
|
||||
services.nginx = {
|
||||
enable = true;
|
||||
recommendedTlsSettings = true;
|
||||
recommendedOptimisation = true;
|
||||
recommendedGzipSettings = true;
|
||||
eventsConfig = "worker_connections 4096;";
|
||||
|
||||
# Catch-all default - friendly error for unknown subdomains
|
||||
virtualHosts."_" = {
|
||||
default = true;
|
||||
useACMEHost = domain;
|
||||
forceSSL = true;
|
||||
locations."/" = {
|
||||
return = "404 'Not Found: This subdomain does not exist.'";
|
||||
extraConfig = ''
|
||||
add_header Content-Type text/plain;
|
||||
'';
|
||||
};
|
||||
};
|
||||
|
||||
virtualHosts."wg.${domain}" = {
|
||||
useACMEHost = domain;
|
||||
forceSSL = true;
|
||||
locations."/" = {
|
||||
proxyPass = "http://127.0.0.1:${toString config.modules.system.wstunnel.listenPort}";
|
||||
proxyWebsockets = true;
|
||||
extraConfig = ''
|
||||
proxy_read_timeout 3600s;
|
||||
proxy_send_timeout 3600s;
|
||||
'';
|
||||
};
|
||||
};
|
||||
|
||||
virtualHosts."ai.${domain}" = let
|
||||
apiKeyAuth = ''
|
||||
set $api_key "";
|
||||
if ($http_authorization ~* "^Bearer (.+)$") {
|
||||
set $api_key $1;
|
||||
}
|
||||
if ($api_key = "") {
|
||||
return 401 '{"error": "Missing Authorization header"}';
|
||||
}
|
||||
include ${config.sops.templates."nginx-ai-auth.conf".path};
|
||||
'';
|
||||
in {
|
||||
useACMEHost = domain;
|
||||
forceSSL = true;
|
||||
|
||||
# Web UI + llama.cpp API (browser, /v1/* calls from the UI)
|
||||
# Auth handled by llama.cpp itself (--api-key flag)
|
||||
locations."/" = {
|
||||
proxyPass = "http://192.168.0.23:8000";
|
||||
proxyWebsockets = true;
|
||||
};
|
||||
|
||||
# Llama Stack API (opencode, programmatic clients)
|
||||
# Clients use baseURL: https://ai.ramos.codes/stack/v1
|
||||
locations."/stack/v1/" = {
|
||||
proxyPass = "http://192.168.0.23:8321/v1/";
|
||||
proxyWebsockets = true;
|
||||
extraConfig = apiKeyAuth + ''
|
||||
proxy_read_timeout 300s;
|
||||
proxy_send_timeout 300s;
|
||||
'';
|
||||
};
|
||||
|
||||
# MCP servers (namespaced, for llama.cpp web UI + direct access)
|
||||
locations."/mcp/web_search/" = {
|
||||
proxyPass = "http://192.168.0.23:8002/";
|
||||
proxyWebsockets = true;
|
||||
extraConfig = ''
|
||||
include ${config.sops.templates."nginx-mcp-auth.conf".path};
|
||||
proxy_read_timeout 300s;
|
||||
proxy_send_timeout 300s;
|
||||
'';
|
||||
};
|
||||
};
|
||||
|
||||
virtualHosts."comfy.${domain}" = {
|
||||
useACMEHost = domain;
|
||||
forceSSL = true;
|
||||
locations."/" = {
|
||||
proxyPass = "http://192.168.0.23:8188";
|
||||
proxyWebsockets = true;
|
||||
extraConfig = privateAccessRules;
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue