1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
|
{ config, pkgs, lib, ... }:
with lib; {
options.krebs.zone-head-config = mkOption {
type = lib.types.attrsOf lib.types.str;
description = ''
The zone configuration head which is being used to create the
zone files. The string for each key is pre-pended to the zone file.
'';
default = {
"krebsco.de" = /* bindzone */ ''
$TTL 60
@ 3600 IN SOA spam.krebsco.de. spam.krebsco.de. 0 7200 3600 86400 3600
@ 3600 IN NS ns1
@ 3600 IN NS ni
@ 3600 IN NS ns2.he.net.
@ 3600 IN NS ns3.he.net.
@ 3600 IN NS ns2.hosting.de.
_acme-challenge IN NS ns1
panda NS panda
panda A 130.61.237.100
xkey A 217.197.83.17
xkey AAAA 2a0a:4580:5011::1
'';
};
};
config = {
environment.etc =
mapAttrs'
(name: pkg: {
name = "zones/${name}";
value.source = pkg;
})
pkgs.krebs.zones;
nixpkgs.overlays = [
# Explicit zones generated from config.krebs.hosts.*.extraZones
(self: super: let
stripEmptyLines = s: (concatStringsSep "\n"
(remove "\n" (remove "" (splitString "\n" s)))) + "\n";
all-zones = foldAttrs (sum: current: sum + "\n" + current) ""
([config.krebs.zone-head-config] ++ combined-hosts);
combined-hosts =
mapAttrsToList (name: getAttr "extraZones") config.krebs.hosts;
in {
krebs = super.krebs or {} // {
zones = super.krebs.zones or {} //
mapAttrs'
(name: value: {
name = name;
value = self.writeText "${name}.zone" (stripEmptyLines value);
})
all-zones;
};
})
# Implicit zones generated from config.krebs.hosts.*.nets.*.ip{4,6}.addr
(self: super: let
# record : { name : str, type : enum [ "A" "AAAA" ], data : str }
# toRecord : record.name -> record.type -> record.data -> record
toRecord = name: type: data:
{ inherit name type data; };
# toRecords : str -> host -> [record]
toRecords = netname: host:
let
net = host.nets.${netname};
in
optionals
(hasAttr netname host.nets)
(filter
(x: x.data != null)
(concatLists [
(map
(name: toRecord name "A" (net.ip4.addr or null))
(concatMap
(name: [ "${name}." "4.${name}." ])
(net.aliases or [])))
(map
(name: toRecord name "AAAA" (net.ip6.addr or null))
(concatMap
(name: [ "${name}." "6.${name}." ])
(net.aliases or [])))
]));
# formatRecord : record -> str
formatRecord = { name, type, data }: "${name} IN ${type} ${data}";
# writeZone : attrs -> package
writeZone =
{ name ? "${domain}.zone"
, domain ? substring 0 1 netname
, nameservers ? [ "ni" ]
, netname
, hosts ? config.krebs.hosts
}:
self.writeText name /* bindzone */ ''
$TTL 60
@ IN SOA ns admin 1 3600 600 86400 60
@ IN NS ns
${concatMapStringsSep "\n"
(name: /* bindzone */ "ns IN CNAME ${name}")
nameservers
}
${concatMapStringsSep
"\n"
formatRecord
(concatMap
(toRecords netname)
(attrValues hosts))
}
'';
in {
krebs = super.krebs or {} // {
zones = super.krebs.zones or {} // {
i = writeZone { netname = "internet"; };
r = writeZone { netname = "retiolum"; };
w = writeZone { netname = "wiregrill"; };
};
};
})
];
};
}
|