Skip to content

Instantly share code, notes, and snippets.

@xddxdd
Last active May 29, 2021 10:00
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save xddxdd/53efacf5b750c0f38759beff8e7b070d to your computer and use it in GitHub Desktop.
Save xddxdd/53efacf5b750c0f38759beff8e7b070d to your computer and use it in GitHub Desktop.
Lan Tian's nginx-based DN42 WHOIS server config
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
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