1
1
Fork 1
mirror of https://github.com/oddlama/nix-config.git synced 2025-10-10 23:00:39 +02:00

feat: adguardhome use DoT; fix loki home proxy; allow arbitrary telegraf secrets

This commit is contained in:
oddlama 2024-05-25 15:49:41 +02:00
parent 93061af475
commit 045f15239a
No known key found for this signature in database
GPG key ID: 14EFE510775FE39A
11 changed files with 114 additions and 173 deletions

View file

@ -42,9 +42,6 @@
}; };
}; };
# TODO track my github stats
# services.telegraf.extraConfig.inputs.github = {};
guests = let guests = let
mkGuest = guestName: { mkGuest = guestName: {
enableStorageDataset ? false, enableStorageDataset ? false,

View file

@ -1,12 +1,10 @@
{ {
config, config,
lib,
nodes, nodes,
... ...
}: let }: let
sentinelCfg = nodes.sentinel.config; sentinelCfg = nodes.sentinel.config;
wardWebProxyCfg = nodes.ward-web-proxy.config; wardWebProxyCfg = nodes.ward-web-proxy.config;
wardCfg = nodes.ward.config;
lokiDomain = "loki.${config.repo.secrets.global.domains.me}"; lokiDomain = "loki.${config.repo.secrets.global.domains.me}";
in { in {
wireguard.proxy-sentinel = { wireguard.proxy-sentinel = {
@ -44,14 +42,11 @@ in {
proxyWebsockets = true; proxyWebsockets = true;
extraConfig = '' extraConfig = ''
auth_basic "Authentication required"; auth_basic "Authentication required";
auth_basic_user_file ${wardWebProxyCfg.age.secrets.loki-basic-auth-hashes.path}; auth_basic_user_file ${sentinelCfg.age.secrets.loki-basic-auth-hashes.path};
proxy_read_timeout 1800s; proxy_read_timeout 1800s;
proxy_connect_timeout 1600s; proxy_connect_timeout 1600s;
${lib.concatMapStrings (ip: "allow ${ip};\n") wardCfg.wireguard.proxy-home.server.reservedAddresses}
deny all;
access_log off; access_log off;
''; '';
}; };
@ -89,7 +84,7 @@ in {
proxyWebsockets = true; proxyWebsockets = true;
extraConfig = '' extraConfig = ''
auth_basic "Authentication required"; auth_basic "Authentication required";
auth_basic_user_file ${sentinelCfg.age.secrets.loki-basic-auth-hashes.path}; auth_basic_user_file ${wardWebProxyCfg.age.secrets.loki-basic-auth-hashes.path};
proxy_read_timeout 1800s; proxy_read_timeout 1800s;
proxy_connect_timeout 1600s; proxy_connect_timeout 1600s;

View file

@ -59,12 +59,11 @@ in {
# allowed_clients = [ # allowed_clients = [
# ]; # ];
#trusted_proxies = []; #trusted_proxies = [];
ratelimit = 60; ratelimit = 300;
upstream_dns = [ upstream_dns = [
"1.1.1.1" "https://dns.cloudflare.com/dns-query"
# FIXME: enable ipv6 "2606:4700:4700::1111" "https://dns.google/dns-query"
"8.8.8.8" "https://doh.mullvad.net/dns-query"
# FIXME: enable ipv6 "2001:4860:4860::8844"
]; ];
bootstrap_dns = [ bootstrap_dns = [
"1.1.1.1" "1.1.1.1"

View file

@ -33,6 +33,72 @@ in {
inherit (acme) certs wildcardDomains; inherit (acme) certs wildcardDomains;
}; };
age.secrets.github-access-token = {
rekeyFile = config.node.secretsDir + "/github-access-token.age";
mode = "440";
group = "telegraf";
};
meta.telegraf.secrets."@GITHUB_ACCESS_TOKEN@" = config.age.secrets.github-access-token.path;
services.telegraf.extraConfig.inputs = {
ping = [
{
method = "native";
urls = [
"192.168.178.1"
"192.168.1.1"
];
tags.type = "internal";
fieldpass = [
"percent_packet_loss"
"average_response_ms"
"standard_deviation_ms"
"reply_received"
"percent_reply_loss"
];
}
{
method = "native";
urls = [
"1.1.1.1"
"8.8.8.8"
config.repo.secrets.global.domains.me
config.repo.secrets.global.domains.personal
];
tags.type = "external";
fieldpass = [
"percent_packet_loss"
"average_response_ms"
"standard_deviation_ms"
"reply_received"
"percent_reply_loss"
];
}
];
# FIXME: pls define this on the relevant hosts. Then we can ping it from multiple other hosts
#http_response = [
# {
# urls = [
# ];
# response_string_match = "Index of /";
# response_status_code = 200;
# }
#];
github = {
access_token = "@GITHUB_ACCESS_TOKEN@";
repositories = [
"oddlama/agenix-rekey"
"oddlama/autokernel"
"oddlama/gentoo-install"
"oddlama/nix-config"
"oddlama/nix-topology"
"oddlama/vane"
];
};
};
services.nginx = { services.nginx = {
upstreams.fritzbox = { upstreams.fritzbox = {
servers."192.168.178.1" = {}; servers."192.168.178.1" = {};

View file

@ -75,25 +75,23 @@ in {
IPForward = "yes"; IPForward = "yes";
IPv6PrivacyExtensions = "yes"; IPv6PrivacyExtensions = "yes";
IPv6SendRA = true; IPv6SendRA = true;
IPv6AcceptRA = false;
DHCPPrefixDelegation = true;
MulticastDNS = true; MulticastDNS = true;
}; };
# Announce a static prefix # Announce a static prefix
ipv6Prefixes = [ ipv6Prefixes = [
{ipv6PrefixConfig.Prefix = lanCidrv6;} {ipv6PrefixConfig.Prefix = lanCidrv6;}
]; ];
# Delegate prefix from wan # Delegate prefix
#dhcpPrefixDelegationConfig = { dhcpPrefixDelegationConfig = {
# UplinkInterface = "wan"; SubnetId = "22";
# Announce = true; };
# SubnetId = "auto";
#};
# Provide a DNS resolver # Provide a DNS resolver
# TODO ipv6SendRAConfig = { ipv6SendRAConfig = {
# TODO EmitDNS = true; EmitDNS = true;
# TODO # TODO change to self later DNS = lib.net.cidr.host 3 lanCidrv6;
# TODO #DNS = lib.net.cidr.host 1 net.lan.ipv6cidr; };
# TODO DNS = ["2606:4700:4700::1111" "2001:4860:4860::8888"];
# TODO };
linkConfig.RequiredForOnline = "routable"; linkConfig.RequiredForOnline = "routable";
}; };
# Remaining macvtap interfaces should not be touched. # Remaining macvtap interfaces should not be touched.

Binary file not shown.

View file

@ -1,139 +0,0 @@
{
config,
lib,
...
}: let
cfg = config.services.oauth2-proxy.nginx;
in {
disabledModules = ["services/security/oauth2-proxy-nginx.nix"];
options.services.oauth2-proxy.nginx = {
proxy = lib.mkOption {
type = lib.types.str;
default = config.services.oauth2-proxy.httpAddress;
defaultText = lib.literalExpression "config.services.oauth2-proxy.httpAddress";
description = ''
The address of the reverse proxy endpoint for oauth2-proxy
'';
};
domain = lib.mkOption {
type = lib.types.str;
description = ''
The domain under which the oauth2-proxy will be accesible and the path of cookies are set to.
This setting must be set to ensure back-redirects are working properly
if oauth2-proxy is configured with {option}`services.oauth2-proxy.cookie.domain`
or multiple {option}`services.oauth2-proxy.nginx.virtualHosts` that are not on the same domain.
'';
};
virtualHosts = lib.mkOption {
type = let
vhostSubmodule = lib.types.submodule {
options = {
allowed_groups = lib.mkOption {
type = lib.types.nullOr (lib.types.listOf lib.types.str);
description = "List of groups to allow access to this vhost, or null to allow all.";
default = null;
};
allowed_emails = lib.mkOption {
type = lib.types.nullOr (lib.types.listOf lib.types.str);
description = "List of emails to allow access to this vhost, or null to allow all.";
default = null;
};
allowed_email_domains = lib.mkOption {
type = lib.types.nullOr (lib.types.listOf lib.types.str);
description = "List of email domains to allow access to this vhost, or null to allow all.";
default = null;
};
};
};
oldType = lib.types.listOf lib.types.str;
convertFunc = x:
lib.warn "services.oauth2-proxy.nginx.virtualHosts should be an attrset, found ${lib.generators.toPretty {} x}"
lib.genAttrs
x (_: {});
newType = lib.types.attrsOf vhostSubmodule;
in
lib.types.coercedTo oldType convertFunc newType;
default = {};
example = {
"protected.foo.com" = {
allowed_groups = ["admins"];
allowed_emails = ["boss@foo.com"];
};
};
description = ''
Nginx virtual hosts to put behind the oauth2 proxy.
You can exclude specific locations by setting `auth_request off;` in the locations extraConfig setting.
'';
};
};
config.services.oauth2-proxy = lib.mkIf (cfg.virtualHosts != {} && (lib.hasPrefix "127.0.0.1:" cfg.proxy)) {
enable = true;
};
config.services.nginx = lib.mkIf (cfg.virtualHosts != {} && config.services.oauth2-proxy.enable) (lib.mkMerge ([
{
virtualHosts.${cfg.domain}.locations."/oauth2/" = {
proxyPass = cfg.proxy;
extraConfig = ''
proxy_set_header X-Scheme $scheme;
proxy_set_header X-Auth-Request-Redirect $scheme://$host$request_uri;
'';
};
}
]
++ lib.optional (cfg.virtualHosts != {}) {
recommendedProxySettings = true; # needed because duplicate headers
}
++ (lib.mapAttrsToList (vhost: conf: {
virtualHosts.${vhost} = {
locations = {
"/oauth2/auth" = let
maybeQueryArg = name: value:
if value == null
then null
else "${name}=${lib.concatStringsSep "," (builtins.map lib.escapeURL value)}";
allArgs = lib.mapAttrsToList maybeQueryArg conf;
cleanArgs = builtins.filter (x: x != null) allArgs;
cleanArgsStr = lib.concatStringsSep "&" cleanArgs;
in {
# nginx doesn't support passing query string arguments to auth_request,
# so pass them here instead
proxyPass = "${cfg.proxy}/oauth2/auth?${cleanArgsStr}";
extraConfig = ''
auth_request off;
proxy_set_header X-Scheme $scheme;
# nginx auth_request includes headers but not body
proxy_set_header Content-Length "";
proxy_pass_request_body off;
'';
};
"@redirectToAuth2ProxyLogin" = {
return = "307 https://${cfg.domain}/oauth2/start?rd=$scheme://$host$request_uri";
extraConfig = ''
auth_request off;
'';
};
};
extraConfig = ''
auth_request /oauth2/auth;
error_page 401 = @redirectToAuth2ProxyLogin;
# pass information via X-User and X-Email headers to backend,
# requires running with --set-xauthrequest flag
auth_request_set $user $upstream_http_x_auth_request_user;
auth_request_set $email $upstream_http_x_auth_request_email;
proxy_set_header X-User $user;
proxy_set_header X-Email $email;
# if you enabled --cookie-refresh, this is needed for it to work with auth_request
auth_request_set $auth_cookie $upstream_http_set_cookie;
add_header Set-Cookie $auth_cookie;
'';
};
})
cfg.virtualHosts)));
}

View file

@ -16,7 +16,6 @@
cfg = config.meta.oauth2-proxy; cfg = config.meta.oauth2-proxy;
in { in {
imports = [./oa2p.nix];
options.meta.oauth2-proxy = { options.meta.oauth2-proxy = {
enable = mkEnableOption "oauth2 proxy"; enable = mkEnableOption "oauth2 proxy";

View file

@ -27,6 +27,15 @@ in {
description = "Scrape sensors with lm_sensors. You should disable this for virtualized hosts."; description = "Scrape sensors with lm_sensors. You should disable this for virtualized hosts.";
}; };
secrets = mkOption {
type = types.attrsOf types.path;
default = {};
example = {
"@INFLUX_TOKEN@" = "/run/agenix/influx-token";
};
description = "Additional secrets to replace in pre-start. The attr name will be searched and replaced in the config with the value read from the given file.";
};
influxdb2 = { influxdb2 = {
domain = mkOption { domain = mkOption {
type = types.str; type = types.str;
@ -86,6 +95,8 @@ in {
group = "telegraf"; group = "telegraf";
}; };
meta.telegraf.secrets."@INFLUX_TOKEN@" = config.age.secrets.telegraf-influxdb-token.path;
security.elewrap.telegraf-sensors = mkIf cfg.scrapeSensors { security.elewrap.telegraf-sensors = mkIf cfg.scrapeSensors {
command = ["${pkgs.lm_sensors}/bin/sensors" "-A" "-u"]; command = ["${pkgs.lm_sensors}/bin/sensors" "-A" "-u"];
targetUser = "root"; targetUser = "root";
@ -125,7 +136,7 @@ in {
outputs = { outputs = {
influxdb_v2 = { influxdb_v2 = {
urls = ["https://${cfg.influxdb2.domain}"]; urls = ["https://${cfg.influxdb2.domain}"];
token = "$INFLUX_TOKEN"; token = "@INFLUX_TOKEN@";
inherit (cfg.influxdb2) organization bucket; inherit (cfg.influxdb2) organization bucket;
}; };
}; };
@ -202,12 +213,19 @@ in {
(pkgs.writeShellScriptBin "sensors" config.security.elewrap.telegraf-sensors.path)) (pkgs.writeShellScriptBin "sensors" config.security.elewrap.telegraf-sensors.path))
]; ];
serviceConfig = { serviceConfig = {
Environment = "INFLUX_TOKEN=\$INFLUX_TOKEN"; # Required so the first envsubst in the original module doesn't change it
ExecStartPre = mkAfter [ ExecStartPre = mkAfter [
(pkgs.writeShellScript "pre-start-token" '' (
export INFLUX_TOKEN=$(< ${config.age.secrets.telegraf-influxdb-token.path}) pkgs.writeShellScript "pre-start-token" (lib.concatLines (
${pkgs.envsubst}/bin/envsubst -i /var/run/telegraf/config.toml -o /var/run/telegraf/config.toml lib.flip lib.mapAttrsToList config.meta.telegraf.secrets (
'') key: secret: ''
${lib.getExe pkgs.replace-secret} \
${lib.escapeShellArg key} \
${lib.escapeShellArg secret} \
/var/run/telegraf/config.toml
''
)
))
)
]; ];
# For wireguard statistics # For wireguard statistics
AmbientCapabilities = ["CAP_NET_ADMIN"]; AmbientCapabilities = ["CAP_NET_ADMIN"];

View file

@ -0,0 +1,8 @@
age-encryption.org/v1
-> ssh-ed25519 NwOpTA Rq5PyLLJdiYKkL+9vW+BS7sbFHBFoLwdxxWgPTH+0wU
wr1wRFGKYVgziwtzOm95pO4ZPnzF+pTuXlhedNd7HoU
-> Or$Ir-grease =Z{2b= (FvA*6m iV4)_
tePL0HELOtPx9UAsd0K7CvKv/56vQP++Y/PI5LMIl1IP7Opv2tiOqlB+R5bqWClO
lzV5jX+CVtQNABFgyDrQDfeqUgrw
--- YYlss0gmwNI2pNYbukrJl0hZpdCC8xKh+trLpAeTqFg
?1Ý7©ˆåˆ§¡êdÒÛ=2P»(û˜­Uuø/98ÊÖ.ËŒ¯;gyþúÄNö]ÄkdÞ|L/QJÞ…6ÀûMUÝ$Ørs9

Binary file not shown.