
NgDNS: https://github.com/selboo/ngdns-server
FROM: https://mp.weixin.qq.com/s/oZ2ftMgPtaDCygrgOUD3QA
最新 Nginx 已经支持 4层服务 ngx_stream_core_module, 有了 4层 支持我们可以做更多服务,
本篇我们用 OpenResty 配合 lua-resty-dns-server 做一个高性能 权威DNS 服务
先来看下压力测试, QPS 10W/s 左右
# cat /tmp/q.txt
lb.sinacloud.com
# queryperf -s 127.0.0.1 -d /tmp/q.txt -l 30
DNS Query Performance Testing Tool
Version: $Id: queryperf.c,v 1.12 2007/09/05 07:36:04 marka Exp $
[Status] Processing input data
[Status] Sending queries (beginning with 10.23.2.241)
[Status] Testing complete
Statistics:
Parse input file: multiple times
Run time limit: 30 seconds
Ran through file: 3212709 times
Queries sent: 3212710 queries
Queries completed: 3212710 queries
Queries lost: 0 queries
Queries delayed(?): 0 queries
RTT max: 0.000836 sec
RTT min: 0.000069 sec
RTT average: 0.000153 sec
RTT std deviation: 0.000030 sec
RTT out of range: 0 queries
Percentage completed: 100.00%
Percentage lost: 0.00%
Started at: Wed Jun 19 17:05:33 2019
Finished at: Wed Jun 19 17:06:03 2019
Ran for: 30.000171 seconds
Queries per second: 107089.722922 qps
OpenResty 安装
参考: http://openresty.org/en/installation.html
lua-resty-dns-server 安装
opm install vislee/lua-resty-dns-server
常见DNS类型, 都以支持
nginx.conf 配置
stream {
server {
listen 53 udp ;
content_by_lua_file conf/53.lua;
}
}
53.lua 代码
local server = require 'resty.dns.server'
local sock, err = ngx.req.socket()
if not sock then
ngx.log(ngx.ERR, "failed to get the request socket: ", err)
return ngx.exit(ngx.ERROR)
end
local req, err = sock:receive()
if not req then
ngx.log(ngx.ERR, "failed to receive: ", err)
return ngx.exit(ngx.ERROR)
end
local dns = server:new()
local request, err = dns:decode_request(req)
if not request then
ngx.log(ngx.ERR, "failed to decode request: ", err)
local resp = dns:encode_response()
local ok, err = sock:send(resp)
if not ok then
ngx.log(ngx.ERR, "failed to send: ", err)
ngx.exit(ngx.ERROR)
end
return
end
local query = request.questions[1]
ngx.log(ngx.DEBUG, "qname: ", query.qname, " qtype: ", query.qtype)
local cname = "sinacloud.com"
if query.qtype == server.TYPE_A then
local err = dns:create_a_answer(query.qname, 600, "192.168.1.1")
local err = dns:create_a_answer(query.qname, 600, "192.168.2.2")
if err then
ngx.log(ngx.ERR, "failed to create cname answer: ", err)
return
end
end
local resp = dns:encode_response()
local ok, err = sock:send(resp)
if not ok then
ngx.log(ngx.ERR, "failed to send: ", err)
return
end
dig 测试
# dig @127.0.0.1 lb.sinacloud.com
; <<>> DiG 9.9.4-RedHat-9.9.4-74.el7_6.1 <<>> @127.0.0.1 lb.sinacloud.com
; (1 server found)
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 45924
;; flags: qr rd; QUERY: 1, ANSWER: 2, AUTHORITY: 0, ADDITIONAL: 0
;; WARNING: recursion requested but not available
;; QUESTION SECTION:
;lb.sinacloud.com. IN A
;; ANSWER SECTION:
lb.sinacloud.com. 600 IN A 192.168.1.1
lb.sinacloud.com. 600 IN A 192.168.2.2
;; Query time: 0 msec
;; SERVER: 127.0.0.1#(127.0.0.1)
;; WHEN: Wed Jun 19 17:27:17 CST 2019
;; MSG SIZE rcvd: 98
后续
目前只是实现了一个很简单的例子, 如果做成一个可持续的服务, 还需要很多工作, 比如:
- DNS记录可以放到, Redis, MySQL 或这本地文件
- 封装 API接口, 可以动态修改 DNS记录
- 从 ngx.var.remote_addr 获取客户端IP, 支持智能解析
- tld 顶级域 QPS限制
- 记录请求日志
- 支持递归查询, 做 LocalDNS 服务
- 等等…
NgDNS: https://github.com/selboo/ngdns-server
转载请注明:爱开源 » 基于 OpenResty 权威DNS 服务
转载请注明:爱开源 » 基于 OpenResty 权威DNS 服务