|
1 #! /usr/bin/perl -w |
|
2 my $USAGE = <<'#'; |
|
3 Usage: $ME [options] |
|
4 -l --logfile=s Name of the logfile we've to read [$opt_logfile] |
|
5 -d --dir=s Where the named.conf's are expected [$opt_zonesdir] |
|
6 -u --[no]update Update the "masters"-entries [$opt_update] |
|
7 -c --[no]create Add newly appeared domains [$opt_create] |
|
8 -f --[no]follow Follow the end of the logfile [$opt_follow] |
|
9 -h --help This text [$opt_help] |
|
10 # |
|
11 # Es wird ein Verzeichnis geben, in diesem Verzeichnis liegt für |
|
12 # *jede* Zone eine eigene Konfigurations-Datei. |
|
13 # Diese ganzen Konfigurationsdateien werden dann zusammengefaßt |
|
14 # und diese zusammengefaßte wird dem bind per "include" mitgeteilt. |
|
15 |
|
16 use strict; |
|
17 use File::Basename; |
|
18 use IO::Handle; |
|
19 use File::Path; |
|
20 use Getopt::Long; |
|
21 use Unix::Syslog qw/:macros :subs/; |
|
22 |
|
23 my $ME = basename $0; |
|
24 |
|
25 |
|
26 my %auth = ( |
|
27 "212.172.233.34" => "pu.schlittermann.de", |
|
28 "212.80.235.130" => "pu2.schlittermann.de", |
|
29 "145.253.160.50" => "bastion.actech.de", |
|
30 "212.172.233.146" => "ns.flaemingnet.de", |
|
31 "212.172.127.34" => "mango.compot.com", |
|
32 "62.144.175.34" => "ns.add-on.de", |
|
33 "195.145.19.34" => "ns.datom.de", |
|
34 ); |
|
35 |
|
36 $SIG{__DIE__} = sub { syslog(LOG_ERR, $_[0]); exit -1; }; |
|
37 $SIG{__WARN__} = sub { syslog(LOG_WARNING, $_[0]); }; |
|
38 |
|
39 my %seen; |
|
40 |
|
41 my $opt_help = 0; |
|
42 my $opt_logfile = "./syslog"; |
|
43 my $opt_zonesdir = "./zones"; |
|
44 my $opt_follow = 0; |
|
45 my $opt_create = 1; |
|
46 my $opt_update = 1; |
|
47 |
|
48 my $naptime = 1; |
|
49 |
|
50 |
|
51 sub updateFile($@); |
|
52 |
|
53 |
|
54 MAIN: { |
|
55 |
|
56 |
|
57 openlog($ME, LOG_PID | LOG_PERROR, LOG_DAEMON); |
|
58 syslog(LOG_NOTICE, "starting"); |
|
59 |
|
60 GetOptions( |
|
61 "help" => \$opt_help, |
|
62 "logfile=s" => \$opt_logfile, |
|
63 "follow!" => \$opt_follow, |
|
64 "dir=s" => \$opt_zonesdir) |
|
65 or die "$ME: Bad Usage\n"; |
|
66 |
|
67 if ($opt_help) { |
|
68 print eval "\"$USAGE\""; |
|
69 exit 0; |
|
70 } |
|
71 |
|
72 open (LOGFILE, $_ = "<$opt_logfile") or die "Can't open $_: $!\n"; |
|
73 for (;;) { |
|
74 my (%masters, my %missing); |
|
75 while (<LOGFILE>) { |
|
76 |
|
77 my ($domain, $ip); |
|
78 |
|
79 # NOTIFY-Zeilen |
|
80 ($domain, $ip) = /NOTIFY.*?\((\S+?),.*?\[([\d.]+)\]/ and do { |
|
81 if (not exists $auth{$ip}) { |
|
82 warn "notify for $domain from unauthorized ip $ip\n"; |
|
83 next; |
|
84 }; |
|
85 $masters{$domain}->{$ip} = 1; |
|
86 next; |
|
87 }; |
|
88 |
|
89 # NOTIFY for vergessene |
|
90 /NOTIFY for "(\S+?)".*not one of our zones/ and do { |
|
91 if (not exists $masters{$1}) { |
|
92 warn "skipping $1 (not authorized)\n"; |
|
93 next; |
|
94 } |
|
95 $missing{$1} = 1; |
|
96 }; |
|
97 } |
|
98 |
|
99 # Jetzt sind wir erstmal durch und verarbeiten alles |
|
100 |
|
101 #foreach my $domain (sort keys %missing) { |
|
102 #updateFile($domain, keys %{$masters{$domain}}); |
|
103 #delete $masters{$domain}; |
|
104 #delete $missing{$domain}; |
|
105 #} |
|
106 |
|
107 foreach my $domain (sort keys %masters) { |
|
108 updateFile($domain, keys %{$masters{$domain}}); |
|
109 delete $masters{$domain}; |
|
110 delete $missing{$domain} if exists $missing{$domain}; |
|
111 } |
|
112 |
|
113 last if !$opt_follow; |
|
114 sleep $naptime; |
|
115 # seek(LOGFILE, 0, 1); |
|
116 LOGFILE->clearerr(); |
|
117 } |
|
118 } |
|
119 |
|
120 sub updateFile($@) |
|
121 { |
|
122 local $_; |
|
123 my $domain = shift; |
|
124 my $masters = join "; ", @_; |
|
125 my $file = "$opt_zonesdir/$domain"; |
|
126 |
|
127 syslog(LOG_NOTICE, "Updating/Creating $file ($masters)\n"); |
|
128 return; |
|
129 |
|
130 if (-f $file) { |
|
131 open (IN, $_ = "<$file") or die "Can't open $_: $!\n"; |
|
132 # ein etwas anderer Versuch - noch nicht fertig |
|
133 $_ = join "", <IN>; |
|
134 close(IN); open(OUT, ">&STDOUT"); # Wenn's geht, dann in's File |
|
135 s/(masters\s*{)(.*?)(};)/$1$2; $masters; $3/; |
|
136 print OUT; |
|
137 } |
|
138 |
|
139 else { |
|
140 open(OUT, $_ = ">$file") or die "Can't open $_: $!\n"; |
|
141 |
|
142 print OUT <<_EOF_; |
|
143 // Autogenerated |
|
144 zone "$domain" { |
|
145 type slave; |
|
146 masters { $masters; }; |
|
147 file "/etc/bind/slave/$domain"; |
|
148 allow-query { any; }; |
|
149 allow-transfer { none; }; |
|
150 allow-update { none; }; |
|
151 }; |
|
152 _EOF_ |
|
153 close OUT; |
|
154 } |
|
155 |
|
156 return; |
|
157 } |
|
158 |
|
159 |
|
160 # vim:sts=4 sw=4 aw ai sm: |