unified certificates

This commit is contained in:
catvayor 2024-08-21 12:20:36 +02:00
parent ddcc0baf1b
commit 918172f777
Signed by: lbailly
GPG key ID: CE3E645251AC63F3
5 changed files with 293 additions and 258 deletions

229
domain-proxies-module.nix Normal file
View file

@ -0,0 +1,229 @@
{ lib, config, ... }:
with lib;
let
vm-module = {
options = {
ip = mkOption { type = types.str; };
ssh = mkOption {
type = types.nullOr types.ints.unsigned;
default = null;
};
aliases = mkOption {
type = types.listOf types.str;
default = [ ];
};
port-forward = mkOption {
type = types.listOf types.ints.unsigned;
default = [ ];
};
};
};
hypervisor-module =
{ config, name, ... }:
{
options = {
ip = mkOption { type = types.str; };
host = mkOption { type = types.str; };
vms = mkOption { type = types.attrsOf (types.submodule vm-module); };
domain-list = mkOption {
type = types.listOf types.str;
internal = true;
readOnly = true;
};
ports = mkOption {
type = types.listOf types.ints.unsigned;
internal = true;
readOnly = true;
};
redirects = mkOption {
type = types.unspecified;
internal = true;
readOnly = true;
};
};
config = rec {
domain-list = flatten (
mapAttrsToList (main: vm: [
main
vm.aliases
]) config.vms
);
ports = flatten (
mapAttrsToList (_: vm: vm.port-forward ++ optional (!isNull vm.ssh) vm.ssh) config.vms
);
redirects = {
stream = flatten (
mapAttrsToList (
_: vm:
optional (!isNull vm.ssh) {
input = vm.ssh;
out = 22;
ip = vm.ip;
}
++ map (port: {
input = port;
out = port;
ip = vm.ip;
}) vm.port-forward
) config.vms
);
http = mapAttrs (_: vm: { inherit (vm) ip aliases; }) config.vms;
domain-list = domain-list;
};
};
};
entry-module =
{ config, name, ... }:
{
options = {
host = mkOption { type = types.str; };
hypervisors = mkOption { type = types.attrsOf (types.submodule hypervisor-module); };
redirects = mkOption {
type = types.unspecified;
internal = true;
readOnly = true;
};
hosts-redirects = mkOption {
type = types.unspecified;
internal = true;
readOnly = true;
};
};
config = rec {
redirects = {
stream = flatten (
mapAttrsToList (
_: hyp:
map (port: {
input = port;
out = port;
ip = hyp.ip;
}) hyp.ports
) config.hypervisors
);
http = mapAttrs (_: hyp: {
ip = hyp.ip;
aliases = hyp.domain-list;
}) config.hypervisors;
domain-list = flatten (
mapAttrsToList (fqdn: hyp: [ fqdn ] ++ hyp.redirects.domain-list) config.hypervisors
);
};
hosts-redirects =
mergeAttrs
(listToAttrs (
mapAttrsToList (main: hyp: {
name = hyp.host;
value = {
fqdn = main;
inherit (hyp.redirects) stream http domain-list;
};
}) config.hypervisors
))
{
${config.host} = {
fqdn = name;
inherit (redirects) stream http domain-list;
};
};
};
};
cfg = config.kat-proxies;
hosts-redirects = zipAttrsWith (_: vals: mergeAttrsList vals) (
mapAttrsToList (_: entry: entry.hosts-redirects) cfg.entries
);
hostname = config.networking.hostName;
redirects = hosts-redirects.${hostname};
in
{
options.kat-proxies = {
enable = mkEnableOption "nginx configuration of proxies";
entries = mkOption { type = types.attrsOf (types.submodule entry-module); };
internal-webroot = mkOption { type = types.package; };
};
config = mkIf cfg.enable {
security.acme.certs.${redirects.fqdn}.extraDomainNames = redirects.domain-list;
networking.firewall.allowedTCPPorts = [
80
443
] ++ map ({ input, ... }: input) redirects.stream;
services.nginx = {
enable = true;
virtualHosts =
mapAttrs (
_:
{ aliases, ip }:
{
useACMEHost = redirects.fqdn;
forceSSL = true;
acmeFallbackHost = ip;
acmeFallbackRecommendedProxySettings = true;
serverAliases = aliases;
locations = {
"/.${hostname}" = {
extraConfig = ''
internal;
error_page 404 =418 /.${hostname}/error/418.html;
'';
root = cfg.internal-webroot;
};
"/" = {
recommendedProxySettings = true;
proxyPass = "https://${ip}/";
extraConfig = ''
proxy_set_header Connection ''';
proxy_http_version 1.1;
chunked_transfer_encoding off;
proxy_buffering off;
proxy_cache off;
error_page 502 =599 "/.${hostname}/error/599.html";
'';
};
};
}
) redirects.http
// {
${redirects.fqdn} = {
default = true;
enableACME = true;
addSSL = true;
locations = {
"/.${hostname}" = {
extraConfig = ''
internal;
error_page 404 =418 /.${hostname}/error/418.html;
'';
root = cfg.internal-webroot;
};
"/" = {
extraConfig = ''
return 418;
error_page 418 =418 /.${hostname}/error/418.html;
'';
};
};
};
};
streamConfig = concatStringsSep "\n" (
map (
{
input,
ip,
out,
}:
''
server {
listen ${toString input};
proxy_pass ${ip}:${toString out};
}
''
) redirects.stream
);
};
};
}

46
domain-proxies.nix Normal file
View file

@ -0,0 +1,46 @@
{
kat-proxies.entries = {
"watcher.katvayor.net" = {
host = "kat-watcher";
hypervisors."manah.katvayor.net" = {
host = "kat-manah";
ip = "100.102.49.84";
vms = {
"degette.katvayor.net" = {
ssh = 22000;
ip = "192.168.122.2";
aliases = [ ];
};
"betamail.katvayor.net" = {
ssh = 22002;
ip = "192.168.122.3";
aliases = [ "catvayor.sh" ];
port-forward = [
25
465
993
];
};
"traque.katvayor.net" = {
ssh = 22001;
ip = "192.168.122.4";
aliases = [
"traque.dgnum.eu"
"test.traque.katvayor.net"
];
};
"son.katvayor.net" = {
ssh = null;
ip = "192.168.122.5";
aliases = [ ];
};
"orchid.katvayor.net" = {
ssh = 22042;
ip = "192.168.122.6";
aliases = [ ];
};
};
};
};
};
}

View file

@ -33,6 +33,8 @@ in
"${sources.home-manager}/nixos"
"${sources.agenix}/modules/age.nix"
"${sources.disko}/module.nix"
./domain-proxies-module.nix
./domain-proxies.nix
];
options.system.build.anywhere = lib.mkOption {
type = lib.types.package;

View file

@ -59,150 +59,16 @@
acceptTerms = true;
defaults.email = "root@katvayor.net";
};
services.nginx =
let
vhosts = {
"degette.katvayor.net" = {
vm = "192.168.122.2";
sshport = 22000;
};
"betamail.katvayor.net" = {
vm = "192.168.122.3";
sshport = 22002;
};
"catvayor.sh" = {
vm = "192.168.122.3";
sshport = null;
};
"traque.dgnum.eu" = {
vm = "192.168.122.4";
sshport = null;
};
"traque.katvayor.net" = {
vm = "192.168.122.4";
sshport = 22001;
};
"test.traque.katvayor.net" = {
vm = "192.168.122.4";
sshport = null;
};
"son.katvayor.net" = {
vm = "192.168.122.5";
sshport = null;
};
"orchid.katvayor.net" = {
vm = "192.168.122.6";
sshport = 22042;
};
};
in
{
kat-proxies = {
enable = true;
virtualHosts =
let
manah-webroot = pkgs.runCommand "manah" { } ''
internal-webroot = pkgs.runCommand "manah" { } ''
mkdir -p $out/.kat-manah/
ln -nsf ${./error} $out/.kat-manah/error
'';
in
{
"manah.katvayor.net" = {
default = true;
enableACME = true;
addSSL = true;
locations = {
"/.kat-manah" = {
extraConfig = ''
internal;
error_page 404 =418 /.kat-manah/error/418.html;
'';
root = manah-webroot;
};
"/" = {
extraConfig = ''
return 418;
error_page 418 =418 /.kat-manah/error/418.html;
'';
};
};
};
}
// builtins.mapAttrs (
_:
{ vm, ... }:
{
enableACME = true;
addSSL = true;
acmeFallbackHost = vm;
acmeFallbackRecommendedProxySettings = true;
locations = {
"/.kat-manah" = {
extraConfig = ''
internal;
error_page 404 =418 /.kat-manah/error/418.html;
'';
root = manah-webroot;
};
"/" = {
recommendedProxySettings = true;
proxyPass = "https://${vm}/";
extraConfig = ''
proxy_set_header Connection ''';
proxy_http_version 1.1;
chunked_transfer_encoding off;
proxy_buffering off;
proxy_cache off;
error_page 502 =599 "/.kat-manah/error/599.html";
'';
};
};
}
) vhosts;
streamConfig =
builtins.concatStringsSep "\n" (
lib.mapAttrsToList (
vhost:
{ vm, sshport }:
lib.optionalString (!isNull sshport) ''
server {
listen ${toString sshport};
proxy_pass ${vm}:22;
}
''
) vhosts
)
+ ''
server {
listen 993;
proxy_pass 192.168.122.3:993;
}
server {
listen 465;
proxy_pass 192.168.122.3:465;
}
server {
listen 25;
proxy_pass 192.168.122.3:25;
}
'';
};
networking.firewall = {
allowedTCPPorts = [
22
25
53
80
443
465
993
];
allowedTCPPortRanges = [
{
from = 22000;
to = 22100;
}
];
allowedTCPPorts = [ 22 ];
allowedUDPPorts = [ 67 ];
};
system.stateVersion = "23.11";

View file

@ -58,105 +58,12 @@
acceptTerms = true;
defaults.email = "root@katvayor.net";
};
services.nginx =
let
kat-r86s = "100.102.49.84";
vhosts = {
"manah.katvayor.net" = null;
"degette.katvayor.net" = 22000;
"traque.katvayor.net" = 22001;
"traque.dgnum.eu" = null;
"betamail.katvayor.net" = 22002;
"catvayor.sh" = null;
"test.traque.katvayor.net" = null;
"son.katvayor.net" = null;
"orchid.katvayor.net" = 22042;
};
in
{
kat-proxies = {
enable = true;
virtualHosts =
let
watcher-webroot = pkgs.runCommand "watcher" { } ''
internal-webroot = pkgs.runCommand "watcher" { } ''
mkdir -p $out/.kat-watcher/
ln -nsf ${./error} $out/.kat-watcher/error
'';
in
{
"watcher.katvayor.net" = {
default = true;
enableACME = true;
addSSL = true;
locations = {
"/.kat-watcher" = {
extraConfig = ''
internal;
error_page 404 =418 /.kat-watcher/error/418.html;
'';
root = watcher-webroot;
};
"/" = {
extraConfig = ''
return 418;
error_page 418 =418 /.kat-watcher/error/418.html;
'';
};
};
};
}
// builtins.mapAttrs (_: _: {
enableACME = true;
forceSSL = true;
acmeFallbackHost = kat-r86s;
acmeFallbackRecommendedProxySettings = true;
locations = {
"/.kat-watcher" = {
extraConfig = ''
internal;
error_page 404 =418 /.kat-watcher/error/418.html;
'';
root = watcher-webroot;
};
"/" = {
recommendedProxySettings = true;
proxyPass = "https://${kat-r86s}/";
extraConfig = ''
proxy_set_header Connection ''';
proxy_http_version 1.1;
chunked_transfer_encoding off;
proxy_buffering off;
proxy_cache off;
error_page 502 =599 "/.kat-watcher/error/599.html";
'';
};
};
}) vhosts;
streamConfig =
builtins.concatStringsSep "\n" (
lib.mapAttrsToList (
vhost: sshport:
lib.optionalString (!isNull sshport) ''
server {
listen ${toString sshport};
proxy_pass ${kat-r86s}:${toString sshport};
}
''
) vhosts
)
+ ''
server {
listen 993;
proxy_pass ${kat-r86s}:993;
}
server {
listen 465;
proxy_pass ${kat-r86s}:465;
}
server {
listen 25;
proxy_pass ${kat-r86s}:25;
}
'';
};
services.dbus.packages = with pkgs; [ dconf ];
@ -182,22 +89,7 @@
services.netbird.enable = true;
networking = {
nftables.enable = true;
firewall = {
allowedTCPPorts = [
22
25
80
443
993
465
];
allowedTCPPortRanges = [
{
from = 22000;
to = 22100;
}
];
};
firewall.allowedTCPPorts = [ 22 ];
};
system.stateVersion = "23.11";