当前位置: 首页 > 工具软件 > Resty > 使用案例 >

openresty lua-resty-dns 域名解析

潘文乐
2023-12-01

openresty lua-resty-dns 域名解析

                

官网:https://github.com/openresty/lua-resty-dns

         

             

                                           

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
        }
    }
}

         

                 

                                           

lua-resty-dns 常量

            

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

          

                    

 类似资料: