From b1def329e9b63fcd76c74e4de6a71648ee5373c8 Mon Sep 17 00:00:00 2001 From: pierre Date: Wed, 15 Apr 2026 09:29:59 +0100 Subject: [PATCH] adding specifiy geoip option --- Nginx.kube.yaml | 6 +++++ nginx-config.configmap.yaml | 34 ++++++++++++++------------- nginx.conf | 4 +++- terraform/geoip.conf.tftpl | 13 +++++++++++ terraform/module.tf | 41 ++++++++++++++++++++++++++++++++- terraform/nginx_config.tftpl | 8 ++++--- terraform/variables.auto.tfvars | 12 ++++++++-- 7 files changed, 95 insertions(+), 23 deletions(-) create mode 100755 terraform/geoip.conf.tftpl diff --git a/Nginx.kube.yaml b/Nginx.kube.yaml index 952001b..4602153 100644 --- a/Nginx.kube.yaml +++ b/Nginx.kube.yaml @@ -44,6 +44,8 @@ spec: mountPath: /etc/nginx/deny.d/ - name: blacklisted-sessions-map mountPath: /etc/nginx/blacklisted.d/ + - name: geoip-allow-terraform + mountPath: /etc/nginx/geoip.d/ - name: blacklisted-memory-volume mountPath: /etc/nginx/blacklisted.memory.d/ - name: reverse-proxy-ssl @@ -111,6 +113,10 @@ spec: configMap: name: deny-ip-terraform defaultMode: 0555 + - name: geoip-allow-terraform + configMap: + name: geoip-allow + defaultMode: 0555 - name: proxy-cache-path-volume emptyDir: medium: Memory diff --git a/nginx-config.configmap.yaml b/nginx-config.configmap.yaml index 931c2c7..c903e9d 100644 --- a/nginx-config.configmap.yaml +++ b/nginx-config.configmap.yaml @@ -1,19 +1,20 @@ apiVersion: v1 data: nginx.conf: "load_module /usr/lib/nginx/modules/ngx_http_geoip2_module.so;\nworker_processes - 1;\nevents { worker_connections 1024; }\n\nhttp {\n\n\tsendfile on;\n\tclient_max_body_size - 1500M; \n\tserver_names_hash_bucket_size 1024;\n proxy_http_version 1.1;\n - \ proxy_set_header X-Forwarded-Scheme $scheme;\n proxy_set_header - \ Accept-Encoding \"\";\n\tproxy_set_header Host $host;\n\tproxy_set_header - \ X-Real-IP $remote_addr;\n\tproxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;\n\tproxy_set_header - \ X-Forwarded-Host $server_name;\n\n\t#compression settings\n\tgzip on;\n\tgzip_types - text/plain application/xml application/json image/svg+xml text/css;\n\tgzip_min_length - 1000;\n \n\t#custom log format to display the webiste visited and the IP - used\n\tlog_format my_custom_format '$http_host \\t $remote_addr - $remote_user - [$time_local] \"$request\" $status $body_bytes_sent \"$http_referer\" \"$http_user_agent\"';\n - \ log_format ip_audit '$remote_addr [$time_local]';\n log_format - backend_debug '$remote_addr - $remote_user [$time_local] '\n '\"$request\" - $status $body_bytes_sent '\n '\"$http_referer\" \"$http_user_agent\" + 1;\nevents { worker_connections 1024; }\n\nhttp {\n\n\tsendfile on;\n\t#client_max_body_size + 1500M;\n client_max_body_size 15000M; \n\tserver_names_hash_bucket_size + 1024;\n proxy_http_version 1.1;\n proxy_set_header X-Forwarded-Scheme + $scheme;\n proxy_set_header Accept-Encoding \"\";\n\tproxy_set_header + \ Host $host;\n\tproxy_set_header X-Real-IP $remote_addr;\n\tproxy_set_header + \ X-Forwarded-For $proxy_add_x_forwarded_for;\n\tproxy_set_header X-Forwarded-Host + $server_name;\n\n\t#compression settings\n\tgzip on;\n\tgzip_types text/plain + application/xml application/json image/svg+xml text/css;\n\tgzip_min_length 1000;\n + \ \n\t#custom log format to display the webiste visited and the IP used\n\tlog_format + my_custom_format '$http_host \\t $remote_addr - $remote_user [$time_local] \"$request\" + $status $body_bytes_sent \"$http_referer\" \"$http_user_agent\"';\n log_format + ip_audit '$remote_addr [$time_local]';\n log_format backend_debug '$remote_addr + - $remote_user [$time_local] '\n '\"$request\" $status + $body_bytes_sent '\n '\"$http_referer\" \"$http_user_agent\" '\n 'upstream_status=$upstream_status';\n log_format localization '$remote_addr - $remote_user [$time_local] '\n '\"$request\" $status $body_bytes_sent '\n '\"$http_referer\" \"$http_user_agent\" @@ -37,9 +38,10 @@ data: of country codes: https://en.wikipedia.org/wiki/List_of_ISO_3166_country_codes\n\n\tmap $allowed_country $should_log_blocked {\n\t\tno 1;\n\t\tdefault 0;\n\t}\n\n\tinclude /etc/nginx/deny.d/*.conf;\n\tinclude /etc/nginx/conf.d/*.conf;\n include - /etc/nginx/blacklisted.d/*.conf;\n\n\t# adding this line for the fial2ban settings\t\n - \ #map $cookie_session_id $blck_lst_ses { include /etc/nginx/blacklisted.d/blacklisted-sessions.map; - }\n\t#add extra file for any extra work \n include /etc/nginx/extra.conf.d/*.conf;\n\n\n\tresolver + /etc/nginx/blacklisted.d/*.conf;\n include /etc/nginx/geoip.d/*.conf;\n\n\t# + adding this line for the fial2ban settings\t\n #map $cookie_session_id + $blck_lst_ses { include /etc/nginx/blacklisted.d/blacklisted-sessions.map; }\n\t#add + extra file for any extra work \n include /etc/nginx/extra.conf.d/*.conf;\n\n\n\tresolver 127.0.0.1 ipv6=off valid=40s; # The DNS IP server\n\t\n\t#https://www.tweaked.io/guide/nginx-proxying/\n\tproxy_cache_path /tmp/cache levels=1:2 keys_zone=cache:60m max_size=1G;\n\n\n}\n\n\n" kind: ConfigMap diff --git a/nginx.conf b/nginx.conf index f750e8c..12bc9d2 100755 --- a/nginx.conf +++ b/nginx.conf @@ -5,7 +5,8 @@ events { worker_connections 1024; } http { sendfile on; - client_max_body_size 1500M; + #client_max_body_size 1500M; + client_max_body_size 15000M; server_names_hash_bucket_size 1024; proxy_http_version 1.1; proxy_set_header X-Forwarded-Scheme $scheme; @@ -81,6 +82,7 @@ http { include /etc/nginx/deny.d/*.conf; include /etc/nginx/conf.d/*.conf; include /etc/nginx/blacklisted.d/*.conf; + include /etc/nginx/geoip.d/*.conf; # adding this line for the fial2ban settings #map $cookie_session_id $blck_lst_ses { include /etc/nginx/blacklisted.d/blacklisted-sessions.map; } diff --git a/terraform/geoip.conf.tftpl b/terraform/geoip.conf.tftpl new file mode 100755 index 0000000..977970e --- /dev/null +++ b/terraform/geoip.conf.tftpl @@ -0,0 +1,13 @@ +map $geoip2_data_country_iso_code $allowed_country_${name} { + default no; + %{ for country in allowed_country_list} + ${country} yes; + %{ endfor ~} +} + +map $allowed_country_${name} $should_log_blocked_${upper(join("_", sort(allowed_country_list)))} { + no 1; + default 0; +} + + diff --git a/terraform/module.tf b/terraform/module.tf index 2d7d4e3..7935a09 100644 --- a/terraform/module.tf +++ b/terraform/module.tf @@ -14,7 +14,8 @@ variable "nginx_sites" { authentication_required = optional(bool, false) redirect_to_https_bool = optional(bool, true) listen_port_80_bool = optional(bool, false) - + geoip_blocking = optional(bool, true) + geoip_allow = optional(list(string), ["FR", "GB"]) })) } @@ -22,6 +23,23 @@ variable "deny_ip" { type = list(string) } +locals { + geoip_allow_list = distinct(flatten([ + for key, value in var.nginx_sites : [{ + name = join("_", sort(value.geoip_allow)) + country_list = sort(value.geoip_allow) + }] if value.enabled == true && value.geoip_allow != null + ])) + + geoip_allow_list_test = distinct([ + for key, value in var.nginx_sites : [{ + value = sort(value.geoip_allow) + }] if value.enabled == true && value.geoip_allow != null + ]) + +} + + resource "kubernetes_config_map" "deny_ip_configmap" { metadata { name = "deny-ip-terraform" @@ -72,11 +90,32 @@ resource "kubernetes_config_map" "automatic-configmap" { authentication_required = value.authentication_required redirect_to_https_bool = value.redirect_to_https_bool listen_port_80_bool = value.listen_port_80_bool + geoip_blocking = value.geoip_blocking + geoip_allow = value.geoip_allow }) if value.enabled == true } } +resource "kubernetes_config_map" "automatic-geoip-allow" { + metadata { + name = "geoip-allow" + namespace = "reverse-proxy" + annotations = { + "reloader.stakater.com/match" : "true", + } + } + + data = { + for key, value in local.geoip_allow_list : + "${value.name}.conf" => templatefile("geoip.conf.tftpl", { + name = value.name + allowed_country_list = value.country_list + }) + } +} + + #resource "null_resource" "cluster" { # provisioner "local-exec" { diff --git a/terraform/nginx_config.tftpl b/terraform/nginx_config.tftpl index a213234..642066a 100644 --- a/terraform/nginx_config.tftpl +++ b/terraform/nginx_config.tftpl @@ -9,11 +9,13 @@ upstream ${name_site}_backend { server { server_name ${name_site}.tryton.geeraert.eu www.${name_site}.tryton.geeraert.eu; - if ($allowed_country = no) { + %{ if geoip_blocking} + if ($allowed_country_${upper(join("_", sort(geoip_allow)))} = no) { return 444; # Forbidden # Or use 'return 444;' to close the connection without a response # The 444 Status: If you want to save bandwidth and "ghost" attackers, use return 444;. It drops the connection immediately without even sending a "Forbidden" header. - } + } + %{ endif } location / { proxy_pass %{ if proxy_pass_https}https%{else}http%{ endif }://${name_site}_backend; @@ -55,7 +57,7 @@ server { access_log /var/log/nginx/access.log my_custom_format; access_log /var/log/nginx/ip_audit.log ip_audit; access_log /var/log/nginx/backend_debug.log backend_debug; - access_log /var/log/nginx/blocked_countries.log blocked_fmt if=$should_log_blocked; + access_log /var/log/nginx/blocked_countries.log blocked_fmt if=$should_log_blocked_${upper(join("_", sort(geoip_allow)))}; ${extra-value} %{~ if http2_bool~} http2 on; diff --git a/terraform/variables.auto.tfvars b/terraform/variables.auto.tfvars index 13f3b6f..92efb54 100644 --- a/terraform/variables.auto.tfvars +++ b/terraform/variables.auto.tfvars @@ -9,6 +9,7 @@ nginx_sites = { # EOT service = "bitwarden-nginx-svc.bitwarden.svc:8080" http2_bool = true + } bookstack = { @@ -22,6 +23,7 @@ nginx_sites = { service = "django-svc.django:8000" proxy_cache = true http2_bool = true + } redirect = { #enabled = false @@ -31,6 +33,8 @@ nginx_sites = { #service = "django-testing-svc.django-testing.svc:8000" proxy_cache = true http2_bool = true + geoip_allow = ["FR", "GB", "NL"] + } reverse = { service = "django-svc.django:8000" @@ -341,7 +345,8 @@ proxy_set_header Connection "upgrade"; } stash = { # enabled = false - service = "stash-svc.stash.svc:9999" + service = "stash-svc.stash.svc:9999" + #geoip_blocking = false #extra-value= <