mirror of
https://github.com/oddlama/nix-config.git
synced 2025-10-10 23:00:39 +02:00
feat: add internal proxy to high-volume applications at home
This commit is contained in:
parent
b01c521830
commit
20a5e1e66a
32 changed files with 301 additions and 21 deletions
|
@ -5,6 +5,7 @@
|
|||
...
|
||||
}: let
|
||||
sentinelCfg = nodes.sentinel.config;
|
||||
wardWebProxyCfg = nodes.ward-web-proxy.config;
|
||||
in {
|
||||
meta.promtail = {
|
||||
enable = true;
|
||||
|
@ -12,7 +13,12 @@ in {
|
|||
};
|
||||
|
||||
# Connect safely via wireguard to skip http authentication
|
||||
networking.hosts.${sentinelCfg.wireguard.proxy-sentinel.ipv4} = [sentinelCfg.networking.providedDomains.influxdb];
|
||||
networking.hosts.${
|
||||
if config.wireguard ? proxy-home
|
||||
then wardWebProxyCfg.wireguard.proxy-home.ipv4
|
||||
else sentinelCfg.wireguard.proxy-sentinel.ipv4
|
||||
} = [sentinelCfg.networking.providedDomains.influxdb];
|
||||
|
||||
meta.telegraf = lib.mkIf (!config.boot.isContainer) {
|
||||
enable = true;
|
||||
scrapeSensors = false;
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
...
|
||||
}: let
|
||||
sentinelCfg = nodes.sentinel.config;
|
||||
wardWebProxyCfg = nodes.ward-web-proxy.config;
|
||||
grafanaDomain = "grafana.${config.repo.secrets.global.domains.me}";
|
||||
in {
|
||||
wireguard.proxy-sentinel = {
|
||||
|
@ -116,6 +117,11 @@ in {
|
|||
}
|
||||
];
|
||||
|
||||
networking.hosts.${wardWebProxyCfg.wireguard.proxy-home.ipv4} = [
|
||||
sentinelCfg.networking.providedDomains.influxdb # technically a duplicate (see ./common.nix)...
|
||||
sentinelCfg.networking.providedDomains.loki
|
||||
];
|
||||
|
||||
services.grafana = {
|
||||
enable = true;
|
||||
settings = {
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
...
|
||||
}: let
|
||||
sentinelCfg = nodes.sentinel.config;
|
||||
wardWebProxyCfg = nodes.ward-web-proxy.config;
|
||||
immichDomain = "immich.${config.repo.secrets.global.domains.me}";
|
||||
|
||||
ipImmichMachineLearning = "10.89.0.10";
|
||||
|
@ -169,10 +170,15 @@ in {
|
|||
client.via = "sentinel";
|
||||
firewallRuleForNode.sentinel.allowedTCPPorts = [2283];
|
||||
};
|
||||
wireguard.proxy-home = {
|
||||
client.via = "ward";
|
||||
firewallRuleForNode.ward-web-proxy.allowedTCPPorts = [2283];
|
||||
};
|
||||
networking.nftables.chains.forward.into-immich-container = {
|
||||
after = ["conntrack"];
|
||||
rules = [
|
||||
"iifname proxy-sentinel ip saddr ${sentinelCfg.wireguard.proxy-sentinel.ipv4} tcp dport 3001 accept"
|
||||
"iifname proxy-home ip saddr ${wardWebProxyCfg.wireguard.proxy-home.ipv4} tcp dport 3001 accept"
|
||||
"iifname podman1 oifname lan accept"
|
||||
];
|
||||
};
|
||||
|
@ -202,6 +208,31 @@ in {
|
|||
};
|
||||
};
|
||||
|
||||
nodes.ward-web-proxy = {
|
||||
services.nginx = {
|
||||
upstreams.immich = {
|
||||
servers."${config.wireguard.proxy-home.ipv4}:2283" = {};
|
||||
extraConfig = ''
|
||||
zone immich 64k;
|
||||
keepalive 2;
|
||||
'';
|
||||
};
|
||||
virtualHosts.${immichDomain} = {
|
||||
forceSSL = true;
|
||||
useACMEWildcardHost = true;
|
||||
locations."/" = {
|
||||
proxyPass = "http://immich";
|
||||
proxyWebsockets = true;
|
||||
};
|
||||
extraConfig = ''
|
||||
client_max_body_size 10G;
|
||||
allow 192.168.1.0/24;
|
||||
deny all;
|
||||
'';
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
systemd.tmpfiles.settings = {
|
||||
"10-immich" = {
|
||||
${upload_folder}.d = {
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
...
|
||||
}: let
|
||||
sentinelCfg = nodes.sentinel.config;
|
||||
wardCfg = nodes.ward.config;
|
||||
influxdbDomain = "influxdb.${config.repo.secrets.global.domains.me}";
|
||||
influxdbPort = 8086;
|
||||
in {
|
||||
|
@ -14,6 +15,11 @@ in {
|
|||
firewallRuleForNode.sentinel.allowedTCPPorts = [influxdbPort];
|
||||
};
|
||||
|
||||
wireguard.proxy-home = {
|
||||
client.via = "ward";
|
||||
firewallRuleForNode.ward-web-proxy.allowedTCPPorts = [influxdbPort];
|
||||
};
|
||||
|
||||
nodes.sentinel = {
|
||||
networking.providedDomains.influxdb = influxdbDomain;
|
||||
|
||||
|
@ -50,6 +56,40 @@ in {
|
|||
};
|
||||
};
|
||||
|
||||
nodes.ward-web-proxy = {
|
||||
services.nginx = {
|
||||
upstreams.influxdb = {
|
||||
servers."${config.wireguard.proxy-home.ipv4}:${toString influxdbPort}" = {};
|
||||
extraConfig = ''
|
||||
zone influxdb 64k;
|
||||
keepalive 2;
|
||||
'';
|
||||
};
|
||||
virtualHosts.${influxdbDomain} = let
|
||||
accessRules = ''
|
||||
${lib.concatMapStrings (ip: "allow ${ip};\n") wardCfg.wireguard.proxy-home.server.reservedAddresses}
|
||||
deny all;
|
||||
'';
|
||||
in {
|
||||
forceSSL = true;
|
||||
useACMEWildcardHost = true;
|
||||
locations."/" = {
|
||||
proxyPass = "http://influxdb";
|
||||
proxyWebsockets = true;
|
||||
extraConfig = accessRules;
|
||||
};
|
||||
locations."/api/v2/write" = {
|
||||
proxyPass = "http://influxdb/api/v2/write";
|
||||
proxyWebsockets = true;
|
||||
extraConfig = ''
|
||||
${accessRules}
|
||||
access_log off;
|
||||
'';
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
age.secrets.influxdb-admin-password = {
|
||||
generator.script = "alnum";
|
||||
mode = "440";
|
||||
|
|
|
@ -1,9 +1,12 @@
|
|||
{
|
||||
config,
|
||||
lib,
|
||||
nodes,
|
||||
...
|
||||
}: let
|
||||
sentinelCfg = nodes.sentinel.config;
|
||||
wardWebProxyCfg = nodes.ward-web-proxy.config;
|
||||
wardCfg = nodes.ward.config;
|
||||
lokiDomain = "loki.${config.repo.secrets.global.domains.me}";
|
||||
in {
|
||||
wireguard.proxy-sentinel = {
|
||||
|
@ -11,6 +14,11 @@ in {
|
|||
firewallRuleForNode.sentinel.allowedTCPPorts = [config.services.loki.configuration.server.http_listen_port];
|
||||
};
|
||||
|
||||
wireguard.proxy-home = {
|
||||
client.via = "ward";
|
||||
firewallRuleForNode.ward-web-proxy.allowedTCPPorts = [config.services.loki.configuration.server.http_listen_port];
|
||||
};
|
||||
|
||||
nodes.sentinel = {
|
||||
networking.providedDomains.loki = lokiDomain;
|
||||
|
||||
|
@ -28,6 +36,51 @@ in {
|
|||
keepalive 2;
|
||||
'';
|
||||
};
|
||||
virtualHosts.${lokiDomain} = {
|
||||
forceSSL = true;
|
||||
useACMEWildcardHost = true;
|
||||
locations."/" = {
|
||||
proxyPass = "http://loki";
|
||||
proxyWebsockets = true;
|
||||
extraConfig = ''
|
||||
auth_basic "Authentication required";
|
||||
auth_basic_user_file ${wardWebProxyCfg.age.secrets.loki-basic-auth-hashes.path};
|
||||
|
||||
proxy_read_timeout 1800s;
|
||||
proxy_connect_timeout 1600s;
|
||||
|
||||
${lib.concatMapStrings (ip: "allow ${ip};\n") wardCfg.wireguard.proxy-home.server.reservedAddresses}
|
||||
deny all;
|
||||
|
||||
access_log off;
|
||||
'';
|
||||
};
|
||||
locations."= /ready" = {
|
||||
proxyPass = "http://loki";
|
||||
extraConfig = ''
|
||||
auth_basic off;
|
||||
access_log off;
|
||||
'';
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
nodes.ward-web-proxy = {
|
||||
age.secrets.loki-basic-auth-hashes = {
|
||||
inherit (nodes.sentinel.config.age.secrets.loki-basic-auth-hashes) rekeyFile;
|
||||
mode = "440";
|
||||
group = "nginx";
|
||||
};
|
||||
|
||||
services.nginx = {
|
||||
upstreams.loki = {
|
||||
servers."${config.wireguard.proxy-home.ipv4}:${toString config.services.loki.configuration.server.http_listen_port}" = {};
|
||||
extraConfig = ''
|
||||
zone loki 64k;
|
||||
keepalive 2;
|
||||
'';
|
||||
};
|
||||
virtualHosts.${lokiDomain} = {
|
||||
forceSSL = true;
|
||||
useACMEWildcardHost = true;
|
||||
|
|
|
@ -6,12 +6,23 @@
|
|||
...
|
||||
}: let
|
||||
sentinelCfg = nodes.sentinel.config;
|
||||
wardWebProxyCfg = nodes.ward-web-proxy.config;
|
||||
paperlessDomain = "paperless.${config.repo.secrets.global.domains.me}";
|
||||
paperlessBackupDir = "/var/cache/paperless-backup";
|
||||
in {
|
||||
microvm.mem = 1024 * 9;
|
||||
microvm.vcpu = 8;
|
||||
|
||||
wireguard.proxy-sentinel = {
|
||||
client.via = "sentinel";
|
||||
firewallRuleForNode.sentinel.allowedTCPPorts = [config.services.paperless.port];
|
||||
};
|
||||
|
||||
wireguard.proxy-home = {
|
||||
client.via = "ward";
|
||||
firewallRuleForNode.ward-web-proxy.allowedTCPPorts = [config.services.paperless.port];
|
||||
};
|
||||
|
||||
nodes.sentinel = {
|
||||
networking.providedDomains.paperless = paperlessDomain;
|
||||
|
||||
|
@ -38,9 +49,30 @@ in {
|
|||
};
|
||||
};
|
||||
|
||||
wireguard.proxy-sentinel = {
|
||||
client.via = "sentinel";
|
||||
firewallRuleForNode.sentinel.allowedTCPPorts = [config.services.paperless.port];
|
||||
nodes.ward-web-proxy = {
|
||||
services.nginx = {
|
||||
upstreams.paperless = {
|
||||
servers."${config.wireguard.proxy-home.ipv4}:${toString config.services.paperless.port}" = {};
|
||||
extraConfig = ''
|
||||
zone paperless 64k;
|
||||
keepalive 2;
|
||||
'';
|
||||
};
|
||||
virtualHosts.${paperlessDomain} = {
|
||||
forceSSL = true;
|
||||
useACMEWildcardHost = true;
|
||||
extraConfig = ''
|
||||
client_max_body_size 512M;
|
||||
allow 192.168.1.0/24;
|
||||
deny all;
|
||||
'';
|
||||
locations."/" = {
|
||||
proxyPass = "http://paperless";
|
||||
proxyWebsockets = true;
|
||||
X-Frame-Options = "SAMEORIGIN";
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
age.secrets.paperless-admin-password = {
|
||||
|
@ -75,7 +107,10 @@ in {
|
|||
PAPERLESS_URL = "https://${paperlessDomain}";
|
||||
PAPERLESS_ALLOWED_HOSTS = paperlessDomain;
|
||||
PAPERLESS_CORS_ALLOWED_HOSTS = "https://${paperlessDomain}";
|
||||
PAPERLESS_TRUSTED_PROXIES = sentinelCfg.wireguard.proxy-sentinel.ipv4;
|
||||
PAPERLESS_TRUSTED_PROXIES = lib.concatStringSep "," [
|
||||
sentinelCfg.wireguard.proxy-sentinel.ipv4
|
||||
wardWebProxyCfg.wireguard.proxy-home.ipv4
|
||||
];
|
||||
|
||||
# Authentication via kanidm
|
||||
PAPERLESS_APPS = "allauth.socialaccount.providers.openid_connect";
|
||||
|
|
|
@ -74,23 +74,26 @@ in {
|
|||
];
|
||||
dhcp.enabled = false;
|
||||
};
|
||||
filtering.rewrites = [
|
||||
# Undo the /etc/hosts entry so we don't answer with the internal
|
||||
# wireguard address for influxdb
|
||||
{
|
||||
domain = nodes.sentinel.config.networking.providedDomains.influxdb;
|
||||
answer = config.repo.secrets.global.domains.me;
|
||||
}
|
||||
filtering.rewrites =
|
||||
[
|
||||
# Undo the /etc/hosts entry so we don't answer with the internal
|
||||
# wireguard address for influxdb
|
||||
{
|
||||
domain = nodes.sentinel.config.networking.providedDomains.influxdb;
|
||||
answer = config.repo.secrets.global.domains.me;
|
||||
}
|
||||
]
|
||||
# Use the local mirror-proxy for some services (not necessary, just for speed)
|
||||
{
|
||||
domain = nodes.sentinel.config.networking.providedDomains.grafana;
|
||||
answer = "192.168.1.4"; # web-proxy
|
||||
}
|
||||
{
|
||||
domain = nodes.sentinel.config.networking.providedDomains.immich;
|
||||
answer = "192.168.1.4"; # web-proxy
|
||||
}
|
||||
];
|
||||
++ map (domain: {
|
||||
inherit domain;
|
||||
answer = "192.168.1.4";
|
||||
}) [
|
||||
nodes.sentinel.config.networking.providedDomains.grafana
|
||||
nodes.sentinel.config.networking.providedDomains.immich
|
||||
nodes.sentinel.config.networking.providedDomains.influxdb
|
||||
nodes.sentinel.config.networking.providedDomains.loki
|
||||
nodes.sentinel.config.networking.providedDomains.paperless
|
||||
];
|
||||
filters = [
|
||||
{
|
||||
name = "AdGuard DNS filter";
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue