项目作者: selboo

项目描述 :
OpenResty DNS Server
高级语言: Lua
项目地址: git://github.com/selboo/ngdns-server.git
创建时间: 2019-05-28T03:29:08Z
项目社区:https://github.com/selboo/ngdns-server

开源协议:MIT License

下载


ngdns-server

docker

  1. # docker pull selboo/ngdns-server
  2. # docker run -itd -p 3053:53/udp selboo/ngdns-server
  3. # dig @127.0.0.1 -p 3053 a.aikaiyuan.com | grep -A 3 "ANSWER SECTION"
  4. # dig @127.0.0.1 -p 3053 c.aikaiyuan.com | grep -A 3 "ANSWER SECTION"
  5. # dig @127.0.0.1 -p 3053 6.aikaiyuan.com AAAA | grep -A 3 "ANSWER SECTION"
  6. # dig @127.0.0.1 -p 3053 t.aikaiyuan.com TXT | grep -A 3 "ANSWER SECTION"
  7. # dig @127.0.0.1 -p 3053 aikaiyuan.com NS | grep -A 3 "ANSWER SECTION"
  8. # dig @127.0.0.1 -p 3053 aikaiyuan.com MX | grep -A 3 "ANSWER SECTION"
  9. # dig @127.0.0.1 -p 3053 srv.aikaiyuan.com SRV | grep -A 3 "ANSWER SECTION"
  10. # dig @127.0.0.1 -p 3053 aikaiyuan.com SOA | grep -A 3 "ANSWER SECTION"

install openresty

  1. # git clone https://github.com/vislee/ngx_stream_ipdb_module.git
  2. # cd ngx_stream_ipdb_module
  3. # git checkout add-lua-api
  4. # sed -i 's/ngx_stream_lua_get_request/ngx_stream_lua_get_req/g' ngx_stream_ipdb_lua.c
  5. # cd ..
  6. # wget https://openresty.org/download/openresty-1.19.3.1.tar.gz
  7. # tar zxvf openresty-1.19.3.1.tar.gz
  8. # cd openresty-1.19.3.1
  9. # ./configure --prefix=/usr/local/ngdns-server/ --with-stream --add-module=../ngx_stream_ipdb_module/ --with-cc-opt="-I $PWD/build/ngx_stream_lua*/src"
  10. # gmake -j
  11. # gmake install

install lua-resty-dns-server

https://github.com/vislee/lua-resty-dns-server

  1. /usr/local/ngdns-server/bin/opm get vislee/lua-resty-dns-server
  2. wget https://github.com/vislee/lua-resty-dns-server/raw/add-feature-subnet/lib/resty/dns/server.lua \
  3. /usr/local/ngdns-server/site/lualib/resty/dns/server.lua

install lua-resty-mlcache

https://github.com/thibaultcha/lua-resty-mlcache

  1. /usr/local/ngdns-server/bin/opm get thibaultcha/lua-resty-mlcache

install lua-resty-logger-socket

https://github.com/p0pr0ck5/lua-resty-logger-socket

  1. /usr/local/ngdns-server/bin/opm get p0pr0ck5/lua-resty-logger-socket

install openresty-dns

  1. wget https://raw.githubusercontent.com/selboo/ngdns-server/master/53.lua \
  2. -O /usr/local/ngdns-server/nginx/conf/53.lua

install qqwry.ipdb

  1. wget https://cdn.jsdelivr.net/npm/qqwry.ipdb/qqwry.ipdb \
  2. -O /usr/local/ngdns-server/nginx/conf/qqwry.ipdb

install redis

  1. # yum install redis -y

config nginx.conf

  1. #user nobody;
  2. worker_processes auto;
  3. error_log logs/error.log ;
  4. pid logs/nginx.pid;
  5. events {
  6. worker_connections 1024;
  7. }
  8. stream {
  9. lua_package_path '/usr/local/ngdns-server/lualib/?.lua;/usr/local/ngdns-server/nginx/conf/?.lua;;';
  10. lua_package_cpath '/usr/local/ngdns-server/lualib/?.so;;';
  11. lua_shared_dict QUERYCACHE 32m;
  12. lua_shared_dict my_locks 1m;
  13. ipdb /usr/local/ngdns-server/nginx/conf/qqwry.ipdb;
  14. ipdb_language "CN";
  15. init_by_lua_block {
  16. local resty_lock = require "resty.lock"
  17. local mlcache = require "resty.mlcache"
  18. local cache, err = mlcache.new("my_cache", "QUERYCACHE", {
  19. lru_size = 100000,
  20. ttl = 10,
  21. neg_ttl = 10,
  22. resty_lock_opts = resty_lock,
  23. shm_locks = my_locks
  24. })
  25. _G.cache = cache
  26. local tld = {
  27. "aikaiyuan.com",
  28. "selboo.com",
  29. "abc.com"
  30. }
  31. local tlds = table.concat(tld, "|")
  32. local zone = {
  33. "(",
  34. tlds,
  35. ")$"
  36. }
  37. _G.zone = table.concat(zone)
  38. local DNSTYPES = {}
  39. DNSTYPES[1] = "A"
  40. DNSTYPES[2] = "NS"
  41. DNSTYPES[5] = "CNAME"
  42. DNSTYPES[6] = "SOA"
  43. DNSTYPES[12] = "PTR"
  44. DNSTYPES[15] = "MX"
  45. DNSTYPES[16] = "TXT"
  46. DNSTYPES[28] = "AAAA"
  47. DNSTYPES[33] = "SRV"
  48. DNSTYPES[99] = "SPF"
  49. DNSTYPES[255] = "ANY"
  50. _G.DNSTYPES = DNSTYPES
  51. local views = {
  52. 电信 = "DX",
  53. 联通 = "LT",
  54. 移动 = "YD",
  55. 中华电信 = "DX",
  56. 鹏博士 = "PBS",
  57. 教育网 = "JY",
  58. 远传电信 = "DX",
  59. 广电网 = "DX",
  60. 亚太电信 = "DX",
  61. 长城 = "PBS"
  62. }
  63. _G.VIEWS = views
  64. }
  65. server {
  66. listen 53 udp ;
  67. content_by_lua_block {
  68. local ngdns = require "53"
  69. local new = ngdns:new({
  70. redis_host = "127.0.0.1",
  71. redis_port = 6379,
  72. redis_timeout = 5,
  73. })
  74. new:run_udp()
  75. }
  76. log_by_lua_block {
  77. local logger = require "resty.logger.socket"
  78. if not logger.initted() then
  79. local ok, err = logger.init{
  80. host = '127.0.0.1',
  81. port = 514,
  82. sock_type = "udp",
  83. flush_limit = 1,
  84. drop_limit = 99999,
  85. }
  86. if not ok then
  87. ngx.log(ngx.ERR, "failed to initialize the logger: ", err)
  88. return
  89. end
  90. end
  91. logger.log(ngx.ctx.log)
  92. }
  93. }
  94. server {
  95. listen 1053 ;
  96. content_by_lua_block {
  97. local ngdns = require "53"
  98. local new = ngdns:new({
  99. redis_host = "127.0.0.1",
  100. redis_port = 6379,
  101. redis_timeout = 5,
  102. tcp = 1,
  103. })
  104. new:run_tcp()
  105. }
  106. log_by_lua_block {
  107. local logger = require "resty.logger.socket"
  108. if not logger.initted() then
  109. local ok, err = logger.init{
  110. host = '127.0.0.1',
  111. port = 514,
  112. sock_type = "udp",
  113. flush_limit = 1,
  114. drop_limit = 99999,
  115. }
  116. if not ok then
  117. ngx.log(ngx.ERR, "failed to initialize the logger: ", err)
  118. return
  119. end
  120. end
  121. logger.log(ngx.ctx.log)
  122. }
  123. }
  124. }

start redis openresty-dns

  1. # systemctl restart redis
  2. # /usr/local/ngdns-server/nginx/sbin/nginx

dns query log

  1. 2019-06-25 15:59:51 127.0.0.1 8.8.8.8 lb.aikaiyuan.com aikaiyuan.com lb * A aikaiyuan.com/lb/*/A
  2. 2019-06-25 15:59:51 127.0.0.1 127.0.0.1 lb.aikaiyuan.com aikaiyuan.com lb * A aikaiyuan.com/lb/*/A

time client_ip subnet_ip domain tld sub view qtype redis_key

dns view type

View Code Region
电信 DX 中国
远传电信 DX 中国
广电网 DX 中国
亚太电信 DX 中国
中华电信 DX 中国
联通 LT 中国
移动 YD 中国
教育网 JY 中国
鹏博士 PBS 中国
长城 PBS 中国
海外 HW 海外
局域网 JYW

数据来源: http://www.cz88.net/ip/

dns type

A

  1. ## tld/sub/view/type value/ttl set
  2. # redis-cli
  3. 127.0.0.1:6379> sadd aikaiyuan.com/lb/*/A 220.181.1.1/3600 220.181.2.2/3600 # 默认区域
  4. OK
  5. 127.0.0.1:6379> sadd aikaiyuan.com/lb/LT/A 123.125.3.3/3600 # 联通区域
  6. OK
  7. # dig @127.0.0.1 lb.aikaiyuan.com

CNAME

  1. ## tld/sub/view/type value/ttl set
  2. # redis-cli
  3. 127.0.0.1:6379> sadd aikaiyuan.com/www/*/CNAME aikaiyuan.appchizi.com./3600 # 默认区域
  4. OK
  5. 127.0.0.1:6379> sadd aikaiyuan.com/www/DX/CNAME dx.appchizi.com./60 # 电信区域
  6. OK
  7. # dig @127.0.0.1 www.aikaiyuan.com CNAME

AAAA

  1. ## tld/sub/view/type value/ttl set
  2. # redis-cli
  3. 127.0.0.1:6379> sadd aikaiyuan.com/ipv6/*/AAAA 240c::6666/60 240c::8888/60
  4. OK
  5. # dig @127.0.0.1 ipv6.aikaiyuan.com AAAA

NS

  1. ## tld/sub/view/type value/ttl set
  2. # redis-cli
  3. 127.0.0.1:6379> sadd aikaiyuan.com/ns/*/NS ns10.aikaiyuan.com./86400
  4. OK
  5. # dig @127.0.0.1 ns.aikaiyuan.com NS

TXT

  1. ## tld/sub/view/type value/ttl set
  2. # redis-cli
  3. 127.0.0.1:6379> sadd aikaiyuan.com/txt/*/TXT txt.aikaiyuan.com/1200
  4. OK
  5. # dig @127.0.0.1 txt.aikaiyuan.com txt

MX

  1. ## tld/sub/view/type value/ttl/preference set
  2. # redis-cli
  3. 127.0.0.1:6379> sadd aikaiyuan.com/@/*/MX smtp1.qq.com./720/10 smtp2.qq.com./720/10
  4. OK
  5. # dig @127.0.0.1 aikaiyuan.com MX

SRV

  1. ## tld/sub/view/type priority/weight/port/value/ttl
  2. # redis-cli
  3. 127.0.0.1:6379> sadd aikaiyuan.com/srv/*/SRV 1/100/800/www.aikaiyuan.com/120
  4. OK
  5. # dig @127.0.0.1 srv.aikaiyuan.com SRV

SOA

  1. ## tld/type mname/rname/serial/refresh/retry/expire/minimum/ttl
  2. # redis-cli
  3. 127.0.0.1:6379> sadd aikaiyuan.com/SOA ns1.aikaiyuan.com/domain.aikaiyuan.com/1558348800/1800/900/604800/86400/7200
  4. OK
  5. # dig @127.0.0.1 aikaiyuan.com SOA
  • mname 名称服务器的 ,该名称服务器是这个区域的数据起源或主要源。
  • rname 一个,它规定负责这个区域的个人的邮箱。由于不支持 @ 这里使用 . 替代 domain.aikaiyuan.com. <=> domain@aikaiyuan.com
  • serial 该区域的原始副本的无符号 32 位版本号。区域传递保存这个值。这个值叠起(wrap),并且应当使用系列空间算法比较这个值。
  • refresh 区域应当被刷新前的 32 位时间间隔
  • retry 在重试失败的刷新前,应当等待的 32 位时间间隔
  • expire 32 位时间值,它规定在区域不再是权威的之前可以等待的时间间隔的上限
  • minimum 无符号 32 位最小值 TTL 字段,应当用来自这个区域的任何 RR 输出它。
  • ttl TTL

TODO

  • edns-client-subnet
  • ngdns-api

Thanks