update bind9.php
[GitHub/Stricted/Domain-Control-Panel.git] / bind9.php
1 <?php
2 /**
3 * @author Jan Altensen (Stricted)
4 * @license GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
5 * @copyright 2014-2016 Jan Altensen (Stricted)
6 */
7 $data = file_get_contents("https://dns-control.eu/API/?key=xxx");
8 $data = json_decode($data, true);
9 if (is_array($data) && !isset($data['error'])) {
10 shell_exec("rm -rf /srv/bind/*");
11
12 foreach ($data as $zone) {
13 $out = $zone['soa']['origin']."\t".$zone['soa']['minimum']."\tIN\tSOA\t".$zone['soa']['ns']." ".$zone['soa']['mbox']." (\n";
14 $out .= "\t\t\t\t".$zone['soa']['serial']."\t; Serial\n";
15 $out .= "\t\t\t\t".$zone['soa']['refresh']."\t\t; Refresh\n";
16 $out .= "\t\t\t\t".$zone['soa']['retry']."\t\t; Retry\n";
17 $out .= "\t\t\t\t".$zone['soa']['expire']."\t\t; Expire\n";
18 $out .= "\t\t\t\t180 )\t\t; Negative Cache TTL\n";
19 $out .= ";\n";
20
21 $signed = false;
22 $zsk = false;
23 $ksk = false;
24 foreach ($zone['rr'] as $record) {
25 if ($record['type'] == "DNSKEY") {
26 if ($record['aux'] == 256) {
27 $zsk = true;
28 }
29 else if ($record['aux'] == 257) {
30 $ksk = true;
31 }
32
33 $out .= $record['name']."\t".$record['ttl']."\tIN\t".$record['type']."\t".$record['aux']."\t".$record['data']."\n";
34 }
35 else if ($record['type'] == "MX" || $record['type'] == "SRV" || $record['type'] == "TLSA" || $record['type'] == "DS") {
36 $out .= $record['name']."\t".$record['ttl']."\tIN\t".$record['type']."\t".$record['aux']."\t".$record['data']."\n";
37 }
38 else if ($record['type'] == "TXT") {
39 $txt = $record['data'];
40
41 if (strpos($txt, " ") !== false && strpos($txt, '" "') !== false && $txt != '" "') {
42 if (substr($txt, 0, 1) != '(' && substr($txt, -1) != ')') {
43 if (substr($txt, 0, 1) != '"' && substr($txt, -1) != '"') {
44 $record['data'] = '("'.$txt.'")';
45 }
46 else {
47 $record['data'] = '('.$txt.')';
48 }
49 }
50 }
51 else if (substr($txt, 0, 1) != '"' && substr($txt, -1) != '"') {
52 $record['data'] = '"'.$txt.'"';
53 }
54
55 if (strpos($record['data'], "v=spf1") !== false) {
56 $out .= $record['name']."\t".$record['ttl']."\tIN\tSPF\t" . $record['data']."\n";
57 }
58
59 $out .= $record['name']."\t".$record['ttl']."\tIN\t".$record['type']."\t" . $record['data']."\n";
60 }
61 else {
62 $out .= $record['name']."\t".$record['ttl']."\tIN\t".$record['type']."\t\t" . $record['data']."\n";
63 }
64 }
65
66 $zskkey = false;
67 $kskkey = false;
68 foreach ($zone['sec'] as $sec) {
69 $dir = "/srv/bind/dnssec/".$zone['soa']['origin']."/";
70 if (!file_exists($dir)) {
71 shell_exec("mkdir -p ".$dir);
72 }
73
74 if ($sec['type'] == "ZSK" || $sec['type'] == "KSK") {
75 if (!empty($sec['public']) && !empty($sec['private'])) {
76 preg_match("/; This is a (key|zone)-signing key, keyid ([0-9]+), for ".$zone['soa']['origin']."/i", $sec['public'], $match);
77 $filename1 = getFileName ($zone['soa']['origin'], $sec['algo'], $match[2], "pub");
78 $filename2 = getFileName ($zone['soa']['origin'], $sec['algo'], $match[2], "priv");
79
80 if (file_exists($dir.$filename1)) {
81 unlink($dir.$filename1);
82 }
83
84 if (file_exists($dir.$filename2)) {
85 unlink($dir.$filename2);
86 }
87
88 $handler = fOpen($dir.$filename1, "a+");
89 fWrite($handler, $sec['public']);
90 fClose($handler);
91
92 $handler = fOpen($dir.$filename2, "a+");
93 fWrite($handler, $sec['private']);
94 fClose($handler);
95
96 if (file_exists($dir.$filename1) && file_exists($dir.$filename2)) {
97 /* fallback for missing DNSKEY record */
98 if ($zsk === false || $ksk === false) {
99 preg_match("/".$zone['soa']['origin']." IN DNSKEY ([0-9]+) ([0-9]+) ([0-9]+) ([\s\S]+)/i", $sec['public'], $match);
100 $out .= $zone['soa']['origin']."\t60\tIN\tDNSKEY\t".$match[1]."\t".$match[2]." ".$match[3]." ".$match[4]."\n";
101 if ($sec['type'] == "ZSK") {
102 $zsk = true;
103 }
104 else if ($sec['type'] == "KSK") {
105 $ksk = true;
106 }
107 }
108
109 if ($sec['type'] == "ZSK") {
110 $zskkey = true;
111 }
112 else if ($sec['type'] == "KSK") {
113 $kskkey = true;
114 }
115 }
116 }
117 }
118 }
119
120 $sign = false;
121 if ($zsk === true && $ksk === true && $zskkey === true && $kskkey === true) {
122 $sign = true;
123 }
124
125 $handler = fOpen("/srv/bind/".$zone['soa']['origin']."db", "a+");
126 fWrite($handler, $out);
127 fClose($handler);
128
129 $signed = false;
130 if ($sign === true) {
131 shell_exec("cd /srv/bind/ && /usr/sbin/dnssec-signzone -r /dev/urandom -A -N INCREMENT -K /srv/bind/dnssec/".$zone['soa']['origin']."/ -o ".$zone['soa']['origin']." -t ".$zone['soa']['origin']."db");
132 if (file_exists("/srv/bind/".$zone['soa']['origin']."db.signed")) {
133 $signed = true;
134 }
135 }
136
137 $cout = "zone \"" . $zone['soa']['origin'] . "\" {\n";
138 $cout .= "\ttype master;\n";
139 $cout .= "\tnotify no;\n";
140 $cout .= "\tfile \"/srv/bind/".$zone['soa']['origin']."db".($signed === true ? ".signed" : "")."\";\n";
141 $cout .= "};\n\n";
142
143 $handler = fOpen("/srv/bind/domains.cfg", "a+");
144 fWrite($handler, $cout);
145 fClose($handler);
146 }
147
148 shell_exec("/etc/init.d/bind9 reload");
149 }
150
151 function getFileName ($zone, $algo, $id, $type) {
152 $len = strlen($id);
153 if ($len == "1") {
154 $id = "0000".$id;
155 }
156 else if ($len == "2") {
157 $id = "000".$id;
158 }
159 else if ($len == "3") {
160 $id = "00".$id;
161 }
162 else if ($len == "4") {
163 $id = "0".$id;
164 }
165 if ($type == "pub") {
166 $type = "key";
167 }
168 else if ($type == "priv") {
169 $type = "private";
170 }
171
172 if ($algo == "8") {
173 $algo = "008";
174 }
175 else if ($algo == "10") {
176 $algo = "010";
177 }
178
179 return "K".$zone."+".$algo."+".$id.".".$type;
180 }