Geo是geographic的缩写,意思是地理的,GeoIP即为IP地理位置数据库,可以根据IP获得地理位置信息。GeoIP库可以根据IP地址(支持IPv4 和 IPv6), 定位该IP所在的 洲、经纬度、国家、省市、ASN 等信息。
GeoIP目前已经升级到GeoIP2,GeoIP2有两个版本,一个免费版(GeoLite2),一个收费版本(GeoIP2, 200$起步)。收费版本的准确率稍高一些,更新频率为每周二更新一次, 免费版是每月第一个周二更新一次。
两者对比可以参考官网说明 GeoIP2 City Accuracy | MaxMind
对于大部分项目来说免费版已经足够使用了.
除了GeoIP外, 其实还有 ip2location、Quova等也提供类似的产品, 但都是收费的,这里我们推荐使用免费版本的GeoIP2
模块名称:ngx_http_geoip2_module
1、下载数据库
登录官网:IP Geolocation and Online Fraud Prevention | MaxMind
下载数据库
注意:需注册登录才能下载
安装libmaxminddb
wget https://github.com/maxmind/libmaxminddb/releases/download/1.6.0/libmaxminddb-1.6.0.tar.gz
tar xf libmaxminddb-1.6.0.tar.gz
cd libmaxminddb-1.6.0 \
&& ./configure \
&& make \
&& make check \
&& make install
2、编译nginx
git clone https://github.com/leev/ngx_http_geoip2_module /usr/src/ngx_http_geoip2_module
cd nginx
./configure --add-dynamic-module=/usr/src/ngx_http_geoip2_module # 动态加载模块
cp GeoLite2-City.mmdb /usr/share/geoip/
cp GeoLite2-Country.mmdb /usr/share/geoip/
3、修改Nginx配置文件
load_module "modules/ngx_http_geoip2_module.so";
http {
map $http_x_forwarded_for $realip {
~^(\d+\.\d+\.\d+\.\d+) $1;
default $remote_addr;
}
geoip2 /usr/share/geoip/GeoLite2-Country.mmdb {
auto_reload 60m;
$geoip2_metadata_country_build metadata build_epoch;
$geoip2_data_country_code source=$realip country iso_code;
$geoip2_data_country_name source=$realip country names en;
}
geoip2 /usr/share/geoip/GeoLite2-City.mmdb {
auto_reload 60m;
$geoip2_metadata_city_build metadata build_epoch;
$geoip2_data_city source=$realip city names en;
$geoip2_data_latitude source=$realip location latitude;
$geoip2_data_longitude source=$realip location longitude;
$geoip2_data_time_zone source=$realip location time_zone;
$geoip2_data_region source=$realip subdivisions iso_code;
$geoip2_data_region_name source=$realip subdivisions names en;
$geoip2_data_country_code source=$realip country iso_code;
$geoip2_data_country_name source=$realip country names en;
$geoip2_data_continent_code source=$realip continent code;
}
include /etc/nginx/mime.types;
default_type application/octet-stream;
log_format main '$remote_addr - $remote_user [$time_iso8601] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
# http://nginx.org/en/docs/http/ngx_http_log_module.html#log_format
log_format json_combined escape=json '{"time_local":"$time_iso8601", '
'"proxy_addr":"$remote_addr", '
'"remote_addr":"$http_x_forwarded_for", '
'"remote_user":"$remote_user", '
'"request":"$request", '
'"status":$status, '
'"geoip":{'
'"ip":"$http_x_forwarded_for", '
'"latitude":"$geoip2_data_latitude", '
'"longitude":"$geoip2_data_longitude", '
'"region_code":"$geoip2_data_region", '
'"region_name":"$geoip2_data_region_name", '
'"city_name":"$geoip2_data_city", '
'"country_name":"$geoip2_data_country_name", '
'"country_code2":"$geoip2_data_country_code", '
'"continent_code":"$geoip2_data_continent_code", '
'"time_zone":"$geoip2_data_time_zone" '
'}, '
'"body_bytes_sent":$body_bytes_sent, '
'"request_length":$request_length, '
'"request_time":$request_time, '
'"upstream_connect_time":"$upstream_connect_time", '
'"upstream_header_time":"$upstream_header_time", '
'"upstream_response_time":"$upstream_response_time", '
'"http_referrer":"$http_referer", '
'"http_user_agent":"$http_user_agent"}';
如果已经添加了nginx-module-vts模块的话可以进一步设置
load_module "modules/ngx_http_geoip2_module.so";
user nginx;
worker_processes auto;
worker_cpu_affinity auto;
worker_rlimit_nofile 65535;
worker_shutdown_timeout 10s;
error_log /var/log/nginx/error.log warn;
pid /var/run/nginx.pid;
events {
worker_connections 65535;
multi_accept on;
use epoll;
accept_mutex on;
accept_mutex_delay 300ms;
worker_aio_requests 128;
}
http {
map $http_x_forwarded_for $realip {
~^(\d+\.\d+\.\d+\.\d+) $1;
default $remote_addr;
}
geoip2 /usr/share/geoip/GeoLite2-Country.mmdb {
auto_reload 60m;
$geoip2_metadata_country_build metadata build_epoch;
$geoip2_data_country_code source=$realip country iso_code;
$geoip2_data_country_name source=$realip country names en;
}
geoip2 /usr/share/geoip/GeoLite2-City.mmdb {
auto_reload 60m;
$geoip2_metadata_city_build metadata build_epoch;
$geoip2_data_city source=$realip city names en;
$geoip2_data_latitude source=$realip location latitude;
$geoip2_data_longitude source=$realip location longitude;
$geoip2_data_time_zone source=$realip location time_zone;
$geoip2_data_region source=$realip subdivisions iso_code;
$geoip2_data_region_name source=$realip subdivisions names en;
$geoip2_data_country_code source=$realip country iso_code;
$geoip2_data_country_name source=$realip country names en;
$geoip2_data_continent_code source=$realip continent code;
}
vhost_traffic_status_zone;
vhost_traffic_status_filter_by_set_key $geoip2_data_country_code country::*;
vhost_traffic_status_filter_by_host on;
include /etc/nginx/mime.types;
default_type application/octet-stream;
log_format main '$remote_addr - $remote_user [$time_iso8601] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
# http://nginx.org/en/docs/http/ngx_http_log_module.html#log_format
log_format json_combined escape=json '{"time_local":"$time_iso8601", '
'"proxy_addr":"$remote_addr", '
'"remote_addr":"$http_x_forwarded_for", '
'"remote_user":"$remote_user", '
'"request":"$request", '
'"status":$status, '
'"geoip":{'
'"ip":"$http_x_forwarded_for", '
'"latitude":"$geoip2_data_latitude", '
'"longitude":"$geoip2_data_longitude", '
'"region_code":"$geoip2_data_region", '
'"region_name":"$geoip2_data_region_name", '
'"city_name":"$geoip2_data_city", '
'"country_name":"$geoip2_data_country_name", '
'"country_code2":"$geoip2_data_country_code", '
'"continent_code":"$geoip2_data_continent_code", '
'"time_zone":"$geoip2_data_time_zone" '
'}, '
'"body_bytes_sent":$body_bytes_sent, '
'"request_length":$request_length, '
'"request_time":$request_time, '
'"upstream_connect_time":"$upstream_connect_time", '
'"upstream_header_time":"$upstream_header_time", '
'"upstream_response_time":"$upstream_response_time", '
'"http_referrer":"$http_referer", '
'"http_user_agent":"$http_user_agent"}';
# access_log /dev/stdout json_combined;
# error_log /dev/stderr info;
# Copy data between file descriptors within the kernel
# Faster then read() + write()
sendfile on;
# Send all headers at once
tcp_nopush on;
# Don't buffer data when sending. Good for small data bursts in real time
tcp_nodelay on;
# Hide all server version information
server_tokens off;
expires 30d;
variables_hash_max_size 2048;
variables_hash_bucket_size 512;
keepalive_timeout 65;
gzip on;
gzip_min_length 10240;
gzip_disable msie6;
gzip_static always;
gunzip on;
gzip_proxied expired no-cache no-store private auth;
gzip_comp_level 6;
gzip_http_version 1.1;
gzip_proxied any;
gzip_buffers 16 8k;
gzip_vary on;
gzip_types text/xml application/xml application/atom+xml application/rss+xml application/xhtml+xml image/svg+xml text/javascript application/javascript application/x-javascript text/x-json application/json application/x-web-app-manifest+json text/css text/plain text/x-component font/opentype application/x-font-ttf application/vnd.ms-fontobject image/x-icon;
add_header X-Frame-Options DENY;
add_header X-XSS-Protection "1; mode=block";
add_header X-Content-Type-Options nosniff;
# Allow the server to close connection on non responding client. This will free up memory
reset_timedout_connection on;
ignore_invalid_headers on;
underscores_in_headers on;
client_header_buffer_size 2k;
large_client_header_buffers 4 16k;
client_header_timeout 30s;
request_pool_size 4k;
merge_slashes on;
msie_padding on;
include /etc/nginx/conf.d/*.conf;
include /etc/nginx/proxy.conf;
server {
listen 11050;
server_name nginx_vts_status
access_log off;
vhost_traffic_status_filter_by_set_key $geoip2_data_country_code country::$server_name;
location /status {
vhost_traffic_status_bypass_limit on;
vhost_traffic_status_bypass_stats on;
vhost_traffic_status_display;
vhost_traffic_status_display_format json;
}
}
}
评论区