最后由 Tabing010102 更新于 2022年11月24日
需求:
openresty根据HTTP协议类型/版本/IP Country分流至不同后端(处理TLS,需部署证书,IPCountry信息使用GeoIP2)
为了使用GeoIP Country信息,我们需要GeoIP2库(libmaxminddb),GitHub地址:点我跳转
下载最新release,解压编译安装:
wget "https://github.com/maxmind/libmaxminddb/releases/download/1.7.1/libmaxminddb-1.7.1.tar.gz"
tar zxvf libmaxminddb-1.7.1.tar.gz
cd libmaxminddb-1.7.1
./configure
make && make install
# 最后刷新动态链接库缓存,否则可能会出现找不到libmaxminddb.so
ldconfig
由于libmaxminddb
默认安装在/usr/local/lib
中,CentOS 7默认并不会在此文件夹搜索,因此需要将/usr/local/lib
添加至搜索路径,再执行ldconfig
:
echo "/usr/local/lib" >> /etc/ld.so.conf.d/local.conf
接下来下载MaxMind的GeoIP2数据库文件(mmdb格式),对于只识别国家的情况,下载GeoLite2 Country即可,然后将其解压至/var/lib/GeoIP
中(或者其他任何地方,需对代码进行相应更改)
接下来安装openresty和opm,openresty官方提供了大部分Linux发行版的包(官方package安装指引),安装openresty
和openresty-opm
包
接下来使用opm安装geoip的LuaJIT(链接):opm get leafo/geoip
openretsy默认安装在/usr/local/openresty
中,为了使用GeoIP2库,需要在openresty安装目录下的lualib
文件夹下创建geoip_helper.lua
(摘自opm页面说明,使加载好的GeoIP2数据库常加载,而不是每接收一个请求重新加载一遍GeoIP2数据库;也可使用其他名字,须在配置中进行相应修改):
local geoip = require "geoip.mmdb"
return {
country_db = assert(geoip.load_database("/var/lib/GeoIP/GeoLite2-Country.mmdb")),
-- load more databases if necessary:
-- asnum_db = ...
-- etc.
}
接下来在nginx/conf
文件夹中创建配置文件stream.conf
,其中50001为对IP为US的客户端的服务器端口,50002为http2服务,50003为http服务,50099为其他类型协议的服务端口:
stream {
resolver 1.1.1.1;
lua_add_variable $ProxyPort;
server {
listen 443 ssl reuseport;
listen [::]:443 ssl reuseport;
# ssl cert config
ssl_certificate "path/to/fullchain.cer";
ssl_certificate_key "path/to/private.key";
ssl_session_cache shared:SSL:1m;
ssl_session_timeout 10m;
# ssl protocol config
ssl_protocols TLSv1.3;
ssl_prefer_server_ciphers off;
# proxy_buffer_size 256k;
# preread size
preread_buffer_size 58;
preread_by_lua_block {
local sock, err = ngx.req.socket()
-- if sock then
-- ngx.log(ngx.NOTICE, "got the request socket")
-- else
-- ngx.log(ngx.NOTICE, "failed to get the request socket: ", err)
-- end
local data, err = sock:peek(16)
-- local data2, err = sock:peek(58)
-- get country iso code
local result = require("geoip_helper").country_db:lookup_value(ngx.var.remote_addr, "country", "iso_code")
-- ngx.log(ngx.NOTICE, "result = " .. result)
if result and string.match(result, "US") then
-- for US IP
-- ngx.log(ngx.NOTICE, "US -> 50001")
ngx.var.ProxyPort = "50001"
elseif string.match(data, "HTTP/2.0") then
-- for http2
-- ngx.log(ngx.NOTICE, "HTTP/2.0 -> 50002")
ngx.var.ProxyPort = "50002"
elseif string.match(data, "HTTP") then
-- for http
-- ngx.log(ngx.NOTICE, "HTTP -> 50003")
ngx.var.ProxyPort = "50003"
-- elseif string.byte(data2:sub(57), 1, 2) == 13 then
-- -- for tj
-- -- ngx.log(ngx.NOTICE, "tj -> 50004")
-- ngx.var.ProxyPort = "50004"
else
-- for other protocol
-- ngx.log(ngx.NOTICE, "other -> 50099")
ngx.var.ProxyPort = "50099"
end
}
proxy_pass 127.0.0.1:$ProxyPort;
access_log off;
}
}
最后需要将nginx/conf
中的主配置文件加入include stream.conf;
,重新启动openresty使配置生效
Views: 56