ngx_http_geoip2_module
ngx_http_geoip2_module copied to clipboard
country names don't match iso code with cloutflare frontend
There's an nginx with the geoip2 module set up.
geoip2 /var/lib/GeoIP/GeoLite2-Country.mmdb {
auto_reload 24h;
$geoip2_country default=XX country iso_code;
$geoip2_country_name country names en;
}
It receives traffic from Cloudflare, and real_ip is configured.
However, in X_GEOIP2_COUNTRY_NAME, the country is correct, but in X_GEOIP2_COUNTRY_CODE, it's not (it shows the country of Cloudflare)."
#> mmdblookup --file /var/lib/GeoIP/GeoLite2-Country.mmdb --ip 212.7.1.5 country iso_code
"EE" <utf8_string>
#> mmdblookup --file /var/lib/GeoIP/GeoLite2-Country.mmdb --ip 212.7.1.5 country names en
"Estonia" <utf8_string>
212.7.1.5 and 212.7.5.1 are different addresses...
Ok :)
this is same newtork
$ mmdblookup --file /var/lib/GeoIP/GeoLite2-Country.mmdb --ip 212.7.5.1 country iso_code "EE" <utf8_string>
$ mmdblookup --file /var/lib/GeoIP/GeoLite2-Country.mmdb --ip 212.7.5.1 country names en "Estonia" <utf8_string>
EE = Estonia, everything is displayed correctly.
The ngx_http_geoip2_module module does not set these headers, look for the problem elsewhere.
As far as I remember the configuration was something like this
params.d/proxy.conf: proxy_set_header X-Geoip2-Country-Code $geoip2_country; params.d/proxy.conf: proxy_set_header X-Geoip2-Country-Name $geoip2_country_name;
But half a year has passed since then ...
simple index.html with ssi
<pre>
1: <!--# echo var="date_local" default="???"-->
2: <!--#echo var="HTTP_USER_AGENT"-->
3: <!--#echo var="geoip2_country"-->
4: <!--#echo var="geoip2_country_name"-->
5: <!--#echo var="remote_addr"-->
</pre>
result
nginx.conf
geoip2 /var/lib/GeoIP/GeoLite2-Country.mmdb {
auto_reload 24h;
$geoip2_country_name country names en;
$geoip2_country default=XX country iso_code;
}
geoip2 /var/lib/GeoIP/GeoLite2-City.mmdb{
$geoip2_city default=Unknown city names en;
}
geoip2 /var/lib/GeoIP/GeoLite2-ASN.mmdb{
$geoip2_asn autonomous_system_number;
}
P.S. Let me remind that I use realip and site behind Coudflare.
Add source=$remote_addr + update .mmdb databases + update and recompile module.
$geoip2_data_country_code default=- source=$remote_addr country iso_code; $geoip2_data_country_name default=- source=$remote_addr country names en;
- let's go back to the beginning. The meaning of this ticket is that the country code and its name do not match (with the default configuration + realip)
Add source=$remote_addr + update .mmdb databases + update and recompile module.
- this strangely breaks the realip_module
access.log before this changes 85.253.117.127 - - [25/Mar/2024:08:51:37 +0200] "GET /test/ HTTP/2.0" 200 194 "-" "..." rt=0.000 ut=- isbot=0 https=on cache=- up=- country=DE asn=2586
access.log after this changes 172.70.243.14 - - [25/Mar/2024:08:55:05 +0200] "GET /test/ HTTP/2.0" 200 194 "-" "..." rt=0.000 ut=- isbot=0 https=on cache=- up=- country=DE asn=2586
85.253.117.127 - my ip 172.70.243.14 - cloudflare proxy ip
What if you try:
geoip2 /var/lib/GeoIP/GeoLite2-Country.mmdb {
auto_reload 24h;
$geoip2_country_name source=$http_cf_connecting_ip country names en;
$geoip2_country source=$http_cf_connecting_ip default=XX country iso_code;
}
What if you try:
geoip2 /var/lib/GeoIP/GeoLite2-Country.mmdb { auto_reload 24h; $geoip2_country_name source=$http_cf_connecting_ip country names en; $geoip2_country source=$http_cf_connecting_ip default=XX country iso_code; }
With this configuration, the iso code and name are equal. but my ticket is not about how to fix it at the configuration level, but about why with default configurations they are different. imho It looks like compatibility problem with the reailip module and your module somehow affects its operation.
If you can provide a small fully working config that can replicate the issue, I could take a look. But I've tried to replicate locally and can't:
config:
lee@debian:~/nginx-1.24.0/install$ cat conf/nginx.conf
load_module "modules/ngx_http_geoip2_module.so";
events {}
daemon off;
http {
geoip2 GeoIP2-City.mmdb {
auto_reload 6h;
$geoip2_country_name country names en;
$geoip2_country default=XX country iso_code;
}
log_format city '$remote_addr - $remote_user [$time_local] '
'"$request" $status $body_bytes_sent '
'"$http_referer" "$http_user_agent" '
'"$realip_remote_addr" "$http_x_ip" "$geoip2_country_name, $geoip2_country"';
server {
listen 8080;
access_log logs/access.log city;
set_real_ip_from 0.0.0.0/0;
set_real_ip_from ::/0;
real_ip_header X-IP;
real_ip_recursive on;
location / {
return 200 "$geoip2_country_name, $geoip2_country\n";
}
}
}
lee@debian:~/nginx-1.24.0/install$
request:
lee@debian:~$ curl http://127.0.0.1:8080 -H "X-IP: 85.253.117.127"
Estonia, EE
lee@debian:~$
logs:
lee@debian:~/nginx-1.24.0/install$ tail -f logs/access.log
85.253.117.127 - - [04/Apr/2024:14:20:48 +0000] "GET / HTTP/1.1" 200 12 "-" "curl/8.5.0" "127.0.0.1" "85.253.117.127" "Estonia, EE"
^C
lee@debian:~/nginx-1.24.0/install$
I'll try it, it'll take a while
What if you try:
geoip2 /var/lib/GeoIP/GeoLite2-Country.mmdb { auto_reload 24h; $geoip2_country_name source=$http_cf_connecting_ip country names en; $geoip2_country source=$http_cf_connecting_ip default=XX country iso_code; }
With this configuration, the iso code and name are equal. but my ticket is not about how to fix it at the configuration level, but about why with default configurations they are different. imho It looks like compatibility problem with the reailip module and your module somehow affects its operation.
There is no issue with the default config. The source IP address must be explicitly specified in the module configuration. You didn't set the correct source initially, which is why you got this result.
I would recommend using this config:
map $http_cf_connecting_ip $x_real_ip {
'' $remote_addr;
default $http_cf_connecting_ip;
}
geoip2 /var/lib/GeoIP/GeoLite2-Country.mmdb {
auto_reload 24h;
$geoip2_country_name source=$x_real_ip country names en;
$geoip2_country source=$x_real_ip default=XX country iso_code;
}
I noticed that, for some reason, you think that the ngx_http_realip_module module settings somehow affect the ngx_http_geoip2_module module, but that's not the case.
map $http_cf_connecting_ip $x_real_ip { '' $remote_addr; default $http_cf_connecting_ip; }
geoip2 /var/lib/GeoIP/GeoLite2-Country.mmdb { auto_reload 24h; $geoip2_country_name source=$x_real_ip country names en; $geoip2_country source=$x_real_ip default=XX country iso_code; }
I noticed that, for some reason, you think that the ngx_http_realip_module module settings somehow affect the ngx_http_geoip2_module module, but that's not the case.
Your configuration is insecure because anyone can set this header and spoof their IP.
Please re-read my first post and check that the module sets the country name - properly and country code - not
How can this be?