目 录CONTENT

文章目录

Nginx利用geoip实现基于地理位置的代理

简中仙
2022-09-07 / 0 评论 / 0 点赞 / 61 阅读 / 0 字 / 正在检测是否收录...
温馨提示:
本文最后更新于2023-10-07,若内容或图片失效,请留言反馈。 本文如有错误或者侵权的地方,欢迎您批评指正!

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;
        }
    }
}
0

评论区