mirror of
https://github.com/Swarsel/.dotfiles.git
synced 2026-04-14 21:29:12 +02:00
feat[server]: add home proxy
This commit is contained in:
parent
75891c3103
commit
c1c7431891
84 changed files with 2961 additions and 1601 deletions
138
modules/nixos/server/adguardhome.nix
Normal file
138
modules/nixos/server/adguardhome.nix
Normal file
|
|
@ -0,0 +1,138 @@
|
|||
{ self, inputs, lib, config, globals, dns, confLib, ... }:
|
||||
let
|
||||
inherit (confLib.gen { name = "adguardhome"; port = 3000; }) serviceName servicePort serviceAddress serviceDomain proxyAddress4 proxyAddress6;
|
||||
inherit (confLib.static) isHome isProxied homeProxy homeProxyIf webProxy webProxyIf homeWebProxy dnsServer homeDnsServer homeServiceAddress nginxAccessRules;
|
||||
|
||||
homeServices = lib.attrNames (lib.filterAttrs (_: serviceCfg: serviceCfg.isHome) globals.services);
|
||||
homeDomains = map (name: globals.services.${name}.domain) homeServices;
|
||||
in
|
||||
{
|
||||
options = {
|
||||
swarselmodules.server.${serviceName} = lib.mkEnableOption "enable ${serviceName} on server";
|
||||
};
|
||||
config = lib.mkIf config.swarselmodules.server.${serviceName} {
|
||||
|
||||
|
||||
globals = {
|
||||
networks = {
|
||||
${webProxyIf}.hosts = lib.mkIf isProxied {
|
||||
${config.node.name}.firewallRuleForNode.${webProxy}.allowedTCPPorts = [ servicePort ];
|
||||
};
|
||||
${homeProxyIf}.hosts = lib.mkIf isHome {
|
||||
${config.node.name}.firewallRuleForNode.${homeProxy}.allowedTCPPorts = [ servicePort ];
|
||||
};
|
||||
};
|
||||
services.${serviceName} = {
|
||||
domain = serviceDomain;
|
||||
inherit proxyAddress4 proxyAddress6 isHome;
|
||||
};
|
||||
};
|
||||
|
||||
networking.firewall = {
|
||||
allowedTCPPorts = [ 53 ];
|
||||
allowedUDPPorts = [ 53 ];
|
||||
};
|
||||
|
||||
services.adguardhome = {
|
||||
enable = true;
|
||||
mutableSettings = false;
|
||||
host = "0.0.0.0";
|
||||
port = servicePort;
|
||||
settings = {
|
||||
dns = {
|
||||
bind_hosts = [
|
||||
globals.networks.home-lan.vlans.services.hosts.${homeDnsServer}.ipv4
|
||||
globals.networks.home-lan.vlans.services.hosts.${homeDnsServer}.ipv6
|
||||
];
|
||||
ratelimit = 300;
|
||||
upstream_dns = [
|
||||
"https://dns.cloudflare.com/dns-query"
|
||||
"https://dns.google/dns-query"
|
||||
"https://doh.mullvad.net/dns-query"
|
||||
];
|
||||
bootstrap_dns = [
|
||||
"1.1.1.1"
|
||||
"2606:4700:4700::1111"
|
||||
"8.8.8.8"
|
||||
"2001:4860:4860::8844"
|
||||
];
|
||||
dhcp.enabled = false;
|
||||
};
|
||||
filtering.rewrites = [
|
||||
]
|
||||
# Use the local mirror-proxy for some services (not necessary, just for speed)
|
||||
++
|
||||
map
|
||||
(domain: {
|
||||
inherit domain;
|
||||
# FIXME: change to homeWebProxy once that is setup
|
||||
answer = globals.networks.home-lan.vlans.services.hosts.${homeWebProxy}.ipv4;
|
||||
# answer = globals.hosts.${webProxy}.wanAddress4;
|
||||
})
|
||||
homeDomains;
|
||||
filters = [
|
||||
{
|
||||
name = "AdGuard DNS filter";
|
||||
url = "https://adguardteam.github.io/AdGuardSDNSFilter/Filters/filter.txt";
|
||||
enabled = true;
|
||||
}
|
||||
{
|
||||
name = "AdAway Default Blocklist";
|
||||
url = "https://adaway.org/hosts.txt";
|
||||
enabled = true;
|
||||
}
|
||||
{
|
||||
name = "OISD (Big)";
|
||||
url = "https://big.oisd.nl";
|
||||
enabled = true;
|
||||
}
|
||||
];
|
||||
};
|
||||
};
|
||||
|
||||
environment.persistence."/persist".directories = lib.mkIf config.swarselsystems.isImpermanence [
|
||||
{
|
||||
directory = "/var/lib/private/AdGuardHome";
|
||||
mode = "0700";
|
||||
}
|
||||
];
|
||||
|
||||
nodes =
|
||||
let
|
||||
genNginx = toAddress: extraConfig: {
|
||||
upstreams = {
|
||||
${serviceName} = {
|
||||
servers = {
|
||||
"${toAddress}:${builtins.toString servicePort}" = { };
|
||||
};
|
||||
};
|
||||
};
|
||||
virtualHosts = {
|
||||
"${serviceDomain}" = {
|
||||
useACMEHost = globals.domains.main;
|
||||
forceSSL = true;
|
||||
acmeRoot = null;
|
||||
oauth2 = {
|
||||
enable = true;
|
||||
allowedGroups = [ "adguardhome_access" ];
|
||||
};
|
||||
locations = {
|
||||
"/" = {
|
||||
proxyPass = "http://${serviceName}";
|
||||
proxyWebsockets = true;
|
||||
};
|
||||
};
|
||||
extraConfig = lib.mkIf (extraConfig != "") extraConfig;
|
||||
};
|
||||
};
|
||||
};
|
||||
in
|
||||
{
|
||||
${dnsServer}.swarselsystems.server.dns.${globals.services.${serviceName}.baseDomain}.subdomainRecords = {
|
||||
"${globals.services.${serviceName}.subDomain}" = dns.lib.combinators.host proxyAddress4 proxyAddress6;
|
||||
};
|
||||
${webProxy}.services.nginx = genNginx serviceAddress "";
|
||||
${homeWebProxy}.services.nginx = genNginx homeServiceAddress nginxAccessRules;
|
||||
};
|
||||
};
|
||||
}
|
||||
|
|
@ -14,6 +14,12 @@ in
|
|||
"${globals.services.${serviceName}.subDomain}" = dns.lib.combinators.host proxyAddress4 proxyAddress6;
|
||||
};
|
||||
|
||||
topology.self.services.${serviceName} = {
|
||||
name = lib.swarselsystems.toCapitalized serviceName;
|
||||
info = "https://${serviceDomain}";
|
||||
# attic does not have a logo
|
||||
};
|
||||
|
||||
globals = {
|
||||
networks = {
|
||||
${webProxyIf}.hosts = lib.mkIf isProxied {
|
||||
|
|
|
|||
16
modules/nixos/server/dns-home.nix
Normal file
16
modules/nixos/server/dns-home.nix
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
{ lib, config, globals, confLib, ... }:
|
||||
let
|
||||
inherit (confLib.gen { name = "dns-home"; }) serviceName homeProxy;
|
||||
in
|
||||
{
|
||||
options.swarselmodules.server.${serviceName} = lib.mkEnableOption "enable ${serviceName} on server";
|
||||
config = lib.mkIf (config.swarselmodules.server.${serviceName}) {
|
||||
|
||||
networking.hosts = {
|
||||
${globals.networks.home-lan.vlans.services.hosts.${homeProxy}.ipv4} = [ "server.${homeProxy}.${globals.domains.main}" ];
|
||||
${globals.networks.home-lan.vlans.services.hosts.${homeProxy}.ipv6} = [ "server.${homeProxy}.${globals.domains.main}" ];
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
{ lib, pkgs, config, globals, confLib, dns, nodes, ... }:
|
||||
{ self, lib, pkgs, config, globals, confLib, dns, nodes, ... }:
|
||||
let
|
||||
inherit (confLib.gen { name = "firezone"; dir = "/var/lib/private/firezone"; }) serviceName serviceDir serviceAddress serviceDomain proxyAddress4 proxyAddress6 isHome isProxied homeProxy webProxy homeProxyIf webProxyIf idmServer dnsServer;
|
||||
inherit (config.swarselsystems) sopsFile;
|
||||
|
|
@ -60,6 +60,12 @@ in
|
|||
};
|
||||
};
|
||||
|
||||
topology.self.services.${serviceName} = {
|
||||
name = lib.swarselsystems.toCapitalized serviceName;
|
||||
info = "https://${serviceDomain}";
|
||||
icon = "${self}/files/topology-images/${serviceName}.png";
|
||||
};
|
||||
|
||||
sops = {
|
||||
secrets = {
|
||||
kanidm-firezone-client = { inherit sopsFile; mode = "0400"; };
|
||||
|
|
@ -314,12 +320,17 @@ in
|
|||
};
|
||||
services.firezone.gateway = {
|
||||
enable = true;
|
||||
logLevel = "trace";
|
||||
# logLevel = "trace";
|
||||
inherit (nodeCfg.node) name;
|
||||
apiUrl = "wss://${globals.services.firezone.domain}/api/";
|
||||
tokenFile = nodeCfg.sops.secrets.firezone-gateway-token.path;
|
||||
package = nodePkgs.stable25_05.firezone-gateway; # newer versions of firezone-gateway are not compatible with server package
|
||||
};
|
||||
|
||||
topology.self.services."${serviceName}-gateway" = {
|
||||
name = lib.swarselsystems.toCapitalized "${serviceName} Gateway";
|
||||
icon = "${self}/files/topology-images/${serviceName}.png";
|
||||
};
|
||||
};
|
||||
${idmServer} =
|
||||
let
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
# inspired by https://github.com/atropos112/nixos/blob/7fef652006a1c939f4caf9c8a0cb0892d9cdfe21/modules/garage.nix
|
||||
{ lib, pkgs, config, globals, dns, confLib, ... }:
|
||||
{ self, lib, pkgs, config, globals, dns, confLib, ... }:
|
||||
let
|
||||
inherit (confLib.gen {
|
||||
name = "garage";
|
||||
|
|
@ -81,6 +81,12 @@ in
|
|||
"*.${subDomain}-web" = dns.lib.combinators.host proxyAddress4 proxyAddress6;
|
||||
};
|
||||
|
||||
topology.self.services.${serviceName} = {
|
||||
name = lib.swarselsystems.toCapitalized serviceName;
|
||||
info = "https://${serviceDomain}";
|
||||
icon = "${self}/files/topology-images/${serviceName}.png";
|
||||
};
|
||||
|
||||
sops = {
|
||||
secrets.garage-admin-token = { inherit sopsFile; };
|
||||
secrets.garage-rpc-secret = { inherit sopsFile; };
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
{ lib, pkgs, config, globals, dns, confLib, ... }:
|
||||
{ self, lib, pkgs, config, globals, dns, confLib, ... }:
|
||||
let
|
||||
inherit (confLib.gen { name = "homebox"; port = 7745; }) servicePort serviceName serviceDomain serviceAddress proxyAddress4 proxyAddress6 isHome isProxied homeProxy webProxy dnsServer homeProxyIf webProxyIf;
|
||||
in
|
||||
|
|
@ -10,7 +10,11 @@ in
|
|||
"${globals.services.${serviceName}.subDomain}" = dns.lib.combinators.host proxyAddress4 proxyAddress6;
|
||||
};
|
||||
|
||||
topology.self.services.${serviceName}.info = "https://${serviceDomain}";
|
||||
topology.self.services.${serviceName} = {
|
||||
name = "Homebox";
|
||||
info = "https://${serviceDomain}";
|
||||
icon = "${self}/files/topology-images/${serviceName}.png";
|
||||
};
|
||||
|
||||
globals = {
|
||||
networks = {
|
||||
|
|
|
|||
|
|
@ -13,6 +13,8 @@ in
|
|||
"${globals.services.${serviceName}.subDomain}" = dns.lib.combinators.host proxyAddress4 proxyAddress6;
|
||||
};
|
||||
|
||||
topology.self.services.${serviceName}.info = "https://${serviceDomain}";
|
||||
|
||||
globals = {
|
||||
networks = {
|
||||
${webProxyIf}.hosts = lib.mkIf isProxied {
|
||||
|
|
|
|||
|
|
@ -228,6 +228,7 @@ in
|
|||
"radicale.access" = { };
|
||||
"slink.access" = { };
|
||||
"opkssh.access" = { };
|
||||
"adguardhome.access" = { };
|
||||
};
|
||||
|
||||
inherit (config.repo.secrets.local) persons;
|
||||
|
|
@ -370,6 +371,11 @@ in
|
|||
"email"
|
||||
"profile"
|
||||
];
|
||||
"adguardhome.access" = [
|
||||
"openid"
|
||||
"email"
|
||||
"profile"
|
||||
];
|
||||
};
|
||||
preferShortUsername = true;
|
||||
claimMaps.groups = {
|
||||
|
|
@ -380,6 +386,7 @@ in
|
|||
"firefly.access" = [ "firefly_access" ];
|
||||
"radicale.access" = [ "radicale_access" ];
|
||||
"slink.access" = [ "slink_access" ];
|
||||
"adguardhome.access" = [ "adguardhome_access" ];
|
||||
};
|
||||
};
|
||||
};
|
||||
|
|
|
|||
|
|
@ -62,7 +62,6 @@ in
|
|||
virtualHosts = {
|
||||
"${serviceDomain}" = {
|
||||
useACMEHost = globals.domains.main;
|
||||
|
||||
forceSSL = true;
|
||||
acmeRoot = null;
|
||||
locations = {
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
{ lib, config, globals, confLib, ... }:
|
||||
{ self, lib, config, globals, confLib, ... }:
|
||||
let
|
||||
inherit (confLib.gen { name = "kea"; dir = "/var/lib/private/kea"; }) serviceName serviceDir;
|
||||
inherit (confLib.gen { name = "kea"; dir = "/var/lib/private/kea"; }) serviceName serviceDir homeDnsServer;
|
||||
dhcpX = intX:
|
||||
let
|
||||
x = builtins.toString intX;
|
||||
|
|
@ -8,6 +8,7 @@ let
|
|||
{
|
||||
enable = true;
|
||||
settings = {
|
||||
reservations-out-of-pool = true;
|
||||
lease-database = {
|
||||
name = "/var/lib/kea/dhcp${x}.leases";
|
||||
persist = true;
|
||||
|
|
@ -24,37 +25,44 @@ let
|
|||
inherit (vlanCfg) id;
|
||||
interface = "me-${vlanName}";
|
||||
subnet = vlanCfg."cidrv${x}";
|
||||
rapid-commit = lib.mkIf (intX == 6) true;
|
||||
pools = [
|
||||
{
|
||||
pool = "${lib.net.cidr.host 20 vlanCfg."cidrv${x}"} - ${lib.net.cidr.host (-6) vlanCfg."cidrv${x}"}";
|
||||
}
|
||||
];
|
||||
pd-pools = lib.mkIf (intX == 6) [
|
||||
{
|
||||
prefix = builtins.replaceStrings [ "::" ] [ ":0:0:100::" ] (lib.head (lib.splitString "/" vlanCfg.cidrv6));
|
||||
prefix-len = 56;
|
||||
delegated-len = 64;
|
||||
}
|
||||
];
|
||||
option-data =
|
||||
lib.optional (intX == 4)
|
||||
{
|
||||
name = "routers";
|
||||
data = vlanCfg.hosts.hintbooth."ipv${x}"; # FIXME: how to advertise v6 address also?
|
||||
data = vlanCfg.hosts.hintbooth."ipv${x}";
|
||||
}
|
||||
# Advertise DNS server for VLANS that have internet access
|
||||
++
|
||||
lib.optional
|
||||
(lib.elem vlanName globals.general.internetVLANs)
|
||||
{
|
||||
name = if (intX == 4) then "domain-name-servers" else "dns-servers";
|
||||
data = globals.networks.home-lan.vlans.services.hosts.${homeDnsServer}."ipv${x}";
|
||||
};
|
||||
# Advertise DNS server for VLANS that have internet access
|
||||
# ++
|
||||
# lib.optional
|
||||
# (lib.elem vlanName [
|
||||
# "services"
|
||||
# "home"
|
||||
# "devices"
|
||||
# "guests"
|
||||
# ])
|
||||
# {
|
||||
# name = "domain-name-servers";
|
||||
# data = globals.networks.home-lan.vlans.services.hosts.hintbooth-adguardhome.ipv4;
|
||||
# };
|
||||
reservations = lib.concatLists (
|
||||
lib.forEach (builtins.attrValues vlanCfg.hosts) (
|
||||
hostCfg:
|
||||
lib.optional (hostCfg.mac != null) {
|
||||
hw-address = hostCfg.mac;
|
||||
hw-address = lib.mkIf (intX == 4) hostCfg.mac;
|
||||
duid = lib.mkIf (intX == 6) "00:03:00:01:${hostCfg.mac}"; # 00:03 = duid type 3; 00:01 = ethernet
|
||||
ip-address = lib.mkIf (intX == 4) hostCfg."ipv${x}";
|
||||
ip-addresses = lib.mkIf (intX == 6) [ hostCfg."ipv${x}" ];
|
||||
prefixes = lib.mkIf (intX == 6) [
|
||||
"${builtins.replaceStrings ["::"] [":0:0:${builtins.toString (256 + hostCfg.id)}::"] (lib.head (lib.splitString "/" vlanCfg.cidrv6))}/64"
|
||||
];
|
||||
}
|
||||
)
|
||||
);
|
||||
|
|
@ -73,6 +81,14 @@ in
|
|||
{ directory = serviceDir; mode = "0700"; }
|
||||
];
|
||||
|
||||
topology = {
|
||||
extractors.kea.enable = false;
|
||||
self.services.${serviceName} = {
|
||||
name = lib.swarselsystems.toCapitalized serviceName;
|
||||
icon = "${self}/files/topology-images/${serviceName}.png";
|
||||
};
|
||||
};
|
||||
|
||||
services.kea = {
|
||||
dhcp4 = dhcpX 4;
|
||||
dhcp6 = dhcpX 6;
|
||||
|
|
|
|||
|
|
@ -13,6 +13,10 @@ in
|
|||
options.swarselmodules.server.${serviceName} = lib.mkEnableOption "enable ${serviceName} on server";
|
||||
config = lib.mkIf config.swarselmodules.server.${serviceName} {
|
||||
|
||||
swarselmodules.server = {
|
||||
podman = true;
|
||||
postgresql = true;
|
||||
};
|
||||
|
||||
nodes.${dnsServer}.swarselsystems.server.dns.${globals.services.${serviceName}.baseDomain}.subdomainRecords = {
|
||||
"${globals.services.${serviceName}.subDomain}" = dns.lib.combinators.host proxyAddress4 proxyAddress6;
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
{ lib, config, globals, dns, confLib, ... }:
|
||||
{ self, lib, config, globals, dns, confLib, ... }:
|
||||
let
|
||||
inherit (config.swarselsystems) sopsFile;
|
||||
inherit (confLib.gen { name = "mailserver"; dir = "/var/lib/dovecot"; user = "virtualMail"; group = "virtualMail"; port = 443; }) serviceName serviceDir servicePort serviceUser serviceGroup serviceAddress serviceDomain proxyAddress4 proxyAddress6 isHome webProxy dnsServer;
|
||||
|
|
@ -32,6 +32,16 @@ in
|
|||
};
|
||||
};
|
||||
|
||||
topology.self.services = lib.listToAttrs (map
|
||||
(service:
|
||||
lib.nameValuePair "${service}" {
|
||||
name = lib.swarselsystems.toCapitalized service;
|
||||
info = lib.mkIf (service == "postfix" || service == "roundcube") (if service == "postfix" then "https://${serviceDomain}" else "https://${roundcubeDomain}");
|
||||
icon = "${self}/files/topology-images/${service}.png";
|
||||
}
|
||||
)
|
||||
[ "postfix" "dovecot" "rspamd" "clamav" "roundcube" ]);
|
||||
|
||||
sops.secrets = {
|
||||
user1-hashed-pw = { inherit sopsFile; owner = serviceUser; };
|
||||
user2-hashed-pw = { inherit sopsFile; owner = serviceUser; };
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
{ lib, config, pkgs, globals, dns, confLib, ... }:
|
||||
{ self, lib, config, pkgs, globals, dns, confLib, ... }:
|
||||
let
|
||||
inherit (confLib.gen { name = "minecraft"; port = 25565; dir = "/opt/minecraft"; proxy = config.node.name; }) serviceName servicePort serviceDir serviceDomain proxyAddress4 proxyAddress6 isHome dnsServer;
|
||||
inherit (config.swarselsystems) mainUser;
|
||||
|
|
@ -12,7 +12,11 @@ in
|
|||
"${globals.services.${serviceName}.subDomain}" = dns.lib.combinators.host proxyAddress4 proxyAddress6;
|
||||
};
|
||||
|
||||
topology.self.services.${serviceName}.info = "https://${serviceDomain}";
|
||||
topology.self.services.${serviceName} = {
|
||||
name = "Minecraft";
|
||||
info = "https://${serviceDomain}";
|
||||
icon = "${self}/files/topology-images/${serviceName}.png";
|
||||
};
|
||||
|
||||
globals.services.${serviceName} = {
|
||||
domain = serviceDomain;
|
||||
|
|
|
|||
|
|
@ -16,6 +16,8 @@ in
|
|||
mpv
|
||||
];
|
||||
|
||||
topology.self.services.${serviceName}.info = "https://${serviceDomain}";
|
||||
|
||||
users = {
|
||||
groups = {
|
||||
${serviceGroup} = {
|
||||
|
|
|
|||
|
|
@ -40,6 +40,7 @@ in
|
|||
nnf-drop.enable = true;
|
||||
nnf-loopback.enable = true;
|
||||
nnf-ssh.enable = true;
|
||||
nnf-dhcpv6.enable = true;
|
||||
};
|
||||
|
||||
rules.untrusted-to-local = {
|
||||
|
|
|
|||
|
|
@ -67,7 +67,7 @@ in
|
|||
};
|
||||
};
|
||||
config = {
|
||||
extraConfig = lib.mkIf topmod.config.defaultStapling (lib.mkAfter ''
|
||||
extraConfig = lib.mkIf topmod.config.defaultStapling (lib.mkBefore ''
|
||||
ssl_stapling on;
|
||||
ssl_stapling_verify on;
|
||||
resolver 1.1.1.1 8.8.8.8 valid=300s;
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
{ lib, config, globals, dns, confLib, ... }:
|
||||
{ self, lib, config, globals, dns, confLib, ... }:
|
||||
let
|
||||
inherit (confLib.gen { name = "nsd"; port = 53; }) serviceName servicePort proxyAddress4 proxyAddress6;
|
||||
inherit (config.swarselsystems) sopsFile;
|
||||
|
|
@ -34,6 +34,11 @@ in
|
|||
};
|
||||
};
|
||||
|
||||
topology.self.services.${serviceName} = {
|
||||
name = lib.toUpper serviceName;
|
||||
icon = "${self}/files/topology-images/${serviceName}.png";
|
||||
};
|
||||
|
||||
services.nsd = {
|
||||
enable = true;
|
||||
keys = {
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@ with dns.lib.combinators; {
|
|||
SOA = {
|
||||
nameServer = "soa";
|
||||
adminEmail = "admin@${globals.domains.main}"; # this option is not parsed as domain (we cannot just write "admin")
|
||||
serial = 2025122401; # update this on changes for secondary dns
|
||||
serial = 2026010201; # update this on changes for secondary dns
|
||||
};
|
||||
|
||||
useOrigin = false;
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
{ lib, config, globals, dns, confLib, ... }:
|
||||
let
|
||||
inherit (confLib.gen { name = "oauth2-proxy"; port = 3004; }) servicePort serviceName serviceUser serviceGroup serviceDomain serviceAddress proxyAddress4 proxyAddress6 isHome isProxied homeProxy webProxy dnsServer homeProxyIf webProxyIf;
|
||||
inherit (confLib.gen { name = "oauth2-proxy"; port = 3004; }) servicePort serviceName serviceUser serviceGroup serviceDomain serviceAddress proxyAddress4 proxyAddress6;
|
||||
inherit (confLib.static) isHome isProxied homeProxy webProxy dnsServer homeProxyIf webProxyIf homeWebProxy oauthServer nginxAccessRules;
|
||||
|
||||
kanidmDomain = globals.services.kanidm.domain;
|
||||
mainDomain = globals.domains.main;
|
||||
|
|
@ -119,10 +120,6 @@ in
|
|||
};
|
||||
config = lib.mkIf config.swarselmodules.server.${serviceName} {
|
||||
|
||||
nodes.${dnsServer}.swarselsystems.server.dns.${globals.services.${serviceName}.baseDomain}.subdomainRecords = {
|
||||
"${globals.services.${serviceName}.subDomain}" = dns.lib.combinators.host proxyAddress4 proxyAddress6;
|
||||
};
|
||||
|
||||
sops = {
|
||||
secrets = {
|
||||
"oauth2-cookie-secret" = { inherit sopsFile; owner = serviceUser; group = serviceGroup; mode = "0440"; };
|
||||
|
|
@ -208,31 +205,41 @@ in
|
|||
};
|
||||
};
|
||||
|
||||
nodes.${webProxy}.services.nginx = {
|
||||
upstreams = {
|
||||
${serviceName} = {
|
||||
servers = {
|
||||
"${serviceAddress}:${builtins.toString servicePort}" = { };
|
||||
};
|
||||
};
|
||||
};
|
||||
virtualHosts = {
|
||||
"${serviceDomain}" = {
|
||||
useACMEHost = globals.domains.main;
|
||||
|
||||
forceSSL = true;
|
||||
acmeRoot = null;
|
||||
locations = {
|
||||
"/" = {
|
||||
proxyPass = "http://${serviceName}";
|
||||
nodes =
|
||||
let
|
||||
genNginx = toAddress: extraConfig: {
|
||||
upstreams = {
|
||||
${serviceName} = {
|
||||
servers = {
|
||||
"${toAddress}:${builtins.toString servicePort}" = { };
|
||||
};
|
||||
};
|
||||
};
|
||||
virtualHosts = {
|
||||
"${serviceDomain}" = {
|
||||
useACMEHost = globals.domains.main;
|
||||
|
||||
forceSSL = true;
|
||||
acmeRoot = null;
|
||||
locations = {
|
||||
"/" = {
|
||||
proxyPass = "http://${serviceName}";
|
||||
};
|
||||
};
|
||||
extraConfig = ''
|
||||
proxy_set_header X-Scheme $scheme;
|
||||
proxy_set_header X-Auth-Request-Redirect $scheme://$host$request_uri;
|
||||
'' + lib.optionalString (extraConfig != "") extraConfig;
|
||||
};
|
||||
};
|
||||
extraConfig = ''
|
||||
proxy_set_header X-Scheme $scheme;
|
||||
proxy_set_header X-Auth-Request-Redirect $scheme://$host$request_uri;
|
||||
'';
|
||||
};
|
||||
in
|
||||
{
|
||||
${dnsServer}.swarselsystems.server.dns.${globals.services.${serviceName}.baseDomain}.subdomainRecords = {
|
||||
"${globals.services.${serviceName}.subDomain}" = dns.lib.combinators.host proxyAddress4 proxyAddress6;
|
||||
};
|
||||
${webProxy}.services.nginx = genNginx serviceAddress "";
|
||||
${homeWebProxy}.services.nginx = genNginx globals.hosts.${oauthServer}.wanAddress4 nginxAccessRules;
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -11,6 +11,7 @@ in
|
|||
options.swarselmodules.server.${serviceName} = lib.mkEnableOption "enable ${serviceName} on server";
|
||||
config = lib.mkIf config.swarselmodules.server.${serviceName} {
|
||||
|
||||
|
||||
services.${serviceName} = {
|
||||
enable = true;
|
||||
user = serviceUser;
|
||||
|
|
|
|||
|
|
@ -13,6 +13,8 @@
|
|||
sops
|
||||
tmux
|
||||
busybox
|
||||
ndisc6
|
||||
tcpdump
|
||||
swarsel-deploy
|
||||
] ++ lib.optionals withHomeManager [
|
||||
swarsel-gens
|
||||
|
|
|
|||
38
modules/nixos/server/podman.nix
Normal file
38
modules/nixos/server/podman.nix
Normal file
|
|
@ -0,0 +1,38 @@
|
|||
{ config, lib, ... }:
|
||||
let
|
||||
serviceName = "podman";
|
||||
in
|
||||
{
|
||||
options.swarselmodules.server.${serviceName} = lib.mkEnableOption "enable ${serviceName} on server";
|
||||
config = lib.mkIf config.swarselmodules.server.${serviceName} {
|
||||
|
||||
virtualisation = {
|
||||
podman.enable = true;
|
||||
oci-containers.backend = "podman";
|
||||
};
|
||||
|
||||
networking.nftables.firewall = lib.mkIf config.networking.nftables.enable {
|
||||
|
||||
zones.podman = {
|
||||
interfaces = [ "podman0" ];
|
||||
};
|
||||
|
||||
rules = {
|
||||
podman-to-postgres = lib.mkIf config.services.postgresql.enable {
|
||||
from = [ "podman" ];
|
||||
to = [ "local" ];
|
||||
before = [ "drop" ];
|
||||
allowedTCPPorts = [ config.services.postgresql.settings.port ];
|
||||
};
|
||||
|
||||
local-to-podman = {
|
||||
from = [ "local" "wgProxy" "wgHme" ];
|
||||
to = [ "podman" ];
|
||||
before = [ "drop" ];
|
||||
verdict = "accept";
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
};
|
||||
}
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
{ lib, config, globals, ... }:
|
||||
{ lib, config, globals, confLib, ... }:
|
||||
let
|
||||
serviceName = "router";
|
||||
bridgeVLANs = lib.mapAttrsToList
|
||||
|
|
@ -9,6 +9,7 @@ let
|
|||
selectVLANs = vlans: map (vlan: { VLAN = globals.networks.home-lan.vlans.${vlan}.id; }) vlans;
|
||||
lan5VLANs = selectVLANs [ "home" "devices" "guests" ];
|
||||
lan4VLANs = selectVLANs [ "home" "services" ];
|
||||
inherit (confLib.gen { }) homeDnsServer;
|
||||
in
|
||||
{
|
||||
options.swarselmodules.server.${serviceName} = lib.mkEnableOption "enable ${serviceName} on server";
|
||||
|
|
@ -16,13 +17,27 @@ in
|
|||
{
|
||||
services.avahi.reflector = true;
|
||||
|
||||
topology.self.interfaces = (lib.mapAttrs'
|
||||
(vlanName: _:
|
||||
lib.nameValuePair "vlan-${vlanName}" {
|
||||
network = lib.mkForce vlanName;
|
||||
}
|
||||
)
|
||||
globals.networks.home-lan.vlans) // (lib.mapAttrs'
|
||||
(vlanName: _:
|
||||
lib.nameValuePair "me-${vlanName}" {
|
||||
network = lib.mkForce vlanName;
|
||||
}
|
||||
)
|
||||
globals.networks.home-lan.vlans);
|
||||
|
||||
networking.nftables = {
|
||||
firewall = {
|
||||
zones = {
|
||||
untrusted.interfaces = [ "lan" ];
|
||||
wgHome.interfaces = [ "wgHome" ];
|
||||
adguardhome.ipv4Addresses = [ globals.networks.home-lan.vlans.services.hosts.hintbooth-adguardhome.ipv4 ];
|
||||
adguardhome.ipv6Addresses = [ globals.networks.home-lan.vlans.services.hosts.hintbooth-adguardhome.ipv6 ];
|
||||
adguardhome.ipv4Addresses = [ globals.networks.home-lan.vlans.services.hosts.${homeDnsServer}.ipv4 ];
|
||||
adguardhome.ipv6Addresses = [ globals.networks.home-lan.vlans.services.hosts.${homeDnsServer}.ipv6 ];
|
||||
}
|
||||
// lib.flip lib.concatMapAttrs globals.networks.home-lan.vlans (
|
||||
vlanName: _: {
|
||||
|
|
@ -32,7 +47,7 @@ in
|
|||
|
||||
rules = {
|
||||
masquerade-internet = {
|
||||
from = map (name: "vlan-${name}") (builtins.attrNames globals.networks.home-lan.vlans);
|
||||
from = map (name: "vlan-${name}") (globals.general.internetVLANs);
|
||||
to = [ "untrusted" ];
|
||||
# masquerade = true; NOTE: custom rule below for ip4 + ip6
|
||||
late = true; # Only accept after any rejects have been processed
|
||||
|
|
@ -41,7 +56,7 @@ in
|
|||
|
||||
# Allow access to the AdGuardHome DNS server from any VLAN that has internet access
|
||||
access-adguardhome-dns = {
|
||||
from = map (name: "vlan-${name}") (builtins.attrNames globals.networks.home-lan.vlans);
|
||||
from = map (name: "vlan-${name}") (globals.general.internetVLANs);
|
||||
to = [ "adguardhome" ];
|
||||
verdict = "accept";
|
||||
};
|
||||
|
|
@ -61,7 +76,7 @@ in
|
|||
services-to-local = {
|
||||
from = [ "vlan-services" ];
|
||||
to = [ "local" ];
|
||||
allowedUDPPorts = [ 52829 ];
|
||||
allowedUDPPorts = [ 52829 547 ];
|
||||
};
|
||||
|
||||
# Forward traffic between wireguard participants
|
||||
|
|
@ -79,7 +94,7 @@ in
|
|||
late = true;
|
||||
rules =
|
||||
lib.forEach
|
||||
(map (name: "vlan-${name}") (builtins.attrNames globals.networks.home-lan.vlans))
|
||||
(map (name: "vlan-${name}") (globals.general.internetVLANs))
|
||||
(
|
||||
zone:
|
||||
lib.concatStringsSep " " [
|
||||
|
|
@ -227,8 +242,14 @@ in
|
|||
IPv6AcceptRA = false;
|
||||
};
|
||||
ipv6Prefixes = [
|
||||
{ Prefix = vlanCfg.cidrv6; }
|
||||
{
|
||||
Prefix = vlanCfg.cidrv6;
|
||||
}
|
||||
];
|
||||
ipv6SendRAConfig = {
|
||||
Managed = true; # set RA M flag -> DHCPv6 for addresses
|
||||
OtherInformation = true; # optional, for “other info” via DHCPv6
|
||||
};
|
||||
linkConfig.RequiredForOnline = "routable";
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -12,6 +12,10 @@ in
|
|||
};
|
||||
config = lib.mkIf config.swarselmodules.server.${serviceName} {
|
||||
|
||||
swarselmodules.server = {
|
||||
podman = true;
|
||||
};
|
||||
|
||||
nodes.${dnsServer}.swarselsystems.server.dns.${globals.services.${serviceName}.baseDomain}.subdomainRecords = {
|
||||
"${globals.services.${serviceName}.subDomain}" = dns.lib.combinators.host proxyAddress4 proxyAddress6;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -10,6 +10,10 @@ in
|
|||
};
|
||||
config = lib.mkIf config.swarselmodules.server.${serviceName} {
|
||||
|
||||
swarselmodules.server = {
|
||||
podman = true;
|
||||
};
|
||||
|
||||
nodes.${dnsServer}.swarselsystems.server.dns.${globals.services.${serviceName}.baseDomain}.subdomainRecords = {
|
||||
"${globals.services.${serviceName}.subDomain}" = dns.lib.combinators.host proxyAddress4 proxyAddress6;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -95,6 +95,14 @@ in
|
|||
)
|
||||
);
|
||||
|
||||
topology.self.interfaces = lib.mapAttrs'
|
||||
(wgName: _:
|
||||
lib.nameValuePair "${wgName}" {
|
||||
network = wgName;
|
||||
}
|
||||
)
|
||||
config.swarselsystems.server.wireguard.interfaces;
|
||||
|
||||
environment.systemPackages = with pkgs; [
|
||||
wireguard-tools
|
||||
];
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue