參考代碼
https://gitee.com/xiaoyun461/blocking-external-networks
首先 需要的依賴:
libmaxminddb
https://github.com/maxmind/libmaxminddb
maxmind-geoip
https://github.com/Dreamacro/maxmind-geoip
libmaxminddb
需要gcc
編譯,可用 Dockerfile
里面編譯生成so文件,然后復(fù)制到 openresty/openresty:centos-rpm
鏡像中,然后把 Country.mmdb
(Ip數(shù)據(jù)庫) 也復(fù)制到鏡像中
Dockerfile 如下:
############## 構(gòu)建 libmaxminddb #####################
FROM gcc:9 AS libmaxminddb-build
ADD lib/libmaxminddb-1.8.0.tar.gz /
WORKDIR /libmaxminddb-1.8.0
RUN ./configure && make && make install && ldconfig -v && ls -f /usr/local/lib/libmaxminddb*
############## 構(gòu)建 openresty #####################
FROM openresty/openresty:centos-rpm
ENV TZ Asia/Shanghai
COPY --from=libmaxminddb-build /usr/local/lib/libmaxminddb.so.0.0.7 /lib64
COPY geoip/20231212/Country.mmdb /etc/nginx/mmdb/Country.mmdb
RUN ln -snf /usr/share/zoneinfo/"$TZ" /etc/localtime && echo "$TZ" > /etc/timezone \
&& opm get anjia0532/lua-resty-maxminddb \
&& ln -s /lib64/libmaxminddb.so.0.0.7 /lib64/libmaxminddb.so \
&& ldconfig -v
然后配置lua腳本,OpenResty(也稱為 ngx_openresty)是一個基于 Nginx 與 Lua 的高性能 Web 平臺,
lua腳本如下:
local function get_client_ip()
local headers = ngx.req.get_headers()
local clientIP = headers["x-forwarded-for"]
if clientIP == nil or string.len(clientIP) == 0 or clientIP == "unknown" then
clientIP = headers["Proxy-Client-IP"]
end
if clientIP == nil or string.len(clientIP) == 0 or clientIP == "unknown" then
clientIP = headers["WL-Proxy-Client-IP"]
end
if clientIP == nil or string.len(clientIP) == 0 or clientIP == "unknown" then
clientIP = ngx.var.remote_addr
end
-- 對于通過多個代理的情況,第一個IP為客戶端真實IP,多個IP按照','分割
if clientIP ~= nil and string.len(clientIP) > 15 then
local pos = string.find(clientIP, ",", 1)
clientIP = string.sub(clientIP, 1, pos - 1)
end
return clientIP;
end
local function check_cn(ip)
local geo = require 'resty.maxminddb'
if not geo.initted() then
geo.init("/etc/nginx/mmdb/Country.mmdb")
end
local res, err = geo.lookup(ip)
if not res then
ngx.log(ngx.ERR, ' failed to lookup by ip , reason :', err)
else
for k, v in pairs(res) do
if (k == "country") then
for key, item in pairs(v) do
if (key == "iso_code") then
if item == "CN" then
ngx.log(ngx.INFO, ' this counrty: ', item)
return 1;
else
ngx.log(ngx.ERR, ' this counrty: ', item)
return 0;
end
end
end
end
end
end
end
-- 獲取nginx 本地緩存
local cache_ngx = ngx.shared.dis_cache;
-- 獲取 請求IP
local clientIP = get_client_ip();
--根據(jù)IP 獲取本地黑名單緩存數(shù)據(jù)
local banIpCache = cache_ngx:get('ban_ip_' .. clientIP);
if banIpCache == 1 then
ngx.log(ngx.ERR, "cache_black_ip:", clientIP)
ngx.exit(403)
else
-- 判斷是否是國外IP, 直接設(shè)為黑名單,并且返回403
local flag = check_cn(clientIP);
if flag == 0 then
-- 本地緩存黑名單 時間1小時
ngx.log(ngx.ERR, "set_local_black_ip:", clientIP)
cache_ngx:set('ban_ip_' .. clientIP, 1, 60 * 60);
ngx.exit(403)
end
end
nginx.conf 配置文件 也要加入 lua腳本校驗,以及 增加128M的本地緩存,方便過濾
nginx.conf如下:
pcre_jit on;
#error_log logs/error.log;
#error_log logs/error.log notice;
#error_log logs/error.log info;
error_log logs/error.log warn;
#pid logs/nginx.pid;
worker_processes auto;
events {
worker_connections 20480;
}
http {
include mime.types;
default_type application/octet-stream;
# Enables or disables the use of underscores in client request header fields.
# When the use of underscores is disabled, request header fields whose names contain underscores are marked as invalid and become subject to the ignore_invalid_headers directive.
# underscores_in_headers off;
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
access_log /dev/stdout main;
# Log in JSON Format
log_format nginxlog_json escape=json '{ "timestamp": "$time_local", '
'"remote_addr": "$remote_addr", '
'"remote_user": "remote_user", '
'"body_bytes_sent": $body_bytes_sent, '
'"request_time": $request_time, '
'"response_status": $status, '
'"request": "$request", '
'"request_method": "$request_method", '
'"host": "$host",'
'"upstream_addr": "$upstream_addr",'
'"upstream_host": "$upstream_http_host",'
'"upstream_resp_time": "$upstream_response_time",'
'"http_x_forwarded_for": "$http_x_forwarded_for",'
'"http_referrer": "$http_referer", '
'"http_user_agent": "$http_user_agent", '
'"http_version": "$server_protocol" ';
map $time_iso8601 $logdate {
'~^(?<ymd>\d{4}-\d{2}-\d{2})' $ymd;
default 'date-not-found';
}
access_log logs/access_json-$logdate.log nginxlog_json;
# See Move default writable paths to a dedicated directory (#119)
# https://github.com/openresty/docker-openresty/issues/119
client_body_temp_path /var/run/openresty/nginx-client-body;
proxy_temp_path /var/run/openresty/nginx-proxy;
fastcgi_temp_path /var/run/openresty/nginx-fastcgi;
uwsgi_temp_path /var/run/openresty/nginx-uwsgi;
scgi_temp_path /var/run/openresty/nginx-scgi;
sendfile on;
#tcp_nopush on;
#keepalive_timeout 0;
keepalive_timeout 65;
client_max_body_size 150m;
# lua cache
lua_shared_dict dis_cache 128m;
gzip on;
gzip_static on;
gzip_min_length 1k; # 設(shè)置允許壓縮的頁面最小字節(jié)數(shù)
gzip_buffers 4 16k; # 用來存儲 gzip 的壓縮結(jié)果
gzip_http_version 1.1; # 識別 HTTP 協(xié)議版本
gzip_comp_level 2; # 設(shè)置 gzip 的壓縮比 1-9。1 壓縮比最小但最快,而 9 相反
gzip_types gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript; # 指定壓縮類型
gzip_proxied any; # 無論后端服務(wù)器的 headers 頭返回什么信息,都無條件啟用壓縮
# 限制國外ip
access_by_lua_file /etc/nginx/lua/access_limit_open.lua;
include /etc/nginx/conf.d/*.conf;
}
全部 樣例代碼 在文章來源:http://www.zghlxwxcb.cn/news/detail-790077.html
https://gitee.com/xiaoyun461/blocking-external-networks
可自行修改文章來源地址http://www.zghlxwxcb.cn/news/detail-790077.html
到了這里,關(guān)于如何通過openresty 限制國外Ip訪問的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!