From b5c1b9de843d1a04161c5005d4b776ddde35c466 Mon Sep 17 00:00:00 2001 From: arcnmx Date: Mon, 24 Jun 2024 10:39:01 -0700 Subject: [PATCH] fix(nginx): cloudflared remote_addr --- modules/nixos/monitoring/source/promtail.nix | 12 +-- modules/nixos/nginx/proxied.nix | 88 +++++++++++++++++--- modules/nixos/nginx/proxy.nix | 1 + nixos/nginx.nix | 6 +- 4 files changed, 89 insertions(+), 18 deletions(-) diff --git a/modules/nixos/monitoring/source/promtail.nix b/modules/nixos/monitoring/source/promtail.nix index fb7224f6..a7b194fd 100644 --- a/modules/nixos/monitoring/source/promtail.nix +++ b/modules/nixos/monitoring/source/promtail.nix @@ -75,21 +75,23 @@ in { stages = [ { regex.expression = concatStringsSep " " [ - ''(?P.*?)'' - ''(?P.*?)'' - ''(?P.*?)(@(?P.*?))?'' + ''(?P.*?)(@-|@(?P.*?)|)'' + ''(-|(?P.*?))(@-|@(?P.*?)|)'' + ''(-|(?P.*?))(@(?P.*?))?'' ''\[(?P.*?)\]'' ''\"(?P.*?) (?P.*?)( (?PHTTP/.*))?\"'' ''(?P.*?)'' ''(?P.*?)'' - ''\"(?P.*?)\"'' - ''\"(?P.*?)\"'' + ''\"(-|(?P.*?))\"'' + ''\"(-|(?P.*?))\"'' ]; } { labels = { remote_addr = null; remote_log_name = null; + request_scheme = null; + request_id = null; userid = null; virtual_host = null; request_method = null; diff --git a/modules/nixos/nginx/proxied.nix b/modules/nixos/nginx/proxied.nix index d9f8cd7f..086f6a61 100644 --- a/modules/nixos/nginx/proxied.nix +++ b/modules/nixos/nginx/proxied.nix @@ -1,4 +1,12 @@ let + xCloudflared = {virtualHost}: let + host = if virtualHost.proxied.cloudflared.host == virtualHost.serverName + then "$server_name" + else "'${virtualHost.proxied.cloudflared.host}'"; + in '' + set $proxied_cf on; + set $proxied_host_cf ${host}; + ''; xHeadersProxied = {xvars}: '' ${xvars.init "forwarded_for" "$proxy_add_x_forwarded_for"} if ($http_x_forwarded_proto) { @@ -11,6 +19,9 @@ let if ($http_x_real_ip) { ${xvars.init "remote_addr" "$http_x_real_ip"} } + if ($http_cf_connecting_ip) { + ${xvars.init "remote_addr" "$http_cf_connecting_ip"} + } if ($http_x_forwarded_host) { ${xvars.init "host" "$http_x_forwarded_host"} } @@ -66,6 +77,9 @@ let }; xvars.enable = mkIf cfg.enabled true; extraConfig = mkMerge [ + (mkIf (cfg.enable == "cloudflared" && virtualHost.proxied.enable != "cloudflared") ( + mkJustBefore (xCloudflared {inherit virtualHost;}) + )) (mkIf emitVars ( mkJustBefore (xHeadersProxied {inherit xvars;}) )) @@ -97,6 +111,10 @@ let default = cfg.enable != false; }; cloudflared = { + host = mkOption { + type = str; + default = config.serverName; + }; ingressSettings = mkOption { type = unmerged.types.attrs; }; @@ -127,12 +145,19 @@ let mkIf (cfg.enable == "cloudflared") { ingressSettings.${config.serverName} = { service = "${scheme}://localhost:${toString listen.port}"; - originRequest.${ - if scheme == "https" - then "noTLSVerify" - else null - } = - true; + originRequest = let + noTLSVerify = + if scheme == "https" + then "noTLSVerify" + else null; + httpHostHeader = + if cfg.cloudflared.host != config.serverName + then "httpHostHeader" + else null; + in { + ${noTLSVerify} = true; + ${httpHostHeader} = cfg.cloudflared.host; + }; }; getIngress = {}: unmerged.mergeAttrs cfg.cloudflared.ingressSettings; }; @@ -146,9 +171,16 @@ let }; }; accessLog = mkIf cfg.enabled { - format = mkDefault "combined_proxied"; + format = mkDefault ( + if cfg.enable == "cloudflared" + then "combined_cloudflared" + else "combined_proxied" + ); }; extraConfig = mkMerge [ + (mkIf (cfg.enable == "cloudflared") ( + mkOrder orderJustBefore (xCloudflared {virtualHost = config;}) + )) (mkIf (cfg.enabled && config.xvars.enable) ( mkOrder (orderJustBefore + 25) (xHeadersProxied {inherit xvars;}) )) @@ -218,10 +250,46 @@ in }; }; commonHttpConfig = mkIf cfg.enable '' - log_format combined_proxied '$x_remote_addr proxied $remote_user@$x_host [$time_local] ' - '"$request" $status $body_bytes_sent ' - '"$http_referer" "$http_user_agent"'; + map "$http_cf_connecting_ip" $proxied_remote_addr_cf { + "" $remote_addr; + default $http_cf_connecting_ip; + } + map "$http_x_real_ip" $proxied_remote_addr_x { + "" $remote_addr; + default $http_x_real_ip; + } + map "$http_x_forwarded_host" $proxied_host_x { + "" $host; + default $http_x_forwarded_host; + } + map "$http_x_forwarded_server" $proxied_forwarded_server_x { + "" $proxied_host_x; + default $http_x_forwarded_server; + } + map "$http_x_forwarded_proto" $proxied_scheme { + "" $scheme; + default $http_x_forwarded_proto; + } + map "$proxied_scheme" $proxied_https { + "https" on; + default ""; + } + map "$proxied_cf" $proxied_remote_addr { + "on" $proxied_remote_addr_cf; + default $proxied_remote_addr_x; + } + map "$proxied_cf" $proxied_host { + "on" $proxied_host_cf; + default $proxied_host_x; + } + + log_format combined_proxied '$proxied_remote_addr@$proxied_scheme proxied $remote_user@$proxied_host [$time_local]' + ' "$request" $status $body_bytes_sent' + ' "$http_referer" "$http_user_agent"'; + log_format combined_cloudflared '$proxied_remote_addr_cf@$proxied_scheme cloudflared@$http_cf_ray $remote_user@$proxied_host_cf [$time_local]' + ' "$request" $status $body_bytes_sent' + ' "$http_referer" "$http_user_agent"'; ''; }; networking.firewall.interfaces.lan = mkIf nginx.enable { diff --git a/modules/nixos/nginx/proxy.nix b/modules/nixos/nginx/proxy.nix index a46232a1..e303a426 100644 --- a/modules/nixos/nginx/proxy.nix +++ b/modules/nixos/nginx/proxy.nix @@ -160,6 +160,7 @@ let then xvars.get.proxy_hostport else cfg.host; Referer = xvars.get.referer; + CF-Connecting-IP = xvars.get.remote_addr; X-Real-IP = xvars.get.remote_addr; X-Forwarded-For = xvars.get.forwarded_for; X-Forwarded-Proto = xvars.get.scheme; diff --git a/nixos/nginx.nix b/nixos/nginx.nix index 3ee22486..dab23435 100644 --- a/nixos/nginx.nix +++ b/nixos/nginx.nix @@ -38,9 +38,9 @@ in { map $scheme $hsts_header { https "max-age=31536000; includeSubdomains; preload"; } - log_format combined_host '$remote_addr - $remote_user@$host [$time_local] ' - '"$request" $status $body_bytes_sent ' - '"$http_referer" "$http_user_agent"'; + log_format combined_host '$remote_addr@$scheme - $remote_user@$host [$time_local]' + ' "$request" $status $body_bytes_sent' + ' "$http_referer" "$http_user_agent"'; ''; clientMaxBodySize = mkDefault "512m"; virtualHosts.fallback = {