diff options
Diffstat (limited to 'dns_wizard/Bind.pm')
-rw-r--r-- | dns_wizard/Bind.pm | 930 |
1 files changed, 930 insertions, 0 deletions
diff --git a/dns_wizard/Bind.pm b/dns_wizard/Bind.pm new file mode 100644 index 00000000..29e2d766 --- /dev/null +++ b/dns_wizard/Bind.pm @@ -0,0 +1,930 @@ +#!/usr/bin/perl -w +# +# version 0.4 +# Copyright (C) 2004 Mandrakesoft +# Author: Antoine Ginies <aginies _ateuh _ mandrakesoft.com> +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2, or (at your option) +# any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +package MDK::Wizard::Bind; +use lib qw(/usr/lib/libDrakX); + +use strict; +use services; +use common; +use MDK::Wizard::Varspaceval; +use MDK::Wizard::Wizcommon; +use network::network; + +my $wiz = new MDK::Wizard::Wizcommon; +my $in = interactive->vnew; +my $SERIAL = chomp_(`date +20%y%m%d`); +my $HOSTNAME = $wiz->{net}->network_get("HOSTNAME"); +my $BIND_CHROOT = "/var/lib/named"; + +my $IPSERVER = $wiz->{net}->itf_get("IPADDR"); +my $sys_wizard_dns = "/etc/sysconfig/drak_dns_wiz"; +if (-f $sys_wizard_dns) { + our ($interface) = cat_($sys_wizard_dns) =~ /INTERFACE=(.*)/; + ($IPSERVER) = `/sbin/ip addr show dev $interface` =~ /^\s*inet\s+(\d+\.\d+\.\d+\.\d+)/m; +} else { + our $interface = "eth0"; + ($IPSERVER) = `/sbin/ip addr show dev $interface` =~ /^\s*inet\s+(\d+\.\d+\.\d+\.\d+)/m; +} + +my $DOMAINNAME = chomp_(`dnsdomainname`); +my $CLIENTIP = get_spe_ip("ipnor", $IPSERVER) . "."; +my $WDIR = "/tmp/dnstest"; +my $NAMED_DIR = $BIND_CHROOT . "/var/named"; +my $DNSKEY = ""; +my $SHORTHOSTNAME = chomp_(`hostname -s`); +my $TEXTINFO = "dns Wizard"; +my $REP_SAVE = "/tmp/bck"; +my $ZONE_DIR = $NAMED_DIR . "/zone"; +my $DATE = `date +%d-%m-20%y`; + +my $o = { + name => 'DNS Configuration Wizard', + var => { + IPOFFORWARDER => '', + ADDSEARCH => '', + DOMAINNAME => $DOMAINNAME, + SHORTHOSTNAME => $SHORTHOSTNAME, + IPMASTER => '', + CLIENTNAME => '', + CLIENTIP => $CLIENTIP, + }, + init => sub { + my ($err, $msg) = test_host_domain($SHORTHOSTNAME, $DOMAINNAME); + if (!$err) { + $in->ask_warn(N('Error'), $msg); + die 'wizcancel'; + } + ($err, $msg) + }, + needed_rpm => [ 'bind' ], + defaultimage => "/usr/share/mcc/themes/default/dns_server-mdk.png", + }; + +my %level = ( + 1 => N("Master DNS server"), + 2 => N("Slave DNS server"), + 3 => N("Add host in DNS"), + 4 => N("Remove host in DNS"), + ); + +my @list_hosts; + +sub list_hosts { + my $iprev = get_spe_ip('iprev', $IPSERVER); + my $db = "$ZONE_DIR/db.$iprev.hosts"; + #my $ipnor = get_spe_ip('iprev', $IPSERVER); +# push @list_hosts, ""; + foreach (cat_($db)) { + my ($h) = /\d{1,3}\tIN\tPTR\t(.*)/; + !$h or push @list_hosts,$h; + } + @list_hosts; +} + +$o->{pages} = { + welcome => { + name => N("DNS Master configuration wizard") . "\n\n" . N("DNS (Domain Name Server) is the service that maps an IP address of a machine with an internet host name.") . "\n\n" . N("This wizard will help you configuring the DNS services of your server. This configuration will provide a local DNS service for local computers names, with non-local requests forwarded to an outside DNS."), + no_back => 1, + pre => sub { + $o->{var}{wiz_level} ||= 1; + }, + post => sub { + if ($o->{var}{wiz_level} == 2) { + return 'slave' } + elsif ($o->{var}{wiz_level} == 1) { + return 'interface' } + elsif ($o->{var}{wiz_level} == 3) { + if (-f $sys_wizard_dns) { return 'addhost' } else { return 'error_notmaster' } } + elsif ($o->{var}{wiz_level} == 4) { + if (-f $sys_wizard_dns) { return 'removehost' } else { return 'error_notmaster' } } + }, + data => [ + { label => '', val => \$o->{var}{wiz_level}, type => 'list', list => [ sort keys %level ], format => sub { $level{$_[0]} } }, + ], + next => 'interface', + }, + interface => { + name => N("DNS server Interface"), + data => [ + { list => [ keys %{$wiz->{net}{itf}} ], val => \$o->{var}{interface} }, + ], + no_back => 1, + next => 'ipforward' + }, + addhost => { + name => N("Client identification:") . "\n\n" . N("Your client on the network will be identified by name, as in clientname.company.net. Every machine on the network must have a (unique) IP address, in the usual dotted syntax.") . "\n\n" . N("(You don't need to add the domain after the name)") . "\n\n" . N("Note that the given IP address and client name should be unique in the network."), + data => [ + { label => N("Server:"), val_ref => \$o->{var}{SHORTHOSTNAME} }, + { label => N("DNS Domainname:"), val_ref => \$o->{var}{DOMAINNAME} }, + { label => N("Name of the machine:"), val => \$o->{var}{CLIENTNAME} }, + { label => N("IP address of the machine:"), val => \$o->{var}{CLIENTIP} }, + ], + complete => sub { + if ($o->{var}{CLIENTIP}) { + if (!is_ip($o->{var}{CLIENTIP})) { + #$in->ask_warn(N('Error'), N('This is not a valid IP address.')); + return 1; + } else { return 0; } + } + }, + no_back => 1, + next => 'summaryadd', no_back => 1, + }, + removehost => { + name => N("Remove host:") . "\n\n" . N("Remove a host in existing DNS configuration.") . "\n\n" . N("Choose the host you want to remove in the following list."), + data => [ + { label => N("Computer Name:"), val => \$o->{var}{CLIENTNAME}, list_ref => \@list_hosts }, + ], + post => \&list_hosts, + next => 'summaryremove', no_back => 1, + }, + slave => { + name => N("Slave DNS server") . "\n\n" . N("A slave name server will take some of the burden away from your primary name server, and will also function as a backup server, in case your master server is unreachable."), + data => [ + { label => N("IP Address of the master DNS server:"), val => \$o->{var}{IPMASTER} }, + ], + complete => sub { + if ($o->{var}{IPMASTER}) { + if (!is_ip($o->{var}{IPMASTER})) { + #$in->ask_warn(N('Error'), N('This is not a valid IP address.')); + return 1; + } else { return 0; } + } + }, + no_back => 1, + next => 'summaryslave', + }, + + ipforward => { + name => N("IP of your forwarder") . "\n\n" . N("Forwarding occurs on only those queries for which the server is not authoritative and does not have the answer in its cache.") . "\n\n" . N("If you need it and know your IP forwarder enter IP address of it, if you dont know leave it blank"), + pre => sub { + ($IPSERVER) = `/sbin/ip addr show dev $o->{var}{interface}` =~ /^\s*inet\s+(\d+\.\d+\.\d+\.\d+)/m; + output($sys_wizard_dns, "INTERFACE=$o->{var}{interface}\n"); + }, + data => [ + { label => N("External DNS:"), val => \$o->{var}{IPOFFORWARDER} }, + ], + complete => sub { + if ($o->{var}{IPOFFORWARDER}) { + if (!is_ip($o->{var}{IPOFFORWARDER})) { + #$in->ask_warn(N('Error'), N('This is not a valid IP address for your forwarder.')); + return 1; + } else { return 0; } + } + }, + no_back => 1, + next => 'addsearch', + }, + addsearch => { + name => N("Add search domain") . "\n\n" . N("Search list for host-name lookup. The search list is normally determined from the local domain name; by default, it contains only the local domain name. This may be changed by listing the desired domain search path following the search keyword") . "\n\n" . N("Domainname of this server is automatically added, and you dont need to add it here."), + + data => [ + { label => N("Default domain name to search:"), val => \$o->{var}{ADDSEARCH} }, + ], + next => 'summary', + }, + error_ipf => { + name => N("This is not a valid IP address for your forwarder... press next to continue"), + ignore => 1, + next => 'ipforward', + }, + error_ipm => { + name => N("This is not a valid Master DNS IP address... press next to continue"), + ignore => 1, + next => 'slave', + }, + error_iph => { + name => N("This is not a valid IP address... press next to continue"), + ignore => 1, + next => 'addhost', + }, + dhcp_warning => { + name => N("Warning") . "\n\n" . N("You are in dhcp, server may not work with your configuration."), + ignore => 1, + next => 'client_id' + }, + error_add => { + name => N("Error.") . "\n\n" . N("It seems that host is already in your DNS configuration... press next to continue"), + ignore => 1, + next => 'addhost', + }, + error_remove => { + name => N("Error:") . "\n\n" . N("It seems that this is not present in your DNS configuration... press next to continue"), + ignore => 1, + next => 'removehost', + }, + error_nosrv => { + name => N("It seems that no DNS server has been set through wizard. Please run DNS wizard: Master DNS server."), + end => 1, + }, + error_notmaster => { + name => N("It seems that you are not a master DNS server, so I can't add/remove host."), + end => 1, + }, + summaryslave => { + name => N("Wizard will Now build your DNS slave configuration") . "\n\n" . N("with this configuration:"), + data => [ + { label => N("IP Address of the master DNS server:"), val_ref => \$o->{var}{IPMASTER} }, + ], + post => \&do_it_slave, + next => 'end', + }, + summaryadd => { + name => N("Client with this identification will be added to your DNS"), + data => [ + { label => N("Server:"), val_ref => \$o->{var}{SHORTHOSTNAME} }, + { label => N("DNS Domainname:"), val_ref => \$o->{var}{DOMAINNAME} }, + { label => N("Computer name:"), val_ref => \$o->{var}{CLIENTNAME} }, + { label => N("Computer IP address:"), val_ref => \$o->{var}{CLIENTIP} }, + ], + post => \&do_it_add, + }, + summaryremove => { + name => N("Client with this identification will be removed from your DNS"), + data => [ + { label => N("Computer name:"), val => \$o->{var}{CLIENTNAME}, list_ref => \@list_hosts }, + ], + post => \&do_it_remove, + next => 'endremove', + }, + summary => { + name => N("The DNS server is about to be configured with the following configuration"), + data => [ + { label => N("Server Hostname:"), val_ref => \$o->{var}{SHORTHOSTNAME} }, + { label => N("Domainname:"), val_ref => \$o->{var}{DOMAINNAME} }, + { label => N("External DNS:"), val_ref => \$o->{var}{IPOFFORWARDER} }, + { label => N("Default domain name to search:"), val_ref => \$o->{var}{ADDSEARCH} }, + ], + post => \&do_it_master, + next => 'end', + }, + endadd => { + name => N("Congratulations"), + data => [ { label => N("The wizard successfully added the host in your DNS.") } ], + no_back => 1, + end => 1, + }, + endremove => { + name => N("Congratulations"), + data => [ { label => N("The wizard successfully removed the host from your DNS.") } ], + no_back => 1, + end => 1, + }, + end => { + name => N("Congratulations"), + data => [ { label => N("The wizard successfully configured the DNS service of your server.") } ], + no_back => 1, + end => 1, + }, + error_end => { + name => N("Failed"), + data => [ { label => N("Please Relaunch drakwizard, and try to change some parameters.") } ], + no_back => 1, + end => 1, + }, + }; + +sub test_srv { + my $dir = $BIND_CHROOT . "/var/named/zone"; + -d $dir or return 'error_nosrv'; +} + +sub interface_to_ip { + my ($interface) = @_; + my ($ip) = `/sbin/ip addr show dev $interface` =~ /^\s*inet\s+(\d+\.\d+\.\d+\.\d+)/m; + $ip; +} + +sub crea_wdir { + if (-e $WDIR) { system("rm -rf $WDIR") } + mkdir_p($WDIR); +} + +sub resolv_ip { + my ($ip) = @_; + gethostbyaddr(Socket::inet_aton($ip), Socket::AF_INET()); +} + +sub resolv_name { + my ($name) = @_; + join(".", unpack "C4", (gethostbyname $name)[4]); +} + + +sub get_spe_ip { + # waiting iprev, ipnorm or ipend + my ($att, $ip) = @_; + my @o = split(/\./, $ip); + if ($att =~ /iprev/) { + my $iprev = $o[2] . "." . $o[1] . "." . $o[0]; + return $iprev; + } elsif ($att =~ /ipnor/) { + my $ipnor = $o[0] . "." . $o[1] . "." . $o[2]; + return $ipnor; + } elsif ($att =~ /ipend/) { + my $ipend = $o[3]; + return $ipend; + } +} + +sub increment_serial { + my ($iprev) = @_; + my ($SERIAL) = cat_("$ZONE_DIR/db.$DOMAINNAME.hosts") =~ m/\s+(.*?)\s+;\s+Serial/; + $SERIAL = chomp_($SERIAL+1); + substInFile { + s/\s+\d+\s+;\s+Serial/ $SERIAL ; Serial/; + } "$ZONE_DIR/db.$DOMAINNAME.hosts"; + + substInFile { + s/\s+\d+\s+;\s+Serial/ $SERIAL ; Serial/; + } "$ZONE_DIR/db.$iprev.hosts"; +} + + +sub crea_db_local { + output($WDIR . "/db.localhost", <<EOF); +\$TTL 3D +\@ IN SOA $HOSTNAME. root.$HOSTNAME. ( + $SERIAL ; Serial + 8H ; Refresh + 2H ; Retry + 4W ; Expire + 1D) ; Minimum TTL + NS $HOSTNAME. +1 IN PTR localhost. +EOF +} +# end of db.local + + +# create named.conf file +sub crea_named_common { + output($WDIR . "/named.conf", <<EOF); +// (oe) Loosely based on the document below and from production server configurations. +// http://www.cymru.com/Documents/secure-bind-template.html + +// secret must be the same as in /etc/rndc.conf +include "/etc/rndc.key"; + +controls { + inet 127.0.0.1 port 953 + allow { 127.0.0.1; } keys { mykey; }; +}; + +options { + version ""; + directory "/var/named"; + dump-file "/var/tmp/named_dump.db"; + pid-file "/var/run/named.pid"; + statistics-file "/var/tmp/named.stats"; + zone-statistics yes; +// datasize 256M; + coresize 100M; +// fetch-glue no; +// recursion no; +// recursive-clients 10000; + auth-nxdomain yes; + query-source address * port *; + listen-on port 53 { any; }; + cleaning-interval 120; + transfers-in 20; + transfers-per-ns 2; + lame-ttl 0; + max-ncache-ttl 10800; + +// forwarders { first_public_nameserver_ip; second_public_nameserver_ip; }; +EOF + !$o->{var}{IPOFFORWARDER} or append_to_file($WDIR . "/named.conf", "\tforwarders { $o->{var}{IPOFFORWARDER}; };\n"); + append_to_file($WDIR . "/named.conf", <<EOF); + +// allow-update { none; }; +// allow-transfer { any; }; +// Prevent DoS attacks by generating bogus zone transfer +// requests. This will result in slower updates to the +// slave servers (e.g. they will await the poll interval +// before checking for updates). + notify no; +// notify explicit; +// also-notify { secondary_name_server }; + +// Generate more efficient zone transfers. This will place +// multiple DNS records in a DNS message, instead of one per +// DNS message. + transfer-format many-answers; + +// Set the maximum zone transfer time to something more +// reasonable. In this case, we state that any zone transfer +// that takes longer than 60 minutes is unlikely to ever +// complete. WARNING: If you have very large zone files, +// adjust this to fit your requirements. + max-transfer-time-in 60; + +// We have no dynamic interfaces, so BIND shouldn't need to +// poll for interface state {UP|DOWN}. + interface-interval 0; + +// Uncoment these to enable IPv6 connections support +// IPv4 will still work +// listen-on { none; }; +// listen-on-v6 { any; }; + + allow-query { any; }; + allow-recursion { any; }; + +// Deny anything from the bogon networks as +// detailed in the "bogon" ACL. +// blackhole { bogon; }; +}; + +// workaround stupid stuff... (OE: Wed 17 Sep 2003) +zone "ac" { type delegation-only; }; +zone "cc" { type delegation-only; }; +zone "com" { type delegation-only; }; +zone "cx" { type delegation-only; }; +zone "lv" { type delegation-only; }; +zone "museum" { type delegation-only; }; +zone "net" { type delegation-only; }; +zone "nu" { type delegation-only; }; +zone "ph" { type delegation-only; }; +zone "sh" { type delegation-only; }; +zone "tm" { type delegation-only; }; +zone "ws" { type delegation-only; }; + +zone "." IN { + type hint; + file "named.ca"; +}; + +zone "localdomain" IN { + type master; + file "master/localdomain.zone"; + allow-update { none; }; +}; + +zone "localhost" IN { + type master; + file "master/localhost.zone"; + allow-update { none; }; +}; + +zone "0.0.127.in-addr.arpa" IN { + type master; + file "reverse/named.local"; + allow-update { none; }; +}; + +zone "0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.ip6.arpa" IN { + type master; + file "reverse/named.ip6.local"; + allow-update { none; }; +}; + +zone "255.in-addr.arpa" IN { + type master; + file "reverse/named.broadcast"; + allow-update { none; }; +}; + +zone "0.in-addr.arpa" IN { + type master; + file "reverse/named.zero"; + allow-update { none; }; +}; + +EOF +} +# end named.conf + +sub crea_named_master { + my ($ip, $d) = @_; + my $iprev = get_spe_ip('iprev', $ip); + append_to_file($WDIR . "/named.conf", <<EOF); +zone "$iprev.in-addr.arpa" { + type master; + file "zone/db.$iprev.hosts"; + forwarders { }; +}; + +zone "$d" { + type master; + file "zone/db.$d.hosts"; + forwarders { }; +}; +EOF +} + +sub crea_named_slave { + my ($ip, $d, $IPM) = @_; + my $iprev = get_spe_ip('iprev', $ip); + append_to_file($WDIR . "/named.conf", <<EOF); +zone "$iprev.in-addr.arpa" { + type slave; + masters { $IPM; }; + file "bak.db.$iprev.hosts"; +}; + +zone "$d" { + type slave; + masters { $IPM; }; + file "bak.db.$d.hosts"; +}; +EOF +} + +# create hints +sub crea_hints { + output($WDIR . "/root.hints", <<EOF); +; <<>> DiG 8.1 <<>> \@A.ROOT-SERVERS.NET. +; (1 server found) +;; res options: init recurs defnam dnsrch +;; got answer: +;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 10 +;; flags: qr aa rd; QUERY: 1, ANSWER: 13, AUTHORITY: 0, ADDITIONAL: 13 +;; QUERY SECTION: +;; ., type = NS, class = IN + +;; ANSWER SECTION: +. 6D IN NS G.ROOT-SERVERS.NET. +. 6D IN NS J.ROOT-SERVERS.NET. +. 6D IN NS K.ROOT-SERVERS.NET. +. 6D IN NS L.ROOT-SERVERS.NET. +. 6D IN NS M.ROOT-SERVERS.NET. +. 6D IN NS A.ROOT-SERVERS.NET. +. 6D IN NS H.ROOT-SERVERS.NET. +. 6D IN NS B.ROOT-SERVERS.NET. +. 6D IN NS C.ROOT-SERVERS.NET. +. 6D IN NS D.ROOT-SERVERS.NET. +. 6D IN NS E.ROOT-SERVERS.NET. +. 6D IN NS I.ROOT-SERVERS.NET. +. 6D IN NS F.ROOT-SERVERS.NET. + +;; ADDITIONAL SECTION: +G.ROOT-SERVERS.NET. 5w6d16h IN A 192.112.36.4 +J.ROOT-SERVERS.NET. 5w6d16h IN A 198.41.0.10 +K.ROOT-SERVERS.NET. 5w6d16h IN A 193.0.14.129 +L.ROOT-SERVERS.NET. 5w6d16h IN A 198.32.64.12 +M.ROOT-SERVERS.NET. 5w6d16h IN A 202.12.27.33 +A.ROOT-SERVERS.NET. 5w6d16h IN A 198.41.0.4 +H.ROOT-SERVERS.NET. 5w6d16h IN A 128.63.2.53 +B.ROOT-SERVERS.NET. 5w6d16h IN A 128.9.0.107 +C.ROOT-SERVERS.NET. 5w6d16h IN A 192.33.4.12 +D.ROOT-SERVERS.NET. 5w6d16h IN A 128.8.10.90 +E.ROOT-SERVERS.NET. 5w6d16h IN A 192.203.230.10 +I.ROOT-SERVERS.NET. 5w6d16h IN A 192.36.148.17 +F.ROOT-SERVERS.NET. 5w6d16h IN A 192.5.5.241 +;; Total query time: 215 msec +;; FROM: roke.uio.no to SERVER: A.ROOT-SERVERS.NET. 198.41.0.4 +;; WHEN: Sun Feb 15 01:22:51 1998 +;; MSG SIZE sent: 17 rcvd: 436 +EOF +} +# end roots.hints + +# create ipreverse +sub crea_iprev { + my ($ip, $d) = @_; + my $iprev = get_spe_ip('iprev', $ip); + my $ipend = get_spe_ip('ipend', $ip); + output($WDIR . "/db." . $iprev . ".hosts", <<EOF); +\$TTL 3D +@ IN SOA $SHORTHOSTNAME.$d. $SHORTHOSTNAME.$d. ( + $SERIAL ; Serial + 10800 ; Refresh + 3600 ; Retry + 604800 ; Expire + 86400) ; Minimum TTL + NS $SHORTHOSTNAME.$d. +$ipend IN PTR $SHORTHOSTNAME.$d. +; use tab to retrieve data in drakwizard bind +; 34 IN PTR xp2400.guibland.com. +EOF + +} +# end create iprev + +# create ipnormal +sub crea_ipnorm { + my ($ip, $d) = @_; + output($WDIR . "/db.$d.hosts", <<EOF); +\$TTL 3D +@ IN SOA $SHORTHOSTNAME.$d. root.$SHORTHOSTNAME.$d. ( + $SERIAL ; Serial + 8H ; Refresh + 2H ; Retry + 4W ; Expire + 1D) ; Minimum TTL + TXT $TEXTINFO + IN NS $SHORTHOSTNAME.$d. +localhost A 127.0.0.1 +dnsmaster IN CNAME $SHORTHOSTNAME.$d. +$SHORTHOSTNAME.$d. IN A $ip +; use tab to retrieve data in drakwizard bind +; xp2400.guibland.com. IN A 10.0.1.34 +EOF +} +# end of ipnorm + + +# create 127.0. +sub crea_127 { + my $d = $DOMAINNAME; + output($WDIR . "/db.127.0.0.1", <<EOF); +\$TTL 3D +\@ IN SOA $d. root.$d. ( + $SERIAL ; Serial + 28800 ; Refresh + 7200 ; Retry + 604800 ; Expire + 86400) ; Minimum TTL + NS $HOSTNAME. +localhost IN A 127.0.0.1 +EOF +} +# end create 127 + +# create rndc.conf +sub crea_rndc { + output($WDIR . "/rndc.conf", <<EOF); +/* +* Copyright (C) 2000, 2001 Internet Software Consortium. +* +* Permission to use, copy, modify, and distribute this software for any +* purpose with or without fee is hereby granted, provided that the above +* copyright notice and this permission notice appear in all copies. +* +* THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM +* DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL +* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL +* INTERNET SOFTWARE CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, +* INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING +* FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, +* NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION +* WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +*/ +/* Id: dns_cluster.pm,v 1.18 2003/04/10 16:01:47 aginies Exp */ +/* +* Sample rndc configuration file. +*/ + +options { + default-server localhost; + default-key "mykey"; +}; + +server localhost { + key "mykey"; +}; + +key "mykey" { + algorithm hmac-md5; + secret "$DNSKEY"; +}; +EOF +} +# end of create rndc + +# save old config files + +sub save_old_config { + if (-d $ZONE_DIR) { + print " - Backup of current configuration in " . $REP_SAVE . "\n"; + } + if (-d "$REP_SAVE/dns") { rm_rf("$REP_SAVE/dns") } + mkdir_p($REP_SAVE . '/dns'); + system("cp -avf $ZONE_DIR/* $REP_SAVE/dns/"); +# cp_af($_, "$REP_SAVE/dns/$_" . '-' . $DATE . '.sauv') foreach glob_($ZONE_DIR . "/*"); + if (-e "$BIND_CHROOT/etc/named.conf") { + cp_af("$BIND_CHROOT/etc/named.conf", "$REP_SAVE/dns/named.conf-$DATE"); + } +} +# end save old config + +sub generate_rndc { + mkdir_p($WDIR); + system("rndc-confgen -a -c $WDIR/rndc.key"); + my ($key) = cat_("$WDIR/rndc.key") =~ /secret "(\S*)";/; + $key; +} + + +# reinit resolv.conf +sub set_resolv { + output($WDIR . "/resolv.conf", <<EOF); +domain $DOMAINNAME +search $DOMAINNAME +nameserver $IPSERVER +EOF + + !$o->{var}{IPMASTER} or return append_to_file($WDIR . "/resolv.conf", "nameserver $o->{var}{IPMASTER}\n"); + !$o->{var}{ADDSEARCH} or return append_to_file($WDIR . "/resolv.conf", "search $o->{var}{ADDSEARCH}\n"); + !$o->{var}{IPOFFORWARDER} or return append_to_file($WDIR . "/resolv.conf", "nameserver $o->{var}{IPOFFORWARDER}\n"); +} +# end set resolv.conf + +# set /etc/hosts +sub set_hosts { + my ($ip, $h) = @_; + if (!any { /$ip\s* $h/ } cat_($WDIR . "/hosts")) { + append_to_file($WDIR . "/hosts", <<EOF); +$ip $h +EOF + } +} +# end set hosts + +# check config of dns +sub check_config { + system('named-checkconf', $WDIR . '/named.conf'); +} +# end check config + +# copy file correct place +sub copy_good { + mkdir_p($ZONE_DIR); + mkdir_p("$BIND_CHROOT/etc"); + cp_af($WDIR . '/named.conf', "$BIND_CHROOT/etc/named.conf"); + cp_af($WDIR . '/rndc.conf', "$BIND_CHROOT/etc/rndc.conf"); + cp_af($WDIR . '/hosts', '/etc/hosts'); + cp_af($WDIR . '/resolv.conf', '/etc/resolv.conf'); + cp_af($WDIR . '/root.hints', $ZONE_DIR . '/'); + cp_af(glob($WDIR . '/db*'), $ZONE_DIR . '/'); +} +# end copy goodplace + +my $ip_regexp = qr/^(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})$/; +sub check_ipm { + my $ip = $o->{var}{IPMASTER}; + $ip or return 'slave'; + my @fields = $ip =~ $ip_regexp or return 'error_ipm'; + every { 0 <= $_ && $_ <= 255 } @fields or return 'error_ipm'; +} + +sub check_ipf { + my $ip = $o->{var}{IPOFFORWARDER}; + $ip or return 'addsearch'; + my @fields = $ip =~ $ip_regexp or return 'error_ipf'; + every { 0 <= $_ && $_ <= 255 } @fields or return 'error_ipf'; +} + + +sub check_iph { + my $ip = $o->{var}{CLIENTIP}; + my @fields = $ip =~ $ip_regexp or return 'error_iph'; + every { 0 <= $_ && $_ <= 255 } @fields or return 'error_iph'; +} + +sub do_it { + $::testing and return; + #my ($st) = @_; + crea_wdir($WDIR); + # create files + crea_db_local(); + crea_127(); + crea_named_common(); + # set host configuration + if (-f $WDIR . '/hosts') { rm_rf($WDIR . '/hosts') } + set_hosts('127.0.0.1', 'localhost.localdomain localhost'); + set_hosts($IPSERVER, $HOSTNAME); +} + +sub end_it { + crea_hints(); + crea_rndc(); + # set configuration files on server + set_resolv(); + # check generated config file are good + check_config(); + # create backup + save_old_config(); + # copy in correct place + copy_good(); + # start or restart the service + if (services::is_service_running('named')) { + services::restart('named') + } else { + services::start('named') + } +} + +sub do_it_master { + return if $::testing; + my $in = 'interactive'->vnew('su', 'dns'); + check_starts_on_boot($in, 'named'); + my $w = $in->wait_message(N("Master DNS server"), N("Configuring your system as Master DNS server ...")); + output($sys_wizard_dns, "INTERFACE=$o->{var}{interface}\n"); + do_it(); + crea_iprev($IPSERVER, $DOMAINNAME); + crea_ipnorm($IPSERVER, $DOMAINNAME); + crea_named_master($IPSERVER, $DOMAINNAME); + end_it(); + undef $w; + check_started('named'); +} + +sub do_it_slave { + return if $::testing; + my $in = 'interactive'->vnew('su', 'dns'); + check_starts_on_boot($in, 'named'); + my $w = $in->wait_message(N("Slave DNS server"), N("Configuring your system as Slave DNS server ...")); + if (-f $sys_wizard_dns) { unlink $sys_wizard_dns } + do_it(); + rm_rf(glob("$NAMED_DIR/bak*")); + crea_named_slave($IPSERVER, $DOMAINNAME, $o->{var}{IPMASTER}); + end_it(); + undef $w; + check_started('named'); +} + +sub get_shortname { +# sure someone can find a better method to do that + my ($name) = @_; + my @DT = split(/\./, $DOMAINNAME); + my $NB = $#DT; + if (any { /$DOMAINNAME$/x } $name) { + my @shortname = split(/\./, $name); + splice(@shortname, -$NB); + my $shortn; + foreach (@shortname) { + $shortn or return $shortn = $_; + !$shortn or return $shortn . "." . $_; + } + } else { return $name } +} + +sub do_it_add { + return if $::testing; + test_srv(); + my $iprev = get_spe_ip('iprev', $IPSERVER); + my $ipend = get_spe_ip('ipend', $o->{var}{CLIENTIP}); + my $SNAME = get_shortname($o->{var}{CLIENTNAME}); + if (any { /$ipend\tIN/ } cat_("$ZONE_DIR/db.$iprev.hosts")) { + return 'error_add'; + } elsif (any { /$SNAME.$DOMAINNAME.$/ } cat_("$ZONE_DIR/db.$iprev.hosts")) { + return 'error_add'; + } else { + append_to_file("$ZONE_DIR/db.$DOMAINNAME.hosts", + "$SNAME.$DOMAINNAME.\tIN\tA\t$o->{var}{CLIENTIP}\n"); + append_to_file("$ZONE_DIR/db.$iprev.hosts", + "$ipend\tIN\tPTR\t$SNAME.$DOMAINNAME.\n"); + } + increment_serial($iprev); + system("service named reload"); + return 'endadd' +} + +sub do_it_remove { + return if $::testing; + test_srv(); + my $iprev = get_spe_ip('iprev', $IPSERVER); + my $NAME = $o->{var}{CLIENTNAME}; + substInFile { + s/^\b$NAME.\b.*//; + s/^\s*$//; + } "$ZONE_DIR/db.$DOMAINNAME.hosts"; + substInFile { + s/^\d+\tIN\tPTR\t$NAME.*//; + s/^\s*$//; + } "$ZONE_DIR/db.$iprev.hosts"; + increment_serial($iprev); + system("service named reload"); +} + + +#34 IN PTR xp2400.guibland.com. +sub do_it_list { + return if $::testing; + my $iprev = get_spe_ip('iprev', $IPSERVER); + my $db = "$ZONE_DIR/db.$iprev.hosts"; + #my $ipnor = get_spe_ip('ipnor', $IPSERVER); + my @hosts; my @ip; + foreach (cat_($db)) { + my ($ipend, $h) = /(\d{1,3})\tIN\tPTR\t(.*)/; + if (!$h) { push @hosts, $h; push @ip, $ipend } + } +} + + +sub new { + my ($class) = @_; + bless $o, $class; +} + +1; |