返回文章列表
2025年12月10日yodfz

#OpenResty动态代理泛域名解析

nginxluaopenresty
10 分钟阅读
2843
yodfz

前言 在互联网服务中,二级域名泛解析,是一种比较常见的技术方案。我在为公司设计系统的时候,遇到了一个问题,那就是,这个业务的域名是动态增减的。而且这个业务需要对所有请求都进行鉴权管理。

所以在选型上面,我采用了业内方案 OpenResty + Redis 对域名进行动态解析。

动态解析二级域名的前缀 由于要进行泛解析,那么我们需要配置域名DNS,将*.domain.com映射到我们的代理服务器上。

动态解析的时候 需要一个数据库来实现domain -> ip的映射 ,我考虑两种方式来保存:

内存保留

redis

我考虑到内存不可靠性与代理服务器横向扩容问题,采用了redis来存储这些映射关系。

并且借用主站点的鉴权机制,直接使用cookie。

数据获取: query数据获取 local arg = ngx.req.get_uri_args() arg['query参数'] 数据库: 连接redis local redis = require "resty.redis" local redisClient = redis:new() local ok, err = redisClient:connect(config.redisHost,config.redisPort) if not ok then ngx.log(ngx.ERR, "failed to connect: ", err) return end redisClient:auth(config.redisPassword) local host = ngx_re.split(ngx.var.host,"\.")[1] local hostRes, err = redisClient:get(host) -- 将解析数据返回 ngx.var.userdomain = hostRes 鉴权:获取cookie数据 local userCookie = ngx.var.cookie_user 这个地方 cookie_user 指从cookie中获取user这个key的值。

nginx 配置 为解析配置新的server。

   # 域名指向都不匹配时,会选择此配置,对于泛解析的域名,可以在这里做一些处理
   listen 443 ssl;
   server_name *.yodfz.com;
   # 限制每个ip连接宽带大小为3mb
   limit_conn_zone $binary_remote_addr zone=one:3m;
   ssl_certificate     /cert/1.crt;
   ssl_certificate_key /cert/2.key;
   ssl_protocols       TLSv1 TLSv1.1 TLSv1.2;
   ssl_ciphers         HIGH:!aNULL:!MD5;
   gzip on;
   gzip_min_length 1k;
   gzip_buffers 4 16k;
   gzip_comp_level 2;
   gzip_types text/plain application/javascript application/x-javascript text/css application/xml text/javascript application/x-httpd-php image/jpeg image/gif image/png;
   gzip_vary off;
   gzip_disable "MSIE [1-6]\.";
   resolver 8.8.8.8 ipv6=off;
   location / {            
   		#正式环境启用
   		lua_code_cache off;
   		#设置$userdomain变量及默认值
   		set $userdomain default;
   		#引入lua文件
   		rewrite_by_lua_file /lua/cname.lua;
   		#反向代理
   		proxy_pass $userdomain;
   		proxy_redirect off;
   		proxy_buffering off;
   		proxy_http_version 1.1;
   		proxy_set_header Upgrade $http_upgrade;
   		proxy_set_header Connection $connection_upgrade;
   		# proxy_set_header Host $userdomain;
   		# proxy_set_header X-Real-IP $remote_addr;
   		# proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
   }

将以下文件保存为cname.lua


local redis = require "resty.redis"
local resty_rsa = require "resty.rsa"
local ngx_re = require "ngx.re"
local cjson = require "cjson"
local config = require "lua.config"

local redisClient = redis:new()

-- 解析二级域名 从redis中获取反代地址
local ok, err = redisClient:connect(config.redisHost,config.redisPort)
if not ok then
    ngx.log(ngx.ERR, "failed to connect: ", err)
    return
end
redisClient:auth(config.redisPassword)
local host = ngx_re.split(ngx.var.host,"\\.")


local hostRes, err = redisClient:get(host[1])
if hostRes then
    ngx.var.userdomain = hostRes
    return
end

local ok, err = redisClient:set_keepalive(10000, 100)
if not ok then
    ngx.say("failed to set keepalive: ", err)
    return
end

nginxluaopenresty
分享:

// End of article

/* Thanks for reading */