WIP. создание реверсных зон по умолчанию для списка префиксов.

This commit is contained in:
135
2024-02-20 23:46:10 +03:00
parent e3ded07a44
commit 55b45642e4

90
arpa.sql Normal file
View File

@@ -0,0 +1,90 @@
-- This file control sum
SET vars.csum TO :'csum';
-- This zone copy hostname
SET vars.ns TO :'NSERVER';
DO $$
-- Наполнение
DECLARE
v_domain text; -- domain name
v_domain_id integer; -- internal domain id
v_ns_admin text := 'hostmaster.example.ru'; -- master DNS admin email
v_soa text; -- zone SOA
v_prefixes cidr[] := ARRAY[
'10.0.0.0/8', -- Private-Use Networks
'100.64.0.0/10', -- CG-NAT
'127.0.0.0/8', -- Loopback
'172.16.0.0/12', -- LLA
'169.254.0.0/16', -- Private-Use Networks
'192.0.0.0/24', -- IETF Protocol Assignments
'192.0.2.0/24', -- TEST-NET-1
'192.88.99.0/24', -- 6to4 Relay Anycast
'192.168.0.0/16', -- Private-Use Networks
'198.18.0.0/15', -- Network Interconnect Device Benchmark Testing
'198.51.100.0/24', -- TEST-NET-2
'203.0.113.0/24' -- TEST-NET-3
];
v_prefixes24 cidr[];
v_prefix cidr;
v_arr text[];
BEGIN
-- пересобираем список префиксов по /24
-- ToDo: префиксы выходящие за границы /8 =< prefix < /24 пропускать
FOREACH v_prefix IN ARRAY v_prefixes LOOP
-- получили размерность
FOR i IN 0 .. 2^(24 - masklen(v_prefix))-1 LOOP
-- добавили каждую /24
v_prefixes24 := ARRAY_APPEND(v_prefixes24, set_masklen(v_prefix + 256 * i, 24));
-- RAISE NOTICE '% %: %', v_prefix, i, set_masklen(v_prefix + 256 * i, 24);
END LOOP;
END LOOP;
FOREACH v_prefix IN ARRAY v_prefixes24 LOOP
-- собираем имя зоны
v_domain := concat_ws('.', -- собираем полностью итоговый v_domain в формате $oct3.$oct2.$oct1.in-addr.arpa
array_to_string( -- результат превращаем в текст
array_reverse( -- разворачиваем массив в обратном направлении для in-addr.arpa
trim_array( -- отрезаем от массива последний октет с маской, так как для /24 в in-addr.arpa надо 3 октета
string_to_array(v_prefix::text, '.'), -- v_prefix переводим в text и разбираем в массив через '.'
1
)
),'.'
),
'in-addr.arpa'
);
SELECT INTO v_domain_id id FROM domains WHERE name = v_domain;
IF NOT FOUND THEN
-- зона отсутствует, будем генерить зону по умолчанию
RAISE NOTICE 'Stub generator for prefix:% zone:%', v_prefix, v_domain;
ELSE
-- зона уже создана, пропустить stub-функционал
RAISE NOTICE 'zone:% already exists, skip stub generation', v_domain;
CONTINUE;
END IF;
/*
чексуммы у зоны нет, поэтому достаточно будет первого запуска по
файлу со спецификой зоны, чтобы затереть зону-заглушку
получаем/создаём домен ID
*/
v_domain_id := domain_id(v_domain);
-- собираем SOA
v_soa := soa_mk(v_domain_id, v_ns_admin);
-- в принципе если мы здесь, то предполагается, что зоны такой не существовало
-- и записей, соответственно, нет. но тем не менее
DELETE FROM records WHERE domain_id = v_domain_id;
-- генерим зону по умолчанию
INSERT INTO records (domain_id, name, ttl, type, prio, content) VALUES
(v_domain_id, v_domain, 10800, 'SOA', 0, v_soa)
, (v_domain_id, v_domain, 10800, 'NS', 0, 'ns1.example.ru')
, (v_domain_id, v_domain, 10800, 'NS', 0, 'ns2.example.ru')
;
END LOOP;
END;
$$;