wip
This commit is contained in:
@@ -17,6 +17,7 @@
|
||||
./emily.nix
|
||||
./jellyfin.nix
|
||||
./yt-archiver.nix
|
||||
./habitat-fwd.nix
|
||||
];
|
||||
|
||||
boot.loader.systemd-boot.enable = true;
|
||||
|
@@ -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" ];
|
||||
# };
|
||||
};
|
||||
};
|
||||
}
|
||||
|
7
triple-dezert/habitat-fwd.nix
Normal file
7
triple-dezert/habitat-fwd.nix
Normal file
@@ -0,0 +1,7 @@
|
||||
{ ... }: {
|
||||
vacu.proxiedServices.habitat = {
|
||||
domain = "habitat.pwrhs.win";
|
||||
ipAddress = "10.78.79.114";
|
||||
port = 8123;
|
||||
};
|
||||
}
|
98
triple-dezert/haproxy-config.nix
Normal file
98
triple-dezert/haproxy-config.nix
Normal 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}
|
||||
''
|
@@ -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";
|
||||
|
@@ -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
|
||||
|
@@ -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";
|
||||
|
@@ -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
43
triple-dezert/llm.nix
Normal 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;
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
@@ -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;
|
||||
};
|
||||
};
|
||||
|
56
triple-dezert/proxied-services.nix
Normal file
56
triple-dezert/proxied-services.nix
Normal 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;
|
||||
})
|
||||
];
|
||||
}));
|
||||
};
|
||||
};
|
||||
}
|
@@ -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;
|
||||
|
@@ -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
|
||||
'';
|
||||
|
Reference in New Issue
Block a user