日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

openresty开发系列40--nginx+lua实现获取客户端ip所在的国家信息

發(fā)布時(shí)間:2025/3/20 编程问答 40 豆豆
生活随笔 收集整理的這篇文章主要介紹了 openresty开发系列40--nginx+lua实现获取客户端ip所在的国家信息 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

openresty開發(fā)系列40--nginx+lua實(shí)現(xiàn)獲取客戶端ip所在的國(guó)家信息

為了實(shí)現(xiàn)業(yè)務(wù)系統(tǒng)針對(duì)不同地區(qū)IP訪問,展示包含不同地區(qū)信息的業(yè)務(wù)交互界面。很多情況下系統(tǒng)需要根據(jù)用戶訪問的IP信息,判斷用戶可能的訪問區(qū)域,針對(duì)不同的區(qū)域提供個(gè)性化的服務(wù)內(nèi)容。本方案在CentOS7.6環(huán)境下基于高性能的Openresty1.13.6.1來實(shí)現(xiàn)。

方案介紹

要通過IP地址確認(rèn)歸屬地,通常可以使用一些在線查詢服務(wù)來實(shí)現(xiàn),但使用在線服務(wù)查詢潛在存在性能問題,同時(shí)通過lua來訪問外部服務(wù)增加額外的代碼量。 通過本地的GeoIP庫來實(shí)現(xiàn)查詢是個(gè)比較好的方案,GeoIP提供免費(fèi)和收費(fèi)服務(wù)(https://www.maxmind.com/en/home),大多數(shù)情況下使用定期更新的GeoIP數(shù)據(jù)庫能滿足基本需求。

因此,可以在openresty中通過lua庫本地GeopIP數(shù)據(jù)庫的方式來實(shí)現(xiàn)快速位置查詢和用戶訪問界面重定向。


環(huán)境準(zhǔn)備

一:OpenResty安裝

OpenResty方便地將Nginx和常用的各類lua庫打包發(fā)布,可以方便地參考 https://openresty.org/en/installation.html 文檔從源碼編譯安裝。主要安裝步驟說明如下:

tar -xvf openresty-VERSION.tar.gz
cd openresty-VERSION/
./configure -j2 --prefix=/usr/local/openresty
make -j2
sudo make install

# vim /etc/profile
export PATH=/usr/local/openresty/bin:$PATH

這里的VERSION 是OpenResty具體版本號(hào),目前為 1.13.6.1,編譯安裝后可以通過如下命令查看版本信息:

[root@node5 conf]# /usr/local/openresty/bin/openresty -V
nginx version: openresty/1.13.6.1
built by gcc 4.8.5 20150623 (Red Hat 4.8.5-36) (GCC)
built with OpenSSL 1.0.2k-fips? 26 Jan 2017
TLS SNI support enabled
configure arguments: --prefix=/usr/local/openresty/nginx --with-cc-opt=-O2 --add-module=../ngx_devel_kit-0.3.0 --add-module=../echo-nginx-module-0.61 --add-module=../xss-nginx-module-0.05 --add-module=../ngx_coolkit-0.2rc3 --add-module=../set-misc-nginx-module-0.31 --add-module=../form-input-nginx-module-0.12 --add-module=../encrypted-session-nginx-module-0.07 --add-module=../srcache-nginx-module-0.31 --add-module=../ngx_lua-0.10.11 --add-module=../ngx_lua_upstream-0.07 --add-module=../headers-more-nginx-module-0.33 --add-module=../array-var-nginx-module-0.05 --add-module=../memc-nginx-module-0.18 --add-module=../redis2-nginx-module-0.14 --add-module=../redis-nginx-module-0.3.7 --add-module=../rds-json-nginx-module-0.15 --add-module=../rds-csv-nginx-module-0.08 --add-module=../ngx_stream_lua-0.0.3 --with-ld-opt=-Wl,-rpath,/usr/local/openresty/luajit/lib --with-pcre --with-http_gzip_static_module --with-http_realip_module --with-http_geoip_module --with-http_ssl_module --with-http_stub_status_module --with-stream --with-stream_ssl_module

openresty包含了自身的包維護(hù)工具opm,該工具采用perl實(shí)現(xiàn)依賴MD5,需要執(zhí)行yum install? -y perl-Digest-MD5 安裝


二:GeoIP2安裝

1.從https://dev.maxmind.com/geoip/geoip2/geolite2/ 下載MaxMind格式的GeoIP2數(shù)據(jù)庫保存到本地服務(wù)器,將數(shù)據(jù)庫文件GeoLite2-City.mmdb保存到/usr/local/openresty目錄下

2.GeoIP2 lua庫安裝,GeoIP2 lua庫位于https://github.com/anjia0532/lua-resty-maxminddb ,可以通過如下命令方便安裝:

# /usr/local/openresty/bin/opm get anjia0532/lua-resty-maxminddb


3.GeoIP2 lua庫依賴動(dòng)態(tài)庫安裝:lua庫依賴libmaxminddb實(shí)現(xiàn)對(duì)mmdb的高效訪問。需要編譯該庫并添加到openresty訪問環(huán)境。
從https://github.com/maxmind/libmaxminddb/releases下載相應(yīng)源碼包到本地編譯部署
基本編譯步驟如下:

tar xf libmaxminddb-1.3.2.tar.gz
cd libmaxminddb-1.3.2
./configure
make
make check
make install
ldconfig

默認(rèn)情況下上述操作會(huì)將libmaxminddb.so部署到/usr/local/lib目錄下,為了讓openresty訪問,可以拷貝到openresty目錄下,或通過如下步驟更新ldconfig。

sh -c "echo /usr/local/lib? >> /etc/ld.so.conf.d/local.conf"
ldconfig

三:配置openresty nginx環(huán)境。

1,配置openresty nginx加載相應(yīng)的lua庫和動(dòng)態(tài)庫,需要在http段添加如下指令,其中的;;表示默認(rèn)庫路徑:

lua_package_path? "/usr/local/openresty/lualib/?.lua;;";
lua_package_cpath? "/usr/local/openresty/lualib/?.so;;";

2,指定lua處理請(qǐng)求的方式。 為了簡(jiǎn)易直觀,如下示例的nginx.conf配置指定 /ipinfo 開始的url請(qǐng)求通過/usr/local/lua/getipinfo.lua腳本來處理,這里沒有做其他復(fù)雜的請(qǐng)求和變量處理工作。
lua_code_cache off;參數(shù)只為測(cè)試使用,生產(chǎn)環(huán)境需設(shè)為on;

nginx.conf的server部分添加如下location:
?? ?location /ipinfo {
??????????????? default_type "text/html";
??????????????? charset utf-8;
??????????????? content_by_lua_file? /usr/local/lua/getipinfo.lua;
??????? }

# 獲取ip歸屬的lua腳本:

# vim /usr/local/lua/getipinfo.luangx.say("<br>IP location query result:<hr><br>")local cjson=require 'cjson' local geo=require 'resty.maxminddb' local arg_ip=ngx.var.arg_ip local arg_node=ngx.var.arg_node ngx.say("IP:",arg_ip,", node:",arg_node,"<br>")if not geo.initted() thengeo.init("/usr/local/openresty/GeoLite2-City.mmdb") endlocal res,err=geo.lookup(arg_ip or ngx.var.remote_addr)if not res thenngx.say("Please check the ip address you provided: <div style='color:red'>",arg_ip,"</div>")ngx.log(ngx.ERR,' failed to lookup by ip , reason :',err) elsengx.say("Result:",cjson.encode(res))if arg_node thenngx.say("node name:",ngx.var.arg_node, " , value:",cjson.encode(res[ngx.var.arg_node] or {}))endend

訪問接口:
http://10.11.0.215/ipinfo?ip=120.76.101.211&node=city


IP location query result:

IP:120.76.101.211, node:city
Result:{"city":{"geoname_id":1808926,"names":{"en":"Hangzhou","ru":"Ханчжоу","fr":"Hangzhou","pt-BR":"Hangzhou","zh-CN":"杭州","es":"Hangzhou","de":"Hangzhou","ja":"杭州市"}},"subdivisions":[{"geoname_id":1784764,"names":{"en":"Zhejiang","fr":"Province de Zhejiang","zh-CN":"浙江省"},"iso_code":"ZJ"}],"country":{"geoname_id":1814991,"names":{"en":"China","ru":"Китай","fr":"Chine","pt-BR":"China","zh-CN":"中國(guó)","es":"China","de":"China","ja":"中國(guó)"},"iso_code":"CN"},"registered_country":{"geoname_id":1814991,"names":{"en":"China","ru":"Китай","fr":"Chine","pt-BR":"China","zh-CN":"中國(guó)","es":"China","de":"China","ja":"中國(guó)"},"iso_code":"CN"},"location":{"time_zone":"Asia\/Shanghai","longitude":120.1619,"accuracy_radius":50,"latitude":30.294},"continent":{"geoname_id":6255147,"names":{"en":"Asia","ru":"Азия","fr":"Asie","pt-BR":"ásia","zh-CN":"亞洲","es":"Asia","de":"Asien","ja":"アジア"},"code":"AS"}} node name:city , value:{"geoname_id":1808926,"names":{"en":"Hangzhou","ru":"Ханчжоу","fr":"Hangzhou","pt-BR":"Hangzhou","zh-CN":"杭州","es":"Hangzhou","de":"Hangzhou","ja":"杭州市"}}


格式化輸出:
{
?? ?"city": {
?? ??? ?"geoname_id": 1808926,
?? ??? ?"names": {
?? ??? ??? ?"en": "Hangzhou",
?? ??? ??? ?"ru": "Ханчжоу",
?? ??? ??? ?"fr": "Hangzhou",
?? ??? ??? ?"pt-BR": "Hangzhou",
?? ??? ??? ?"zh-CN": "杭州",
?? ??? ??? ?"es": "Hangzhou",
?? ??? ??? ?"de": "Hangzhou",
?? ??? ??? ?"ja": "杭州市"
?? ??? ?}
?? ?},
?? ?"subdivisions": [{
?? ??? ?"geoname_id": 1784764,
?? ??? ?"names": {
?? ??? ??? ?"en": "Zhejiang",
?? ??? ??? ?"fr": "Province de Zhejiang",
?? ??? ??? ?"zh-CN": "浙江省"
?? ??? ?},
?? ??? ?"iso_code": "ZJ"
?? ?}],
?? ?"country": {
?? ??? ?"geoname_id": 1814991,
?? ??? ?"names": {
?? ??? ??? ?"en": "China",
?? ??? ??? ?"ru": "Китай",
?? ??? ??? ?"fr": "Chine",
?? ??? ??? ?"pt-BR": "China",
?? ??? ??? ?"zh-CN": "中國(guó)",
?? ??? ??? ?"es": "China",
?? ??? ??? ?"de": "China",
?? ??? ??? ?"ja": "中國(guó)"
?? ??? ?},
?? ??? ?"iso_code": "CN"
?? ?},
?? ?"registered_country": {
?? ??? ?"geoname_id": 1814991,
?? ??? ?"names": {
?? ??? ??? ?"en": "China",
?? ??? ??? ?"ru": "Китай",
?? ??? ??? ?"fr": "Chine",
?? ??? ??? ?"pt-BR": "China",
?? ??? ??? ?"zh-CN": "中國(guó)",
?? ??? ??? ?"es": "China",
?? ??? ??? ?"de": "China",
?? ??? ??? ?"ja": "中國(guó)"
?? ??? ?},
?? ??? ?"iso_code": "CN"
?? ?},
?? ?"location": {
?? ??? ?"time_zone": "Asia\/Shanghai",
?? ??? ?"longitude": 120.1619,
?? ??? ?"accuracy_radius": 50,
?? ??? ?"latitude": 30.294
?? ?},
?? ?"continent": {
?? ??? ?"geoname_id": 6255147,
?? ??? ?"names": {
?? ??? ??? ?"en": "Asia",
?? ??? ??? ?"ru": "Азия",
?? ??? ??? ?"fr": "Asie",
?? ??? ??? ?"pt-BR": "ásia",
?? ??? ??? ?"zh-CN": "亞洲",
?? ??? ??? ?"es": "Asia",
?? ??? ??? ?"de": "Asien",
?? ??? ??? ?"ja": "アジア"
?? ??? ?},
?? ??? ?"code": "AS"
?? ?}
}
node name: city, value: {
?? ?"geoname_id": 1808926,
?? ?"names": {
?? ??? ?"en": "Hangzhou",
?? ??? ?"ru": "Ханчжоу",
?? ??? ?"fr": "Hangzhou",
?? ??? ?"pt-BR": "Hangzhou",
?? ??? ?"zh-CN": "杭州",
?? ??? ?"es": "Hangzhou",
?? ??? ?"de": "Hangzhou",
?? ??? ?"ja": "杭州市"
?? ?}
}

線上環(huán)境獲取客戶端ip所在國(guó)家的示例:
nginx.conf主配置,引入ip庫

[root@gdpr04:~]# cat /usr/local/nginx/conf//nginx.conf

#user apache; worker_processes 8;#error_log logs/error.log; #error_log logs/error.log notice; #error_log logs/error.log info;#pid logs/nginx.pid; pid /data/www/logs/nginx.pid;worker_rlimit_nofile 65535;events {use epoll; worker_connections 10240; }http {include mime.types;default_type application/octet-stream;#set_real_ip_from 0.0.0.0/0;#real_ip_header X-Forwarded-For;#proxy_set_header Host $host; #proxy_set_header X-Real-IP $remote_addr; #proxy_set_header X-Forwarded-For $http_x_forwarded_for; #proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_headers_hash_max_size 51200;proxy_headers_hash_bucket_size 6400;ssl_session_cache shared:SSL:10m;ssl_session_timeout 10m;# fastcgi_cache_path /usr/local/nginx/fastcgi_cache levels=1:2 keys_zone=TEST:10m inactive=5m; fastcgi_connect_timeout 300; fastcgi_send_timeout 300; fastcgi_read_timeout 300; fastcgi_buffer_size 64k; fastcgi_buffers 4 64k; # fastcgi_busy_buffers_size 128k; fastcgi_temp_file_write_size 128k; # fastcgi_cache TEST; #fastcgi_cache_valid 200 302 1h; # fastcgi_cache_valid 301 1d; #fastcgi_cache_valid any 1m; # fastcgi_cache_min_uses 1;#geoip_country /usr/local/nginx/conf/GeoIP.dat;#fastcgi_param GEOIP_COUNTRY_CODE $geoip_country_code;geoip2 conf/GeoIP2/GeoIP2-Country.mmdb {auto_reload 5m;$geoip2_metadata_country_build metadata build_epoch;$geoip2_data_country_code source=$remote_addr country iso_code;$geoip2_data_country_name country names en;}geoip2 conf/GeoIP2/GeoIP2-City.mmdb {$geoip2_data_city_name city names en;}fastcgi_param COUNTRY_CODE $geoip2_data_country_code;fastcgi_param COUNTRY_NAME $geoip2_data_country_name;fastcgi_param CITY_NAME $geoip2_data_city_name;open_file_cache max=204800 inactive=20s;open_file_cache_min_uses 1;open_file_cache_valid 30s; #log_format main '$remote_addr - $remote_user [$time_local] "$request" '# '$status $body_bytes_sent "$http_referer" '# '"$http_user_agent" "$http_x_forwarded_for"';# log_format main '[$time_local] $remote_addr $status $request_time $body_bytes_sent "$request" "$http_referer" $upstream_addr $http_x_real_ip $http_x_forwarded_for $http_user_agent $request_filename';log_format main '$remote_addr - - [$time_local] - - "$request" $status $body_bytes_sent "$http_referer" "$http_user_agent" $request_time '; # log_format test '[$fastcgi_script_name] [$time_local] $remote_addr $status $request_time $body_bytes_sent "$request" "$http_referer" $upstream_addr $http_x_real_ip $http_x_forwarded_for $http_user_agent ';log_format error '$remote_addr - - [$time_local] - - "$request" $status $body_bytes_sent "$http_referer" "$http_user_agent" $request_time '; #access_log logs/access.log main;sendfile on;tcp_nodelay on;keepalive_timeout 70;#----for upload fileclient_max_body_size 8M;client_body_buffer_size 2M;#--- for resolve 400 errorclient_header_buffer_size 64k;large_client_header_buffers 4 64k;proxy_connect_timeout 60s;proxy_read_timeout 60s;#60s內(nèi)后端服務(wù)器需要返回成功proxy_send_timeout 60s; proxy_buffer_size 16k;proxy_buffers 4 32k;proxy_busy_buffers_size 64k;proxy_temp_file_write_size 64k;gzip on;gzip_vary off;gzip_min_length 1k;gzip_buffers 4 16k;gzip_http_version 1.0;gzip_comp_level 3;gzip_disable "MSIE [1-6]\.";gzip_types text/plain text/css text/javascript application/x-javascript text/xml application/xml;fastcgi_intercept_errors on;ssi on;ssi_silent_errors on;#ssi_types text/shtml;expires 30d;server_names_hash_bucket_size 20480;#if_modified_since before;#limit_req_zone $binary_remote_addr zone=all_zone:10m rate=3r/s;#limit_req zone=all_zone burst=2 nodelay;limit_req_zone $binary_remote_addr $host $request_uri zone=all_zone:30m rate=4r/s;geo $white_ip {ranges;default 0;1.1.1.1-1.1.1.254 1;192.168.254.1-192.168.254.254 2;}limit_req_whitelist geo_var_name=white_ip geo_var_value=1;limit_req_whitelist geo_var_name=white_ip geo_var_value=2;limit_req_whitelist geo_var_name=white_ip geo_var_value=3;limit_req_whitelist geo_var_name=white_ip geo_var_value=4;limit_req_whitelist geo_var_name=white_ip geo_var_value=5;limit_req_whitelist geo_var_name=white_ip geo_var_value=6;# upstream php_pool{# ip_hash;# server unix:/tmp/php-cgi.sock;# server 192.168.254.126:9000 max_fails=0 fail_timeout=30s weight=3;# keepalive 32;# keepalive_timeout 30s;# check interval=3000 rise=2 fall=5 timeout=1000 type=tcp port=9000;# check_keepalive_requests 100;# check_http_send "HEAD / HTTP/1.1\r\nConnection: keep-alive\r\n\r\n";# check_http_expect_alive http_2xx http_3xx;# }include vhost.d/*.conf;server {listen 80 default_server;server_name localhost;location / {root /data/www/html;index index.html index.htm;}error_page 500 502 503 504 /50x.html;location = /50x.html {root html;}location /ws_status {stub_status on;access_log off;}} } # 具體vhost的配置 # cat country-info.chinasoft.com.conf server {listen 80;server_name country-info.chinasoft.com ;#access_log /data/www/logs/nginx_log/access/country-info.chinasoft.com_access.log main ;#error_log /data/www/logs/nginx_log/error/country-info.chinasoft.com_error.log ;root /data/www/vhosts/common-info.chinasoft.com/httpdocs ;index index.html index.shtml index.php ;error_page 404 403 /404.html;location /api/v1/checkeu {add_header 'Access-Control-Allow-Origin' '*';add_header 'Access-Control-Allow-Credentials' 'true';add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';add_header 'Access-Control-Allow-Headers' 'DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type';default_type 'text/plain';content_by_lua_file '/usr/local/nginx/conf/vhost.d/checkeu.lua';}}server {listen 443;ssl on;ssl_certificate /usr/local/nginx/conf/cert2016/iskysoft_com.crt; ssl_certificate_key /usr/local/nginx/conf/cert2016/iskysoft_com.key;ssl_session_timeout 5m;ssl_protocols TLSv1 TLSv1.1 TLSv1.2;ssl_ciphers "ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-DSS-AES128-GCM-SHA256:kEDH+AESGCM:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-DSS-AES128-SHA256:DHE-RSA-AES256-SHA256:DHE-DSS-AES256-SHA:DHE-RSA-AES256-SHA:!AES128-GCM-SHA256:!AES256-GCM-SHA384:!AES128-SHA256:!AES256-SHA256:!AES128-SHA:!AES256-SHA:AES:!CAMELLIA:DES-CBC3-SHA:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!MD5:!PSK:!aECDH:!EDH-DSS-DES-CBC3-SHA:EDH-RSA-DES-CBC3-SHA:!KRB5-DES-CBC3-SHA";ssl_prefer_server_ciphers on;server_name country-info.chinasoft.com;access_log /data/www/logs/nginx_log/access/country-info.chinasoft.com_access.log main ;error_log /data/www/logs/nginx_log/error/country-info.chinasoft.com_error.log ;root /data/www/vhosts/common-info.chinasoft.com/httpdocs ;index index.html ;error_page 404 403 /404.html;location /api/v1/checkeu {add_header 'Access-Control-Allow-Origin' '*';add_header 'Access-Control-Allow-Credentials' 'true';add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';add_header 'Access-Control-Allow-Headers' 'DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type';default_type 'text/plain';content_by_lua_file '/usr/local/nginx/conf/vhost.d/checkeu.lua';} }

# 獲取國(guó)家的lua腳本
# cat /usr/local/nginx/conf/vhost.d/checkeu.lua

--ngx.say(" {\"c_type\":0}") local ngxmatch=ngx.re.match usercountry = ngx.var.geoip2_data_country_code --usercountry = ngx.var.geoip_country_code eopcountry = "AT|BE|BG|CY|HR|CZ|DK|EE|FI|FR|DE|GR|HU|IE|IT|LV|LT|LU|MT|NL|PL|PT|RO|SK|SI|ES|SE|GB" if not usercountry thenusercountry = '' endif not usercity thenusercity = '' end if ngxmatch(usercountry,eopcountry,"isjo") thenngx.say("{\"c_type\":1,\"country_code\":\""..usercountry.."\"}") elsengx.say("{\"c_type\":0,\"country_code\":\""..usercountry.."\"}") end

訪問:
http://common-info.chinasoft.com/api/v1/checkeu

返回:

?{"c_type":0}
{"c_type":0,"country_code":"CN"}

轉(zhuǎn)載于:https://www.cnblogs.com/reblue520/p/11459250.html

總結(jié)

以上是生活随笔為你收集整理的openresty开发系列40--nginx+lua实现获取客户端ip所在的国家信息的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。