This commit is contained in:
Shelvacu
2024-10-19 18:18:53 -07:00
parent 01aa80919e
commit 565bb08be3
13 changed files with 290 additions and 61 deletions

View File

@@ -17,6 +17,7 @@
./emily.nix
./jellyfin.nix
./yt-archiver.nix
./habitat-fwd.nix
];
boot.loader.systemd-boot.enable = true;

View File

@@ -1,10 +1,9 @@
{
config,
pkgs,
inputs,
lib,
...
}:
}@args:
let
# How to register a new domain in acme-dns before deploying the nix config:
# From trip:
@@ -18,8 +17,23 @@ let
"pwrhs.win"
"jf.finaltask.xyz"
];
proxied = lib.pipe [
config.vacu.proxiedServices
lib.attrVals
(lib.filter (c: c.enabled))
];
serviceValidDomainAssertions = map (proxiedConfig: {
assertion = lib.any (availableDomain:
(lib.endsWith proxiedConfig.domain ("." + availableDomain)) ||
(proxiedConfig.domain == availableDomain)
) domains;
message = "proxiedService ${proxiedConfig.name}'s `domain` does not match any of the known domains";
}) proxied;
mapListToAttrs = f: list: lib.listToAttrs (map f list);
in
{
assertions = [ ]
++ serviceValidDomainAssertions;
security.acme.acceptTerms = true;
security.acme.defaults = {
email = "nix-acme@shelvacu.com";
@@ -32,10 +46,10 @@ in
};
security.acme.certs = builtins.listToAttrs (
map (d: {
name = d;
map (domain: {
name = domain;
value = {
extraDomainNames = [ "*.${d}" ];
extraDomainNames = [ "*.${domain}" ];
};
}) domains
);
@@ -71,30 +85,23 @@ in
}) domains
);
config =
{ config, pkgs, ... }:
{ config, ... }:
{
system.stateVersion = "23.11";
users.groups.acme.gid = outer_config.users.groups.acme.gid;
users.users.haproxy.extraGroups = [ config.users.groups.acme.name ];
services.haproxy.enable = true;
services.haproxy.config = ''
# # ssl keylogging
# global
# tune.ssl.keylog on
# lua-load ${pkgs.writeText "sslkeylog.lua" (builtins.readFile ./sslkeylog.lua)}
# haproxy-config.cfg
${builtins.readFile ./haproxy-config.cfg}
'';
networking.hosts = {
"${outer_config.containers.vacustore.localAddress}" = [ "vacustore" ];
"127.4.20.165" = [ "kani" ];
# "${outer_config.containers.keycloak.localAddress}" = [ "keycloak" ];
"${outer_config.containers.nix-cache-nginx.localAddress}" = [ "nix-cache" ];
"${outer_config.containers.jl-stats.localAddress}" = [ "jl_stats" ];
"${outer_config.containers.static-stuff.localAddress}" = [ "static_stuff" ];
"${outer_config.containers.jellyfin.localAddress}" = [ "jellyfin" ];
};
services.haproxy.config = import ./haproxy-config.nix { inherit lib domains proxied; };
networking.hosts = mapListToAttrs (c: lib.nameValuePair c.ipAddress [ c.name ]) proxied;
# networking.hosts = {
# "${outer_config.containers.vacustore.localAddress}" = [ "vacustore" ];
# "127.4.20.165" = [ "kani" ];
# # "${outer_config.containers.keycloak.localAddress}" = [ "keycloak" ];
# "${outer_config.containers.nix-cache-nginx.localAddress}" = [ "nix-cache" ];
# "${outer_config.containers.jl-stats.localAddress}" = [ "jl_stats" ];
# "${outer_config.containers.static-stuff.localAddress}" = [ "static_stuff" ];
# "${outer_config.containers.jellyfin.localAddress}" = [ "jellyfin" ];
# };
};
};
}

View File

@@ -0,0 +1,7 @@
{ ... }: {
vacu.proxiedServices.habitat = {
domain = "habitat.pwrhs.win";
ipAddress = "10.78.79.114";
port = 8123;
};
}

View File

@@ -0,0 +1,98 @@
{
lib,
domains,
proxied,
...
}:
let
enableKeylog = false;
cleanName = name: lib.replaceStrings ["-" " "] [ "_" "_" ] name;
aclName = config: "host_" + (cleanName config.name);
backendName = config: "backend_" + (cleanName config.name);
concatMap = sep: f: list: lib.concatStringsSep sep (map f list);
mapLines = f: list: concatMap "\n" f list;
certs = concatMap " " (d: "crt /certs/${d}/full.pem") domains;
in
''
${lib.optionalString enableKeylog ''
# ssl keylogging
global
tune.ssl.keylog on
lua-load ${./sslkeylog.lua}
''}
global
close-spread-time 1s
hard-stop-after 3s
description "triple-dezert frontproxy"
no insecure-fork-wanted
log stdout format short daemon
numa-cpu-mapping
tune.listener.default-shards by-thread
tune.ssl.lifetime 24h
zero-warning
log 127.0.0.1 syslog debug
defaults
# https://world.hey.com/goekesmi/haproxy-chrome-tcp-preconnect-and-error-408-a-post-preserved-from-the-past-2497d1f7
timeout server 30s
timeout client 10s
timeout connect 10s
option http-ignore-probes
timeout tunnel 1h
log global
mode http
option httplog
frontend main
bind :80
bind :443 ssl ${certs}
mode http
acl has_sni ssl_fc_sni -m found
acl has_host_hdr req.fhdr(host) -m found
http-request set-var(req.host) req.fhdr(host),host_only
# Check whether the client is attempting domain fronting.
acl ssl_sni_http_host_match ssl_fc_sni,strcmp(req.host) eq 0
${mapLines (c:
'' acl ${aclName c} var(req.host) -m str "${c.domain}"''
) proxied}
http-after-response set-header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" if { ssl_fc }
http-request deny status 400 if !{ req.fhdr_cnt(host) eq 1 }
http-request deny status 421 if has_sni has_host_hdr !ssl_sni_http_host_match
http-request return lf-string "%ci\n" content-type text/plain if host_shelvacu { path /ip }
http-request redirect scheme https code 301 if !{ ssl_fc }
# garunteed ssl-only from here on
${mapLines (d:
'' http-request redirect location "https://${d}%[capture.req.uri]" code 301 if { var(req.host) -m str "www.${d}" }''
) domains}
http-request return string "Shelvacu is awesome" content-type text/plain if { path / } { var(req.host) -m str "shelvacu.com" }
http-request return string "Jean-luc is awesome" content-type text/plain if { path / } { var(req.host) -m str "jean-luc.org" }
${mapLines (c:
'' http-request allow if ${aclName c}''
) proxied}
http-request return status 404 string "not found" content-type text/plain
${mapLines (c:
'' use_backend ${backendName c} if ${aclName c}''
) proxied}
${concatMap "\n\n" (c:
''
backend ${backendName c}
mode http
${lib.optionalString c.forwardFor "option forwardfor"}
server main ${c.name}:${c.port} check maxconn ${c.maxConnections} ${if c.useSSL then "ssl verify none ssl-reuse" else "proto h1"}
''
) proxied}
''

View File

@@ -7,6 +7,13 @@ in
mode = "0755";
};
vacu.proxiedServices.${name} = {
domain = "jf.finaltask.xyz";
fromContainer = name;
port = 8096;
maxConnections = 100;
};
containers.${name} = {
privateNetwork = true;
hostAddress = "192.168.100.22";

View File

@@ -1,8 +1,6 @@
{
config,
pkgs,
inputs,
lib,
...
}:
let
@@ -15,6 +13,11 @@ let
in
{
vacu.databases.${name}.authByIp = contain.localAddress;
vacu.proxiedServices.${name} = {
domain = "stats.jean-luc.org";
fromContainer = name;
port = 80;
};
networking.firewall.extraCommands = ''
iptables -t filter -I nixos-fw -i ve-${name} -p tcp -m tcp --dport 5432 -j nixos-fw-accept

View File

@@ -1,21 +1,23 @@
{
config,
pkgs,
inputs,
lib,
...
}:
let
webListenPort = 8443;
in
{
networking.firewall.allowedTCPPorts = [ 636 ];
services.postgresql = {
ensureUsers = [
{
name = "kanidm";
ensureDBOwnership = true;
}
];
ensureDatabases = [ "kanidm" ];
vacu.databases.kanidm = {
authByUser = true;
};
vacu.proxiedServices.kanidm = {
domain = "id.shelvacu.com";
forwardFor = true;
useSSL = true;
port = webListenPort;
};
environment.systemPackages = [ config.services.kanidm.package ]; # adds the binary to the PATH
@@ -43,7 +45,7 @@
origin = "https://id.shelvacu.com";
# db_path = "/trip/sqlites/kani/kani.sqlite";
db_fs_type = "zfs";
bindaddress = "127.4.20.165:8443";
bindaddress = "127.4.20.165:${webListenPort}";
ldapbindaddress = "[::]:636";
trust_x_forward_for = true;
tls_chain = tls_dir + "/fullchain.pem";

View File

@@ -1,16 +1,21 @@
{
config,
pkgs,
inputs,
lib,
...
}:
let
contain = config.containers.keycloak;
settings = contain.config.services.keycloak.settings;
in
{
vacu.databases.keycloak.authByIp = contain.localAddress;
vacu.proxiedServices.keycloak = {
domain = settings.hostname;
port = settings.http-port;
forwardFor = true;
fromContainer = "keycloak";
};
networking.firewall.extraCommands = ''
iptables -t filter -I nixos-fw -i ve-keycloak -p tcp -m tcp --dport 5432 -j nixos-fw-accept
'';
@@ -28,13 +33,8 @@ in
restartIfChanged = true;
config =
let
outer_config = config;
in
{
config,
pkgs,
lib,
...
}:
{

43
triple-dezert/llm.nix Normal file
View File

@@ -0,0 +1,43 @@
{
...
}:
{
systemd.tmpfiles.settings.whatever."/trip/llm-models".d = {
mode = "0744";
};
containers.llm = {
privateNetwork = true;
hostAddress = "192.168.100.26";
localAddress = "192.168.100.27";
autoStart = true;
ephemeral = false;
restartIfChanged = true;
bindMounts."/models" = {
hostPath = "/trip/llm-models";
isReadOnly = false;
};
config =
{ config, ... }:
{
system.stateVersion = "24.05";
networking.firewall.enable = false;
services.open-webui = {
enable = true;
port = 8080;
environment.OLLAMA_API_BASE_URL = "http://${config.services.ollama.listenAddress}";
};
services.ollama = {
enable = true;
listenAddress = "127.0.0.1:11434";
models = "/models";
sandbox = true;
writablePaths = "/models";
acceleration = false;
};
};
};
}

View File

@@ -4,6 +4,11 @@
# nix copy --to 'file:///trip/nix-binary-cache?parallel-compression=true&secret-key=/root/cache-priv-key.pem&want-mass-query=true&write-nar-listing=true' .#nixosConfigurations."compute-deck".config.system.build.toplevel
{ config, lib, ... }:
{
vacu.proxiedServices.nix-cache = {
domain = "nixcache.shelvacu.com";
fromContainer = "nix-cache-nginx";
port = 80;
};
containers.nix-cache-nginx = {
privateNetwork = true;
hostAddress = "192.168.100.12";
@@ -19,21 +24,15 @@
config =
let
outer_config = config;
container = config.containers.nix-cache-nginx;
in
{
config,
pkgs,
lib,
...
}:
{
system.stateVersion = "23.11";
networking.firewall.enable = false;
services.nginx.enable = true;
services.nginx.virtualHosts.binary-cache = {
root = "/www/";
listenAddresses = [ outer_config.containers.nix-cache-nginx.localAddress ];
listenAddresses = [ container.localAddress ];
default = true;
};
};

View File

@@ -0,0 +1,56 @@
{ lib, config, ... }:
let
inherit (lib) mkOption types;
outerConfig = config;
ip4Address = types.addCheck
(types.strMatching ''\\d{1,3}.\d{1,3}.\d{1,3}.d{1,3}'')
(s:
lib.all (p: (lib.toInt p) < 255) (lib.stringSplit "." s)
)
;
# Note: This accepts plenty of strings that aren't valid ipv6 addresses, this is just to catch when you accidentally put an ipv4 or something else in
ip6Address = types.strMatching ''([a-fA-F0-9]{4}::?){1,7}[a-fA-F0-9]{4}'';
ipAddress = types.either ip4Address ip6Address;
in
{
options.vacu.proxiedServices = {
services = mkOption {
default = {};
type = types.attrsOf (types.submodule ({name, config, ...}: {
options = {
enable = mkOption { type = types.bool; default = false; };
name = mkOption {
default = name;
type = types.str;
};
fromContainer = mkOption {
default = null;
type = types.nullOr types.str;
};
port = mkOption { type = types.port; };
ipAddress = mkOption {
type = ipAddress;
};
domain = mkOption { type = types.str; };
forwardFor = mkOption { type = types.bool; default = false; };
maxConnections = mkOption { type = types.int; default = 500; };
useSSL = mkOption { type = types.bool; default = false; };
};
config = lib.mkMerge [
(lib.mkIf (config.fromContainer != null) {
ipAddress = outerConfig.containers.${config.fromContainer}.localAddress;
})
];
}));
};
};
}

View File

@@ -1,14 +1,13 @@
{
config,
pkgs,
inputs,
lib,
...
}:
let
contain = config.containers.keycloak;
in
{
vacu.proxiedServices.static-stuff = {
domain = "tulpaudcast.jean-luc.org";
fromContainer = "static-stuff";
port = 80;
};
systemd.tmpfiles.settings.asdf."/trip/static-stuff".d = {
mode = "0744";
};
@@ -27,7 +26,6 @@ in
};
config =
{ pkgs, ... }:
{
system.stateVersion = "23.11";
networking.firewall.enable = false;

View File

@@ -5,6 +5,14 @@
authByIp = config.containers.vacustore.localAddress;
};
vacu.proxiedServices.vacustore = {
domain = "vacu.store";
fromContainer = "vacustore";
port = 80;
forwardFor = true;
maxConnections = 100;
};
networking.firewall.extraCommands = ''
iptables -t filter -I nixos-fw -i ve-vacustore -p tcp -m tcp --dport 5432 -j nixos-fw-accept
'';