官网:https://github.com/openresty/lua-resty-dns
This library is considered production ready
* lua-resty-dns已经处于生产状态
This Lua library provides a DNS resolver for the ngx_lua nginx module
This Lua library takes advantage of ngx_lua's cosocket API, which
ensures 100% nonblocking behavior.
* ngx_lua用lua-resty-dns解析域名
* lua-resty-dns利用ngx_lua的cosocket api,非阻塞执行
Note that at least ngx_lua 0.5.12 or OpenResty 1.2.1.11 is required.
Also, the bit library is also required. If you're using LuaJIT 2.0
with ngx_lua, then the bit library is already available by default.
* lua-resty-dns适配版本:ngx_lua 0.5.12及以上、OpenResty 1.2.1.11及以上
Note that, this library is bundled and enabled by default in the OpenResty bundle.
* lua-resty-dns在openresty中默认绑定
IMPORTANT: to be able to generate unique ids, the random generator must
be properly seeded using math.randomseed prior to using this module
* 为了生成唯一的id,随机生成器(使用math.randomseed)优先于lua-resty-dns执行
new:创建域名解析对象
语法格式:r, err = class:new(opts)
Creates a dns.resolver object. Returns nil and a message string on error.
* 创建域名解析对象
* 创建失败,返回nil、错误描述信息
It accepts a opts table argument. The following options are supported:
* 接收table表参数
* nameservers:域名解析服务器列表
a list of nameservers to be used. Each nameserver entry can be either
a single hostname string or a table holding both the hostname string and
the port number. The nameserver is picked up by a simple round-robin
algorithm for each query method call. This option is required.
* retrans:域名解析重试总次数
the total number of times of retransmitting the DNS request when
receiving a DNS response times out according to the timeout setting.
Defaults to 5 times. When trying to retransmit the query, the next
nameserver according to the round-robin algorithm will be picked up.
* timeout:超时时间,单位毫秒
the time in milliseconds for waiting for the response for a single
attempt of request transmission. note that this is ''not'' the maximal
total waiting time before giving up, the maximal total waiting time can
be calculated by the expression timeout x retrans. The timeout setting
can also be changed by calling the set_timeout method. The default
timeout setting is 2000 milliseconds, or 2 seconds.
* no_recurse:是否禁用recursion desired,默认false
a boolean flag controls whether to disable the "recursion desired"
(RD) flag in the UDP request. Defaults to false.
* no_random:是否总是挑选列表第一个域名解析器,默认false(随机挑选)
a boolean flag controls whether to randomly pick the nameserver to
query first, if true will always start with the first nameserver listed.
Defaults to false
query:域名解析
语法格式:answers, err, tries? = r:query(name, options?, tries?)
Performs a DNS standard query to the nameservers specified by the new
method, and returns all the answer records in an array-like Lua table.
In case of errors, it will return nil and a string describing the
error instead.
* 向域名解析器发起查询,返回数组类型的table数据,表示所有解析结果
* 如果失败,返回nil、错误描述信息
If the server returns a non-zero error code, the fields errcode and
errstr will be set accordingly in the Lua table returned.
* 如果返回非0错误码,errcode、errstr也会在table中设置
Each entry in the answers returned table value is also a hash-like Lua
table which usually takes some of the following fields:
* 返回的结果字段如下
* name:解析的资源名称
The resource record name.
* type:解析的资源结果类型
The current resource record type, possible values are 1 (TYPE_A), 5
(TYPE_CNAME), 28 (TYPE_AAAA), and any other values allowed by RFC 1035.
* address:ip地址(ipv4、ipv6)
The IPv4 or IPv6 address in their textual representations when the
resource record type is either 1 (TYPE_A) or 28 (TYPE_AAAA), respectively
Successive 16-bit zero groups in IPv6 addresses will not be compressed by
default, if you want that, you need to call the compress_ipv6_addr static
method instead.
* section:section标识符
The identifier of the section that the current answer record belongs
to. Possible values are 1 (SECTION_AN), 2 (SECTION_NS), and 3 (SECTION_AR).
* cname:别名
The (decoded) record data value for CNAME resource records. Only
present for CNAME records.
* ttl:资源结果剩余存活时间
The time-to-live (TTL) value in seconds for the current resource record.
*class:资源结果类
The current resource record class, possible values are 1 (CLASS_IN) or
any other values allowed by RFC 1035.
* preference:MX type结果的最大数字
The preference integer number for MX resource records. Only present for
MX type records.
* exchange:MX resource的交换域名
The exchange domain name for MX resource records. Only present for MX
type records.
* nsdname:NS type域名
A domain-name which specifies a host which should be authoritative for
the specified class and domain. Usually present for NS type records.
* rdata:无法识别的域名
The raw resource data (RDATA) for resource records that are not recognized.
* txt:TXT records
The record value for TXT records. When there is only one character string
in this record, then this field takes a single Lua string. Otherwise this
field takes a Lua table holding all the strings.
* ptrdname:PTR records
The record value for PTR records
This method also takes an optional options argument table, which takes the following fields:
* 可选参数
* qtype:查询类型
The type of the question. Possible values are 1 (TYPE_A), 5 (TYPE_CNAME),
28 (TYPE_AAAA), or any other QTYPE value specified by RFC 1035 and RFC 3596.
Default to 1 (TYPE_A).
* authority_section:认证section,默认false
When set to a true value, the answers return value includes the Authority
section of the DNS response. Default to false.
* additional_section:额外的section,默认false
When set to a true value, the answers return value includes the Additional
section of the DNS response. Default to false.
The optional parameter tries can be provided as an empty table, and will be
returned as a third result. The table will be an array with the error message
for each (if any) failed try.
* tries参数可以是一个空table,并且会作为第三个结果参数返回
* 如果发生错误,会记录错误信息
When data truncation happens, the resolver will automatically retry using the
TCP transport mode to query the current nameserver. All TCP connections are
short lived
* 如果发生数据截断,会进行重试
* 所有的tcp连接都是短连接
tcp_query:tcp连接查询
语法格式:answers, err = r:tcp_query(name, options?)
Just like the query method, but enforce the TCP transport mode instead of UDP.
All TCP connections are short lived
* 和query方法功能类似,强制使用tcp传输方式
* 所有的tcp连接都是短连接
set_timeout:设置超时时间
语法格式:r:set_timeout(time)
Overrides the current timeout setting by the time argument in
milliseconds for all the nameserver peers
* 设置超时时间,单位毫秒
compress_ipv6_addr:压缩ipv6地址
语法格式:compressed = resty.dns.resolver.compress_ipv6_addr(address)
Compresses the successive 16-bit zero groups in the textual format
of the IPv6 address
* 压缩ipv6地址
# 示例
local resolver = require "resty.dns.resolver"
local compress = resolver.compress_ipv6_addr
local new_addr = compress("FF01:0:0:0:0:0:0:101")
==> FF01::101
expand_ipv6_addr:还原压缩的ipv6地址
语法格式:expanded = resty.dns.resolver.expand_ipv6_addr(address)
Expands the successive 16-bit zero groups in the textual format
of the IPv6 address
* 还原压缩的ipv6地址
# 示例
local resolver = require "resty.dns.resolver"
local expand = resolver.expand_ipv6_addr
local new_addr = expand("FF01::101")
==> FF01:0:0:0:0:0:0:101
arpa_str:反转ip地址
语法格式:rpa_record = resty.dns.resolver.arpa_str(address)
Generates the reverse domain name for PTR lookups for both IPv4 and
IPv6 addresses. Compressed IPv6 addresses will be automatically expanded
* 反转ipv4、ipv6地址
# 示例
local resolver = require "resty.dns.resolver"
local ptr4 = resolver.arpa_str("1.2.3.4")
local ptr6 = resolver.arpa_str("FF01::101")
==> 4.3.2.1.in-addr.arpa
1.0.1.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.1.0.F.F.ip6.arpa
reverse_query:ptr反向解析
语法格式:answers, err = r:reverse_query(address)
Performs a PTR lookup for both IPv4 and IPv6 addresses. This function
is basically a wrapper for the query command which uses the arpa_str
command to convert the IP address on the fly
* ptr反向解析
示例
lua_package_path "/path/to/lua-resty-dns/lib/?.lua;;";
server {
location = /dns {
content_by_lua_block {
local resolver = require "resty.dns.resolver"
local r, err = resolver:new{
nameservers = {"8.8.8.8", {"8.8.4.4", 53} },
retrans = 5, -- 5 retransmissions on receive timeout
timeout = 2000, -- 2 sec
no_random = true, -- always start with first nameserver
}
if not r then
ngx.say("failed to instantiate the resolver: ", err)
return
end
local answers, err, tries = r:query("www.google.com", nil, {})
if not answers then
ngx.say("failed to query the DNS server: ", err)
ngx.say("retry historie:\n ", table.concat(tries, "\n "))
return
end
if answers.errcode then
ngx.say("server returned error code: ", answers.errcode,
": ", answers.errstr)
end
for i, ans in ipairs(answers) do
ngx.say(ans.name, " ", ans.address or ans.cname,
" type:", ans.type, " class:", ans.class,
" ttl:", ans.ttl)
end
}
}
}
TYPE_A ==> The A resource record type, equal to the decimal number 1
TYPE_NS ==> The NS resource record type, equal to the decimal number 2
TYPE_CNAME ==> The CNAME resource record type, equal to the decimal number 5
TYPE_SOA ==> The SOA resource record type, equal to the decimal number 6
TYPE_PTR ==> The PTR resource record type, equal to the decimal number 12
TYPE_MX ==> The MX resource record type, equal to the decimal number 15
TYPE_TXT ==> The TXT resource record type, equal to the decimal number 16
TYPE_AAAA ==> The AAAA resource record type, equal to the decimal number 28
TYPE_SRV ==> The SRV resource record type, equal to the decimal number 33
TYPE_SPF ==> The SPF resource record type, equal to the decimal number 99
CLASS_IN ==> The Internet resource record type, equal to the decimal number 1
SECTION_AN ==> Identifier of the Answer section in the DNS response.
Equal to decimal number 1
SECTION_NS ==> Identifier of the Authority section in the DNS response.
Equal to the decimal number 2
SECTION_AR ==> Identifier of the Additional section in the DNS response.
Equal to the decimal number 3
default.conf
server {
listen 80;
server_name localhost;
location / {
root /usr/local/openresty/nginx/html;
index index.html index.htm;
}
location /test {
content_by_lua_block {
local resolver = require "resty.dns.resolver"
local cjson = require 'cjson';
local r, err = resolver:new({
nameservers = {"8.8.8.8", {"8.8.4.4", 53} },
retrans = 5, -- 5 retransmissions on receive timeout
timeout = 2000, -- 2 sec
});
if not r then
ngx.say("创建解析实例失败 ==> ", err)
return
end
local answers, err, tries = r:query("www.google.com", nil, {})
if not answers then
ngx.say("解析域名www.google.com失败 ==> ", err)
ngx.say("重试解析记录 ==> ", table.concat(tries, "\n "))
return
end
if answers.errcode then
ngx.say("域名服务器解析出错 ==> ", answers.errcode, " ==> ", answers.errstr)
end
ngx.say("解析结果 ==> ", cjson.encode(answers));
for i, ans in ipairs(answers) do
ngx.say(ans.name, " ", ans.address or ans.cname,
" type:", ans.type, " class:", ans.class,
" ttl:", ans.ttl)
end
answers, err = r:query("www.baidu.com")
if not answers then
ngx.say("解析域名www.baidu.com失败 ==> ", err)
return
end
if answers.errcode then
ngx.say("域名服务器解析出错 ==> ", answers.errcode, " ==> ", answers.errstr)
end
ngx.say("\n解析结果 ==> ", cjson.encode(answers));
for i, ans in ipairs(answers) do
ngx.say(ans.name, " ", ans.address or ans.cname,
" type:", ans.type, " class:", ans.class,
" ttl:", ans.ttl)
end
answers, err = r:reverse_query("www.taobao.com")
if not answers then
ngx.say("解析域名www.taobao.com失败 ==> ", err)
return
end
if answers.errcode then
ngx.say("域名服务器解析出错 ==> ", answers.errcode, " ==> ", answers.errstr)
end
ngx.say("\n解析结果 ==> ", cjson.encode(answers));
for i, ans in ipairs(answers) do
ngx.say(ans.name, " ", ans.address or ans.cname,
" type:", ans.type, " class:", ans.class,
" ttl:", ans.ttl)
end
}
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root /usr/local/openresty/nginx/html;
}
}
创建openresty 容器
docker run -it -d --net fixed --ip 172.18.0.2 -p 9000:80 \
-v /Users/huli/lua/openresty/dns/default.conf:/etc/nginx/conf.d/default.conf \
--name open-dns lihu12344/openresty
使用测试
huli@hudeMacBook-Pro dns % curl localhost:9000/test
解析结果 ==> [{"ttl":204,"type":1,"section":1,"address":"104.244.46.85","name":"www.google.com","class":1}]
www.google.com 104.244.46.85 type:1 class:1 ttl:204
解析结果 ==> [{"ttl":752,"type":5,"section":1,"cname":"www.a.shifen.com","name":"www.baidu.com","class":1},{"ttl":11,"type":5,"section":1,"cname":"www.wshifen.com","name":"www.a.shifen.com","class":1},{"ttl":200,"type":1,"section":1,"address":"103.235.46.40","name":"www.wshifen.com","class":1}]
www.baidu.com www.a.shifen.com type:5 class:1 ttl:752
www.a.shifen.com www.wshifen.com type:5 class:1 ttl:11
www.wshifen.com 103.235.46.40 type:1 class:1 ttl:200
解析结果 ==> [{"ttl":600,"type":5,"section":1,"cname":"www.taobao.com.danuoyi.tbcache.com","name":"www.taobao.com","class":1}]
www.taobao.com www.taobao.com.danuoyi.tbcache.com type:5 class:1 ttl:600