summary refs log tree commit diff
diff options
context:
space:
mode:
authorMel <mel@rnrd.eu>2025-08-22 03:15:45 +0200
committerMel <mel@rnrd.eu>2025-08-22 03:15:45 +0200
commit9e4dc7114f74ed5b86cca8d34cb62b333081a4fe (patch)
treee8e56264d19e8969c696d95221a0f95191e11bf6
parent053dcf87674a3c75245f87ee69beab197e8fb7a8 (diff)
downloadnetwork-9e4dc7114f74ed5b86cca8d34cb62b333081a4fe.tar.zst
network-9e4dc7114f74ed5b86cca8d34cb62b333081a4fe.zip
Grab real remote IP through Cloudflare proxy
Signed-off-by: Mel <mel@rnrd.eu>
-rw-r--r--flake.lock26
-rw-r--r--flake.nix9
-rw-r--r--modules/foundation/www/default.nix63
3 files changed, 79 insertions, 19 deletions
diff --git a/flake.lock b/flake.lock
index fc4718c..f78d47f 100644
--- a/flake.lock
+++ b/flake.lock
@@ -25,6 +25,30 @@
         "type": "github"
       }
     },
+    "cloudflare-ips-v4": {
+      "flake": false,
+      "locked": {
+        "narHash": "sha256-V4dThTb8iw02hjngubVtSJbEeWgOS1e/ODt1fLjLZvk=",
+        "type": "file",
+        "url": "https://www.cloudflare.com/ips-v4"
+      },
+      "original": {
+        "type": "file",
+        "url": "https://www.cloudflare.com/ips-v4"
+      }
+    },
+    "cloudflare-ips-v6": {
+      "flake": false,
+      "locked": {
+        "narHash": "sha256-BgpkXCAh/MmK3GTAElKiGJctCYUN+/UgvpuawqGmitE=",
+        "type": "file",
+        "url": "https://www.cloudflare.com/ips-v6"
+      },
+      "original": {
+        "type": "file",
+        "url": "https://www.cloudflare.com/ips-v6"
+      }
+    },
     "darwin": {
       "inputs": {
         "nixpkgs": [
@@ -149,6 +173,8 @@
     "root": {
       "inputs": {
         "agenix": "agenix",
+        "cloudflare-ips-v4": "cloudflare-ips-v4",
+        "cloudflare-ips-v6": "cloudflare-ips-v6",
         "flake-compat": "flake-compat",
         "home-manager": "home-manager",
         "nixos-hardware": "nixos-hardware",
diff --git a/flake.nix b/flake.nix
index 53de231..16ef267 100644
--- a/flake.nix
+++ b/flake.nix
@@ -25,6 +25,15 @@
       url = "github:sjhgvr/oisd";
       flake = false;
     };
+
+	cloudflare-ips-v4 = {
+	  url = "https://www.cloudflare.com/ips-v4";
+	  flake = false;
+	};
+	cloudflare-ips-v6 = {
+	  url = "https://www.cloudflare.com/ips-v6";
+	  flake = false;
+	};
   };
 
   outputs = inputs @ { self, nixpkgs, nixpkgs-unstable, home-manager, agenix, ... }:
diff --git a/modules/foundation/www/default.nix b/modules/foundation/www/default.nix
index 97e2f2f..5030799 100644
--- a/modules/foundation/www/default.nix
+++ b/modules/foundation/www/default.nix
@@ -4,6 +4,8 @@
   pkgs,
   lib,
   util,
+  cloudflare-ips-v4,
+  cloudflare-ips-v6,
   ...
 }:
 
@@ -13,6 +15,9 @@ let
     mkIf
     mkEnableOption
     mkOption
+    concatMapStrings
+    concatLines
+    splitString
     ;
   inherit (config.age) secrets;
 
@@ -109,25 +114,45 @@ in
 
       statusPage = true;
 
-      commonHttpConfig = ''
-        log_format json_combined escape=json '{'
-          '"time_local":"$time_local",'
-          '"remote_addr":"$remote_addr",'
-          '"remote_user":"$remote_user",'
-          '"request":"$request",'
-          '"status": "$status",'
-          '"body_bytes_sent":"$body_bytes_sent",'
-          '"request_length":"$request_length",'
-          '"request_time":"$request_time",'
-          '"http_referrer":"$http_referer",'
-          '"http_user_agent":"$http_user_agent",'
-          '"upstream_response_time":"$upstream_response_time",'
-          '"upstream_addr":"$upstream_addr",'
-          '"upstream_status":"$upstream_status"'
-        '}';
-        access_log /var/log/nginx/access.log json_combined;
-        error_log /var/log/nginx/error.log warn;
-      '';
+      commonHttpConfig =
+        let
+          logs = ''
+            log_format json_combined escape=json '{'
+              '"time_local":"$time_local",'
+              '"remote_addr":"$remote_addr",'
+              '"remote_user":"$remote_user",'
+              '"request":"$request",'
+              '"status": "$status",'
+              '"body_bytes_sent":"$body_bytes_sent",'
+              '"request_length":"$request_length",'
+              '"request_time":"$request_time",'
+              '"http_referrer":"$http_referer",'
+              '"http_user_agent":"$http_user_agent",'
+              '"upstream_response_time":"$upstream_response_time",'
+              '"upstream_addr":"$upstream_addr",'
+              '"upstream_status":"$upstream_status",'
+              '"cf_connecting_ip":"$http_cf_connecting_ip"'
+            '}';
+            access_log /var/log/nginx/access.log json_combined;
+            error_log /var/log/nginx/error.log warn;
+          '';
+
+          cloudflareAddresses = builtins.filter (ip: ip != "") (
+            splitString "\n" ''
+              ${builtins.readFile cloudflare-ips-v4}
+              ${builtins.readFile cloudflare-ips-v6}
+            ''
+          );
+
+          realIpLine = ip: "set_real_ip_from ${ip};\n";
+
+          cloudflare = ''
+            ${concatMapStrings realIpLine cloudflareAddresses}
+
+            real_ip_header CF-Connecting-IP;
+          '';
+        in
+        concatLines [ logs cloudflare ];
 
       virtualHosts = {
         base = mkIf cfg.public (defaultHost rnrdUrl "rnrd.eu" cfg.defaultPage "base");