Last active
May 29, 2021 10:00
-
-
Save xddxdd/53efacf5b750c0f38759beff8e7b070d to your computer and use it in GitHub Desktop.
Lan Tian's nginx-based DN42 WHOIS server config
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
local lantian_whois = {} | |
function lantian_whois.file_exists(subdir, target) | |
if target == nil then return false end | |
local f = io.open(ngx.var.document_root .. "/" .. subdir .. "/" .. string.gsub(target, "/", "_"), "rb") | |
if f == nil then return false end | |
f:close() | |
return true | |
end | |
function lantian_whois.file_read(subdir, target) | |
if target == nil then return nil end | |
local f = io.open(ngx.var.document_root .. "/" .. subdir .. "/" .. string.gsub(target, "/", "_"), "rb") | |
if f == nil then return nil end | |
local content = f:read("*all") | |
f:close() | |
return content | |
end | |
function lantian_whois.ipv4_find(subdir, a1, a2, a3, a4, amask) | |
local o1 = tonumber(a1) | |
local o2 = tonumber(a2) | |
local o3 = tonumber(a3) | |
local o4 = tonumber(a4) | |
local mask = tonumber(amask) | |
if o1 < 0 or o1 > 255 or o2 < 0 or o2 > 255 or o3 < 0 or o3 > 255 or o4 < 0 or o4 > 255 or mask < 0 or mask > 32 then | |
return nil | |
end | |
local b = 2^24 * o1 + 2^16 * o2 + 2^8 * o3 + o4 | |
for i = mask, 0, -1 do | |
local num = 0 | |
if i > 0 then num = bit.band(b, bit.lshift(4294967295, 32 - i)) end | |
local new_ip = bit.band(bit.rshift(num, 24), 255) .. '.' | |
new_ip = new_ip .. bit.band(bit.rshift(num, 16), 255) .. '.' | |
new_ip = new_ip .. bit.band(bit.rshift(num, 8), 255) .. '.' | |
new_ip = new_ip .. bit.band(bit.rshift(num, 0), 255) | |
new_ip = new_ip .. '/' .. i | |
if lantian_whois.file_exists(subdir, new_ip) then | |
return new_ip | |
end | |
end | |
return nil | |
end | |
--explode, credit: http://richard.warburton.it | |
function lantian_whois.explode( string, divide ) | |
if divide == '' then return false end | |
local pos, arr = 0, {} | |
--for each divider found | |
for st, sp in function() return string.find( string, divide, pos, true ) end do | |
table.insert( arr, string.sub( string, pos, st - 1 ) ) --attach chars left of current divider | |
pos = sp + 1 --jump past current divider | |
end | |
table.insert( arr, string.sub( string, pos ) ) -- Attach chars right of last divider | |
return arr | |
end | |
-- Thanks to https://github.com/Fizzadar/Lua-Bits/blob/master/ipv6.lua | |
function lantian_whois.ipv6_split(ip) | |
--get ip bits | |
local ipbits = lantian_whois.explode( ip, ':' ) | |
--now to build an expanded ip | |
local zeroblock | |
for k, v in pairs( ipbits ) do | |
--length 0? we're at the :: bit | |
if v:len() == 0 then | |
zeroblock = k | |
ipbits[k] = 0 | |
else | |
ipbits[k] = tonumber(ipbits[k], 16) | |
end | |
end | |
if zeroblock and #ipbits < 8 then | |
--remove zeroblock | |
ipbits[zeroblock] = 0 | |
local padding = 8 - #ipbits | |
for i = 1, padding do | |
table.insert( ipbits, zeroblock, 0 ) | |
end | |
end | |
return ipbits | |
end | |
function lantian_whois.ipv6_recompose(ipbits) | |
local zero_begin = 0; | |
local zero_end = 0; | |
local zero_begin_tmp = 0; | |
local zero_end_tmp = 0; | |
for i = 1, 9, 1 do | |
if i < 9 and ipbits[i] == 0 then | |
if zero_begin_tmp == 0 then | |
zero_begin_tmp = i | |
else | |
zero_end_tmp = i | |
end | |
else | |
if zero_end_tmp - zero_begin_tmp > zero_end - zero_begin then | |
zero_begin = zero_begin_tmp | |
zero_end = zero_end_tmp | |
end | |
zero_begin_tmp = 0 | |
zero_end_tmp = 0 | |
end | |
end | |
local s = "" | |
for i = 1, 8, 1 do | |
if zero_end > 0 and i == zero_begin then | |
if i == 1 then | |
s = s .. "::" | |
else | |
s = s .. ":" | |
end | |
elseif zero_end > 0 and i > zero_begin and i <= zero_end then | |
-- do nothing | |
else | |
if i < 8 then | |
s = s .. string.format("%x:", ipbits[i]) | |
else | |
s = s .. string.format("%x", ipbits[i]) | |
end | |
end | |
end | |
return s | |
end | |
function lantian_whois.ipv6_find(subdir, ip, mask) | |
mask = tonumber(mask) | |
local ipbits = lantian_whois.ipv6_split(ip) | |
for i = 128, 0, -1 do | |
if i < 128 then | |
local idx = math.floor(i / 16 + 1) | |
ipbits[idx] = bit.band(ipbits[idx], bit.lshift(65535, 16 - i % 16)) | |
end | |
if i <= mask then | |
local new_ip = lantian_whois.ipv6_recompose(ipbits) .. "/" .. i | |
if lantian_whois.file_exists(subdir, new_ip) then | |
return new_ip | |
end | |
end | |
end | |
return nil | |
end | |
return lantian_whois |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
server { | |
listen 43 plain default_server; | |
listen [::]:43 plain default_server; | |
listen 80; | |
listen [::]:80; | |
root /srv/cache/dn42-registry/data; | |
server_name whois.lantian.pub whois.lantian.dn42 whois.lantian.neo; | |
error_page 404 /lantian-404; | |
location / { | |
rewrite "^/([0-9]{1})$" /aut-num/AS424242000$1 last; | |
rewrite "^/([0-9]{2})$" /aut-num/AS42424200$1 last; | |
rewrite "^/([0-9]{3})$" /aut-num/AS4242420$1 last; | |
rewrite "^/([0-9]{4})$" /aut-num/AS424242$1 last; | |
rewrite "^/([Aa][Ss]|)([0-9]+)$" /aut-num/AS$2 last; | |
rewrite "^/([0-9]+)\.([0-9]+)\.([0-9]+)\.([0-9]+)/([0-9]+)$" /inetnum/$1.$2.$3.$4_$5 last; | |
rewrite "^/([0-9]+)\.([0-9]+)\.([0-9]+)\.([0-9]+)$" /inetnum/$1.$2.$3.$4_32 last; | |
rewrite "^/([0-9a-fA-F:]+)/([0-9]+)$" /inet6num/$1_$2 last; | |
rewrite "^/([0-9a-fA-F:]+)$" /inet6num/$1_128 last; | |
rewrite "^/([^/]+)-([Dd][Nn]42)$" /person/$1-DN42 last; | |
rewrite "^/([^/]+)-([Mm][Nn][Tt])$" /mntner/$1-MNT last; | |
rewrite "^/([^/]+)-([Ss][Cc][Hh][Ee][Mm][Aa])$" /schema/$1-SCHEMA last; | |
rewrite "^/([Oo][Rr][Gg])-(.+)$" /organisation/ORG-$2 last; | |
rewrite "^/([Ss][Ee][Tt])-(.+)-([Tt][Ii][Nn][Cc])$" /tinc-keyset/SET-$2-TINC last; | |
rewrite "^/([^/]+)-([Tt][Ii][Nn][Cc])$" /tinc-key/$1-TINC last; | |
rewrite "^/([Rr][Ss])-(.+)$" /route-set/RS-$2 last; | |
rewrite "^/([Aa][Ss])([0-9]+)-([Aa][Ss])([0-9]+)$" /as-block/$1$2-$3$4 last; | |
rewrite "^/[Aa][Ss](.+)$" /as-set/AS$1 last; | |
rewrite "^/([^/]+)$" /dns/$1 last; | |
} | |
location ~* "^/(inetnum|route)/([0-9]+)\.([0-9]+)\.([0-9]+)\.([0-9]+)_([0-9]+)$" { | |
set $o1 $2; | |
set $o2 $3; | |
set $o3 $4; | |
set $o4 $5; | |
set $mask $6; | |
content_by_lua_block { | |
local lantian_whois = require "lantian_whois"; | |
local target = lantian_whois.ipv4_find("inetnum", ngx.var.o1, ngx.var.o2, ngx.var.o3, ngx.var.o4, ngx.var.mask) | |
if target == nil then target = "" end | |
local content = lantian_whois.file_read("inetnum", target) | |
ngx.say("% Lan Tian Nginx-based WHOIS Server Lua Logic") | |
ngx.say("% GET " .. ngx.var.request_uri) | |
if content then | |
ngx.print(content) | |
else | |
ngx.say("% 404") | |
end | |
target = lantian_whois.ipv4_find("route", ngx.var.o1, ngx.var.o2, ngx.var.o3, ngx.var.o4, ngx.var.mask) | |
if target == nil then target = "" end | |
content = lantian_whois.file_read("route", target) | |
ngx.say("% Relevant route object:") | |
if content then | |
ngx.print(content) | |
else | |
ngx.say("% 404") | |
end | |
} | |
} | |
location ~* "^/(inet6num|route6)/([0-9a-fA-F:]+)_([0-9]+)$" { | |
set $parsed_ip $2; | |
set $parsed_mask $3; | |
content_by_lua_block { | |
local lantian_whois = require "lantian_whois"; | |
local target = lantian_whois.ipv6_find("inet6num", ngx.var.parsed_ip, ngx.var.parsed_mask) | |
if target == nil then target = "" end | |
local content = lantian_whois.file_read("inet6num", target) | |
ngx.say("% Lan Tian Nginx-based WHOIS Server Lua Logic") | |
ngx.say("% GET " .. ngx.var.request_uri) | |
if content then | |
ngx.print(content) | |
else | |
ngx.say("% 404") | |
end | |
ngx.say("% Relevant route:") | |
target = lantian_whois.ipv6_find("route6", ngx.var.parsed_ip, ngx.var.parsed_mask) | |
if target == nil then target = "" end | |
content = lantian_whois.file_read("route6", target) | |
ngx.say("% Relevant route object:") | |
if content then | |
ngx.print(content) | |
else | |
ngx.say("% 404") | |
end | |
} | |
} | |
location ~* "^/(dns)/(.*)$" { | |
set_by_lua $uri_norm "return '/' .. ngx.arg[1]:lower() .. '/' .. ngx.arg[2]:lower()" $1 $2; | |
#return 200 $uri_norm; | |
try_files $uri_norm $uri =404; | |
add_before_body /lantian-prepend; | |
addition_types '*'; | |
} | |
location ~* "^/(aut-num|person|mntner|schema|organisation|tinc-keyset|tinc-key|as-set|route-set|as-block)/(.*)$" { | |
set_by_lua $uri_norm "return '/' .. ngx.arg[1]:lower() .. '/' .. ngx.arg[2]:upper()" $1 $2; | |
#return 200 $uri_norm; | |
try_files $uri_norm $uri =404; | |
add_before_body /lantian-prepend; | |
addition_types '*'; | |
} | |
location = /lantian-prepend { | |
internal; | |
return 200 "% Lan Tian Nginx-based WHOIS Server\n% GET $request_uri:\n"; | |
} | |
location = /lantian-404 { | |
internal; | |
return 200 "% Lan Tian Nginx-based WHOIS Server\n% GET $request_uri:\n% 404 Not Found\n"; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment