openresty开发系列40--nginx+lua实现获取客户端ip所在的国家信息
openresty开发系列40--nginx+lua实现获取客户端ip所在的国家信息
为了实现业务系统针对不同地区IP访问,展示包含不同地区信息的业务交互界面。很多情况下系统需要根据用户访问的IP信息,判断用户可能的访问区域,针对不同的区域提供个性化的服务内容。本方案在CentOS7.6环境下基于高性能的Openresty1.13.6.1来实现。
方案介绍
要通过IP地址确认归属地,通常可以使用一些在线查询服务来实现,但使用在线服务查询潜在存在性能问题,同时通过lua来访问外部服务增加额外的代码量。 通过本地的GeoIP库来实现查询是个比较好的方案,GeoIP提供免费和收费服务(https://www.maxmind.com/en/home),大多数情况下使用定期更新的GeoIP数据库能满足基本需求。
因此,可以在openresty中通过lua库本地GeopIP数据库的方式来实现快速位置查询和用户访问界面重定向。
环境准备
一:OpenResty安装
OpenResty方便地将Nginx和常用的各类lua库打包发布,可以方便地参考 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具体版本号,目前为 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包含了自身的包维护工具opm,该工具采用perl实现依赖MD5,需要执行yum install -y perl-Digest-MD5 安装
二:GeoIP2安装
1.从https://dev.maxmind.com/geoip/geoip2/geolite2/ 下载MaxMind格式的GeoIP2数据库保存到本地服务器,将数据库文件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库依赖动态库安装:lua库依赖libmaxminddb实现对mmdb的高效访问。需要编译该库并添加到openresty访问环境。
从https://github.com/maxmind/libmaxminddb/releases下载相应源码包到本地编译部署
基本编译步骤如下:
tar xf libmaxminddb-1.3.2.tar.gz
cd libmaxminddb-1.3.2
./configure
make
make check
make install
ldconfig
默认情况下上述操作会将libmaxminddb.so部署到/usr/local/lib目录下,为了让openresty访问,可以拷贝到openresty目录下,或通过如下步骤更新ldconfig。
sh -c "echo /usr/local/lib  >> /etc/ld.so.conf.d/local.conf"
ldconfig
三:配置openresty nginx环境。
1,配置openresty nginx加载相应的lua库和动态库,需要在http段添加如下指令,其中的;;表示默认库路径:
lua_package_path  "/usr/local/openresty/lualib/?.lua;;";
lua_package_cpath  "/usr/local/openresty/lualib/?.so;;";
2,指定lua处理请求的方式。 为了简易直观,如下示例的nginx.conf配置指定 /ipinfo 开始的url请求通过/usr/local/lua/getipinfo.lua脚本来处理,这里没有做其他复杂的请求和变量处理工作。
lua_code_cache off;参数只为测试使用,生产环境需设为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.lua
ngx.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() then
        geo.init("/usr/local/openresty/GeoLite2-City.mmdb")
end
local res,err=geo.lookup(arg_ip or ngx.var.remote_addr)
if not res then
        ngx.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)
else
        ngx.say("Result:",cjson.encode(res))
        if arg_node then
                ngx.say("node name:",ngx.var.arg_node, " , value:",cjson.encode(res[ngx.var.arg_node] or {}))
        end
end
访问接口:
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":"中国","es":"China","de":"China","ja":"中国"},"iso_code":"CN"},"registered_country":{"geoname_id":1814991,"names":{"en":"China","ru":"Китай","fr":"Chine","pt-BR":"China","zh-CN":"中国","es":"China","de":"China","ja":"中国"},"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": "中国",
            "es": "China",
            "de": "China",
            "ja": "中国"
        },
        "iso_code": "CN"
    },
    "registered_country": {
        "geoname_id": 1814991,
        "names": {
            "en": "China",
            "ru": "Китай",
            "fr": "Chine",
            "pt-BR": "China",
            "zh-CN": "中国",
            "es": "China",
            "de": "China",
            "ja": "中国"
        },
        "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": "杭州市"
    }
}
线上环境获取客户端ip所在国家的示例:
nginx.conf主配置,引入ip库
[root@gdpr04:~]# cat /usr/local/nginx/conf//nginx.conf
#user apache;
worker_processes ; #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 ; events {
use epoll;
worker_connections ;
} http {
include mime.types;
default_type application/octet-stream;
#set_real_ip_from 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 ;
proxy_headers_hash_bucket_size ; ssl_session_cache shared:SSL:10m;
ssl_session_timeout 10m; # fastcgi_cache_path /usr/local/nginx/fastcgi_cache levels=: keys_zone=TEST:10m inactive=5m;
fastcgi_connect_timeout ;
fastcgi_send_timeout ;
fastcgi_read_timeout ;
fastcgi_buffer_size 64k;
fastcgi_buffers 64k;
# fastcgi_busy_buffers_size 128k;
fastcgi_temp_file_write_size 128k;
# fastcgi_cache TEST;
#fastcgi_cache_valid 1h;
# fastcgi_cache_valid 1d;
#fastcgi_cache_valid any 1m;
# fastcgi_cache_min_uses ;
#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= inactive=20s;
open_file_cache_min_uses ;
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 ;
#----for upload file
client_max_body_size 8M;
client_body_buffer_size 2M;
#--- for resolve error
client_header_buffer_size 64k;
large_client_header_buffers 64k;
proxy_connect_timeout 60s;
proxy_read_timeout 60s;
#60s内后端服务器需要返回成功
proxy_send_timeout 60s;
proxy_buffer_size 16k;
proxy_buffers 32k;
proxy_busy_buffers_size 64k;
proxy_temp_file_write_size 64k;
gzip on;
gzip_vary off;
gzip_min_length 1k;
gzip_buffers 16k;
gzip_http_version 1.0;
gzip_comp_level ;
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 ;
#if_modified_since before;
#limit_req_zone $binary_remote_addr zone=all_zone:10m rate=3r/s;
#limit_req zone=all_zone burst= nodelay; limit_req_zone $binary_remote_addr $host $request_uri zone=all_zone:30m rate=4r/s; geo $white_ip {
ranges;
default ;
1.1.1.1-1.1.1.254 ;
192.168.254.1-192.168.254.254 ;
} limit_req_whitelist geo_var_name=white_ip geo_var_value=;
limit_req_whitelist geo_var_name=white_ip geo_var_value=;
limit_req_whitelist geo_var_name=white_ip geo_var_value=;
limit_req_whitelist geo_var_name=white_ip geo_var_value=;
limit_req_whitelist geo_var_name=white_ip geo_var_value=;
limit_req_whitelist geo_var_name=white_ip geo_var_value=; # upstream php_pool{
# ip_hash;
# server unix:/tmp/php-cgi.sock;
# server 192.168.254.126: max_fails= fail_timeout=30s weight=; # keepalive ;
# keepalive_timeout 30s; # check interval= rise= fall= timeout= type=tcp port=;
# check_keepalive_requests ;
# 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 ;
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 /.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 ;
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. TLSv1.;
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 /.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';
}
}
# 获取国家的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 then
   usercountry = ''
end
if not usercity then
   usercity = ''
end
if ngxmatch(usercountry,eopcountry,"isjo") then
   ngx.say("{\"c_type\":1,\"country_code\":\""..usercountry.."\"}")
else
   ngx.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"}
# 如果国家是中国,则跳转指定网站
# nginx.conf的http部分添加
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;
# server 部分添加
if ($geoip2_data_country_code = CN) {
    rewrite ^/(.*)$ https://www.baidu.com/$1 permanent;
}
# 当访问 www.chinasoft.com 是中国时,跳转到cn页面
如果按照一般思维就是这么写,但是nginx不支持这种写法
if ($geoip2_data_country_code = CN && $request_uri !~* "cn") { 
   rewrite ^/(.*)$ https://www.chinasoft.com/cn/$1 permanent;
}
# 可以曲线救国,具体如下
set $flag 0; 
if ($geoip2_data_country_code = CN) { 
   set $flag "${flag}1"; 
} 
if ($request_uri !~* "cn") { 
   set $flag "${flag}2"; 
} 
if ($flag = "012") { 
    rewrite ^/(.*)$ https://www.chinasoft.com/cn/$1 permanent;
}
示例2:当国家为cn即中国则跳转到forbidden.html页面
set $flag ;
if ($geoip2_data_country_code = CN) {
set $flag "${flag}1";
}
if ($request_uri !~* "/forbidden.html") {
set $flag "${flag}2";
}
if ($flag = "") {
rewrite ^/(.*)$ https://my.xx.com/forbidden.html permanent;
}
条件组合示例:
# cat /usr/local/nginx/conf//vhost.d/chinasoft.com.conf
整体规则是01///04为白名单
/06为黑名单 map $http_origin $corsHost {
default "none" ;
"~https://chinasoft.com" https://chinasoft.com ;
"~https://chinasoft-com.cdn.ampproject.org" https://chinasoft-com.cdn.ampproject.org ;
"~https://chinasoft.com.amp.cloudflare.com" https://chinasoft.com.amp.cloudflare.com ;
"~https://cdn.ampproject.org" https://cdn.ampproject.org ;
"~https://images.chinasoft.com" https://images.chinasoft.com ;
"~https://my.chinasoft.com" https://my.chinasoft.com ;
"~https://store.chinasoft.com" https://store.chinasoft.com ;
"~https://my.chinasoft.jp" https://my.chinasoft.jp ;
"~https://support.chinasoft.com" https://support.chinasoft.com;
} server {
listen ;
server_name chinasoft.com www.chinasoft.com ori-www.chinasoft.com;
access_log /data/www/logs/nginx_log/access/chinasoft.com_access.log main ;
error_log /data/www/logs/nginx_log/error/chinasoft.com_error.log ;
root /data/www/vhosts/chinasoft.com/httpdocs ;
index index.html index.shtml index.php ;
include rewrite.d/chinasoft.com.conf ;
error_page /.html;
rewrite ^/(.*)$ https://www.chinasoft.com/$1 permanent; #跳转到Https location ~ \.php$ {
fastcgi_pass unix:/tmp/php-cgi.sock;
fastcgi_index index.php;
#fastcgi_param SCRIPT_FILENAME ;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
expires -;
} location / {
include proxy_params;
if (!-d $request_filename){
set $flag $flag;
}
if (!-f $request_filename){
set $flag $flag;
}
if ($flag = ""){
rewrite ^(.*)$ /index.php last;
expires -;
} } } server {
listen ;
ssl on; ssl_certificate cert2016/chinasoft_com.crt;
ssl_certificate_key cert2016/chinasoft_com.key;
ssl_dhparam cert2016/dh_2048.pem; ssl_session_timeout 5m;
ssl_protocols TLSv1 TLSv1. TLSv1.; 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-SA: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;
# add_header Strict-Transport-Security max-age=; #ssl_stapling on;
#ssl_stapling_verify on; server_name chinasoft.com www.chinasoft.com ori-www.chinasoft.com ;
access_log /data/www/logs/nginx_log/access/chinasoft.com_access.log main ;
error_log /data/www/logs/nginx_log/error/chinasoft.com_error.log ; root /data/www/vhosts/chinasoft.com/httpdocs ;
index index.html index.shtml index.php ;
include rewrite.d/chinasoft.com.conf ; error_page /.html; add_header 'Access-Control-Allow-Origin' '*'; add_header Access-Control-Allow-Origin $corsHost;
add_header Access-Control-Allow-Methods 'GET, POST, OPTIONS';
add_header Access-Control-Allow-Headers 'DNT,X-Mx-ReqToken,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Authorization';
#add 2020.03.
set $flag ;
#公司IP白名单
#include route.sz_office.conf; #容许爬虫
if ($http_user_agent ~ .*(Googlebot|Baiduspider).*){
set $flag "${flag}1";
} if ($request_uri ~ "(forbidden.html|contact.html|feedback-successful.html|error.html)") {
set $flag "${flag}2";
} #公司IP白名单
if ($remote_addr ~ "(1.1.1.1|1.1.1.2)") {
set $flag "${flag}3";
} if ($request_uri ~ .*(\/ad\/).*){
set $flag "${flag}4";
} #限制特定国家访问
if ($geoip2_data_country_code ~ "^(HK|MO|TW|DK|UA|IL|RU|BG|HR|IS|LI|CA|HU|LU|SM|RS|AT|AD|GR|DE|IT|LV|NO|CZ|MD|MC|SK|SI|SG|NZ|JP|CL|VA|BE|FR|FO|PL|AU|IE|EE|SE|CH|BY|LT|RO|US|FI|GB|NL|PT|ES|AL|AR|MK|MT|KR|BA)") {
set $flag "${flag}5";
} if ($geoip2_data_country_code ~ "^(CN)") {
set $flag "${flag}6";
} # 黑名单规则
if ($flag = "") {
rewrite ^/(.*)$ https://www.chinasoft.com/forbidden.html permanent;
} # 黑名单规则
if ($flag = "") {
rewrite ^/(.*)$ https://www.chinasoft.com/error.html permanent;
} location ~ \.php$ {
try_files $uri =;
fastcgi_pass unix:/tmp/php-cgi.sock;
fastcgi_index index.php;
#fastcgi_param SCRIPT_FILENAME ;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
expires -;
} location / {
include proxy_params;
if (!-d $request_filename){
set $flag $flag;
}
if (!-f $request_filename){
set $flag $flag;
}
if ($flag = ""){
rewrite ^(.*)$ /index.php last ;
expires -;
}
} } # /usr/local/nginx/conf/route.sz_office.conf
allow 1.1.1.2/;
allow 2.2.2.2;
allow 127.0.0.1 ;
#deny all ;
整体规则是01/02/03/04为白名单
05/06为黑名单
map $http_origin $corsHost {  
default "none" ; 
"~https://chinasoft.com" https://chinasoft.com ;
"~https://chinasoft-com.cdn.ampproject.org" https://chinasoft-com.cdn.ampproject.org ;
"~https://chinasoft.com.amp.cloudflare.com" https://chinasoft.com.amp.cloudflare.com ;
"~https://cdn.ampproject.org" https://cdn.ampproject.org ;
"~https://images.chinasoft.com" https://images.chinasoft.com ;
"~https://my.chinasoft.com" https://my.chinasoft.com ;
"~https://store.chinasoft.com" https://store.chinasoft.com ;
"~https://my.chinasoft.jp" https://my.chinasoft.jp ;
"~https://support.chinasoft.com" https://support.chinasoft.com;
}
server {
        listen 80;
        server_name     chinasoft.com  www.chinasoft.com ori-www.chinasoft.com;
        access_log      /data/www/logs/nginx_log/access/chinasoft.com_access.log main ;
        error_log       /data/www/logs/nginx_log/error/chinasoft.com_error.log ;
        root            /data/www/vhosts/chinasoft.com/httpdocs ;
        index           index.html index.shtml index.php ;
    include        rewrite.d/chinasoft.com.conf ;
    error_page  404 403             /404.html;    
        rewrite ^/(.*)$ https://www.chinasoft.com/$1 permanent;    #跳转到Https
location ~ \.php$ {
                fastcgi_pass unix:/tmp/php-cgi.sock;
                fastcgi_index index.php;
                #fastcgi_param SCRIPT_FILENAME ;
                fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
                include fastcgi_params;
                expires -1;
        }
location / {
            include proxy_params;
        if (!-d $request_filename){
            set $flag 1$flag;
        }
        if (!-f $request_filename){
            set $flag 2$flag;
        }
        if ($flag = "21"){
                    rewrite ^(.*)$ /index.php last;
            expires -1;    
        }
        
        }
}
server {
        listen 443;
        ssl on;
ssl_certificate         cert2016/chinasoft_com.crt;
        ssl_certificate_key     cert2016/chinasoft_com.key;
        ssl_dhparam     cert2016/dh_2048.pem;
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-SA: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;
#       add_header Strict-Transport-Security max-age=15768000;
#ssl_stapling        on;
        #ssl_stapling_verify        on;
server_name     chinasoft.com www.chinasoft.com ori-www.chinasoft.com ;
        access_log      /data/www/logs/nginx_log/access/chinasoft.com_access.log main ;
        error_log       /data/www/logs/nginx_log/error/chinasoft.com_error.log ;
root            /data/www/vhosts/chinasoft.com/httpdocs ;
        index           index.html index.shtml index.php ;
        include         rewrite.d/chinasoft.com.conf ;
        
    error_page  404 403             /404.html;
add_header 'Access-Control-Allow-Origin' '*';
add_header Access-Control-Allow-Origin $corsHost;
    add_header Access-Control-Allow-Methods 'GET, POST, OPTIONS';
    add_header Access-Control-Allow-Headers 'DNT,X-Mx-ReqToken,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Authorization';
    #add 2020.03.26 
    set $flag 0;
    #公司IP白名单
    #include route.sz_office.conf;
    
    #容许爬虫
    if ($http_user_agent ~ .*(Googlebot|Baiduspider).*){
           set $flag "${flag}1";
    }
if ($request_uri ~ "(forbidden.html|contact.html|feedback-successful.html|error.html)") {
           set $flag "${flag}2";
        }
#公司IP白名单
        if ($remote_addr ~ "(1.1.1.1|1.1.1.2)") {
           set $flag "${flag}3";
        }
if ($request_uri ~ .*(\/ad\/).*){
           set $flag "${flag}4";
        }
#限制特定国家访问
        if ($geoip2_data_country_code ~ "^(HK|MO|TW|DK|UA|IL|RU|BG|HR|IS|LI|CA|HU|LU|SM|RS|AT|AD|GR|DE|IT|LV|NO|CZ|MD|MC|SK|SI|SG|NZ|JP|CL|VA|BE|FR|FO|PL|AU|IE|EE|SE|CH|BY|LT|RO|US|FI|GB|NL|PT|ES|AL|AR|MK|MT|KR|BA)") {
           set $flag "${flag}5";
        }
if ($geoip2_data_country_code ~ "^(CN)") {
           set $flag "${flag}6";
        }
    
    # 黑名单规则
        if ($flag = "05") {
            rewrite ^/(.*)$ https://www.chinasoft.com/forbidden.html permanent;
        }
# 黑名单规则
        if ($flag = "06") {
            rewrite ^/(.*)$ https://www.chinasoft.com/error.html permanent;
        }
location ~ \.php$ {
        try_files $uri =404;
                fastcgi_pass unix:/tmp/php-cgi.sock;
                fastcgi_index index.php;
                #fastcgi_param SCRIPT_FILENAME ;
                fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
                include fastcgi_params;
                expires -1;
        }
location / {
                include proxy_params;
                if (!-d $request_filename){
                        set $flag 1$flag;
                }
                if (!-f $request_filename){
                        set $flag 2$flag;
                }
                if ($flag = "21"){
                        rewrite ^(.*)$ /index.php last ;
                        expires -1;
                }
        }
}
# /usr/local/nginx/conf/route.sz_office.conf 
allow   1.1.1.2/29;
allow   2.2.2.2;
allow   127.0.0.1 ;
#deny    all ;
openresty开发系列40--nginx+lua实现获取客户端ip所在的国家信息的更多相关文章
- openresty开发系列38--通过Lua+Redis 实现动态封禁IP
		
openresty开发系列38--通过Lua+Redis 实现动态封禁IP 一)需求背景为了封禁某些爬虫或者恶意用户对服务器的请求,我们需要建立一个动态的 IP 黑名单.对于黑名单之内的 IP ,拒绝 ...
 - openresty开发系列24--openresty中lua的引入及使用
		
openresty开发系列24--openresty中lua的引入及使用 openresty 引入 lua 一)openresty中nginx引入lua方式 1)xxx_by_lua ---> ...
 - 获取客户端IP地址定位城市信息
		
获取客户端IP地址定位城市信息 1.首先获取客户端的IP地址 function getIPaddress(){ $IPaddress=''; if (isset($_SERVER)){ if (iss ...
 - WebService 获取客户端 IP 和 MAC 等信息
		
IP地址 public string getClientIP() { string result = HttpContext.Current.Request.ServerVariables[" ...
 - (效果五)js获取客户端ip地址及浏览器信息
		
在前端开发的时候,有时候为了测试需要得到访问客户的ip地址.虽说是后端来做的,但是我们前端也可以完成. 先说下获取用户ip地址,包括像ipv4,ipv6,掩码等内容,但是大部分都要根据浏览器的支持情况 ...
 - JAVA中经过nginx反向代理获取客户端ip并获取相关坐标等信息
		
关于搜狐新浪ip库查询接口的使用 直接输出访客ip及所在城市: <script src="http://pv.sohu.com/cityjson?ie=utf-8" > ...
 - openresty开发系列28--openresty中操作mysql
		
openresty开发系列28--openresty中操作mysql Mysql客户端 应用中最常使用的就是数据库了,尤其mysql数据库,那openresty lua如何操作mysql呢? ...
 - 【原创】大叔问题定位分享(36)openresty(nginx+lua)中获取不到post数据,ngx.req.get_body_data返回nil
		
openresty(nginx+lua)中获取不到post数据,ngx.req.get_body_data返回nil This function returns nil if the request ...
 - openresty开发系列37--nginx-lua-redis实现访问频率控制
		
openresty开发系列37--nginx-lua-redis实现访问频率控制 一)需求背景 在高并发场景下为了防止某个访问ip访问的频率过高,有时候会需要控制用户的访问频次在openresty中, ...
 
随机推荐
- 【Mybatis异常】 org.apache.ibatis.binding.BindingException: Parameter 'storeId' not found. Available parameters are [form, param1]
			
一.异常信息 2019-05-31 16:06:25.272 [http-nio-10650-exec-3] WARN o.s.w.s.m.m.a.ExceptionHandlerExceptionR ...
 - Linux之RHEL7root密码破解(二)
			
破解Linux root密码的第二种方法,如下: 首先开机,进入启动界面,接着找到如下图所示的代码字段,将ro改成rw init=/sysroot/bin/sh ,如下图: 之后按“Ctrl+X”之后 ...
 - beta版本——第五次冲刺
			
第五次冲刺 (1)SCRUM部分☁️ 成员描述: 姓名 李星晨 完成了哪个任务 界面优化 花了多少时间 2h 还剩余多少时间 2h 遇到什么困难 没有 这两天解决的进度 2/2 后续两天的计划 完成文 ...
 - HRBUST  2040 二叉树的遍历
			
给出一棵二叉树的中序和前序遍历,输出它的后序遍历. Input 本题有多组数据,输入处理到文件结束. 每组数据的第一行包括一个整数n,表示这棵二叉树一共有n个节点. 接下来的一行每行包括n个整数,表示 ...
 - IntelliJ IDEA自身以及maven项目打包方式
			
1. Idea自身打包方式 1.1 创建Artifacts 快捷键(Ctrl+Alt+Shift+S)打开项目的Project Structure.在Artifacts创建 接着,指定main cla ...
 - jQuery 查找和过滤
			
通常情况下选择器可以直接定位到我们想要的元素,但是,当我们拿到一个jQuery对象后,还可以以这个对象为基准,进行查找和过滤. 最常见的查找是在某个节点的所有子节点中查找,使用find()方法,它本身 ...
 - 13-Flutter移动电商实战-ADBanner组件的编写
			
1.AdBanner组件的编写 我们还是把这部分单独出来,需要说明的是,这个Class你也是可以完全独立成一个dart文件的.代码如下: 广告图片class AdBanner extends Stat ...
 - CentOS7中使用yum安装nginx和php7.2的方法
			
c 1.安装源 安装php72w,是需要配置额外的yum源地址的,否则会报错不能找到相关软件包. php高版本的yum源地址,有两部分,其中一部分是epel-release,另外一部分来自webtat ...
 - (尚020)Vue打包发布项目
			
1.项目的打包与发布 1.1打包: npm run build 报错: 原因:原来eslint是一个语法检查工具,但是限制很严格,在我的vue文件里面很多空格都会导致红线(红线可以关闭提示),虽然可以 ...
 - jaeger使用yugabyte作为后端存储的尝试以及几个问题
			
前边写过使用scylladb 做为jaeger 的后端存储,还是一个不错选择的包括性能以及 兼容性,对于 yugabyte 当前存在兼容性的问题,需要版本的支持,或者尝试进行一些变动 create 语 ...