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:
parent
93061af475
commit
045f15239a
11 changed files with 114 additions and 173 deletions
|
@ -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,
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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"
|
||||||
|
|
|
@ -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" = {};
|
||||||
|
|
|
@ -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.
|
||||||
|
|
BIN
hosts/ward/secrets/web-proxy/github-access-token.age
Normal file
BIN
hosts/ward/secrets/web-proxy/github-access-token.age
Normal file
Binary file not shown.
139
modules/oa2p.nix
139
modules/oa2p.nix
|
@ -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)));
|
|
||||||
}
|
|
|
@ -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";
|
||||||
|
|
||||||
|
|
|
@ -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"];
|
||||||
|
|
|
@ -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.
Loading…
Add table
Add a link
Reference in a new issue