Página 1 de 1

Transferencia de zonas DNS con Net::DNS::Resolver

NotaPublicado: 2010-01-29 09:39 @444
por situ
Estoy tratando de armar un script el cual me entrega los servidores DNS de un dominio y luego consulta la zona de transferencia pero no me funciona.

El script no está del todo bien programado ya que no soy programador. Como verán, lee un archivo externo con los dns que fueron descubiertos en las primeras líneas. Mi idea en realidad era que lea los dns de una variable donde se van a guardar los dns apenas descubiertos pero la verdad que no sé cómo realizar este paso.

Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. #!/usr/bin/perl -w
  2.  
  3. use Net::DNS;
  4.  
  5. open (F,">> dns.conf");
  6. $addr  = shift || "dominio.com";
  7. $res   = Net::DNS::Resolver->new();
  8. $query = $res->query($addr, "NS");
  9.  
  10. if ($query) {
  11.     foreach  $rr (grep { $_->type eq 'NS' } $query->answer) {
  12.         print F $rr->nsdname, "\n";
  13.     }
  14. else {
  15.     warn "query failed: ", $res->errorstring, "\n";
  16. }
  17.  
  18. open  $FILE, '<', "dns.conf" or die $!;
  19. @archivos = <$FILE>;
  20.  
  21. for $archivo(@archivos) {
  22.     chomp $archivo;
  23.  
  24.     $res = Net::DNS::Resolver->new(
  25.         nameservers => [qw($archivo)],
  26.     );
  27.     @zone = $res->axfr('dominio.com');
  28.  
  29.     if (@zone) {
  30.         foreach  $rr (@zone) {
  31.             $rr->print;
  32.         }
  33.     }
  34.     else {
  35.         print 'Zone transfer failed: ', $res->errorstring, "\n";
  36.     }
  37. }
  38.  
Coloreado en 0.003 segundos, usando GeSHi 1.0.8.4

Re: Net::DNS

NotaPublicado: 2010-01-29 11:08 @506
por explorer
No hace falta usar un fichero aparte para intercambiar información. Te vale usar el mismo arreglo que tienes ahora... Usa push() para guardarlos.

Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1.         push @archivos, $rr->nsdname;
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4


El bucle que sigue, no te hace falta, sino que puedes mandarle al módulo todos los servidores encontrados.

Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. $res = Net::DNS::Resolver->new( nameservers => [ @archivos ] );
  2.  
  3. my @zone = $res->axfr('perlenespanol.com');
  4.  
  5. if (@zone) {
  6.     foreach my $rr (@zone) {
  7.         $rr->print;
  8.     }
  9. }
  10. else {
  11.     print 'Zone transfer failed: ', $res->errorstring, "\n";
  12. }
  13.  
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4

Y de esa manera obtenemos la zona.

Otro tema distinto es que quieras obtener la misma zona usando todos los servidores DNS encontrados, que entonces sí que debes hacer un bucle por @archivos, y crear un nuevo objeto del módulo:
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. $res = Net::DNS::Resolver->new( nameservers => [ $archivo ] );
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4

Re: Net::DNS

NotaPublicado: 2010-01-29 13:44 @614
por situ
Como siempre un lujo =)

Dejo el script por si alguna persona lo necesita.

Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. #!/usr/bin/perl -w
  2. # Obtener una zona de un dominio,
  3. # a partir de sus propios servidores DNS
  4.  
  5. # Compruebo que esté el modulo instalado
  6. BEGIN {
  7.     eval "use Net::DNS";
  8.     if ( $@ ) {
  9.         warn  "Error al cargar el módulo: Net::DNS\n"
  10.         . "Instalar módulo:\n"      
  11.         . "\t\tcpan\n"
  12.         . "\t\tcpan> install Net::DNS\n";
  13.  
  14.         exit ();
  15.     }
  16. }
  17.  
  18. # Compruebo que esté el argumento pasado
  19. if ( @ARGV != 1 ) {
  20.     die "\nUso: $0 <dominio> \n\n"
  21.       . "   <dominio>  Dominio [ej -> dominio.com]\n"
  22.       ;
  23. }
  24.  
  25. $dominio = $ARGV[0];
  26. chomp $dominio;
  27.  
  28. use Net::DNS;
  29. $addr = shift || "$dominio";
  30. $res   = Net::DNS::Resolver->new;
  31. $query = $res->query($addr, "NS");
  32.  
  33. if ($query) {
  34.     foreach  $rr (grep { $_->type eq 'NS' } $query->answer) {
  35.         push @archivos, $rr->nsdname;
  36.     }
  37. }
  38. else {
  39.     warn "query failed: ", $res->errorstring, "\n";
  40. }
  41.  
  42. $res = Net::DNS::Resolver->new( nameservers => [ @archivos ] );
  43.  
  44. my @zone = $res->axfr($dominio);
  45.  
  46. if (@zone) {
  47.     foreach my $rr (@zone) {
  48.          $rr->print;
  49.     }
  50. }
  51. else {
  52.     print 'Fallo en la transferencia de la zona: ', $res->errorstring, "\n";
  53. }
  54.  
Coloreado en 0.002 segundos, usando GeSHi 1.0.8.4


Saludos.

Re: Transferencia de zonas DNS con Net::DNS::Resolver

NotaPublicado: 2010-01-29 14:51 @661
por explorer
Unos comentarios...

* Si estás haciendo una prueba, dentro del BEGIN{}, para comprobar la existencia del módulo Net::DNS, luego ya no es necesaria la línea 28

* No es necesario crear un nuevo objeto Net::DNS::Resolver para agregar los servidores de nombres encontrados. Basta con usar la función nameserver() para actualizarlos

* En la mayoría de las ocasiones, "$dominio" es igual $dominio. Es decir, no es necesario entrecomillar una variable si solo es esa la variable que hay entre las comillas

* Aparte de entrar en el shell de cpan, se puede instalar el módulo de varias maneras. Si se quiere seguir usando el comando cpan, se puede usar de forma directa: cpan Net::DNS.

Se podría quedar así (por ejemplo).
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. #!/usr/bin/perl
  2. #
  3. # Obtener la zona de un dominio,
  4. # a partir de los servidores de nombres
  5. # del propio dominio.
  6. #
  7. #use strict;
  8. #use warnings;
  9. #use diagnostics;
  10.  
  11. # Comprobar la existencia del módulo Net::DNS
  12. BEGIN {
  13.     eval "use Net::DNS";
  14.     die "ERROR al cargar el módulo Net::DNS. Instalarlo con el comando\n  cpan Net::DNS\n\n"
  15.         if $@;
  16. }
  17.  
  18.  
  19. # Argumentos: un nombre de dominio
  20. die "  Uso: $0 <dominio>\n\n"
  21.     if ! @ARGV;
  22.  
  23.  
  24. # Dominio y objeto Net::DNS::Resolver
  25. my $dominio  = $ARGV[0];
  26. my $resolver = Net::DNS::Resolver->new();
  27.  
  28.  
  29. # Obtener los servidores de nombres del $dominio
  30. my @servidores_encontrados;
  31. my $query = $resolver->query($dominio, 'NS');
  32.  
  33. die "Falló la obtención de servidores de DNS: ", $resolver->errorstring, "\n"
  34.     if !$query;
  35.  
  36. push @servidores_encontrados,    # almacenamos
  37.     map  { $_->nsdname      }    # el servidor de nombre
  38.     grep { $_->type eq 'NS' }    # que es un registro de tipo NS
  39.     $query->answer;              # extraído de la respuesta
  40.  
  41.  
  42. # Los vamos a usar para obtener la zona
  43. $resolver->nameservers( @servidores_encontrados );
  44.  
  45.  
  46. # Obtención de la zona
  47. my @zona = $resolver->axfr($dominio);
  48.  
  49. die 'Falló la transferencia de zona: ', $resolver->errorstring, "\n"
  50.     if ! @zona;
  51.  
  52. $_->print for @zona;
  53.  
  54. exit 0;
  55.  
Coloreado en 0.002 segundos, usando GeSHi 1.0.8.4