diff --git a/app/app.pm b/app/app.pm index 306f062..4ddff96 100644 --- a/app/app.pm +++ b/app/app.pm @@ -16,8 +16,9 @@ use Moose; has dbh => ( is => 'rw', builder => '_void'); has dnsi => ( is => 'rw', builder => '_void'); +has dnsisec => ( is => 'rw', builder => '_void'); has um => ( is => 'rw', builder => '_void'); -has [ qw/zdir dbname dbhost dbport dbuser dbpass sgbd dnsapp sshhost sshuser sshport/ ] => qw/is ro required 1/; +has [ qw/zdir dbname dbhost dbport dbuser dbpass sgbd dnsapp dnsappsec sshhost sshhostsec sshuser sshusersec sshport sshportsec nsmasterv4 nsmasterv6/ ] => qw/is ro required 1/; sub _void { my $x = ''; \$x; } ### users @@ -38,10 +39,15 @@ sub init { || die "Could not connect to database: $DBI::errstr"; ($success, ${$self->dnsi}) = app::zone::interface ->new() - ->get_interface($self->dnsapp, $self->zdir); + ->get_interface($self->dnsapp, $self); die("zone interface") unless $success; + ($success, ${$self->dnsisec}) = app::zone::interface ->new() + ->get_interface($self->dnsappsec, $self); + + die("zone interface (secondary ns)") unless $success; + ${$self->um} = app::bdd::management->new(dbh => ${$self->dbh}); } @@ -78,6 +84,19 @@ sub delete_user { ### domains +sub _get_zone_edit { + my ($self, $domain) = @_; + + return app::zone::edit->new( + zname => $domain + , dnsapp => $self->dnsapp + , dnsappsec => $self->dnsappsec + , zdir => $self->zdir + , host => $self->sshhost + , user => $self->sshuser + , port => $self->sshport ); +} + # return yes or no sub add_domain { my ($self, $login, $domain) = @_; @@ -91,11 +110,7 @@ sub add_domain { return 0; } - my $ze = app::zone::edit->new(zname => $domain - , zdir => $self->zdir - , host => $self->sshhost - , user => $self->sshuser - , port => $self->sshport ); + my $ze = _get_zone_edit($domain); $ze->addzone(); } @@ -107,11 +122,7 @@ sub delete_domain { return 0 unless $success; return 0 unless $user->delete_domain($domain); - my $ze = app::zone::edit->new(zname => $domain - , zdir => $self->zdir - , host => $self->sshhost - , user => $self->sshuser - , port => $self->sshport ); + my $ze = _get_zone_edit($domain); $ze->del(); 1; @@ -120,31 +131,19 @@ sub delete_domain { sub update_domain_raw { my ($self, $zone, $domain) = @_; - my $ze = app::zone::edit->new(zname => $domain - , zdir => $self->zdir - , host => $self->sshhost - , user => $self->sshuser - , port => $self->sshport ); + my $ze = _get_zone_edit($domain); $ze->update_raw($zone); } sub update_domain { my ($self, $zone, $domain) = @_; - my $ze = app::zone::edit->new(zname => $domain - , zdir => $self->zdir - , host => $self->sshhost - , user => $self->sshuser - , port => $self->sshport ); + my $ze = _get_zone_edit($domain); $ze->update($zone); } sub get_domain { my ($self, $domain) = @_; - my $ze = app::zone::edit->new(zname => $domain - , zdir => $self->zdir - , host => $self->sshhost - , user => $self->sshuser - , port => $self->sshport ); + my $ze = _get_zone_edit($domain); $ze->get(); } @@ -167,11 +166,7 @@ sub get_all_users { sub new_tmp { my ($self, $domain) = @_; - my $ze = app::zone::edit->new(zname => $domain - , zdir => $self->zdir - , host => $self->sshhost - , user => $self->sshuser - , port => $self->sshport ); + my $ze = _get_zone_edit($domain); $ze->new_tmp(); } diff --git a/app/zone/edit.pm b/app/zone/edit.pm index 30d85b5..4cd02d8 100644 --- a/app/zone/edit.pm +++ b/app/zone/edit.pm @@ -7,11 +7,11 @@ use Net::SSH q; use v5.14; use lib '../../'; -use app::zone::rndc_interface; +use app::zone::interface; package app::zone::edit; use Moose; -has [ qw/zname zdir host user port/ ] => qw/is ro required 1/; +has [ qw/dnsapp dnsappsec zname zdir host user port/ ] => qw/is ro required 1/; sub get { my ($self) = @_; @@ -25,7 +25,7 @@ sub get { =pod copie du template pour créer une nouvelle zone update du serial - ajout de la zone via rndc + ajout de la zone via dnsapp (rndc, knot…) retourne la zone + le nom de la zone =cut @@ -51,8 +51,15 @@ sub addzone { $self->_scp_put($tmpfile, $file); # put the final zone on the server unlink($tmpfile); # del the temporary file - my $rndc = app::zone::rndc_interface->new(); - $rndc->addzone($self->zdir, $self->zname); + # add new zone on the primary ns + my $prim = app::zone::interface->new() + ->get_interface($self->dnsapp); + $prim->addzone($self->zdir, $self->zname); + + # add new zone on the secondary ns + my $sec = app::zone::interface->new() + ->get_interface($self->dnsappsec); + $sec->addzone_sec($self->zdir, $self->zname); return $zonefile; } @@ -80,8 +87,9 @@ sub update { $self->_scp_put($tmpfile, $file); # put the final zone on the server unlink($tmpfile); # del the temporary file - my $rndc = app::zone::rndc_interface->new(); - $rndc->reload($self->zname); + my $prim = app::zone::interface->new() + ->get_interface($self->dnsapp); + $prim->reload($self->zname); 1; } @@ -163,9 +171,15 @@ sub _sed { sub del { my ($self) = @_; - my $rndc = app::zone::rndc_interface->new(); - $rndc->delzone($self->zdir, $self->zname); - $rndc->reconfig(); + my $prim = app::zone::interface->new() + ->get_interface($self->dnsapp); + $prim->delzone($self->zdir, $self->zname); + $prim->reconfig(); + + my $sec = app::zone::interface->new() + ->get_interface($self->dnsappsec); + $sec->delzone($self->zdir, $self->zname); + $sec->reload($self->zdir, $self->zname); my $file = $self->zdir.'/'.$self->zname; my $host = $self->host; @@ -177,7 +191,6 @@ sub del { close(READER); close(WRITER); - 1; } diff --git a/app/zone/interface.pm b/app/zone/interface.pm index 26bb334..908d429 100644 --- a/app/zone/interface.pm +++ b/app/zone/interface.pm @@ -1,12 +1,16 @@ use lib '../../'; use app::zone::rndc_interface; +use app::zone::knot_interface; +use app::zone::nsdc_interface; package app::zone::interface; use Moose; sub get_interface { - my ($self, $type, $zp) = @_; - return 1, app::zone::rndc_interface->new(zdir => $zp) if $type eq 'rndc'; - return 0; + my ($self, $type, $data) = @_; + return 1, app::zone::rndc_interface->new(data => $data) if $type eq 'rndc'; + return 1, app::zone::knot_interface->new(data => $data) if $type eq 'knot'; + return 1, app::zone::nsdc_interface->new(data => $data) if $type eq 'nsdc'; + return 0; } 1; diff --git a/app/zone/nsdc_interface.pm b/app/zone/nsdc_interface.pm new file mode 100644 index 0000000..d56f42f --- /dev/null +++ b/app/zone/nsdc_interface.pm @@ -0,0 +1,108 @@ +use v5.14; +package app::zone::nsdc_interface; +use Moose; + +has [ qw/data/ ] => qw/is ro required 1/; + +# on suppose que tout est déjà mis à jour dans le fichier +sub reload { + my ($self, $zname) = @_; + system("ssh " + . $self->data->sshsec + . " nsdc reload $zname 2>/dev/null 1>/dev/null"); +} + +sub addzone_sec { + my ($self, $zdir, $zname, $opt) = @_; + + # get the file + # modify the file + # push the file + my $f = "/tmp/nsd.conf"; + + _scp_get($self->data->sshusersec + , $self->data->sshhostsec + , $self->data->sshportsec + , "/etc/nsd3/nsd.conf" + , $f); + + my %slavedzones = $self->data->get_all_domains(); + + my $data = read_file($f); + my $debut = "## BEGIN_GENERATED"; + my $nouveau = ''; # TODO + + for(keys %slavedzones) { + $nouveau .= "zone:\n\tname: \"$_\"\n" + . "\tzonefile: \"slave/$_\"\n"; + + # allow notify & request xfr, v4 & v6 + $nouveau .= + "\tallow-notify: " . $self->data->nsmasterv4. "\n" + . "\trequest-xfr: " . $self->data->nsmasterv4 . "\n"; + + $nouveau .= + "\tallow-notify: " . $self->data->nsmasterv6. "\n" + . "\trequest-xfr: " . $self->data->nsmasterv6 . "\n\n"; + } + + $data =~ s/$debut.*/$debut\n$nouveau/gsm; + + write_file($f, $data); + + _scp_put($self->data->sshusersec + , $self->data->sshhostsec + , $self->data->sshportsec + , $f + , "/etc/nsd3/"); +} + +sub _scp_get { + my ($self, $user, $host, $port, $src, $dest) = @_; + + my $co = $user . '@' . $host . ':' . $port; + my $ssh = Net::OpenSSH->new($co); + $ssh->scp_get($src, $dest) or die "scp failed: " . $ssh->error; +} + +sub _scp_put { + my ($self, $user, $host, $port, $src, $dest) = @_; + + my $co = $user . '@' . $host . ':' . $port; + my $ssh = Net::OpenSSH->new($co); + $ssh->scp_put($src, $dest) or die "scp failed: " . $ssh->error; +} + +sub reconfig { + my ($self, $zname) = @_; + system("nsdc reconfig 2>/dev/null 1>/dev/null"); +} + +sub delzone { + my ($self, $zdir, $zname) = @_; + system("nsdc delzone $zname 2>/dev/null 1>/dev/null"); +} + +sub read_file { + my ($filename) = @_; + + open my $entree, '<:encoding(UTF-8)', $filename or + die "Impossible d'ouvrir '$filename' en lecture : $!"; + local $/ = undef; + my $tout = <$entree>; + close $entree; + + return $tout; +} + +sub write_file { + my ($filename, $data) = @_; + + open my $sortie, '>:encoding(UTF-8)', $filename or die "Impossible d'ouvrir '$filename' en écriture : $!"; + print $sortie $data; + close $sortie; + + return; +} + +1; diff --git a/app/zone/rndc_interface.pm b/app/zone/rndc_interface.pm index 9bc17d6..9768e54 100644 --- a/app/zone/rndc_interface.pm +++ b/app/zone/rndc_interface.pm @@ -2,6 +2,8 @@ use v5.14; package app::zone::rndc_interface; use Moose; +has [ qw/data/ ] => qw/is ro required 1/; + # on suppose que tout est déjà mis à jour dans le fichier sub reload { my ($self, $zname) = @_; diff --git a/www/conf/config.ini b/www/conf/config.ini index 6748cdb..607b6de 100644 --- a/www/conf/config.ini +++ b/www/conf/config.ini @@ -13,11 +13,24 @@ user = monutilisateur passwd = motdepasse # other options : see DBI module -# possible options for dnsserver : bind rndc -dnsapp = rndc +# possible options for dnsserver : +# rndc (bind) +# knot +# then secondary nameserver +dnsapp = rndc +dnsappsec = knot zones_path = "/var/named/rndczones/" # to access zones on the server sshhost = host sshuser = dnsmanager sshport = 2222 + +# name the IP of the primary named server +nsmasterv4 = 89.234.141.65 +nsmasterv6 = 2a00:5881:8100:1000::2 + +# to access to the slave DNS server +sshhostsec = host +sshusersec = dnsmanager +sshportsec = 2222 diff --git a/www/lib/DNSManager.pm b/www/lib/DNSManager.pm index dd1a05f..27acfb1 100755 --- a/www/lib/DNSManager.pm +++ b/www/lib/DNSManager.pm @@ -39,10 +39,16 @@ sub initco { , dbuser => $cfg->param('user') , dbpass => $cfg->param('passwd') , sgbd => $cfg->param('sgbd') + , nsmasterv4 => $cfg->param('nsmasterv4') + , nsmasterv6 => $cfg->param('nsmasterv6') , sshhost => $cfg->param('sshhost') + , sshhostsec => $cfg->param('sshhostsec') , sshuser => $cfg->param('sshuser') + , sshusersec => $cfg->param('sshusersec') , sshport => $cfg->param('sshport') - , dnsapp => $cfg->param('dnsapp') ); + , sshportsec => $cfg->param('sshportsec') + , dnsapp => $cfg->param('dnsapp') + , dnsappsec => $cfg->param('dnsappsec') ); $app->init();