Ir al contenido principal
Tu aplicación está indicando que tiene problemas para conectarse al servidor de base de datos de fondo en 172.16.1.116, o quizá estés a punto de configurar una nueva aplicación y quieras asegurarte de que puede conectarse al servidor de base de datos de fondo. La primera herramienta que viene a la mente es ping, pero muchos hosts ya no responden a las solicitudes de eco ICMP (ping) y, de los que sí lo hacen, existe una alta probabilidad de que sus cortafuegos de red bloqueen tus solicitudes de ping o sus respuestas. Si ping agota el tiempo de espera (figura 1), hay otras formas de comprobar la conectividad de red.
ping 172.16.1.116
Pinging host 172.16.1.116 : 172.16.1.116
ping: No reply. Time Out !!
ping: No reply. Time Out !!
ping: No reply. Time Out !!
ping: No reply. Time Out !!
Host 172.16.1.116 replied to 0 of the 4 pings
ready 12:26:32
Figura 1: el comando ping agota el tiempo de espera
Suponiendo que el servidor al que intentas conectarte esté ejecutando un servicio basado en TCP (en lugar de UDP), basta con conectarte mediante Telnet al servidor y especificar el número de puerto del servicio. Hay cuatro respuestas posibles: una conexión (figura 2), un rechazo (figura 6), un aviso de error (figuras 7 y 8) o un tiempo de espera agotado (figura 9).
telnet 172.16.1.116 1830
Trying...
Connected to 172.16.1.116.
Escape character is '^]'.
Figura 2 – Conexión
Un mensaje de «Conectado» indica que estás conectado al servidor... probablemente. Algunos aceleradores de WAN interceptan la conexión y la completan, actuando como un proxy. Si te conectas y, unos segundos después, te desconectas, es posible que te hayas conectado al acelerador y que este no haya podido conectarse al destino final, por lo que se ha desconectado de ti. Por supuesto, también podría ser que te hayas conectado al host real y la aplicación se haya bloqueado. Vale la pena saber si estás utilizando algún hardware acelerador y cómo funciona exactamente.
Para desconectarse, pulse Ctrl+] y escriba «quit» en el indicador telnet>.
telnet 172.16.1.116 1830
Trying...
Connected to 172.16.1.116.
Escape character is '^]'.
telnet> quit
Figura 3: Desconexión de una sesión activa
La única forma de estar completamente seguro de que has conectado con el servicio correcto en el host de destino es que dicho servicio responda a la solicitud de conexión con algún tipo de mensaje de bienvenida. Por ejemplo, una pantalla de inicio de sesión que identifique el host. Si tienes acceso al host de destino y este tiene instalado Perl, puedes ejecutar el script de Perl «tcplisten», que enviará un mensaje de bienvenida específico cuando acepte una conexión.
On target system (Linux)
[ndav@phx-lab-lnx64 ~]$ perl tcplisten.pl -p 1830 -m 'Connection has been accepted'
perl tcplisten.pl -port 1830 -message 'Connection has been accepted'
On OpenVOS client
stp -ttp ascii
ready 12:16:34
telnet 164.152.77.155 1830
Trying...
Connected to 164.152.77.155.
Escape character is '^]'.
Connection has been accepted
Escape character is '^]'.Connection closed by forei.
Ready 12:16:40
Figura 4: ejecución de tcplisten.pl en un sistema Linux con un cliente OpenVOS
Dado que el cliente Telnet de OpenVOS borra el contenido de la ventana del terminal al cerrarse la conexión, es probable que tengas que configurar el tipo de terminal en ASCII para poder ver el mensaje de conexión.
También puedes ejecutar tcplisten en OpenVOS (siempre que tengas instalada la biblioteca gnu_library).
On OpenVOS target system
perl tcplisten.pl -p 1830 -m 'made it to m16'
perl tcplisten.pl -port 1830 -message 'made it to m16'
On Linux client
[ndav@phx-lab-lnx64 ~]$ telnet 164.152.77.128 1830
Trying 164.152.77.128...
Connected to rigel.az.stratus.com (164.152.77.128).
Escape character is '^]'.
made it to m16
Connection closed by foreign host.
[ndav@phx-lab-lnx64 ~]$
Figura 5: ejecución de tcplisten.pl en un sistema OpenVOS con un cliente Linux
Un mensaje de «rechazado» indica que has llegado al host de destino, pero que este no tenía ningún servicio a la escucha en ese puerto —probablemente—.
telnet 172.16.1.116 1830
Trying...
telnet: Unable to connect to remote host: The connection was refused.
ready 12:31:28
Figura 6 – Rechazo
Algunos cortafuegos pueden enviar un comando de reinicio en respuesta a una solicitud de conexión no autorizada. Es muy difícil, si no imposible, determinar qué situación se está produciendo, al menos desde el lado del cliente.
Si Telnet recibe una indicación de que no se puede acceder a la red (figura 7) o al host (figura 8), lo notificará. El mensaje «red… inaccesible» indica que OpenVOS no tiene una ruta hacia la red de destino o que algún enrutador en medio de la red no pudo llegar a la red de destino. El mensaje «Sin ruta al host» indica que el enrutador conectado a la red de destino no pudo llegar al host de destino. Lo más probable es que esto signifique que el host de destino está inactivo.
telnet 172.16.1.116 1830
Trying...
telnet: Unable to connect to remote host: Network trying to be reached is unreac
+hable.
ready 12:54:34
Figura 7: El cliente Telnet de OpenVOS indica que no se puede acceder a la red.
telnet 172.16.1.116 1830
Trying...
telnet: Unable to connect to remote host: No route to host.
ready 12:55:44
Figura 8: El cliente Telnet de OpenVOS indica que no se puede contactar con el host
Telnet no indica el origen de estos errores. El script de Perl tuc.pl (prueba de conexión UDP), dirigido a la misma dirección IP y número de puerto, sí indica la dirección IP de origen (véase la explicación siguiente sobre las pruebas UDP).
Un tiempo de espera indica que no se puede contactar con el host, probablemente. La mayoría de los hosts responderán aceptando la conexión o rechazándola, pero si un host cuenta con un cortafuegos integrado, es posible que simplemente descarte la solicitud sin responder. Del mismo modo, un cortafuegos de red también puede descartar la solicitud sin responder; y, por supuesto, cualquier mensaje ICMP enviado por un router o un host también puede ser descartado por otro router o cortafuegos.
telnet 172.16.1.116 1830
Trying...
telnet: Unable to connect to remote host: The operation timed out.
Figura 9: Cliente Telnet de OpenVOS que indica un tiempo de espera agotado
En resumen, hay cinco resultados posibles
Mensaje
Significado
Conectado (con banner)
Se puede acceder al servidor y a la aplicación
Conectado (sin banner)
Es probable que pueda conectarse al servidor y a la aplicación
Rechazado
Se puede conectar al servidor, pero no a la aplicación – probablemente
Inalcanzable
No se puede conectar con el servidor
Tiempo de espera
No se puede contactar con el host – probablemente
Figura 10: resumen de los resultados y las interpretaciones para las conexiones TCP
Si la aplicación utiliza un puerto UDP, la cosa se complica. En primer lugar, en OpenVOS no hay utilidades estándar para enviar un datagrama UDP. En segundo lugar, la respuesta puede llegar como un datagrama UDP o como un mensaje ICMP. El script Perl tuc.pl (test UDP connection) enviará un datagrama que contiene la fecha y hora actuales al host y puerto especificados. A continuación, espera un datagrama UDP o un mensaje ICMP. Lo ideal es que su aplicación devuelva un mensaje que luego se muestre. La figura 11 muestra que la aplicación en escucha repitió el mensaje enviado por el script.
perl tuc.pl -i 172.16.1.116 -p 1830
Reply received on UDP socket from 164.152.77.128 message: echoed by udpecho.pl:
+sent by tuc.pl at Mon Aug 30 13:31:34 2010
ready 13:31:34
Figura 11: La aplicación del servidor UDP repite el mensaje recibido
Si el servidor no está a la escucha en el puerto de destino, debería enviar un mensaje de «puerto de destino inaccesible». Suponiendo que el mensaje se reciba desde la dirección IP de destino, esto significa que se ha conectado con el servidor, pero que ninguna aplicación estaba a la escucha.
perl tuc.pl -i 172.16.1.116 -p 1830
ICMP Destination port unreachable message received from 172.16.1.116
ready 11:40:12
Figura 12: el host de destino envía un mensaje de puerto inaccesible
Al igual que con las pruebas de Telnet, puedes recibir mensajes ICMP que indiquen problemas de red o del host y, como he comentado anteriormente, obtienes la dirección IP del remitente, lo que te proporciona un punto de partida más concreto para iniciar tus investigaciones.
perl tuc.pl -i 172.16.1.116 -p 1830
ICMP Destination network unreachable message received from 164.152.77.171
ready 11:43:50
perl tuc.pl -i 172.16.1.116 -p 1830
ICMP Destination host unreachable message received from 164.152.77.171
ready 11:44:54
Figura 13: mensajes de red y de host inaccesible
Es probable que los errores anteriores sean dos de los más comunes. Otro indica un bucle de enrutamiento
perl tuc.pl -i 172.16.1.116 -p 1830
ICMP Time exceeded , TTL expired in transit message received from 164.152.77.34
ready 11:45:39
Figura 14 – Mensaje ICMP que indica un bucle de enrutamiento
Hay muchos otros errores, algunos de los cuales indican que se han tomado medidas administrativas para impedir el flujo de paquetes. Puedes estar bastante seguro de que estos mensajes indican que un cortafuegos está bloqueando tus paquetes.
Sin embargo, muchas aplicaciones esperan un mensaje con un formato específico. En ese caso, es probable que no recibas respuesta. Por defecto, el script agotará el tiempo de espera tras 5 segundos y mostrará el mensaje «sin respuesta».
perl tuc.pl -i 172.16.1.116 -p 1830
No response was received from 172.16.1.116
ready 16:43:26
Figura 15 – Sin respuesta
Si quieres esperar más tiempo (o menos), puedes usar la «opción -t»
perl tuc.pl -i 172.16.1.117 -p 1830 -t 10
No response was received from 172.16.1.117
ready 12:06:26
perl tuc.pl -i 172.16.1.117 -p 1830 -t 1
No response was received from 172.16.1.117
ready 12:06:32
Figura 16: cómo cambiar el tiempo de espera predeterminado
El silencio no tiene por qué ser malo. Podría significar que has llegado al host de destino, que este está a la escucha en el puerto de destino, pero que simplemente no le ha gustado el mensaje de prueba que se le ha enviado. Desgraciadamente, también podría significar que el paquete de prueba nunca llegó al host de destino y que cualquier mensaje ICMP enviado para indicarlo fue bloqueado. Si tienes acceso al servidor, puedes ejecutar el script Perl udpecho.pl, que añadirá su propia cabecera y luego repetirá lo que se le haya enviado (figura 11).
En resumen
Mensaje
Significado
Mensaje del banner de la aplicación
Se puede acceder al servidor y a la aplicación
Mensaje ICMP de red/host
No se puede conectar con el servidor
Mensaje ICMP del puerto del host
Puedo conectarme al servidor, pero no a la aplicación
Si no hay respuesta, la aplicación muestra un mensaje en la barra superior
No se puede conectar con el servidor
No hay respuesta; la aplicación no envía el mensaje del banner
Es posible que se pueda o no se pueda contactar con el servidor
Figura 17: resumen de los resultados y las interpretaciones para las conexiones UCP

tcplisten.pl

# tcplisten.pl begins here

#

# Versión 1.00 30 de julio de 2010

# Este script se ha probado en

# Open VOS 17.0.2ah con Perl v5.8.0 compilado para i686-vos

# Microsoft Windows XP con el Service Pack 3 instalado

# ActiveState Perl v5.10.0 compilado para MSWin32-x86-multihilo

# Red Hat 4AS-5.5 en ejecución

# Perl v5.8.5 compilado para x86_64-linux-thread-multi

#

#stratus

#

use IO::Socket;

use Getopt::Long;

use Sys::Hostname;

use strict;

my ($result);

my ($localPort, $message, $peerAddr);

my ($newSock, $data);

$result = GetOptions(‘port=s’ => $localPort,

‘message=s’ => $message);

si (($result != 1) || !(defined($localPort)))

{

imprimir «nnUso:n»;

imprimir «tperl tcplisten.pl -port NÚMERO-DE-PUERTO [-message MENSAJE]nn»;

salir;

}

si (!defined($message))

{

imprimir «No se ha especificado ningún mensaje: creando mensaje»;

$message = «Conexión aceptada por tcplisten, que se ejecuta en » . hostname;

}

imprimir “perl tcplisten.pl -port $localPort -message ‘” . $message . “‘n”;

my $sock = IO::Socket::INET->new(

Proto => «tcp»,

LocalPort => $localPort,

LocalAddr => «0.0.0.0»,

Escuchar => 1,

) o se produce un error: «No se ha podido crear el socket para el puerto $localPort: $!n»;

mientras (1)

{

my $newSock = $sock->accept ();

imprimir «Conexión aceptada desde » . $newSock->peerhost .

» en » . localtime () . «n»;

imprimir $newSock $message . “n”;

$newSock -> shutdown(2);

$sock->read($data, 1024); # espera a recibir una señal de cierre */

$newSock->close();

}

#

# tcplisten.pl termina aquí

tuc.pl

# tuc.pl begins here

#

# Versión 1.00 30 de julio de 2010

# Este script se ha probado en

# Open VOS 17.0.2ah con Perl v5.8.0 compilado para i686-vos

# Microsoft Windows XP con el Service Pack 3 instalado

# ActiveState Perl v5.10.0 compilado para MSWin32-x86-multihilo

# Red Hat 4AS-5.5 en ejecución

# Perl v5.8.5 compilado para x86_64-linux-thread-multi

#

#stratus

#

use IO::Socket;

use IO::Select;

use Getopt::Long;

use strict;

my ($result);

my ($destIP, $destPort, $timeout, $result, $message, $flags);

my ($ready, $socket);

my ($x, $c, $icmpAlready);

$result = GetOptions(‘ip=s’ => $destIP,

‘port=s’ => $destPort,

‘timeout=s’ => $timeout);

si (($result != 1) || !(defined($destIP) && defined($destPort)))

{

imprimir «nnUso:n»;

imprimir «tperl tuc.pl -ip DIRECCIÓN-IP-DE-DESTINO » .

«-puerto NÚMERO-DE-PUERTO-DE-DESTINO-nn»;

salir;

}

if (!defined($timeout)) { $timeout = 5; }

elsif ($timeout > 15) { print “OK, pero ” . $timeout .

«parece excesivamente largo.n»; }

$message = «enviado por tuc.pl a las » . localtime();

my $sock = IO::Socket::INET->new(

Proto => «udp»,

Puerto de origen => $destPort,

PeerAddr => $destIP

) o se produce el error «No se ha podido crear el socket para el destino $destIP: $!n»;

my $isock = IO::Socket::INET->new(

Proto => ‘icmp’);

$sock->send($message) o die «Error al enviar: $!n»;

$message = “”;

my $read_set = new IO::Select();

$read_set->add($sock);

$read_set->add($isock);

($ready) = IO::Select->select($read_set, undef, undef, $timeout);

$icmpAlready = 0;

$c = 0;

foreach $socket (@$ready)

{

$c = $c + 1;

si ($socket == $sock)

{

$x = «Respuesta recibida en el socket UDP desde «;

$socket->recv($message, 100, $flags);

si ($icmpAlready == 0)

{

si (longitud($mensaje) > 0)

{ print $x . $socket->peerhost . ” message: ” . $message . “n”; }

else { print $x . $socket->peerhost . “n”; }

}

}

en caso contrario # se ha recibido un mensaje ICMP

{

$icmpAlready = 1;

$socket->recv($message, 100, $flags);

si (longitud($mensaje) > 98)

{ print «Demasiado largo (» . length($message) .

«») Mensaje ICMP procedente de » . $socket->peerhost .

"mensaje: " . $mensaje . "n"; }

elsif (length ($message) < 52)

{ print «Inesperadamente corto (» . length($message) .

“) Mensaje ICMP procedente de ” . $socket->peerhost . “n”; }

en caso contrario # procesar el mensaje ICMP

{

my $type = ord (substr ($message, 20, 1));

my $code = ord(substr($message, 21, 1));

my $port = ord (substr ($message, 50, 1)) * 256 +

ord(substr($message, 51, 1));

si ($port != $destPort)

{ print «Se ha recibido un mensaje ICMP inesperado de » .

$socket->peerhost . ” mensaje: ” . substr($message, 20) .

«n»; }

si no, el mensaje ICMP es correcto

{

si ($type == 3)

{

if ($code == 0) { print «ICMP: red de destino » .

«Se ha recibido un mensaje de un número inaccesible».

$socket->peerhost . «n»; }

elsif ($code == 1) { print “ICMP: Host de destino ” .

«Se ha recibido un mensaje de un número inaccesible».

$socket->peerhost . «n»; }

elsif ($code == 3) { print “Puerto de destino ICMP ” .

«Se ha recibido un mensaje de un número inaccesible».

$socket->peerhost . «n»; }

elsif ($code == 6) { print “Red de destino ICMP ” .

«Se ha recibido un mensaje desconocido de...».

$socket->peerhost . «n»; }

elsif ($code == 7) { print “ICMP: Host de destino desconocido” .

«Mensaje recibido de » . $socket->peerhost . «n»; }

elsif ($code == 8) { print “Host de origen ICMP aislado ” .

«mensaje recibido de » .

$socket->peerhost . «n»; }

elsif ($code == 9) { print “ICMP: red bloqueada administrativamente ” .

«Se ha recibido un mensaje no autorizado de...».

$socket->peerhost . «n»; }

elsif ($code == 10) { print “Host ICMP administrativamente ” .

«Se ha recibido un mensaje no autorizado de...».

$socket->peerhost . «n»; }

elsif ($code == 11) { print “Red ICMP inaccesible para ” .

«Mensaje TOS recibido de » .

$socket->peerhost . «n»; }

elsif ($code == 12) { print “ICMP: host inaccesible para ” .

«Mensaje TOS recibido de » .

$socket->peerhost . «n»; }

elsif ($code == 13) { print “Comunicación ICMP ” .

«Mensaje administrativamente prohibido recibido de » .

$socket->peerhost . «n»; }

else { print “Se ha recibido un mensaje ICMP inesperado de tipo = ” .

$type . «, code = » . $code . « de » .

$socket->peerhost . «n»; }

} # si ($type == 3)

elsif (($type == 11) && ($code == 0))

{ print «Tiempo de ICMP agotado, TTL caducado durante la transmisión» .

«Mensaje recibido de » . $socket->peerhost . «n»; }

else { print “Se ha recibido un mensaje ICMP inesperado de tipo = ” .

$type . «, code = » . $code . « de » .

$socket->peerhost . «n»; }

} # si no # el mensaje ICMP es correcto

} # en caso contrario # procesar el mensaje ICMP

} # else # se ha recibido un mensaje ICMP

} # foreach $socket (@$ready)

if ($c == 0) { print «No se ha recibido respuesta de » .

$sock->peerhost . «n»; }

#

# tuc.pl termina aquí

udpecho.pl

# udpecho.pl begins here

#

# Versión 1.00 30 de julio de 2010

# Este script se ha probado en

# Open VOS 17.0.2ah con Perl v5.8.0 compilado para i686-vos

# Microsoft Windows XP con el Service Pack 3 instalado

# ActiveState Perl v5.10.0 compilado para MSWin32-x86-multihilo

# Red Hat 4AS-5.5 en ejecución

# Perl v5.8.5 compilado para x86_64-linux-thread-multi

#

#stratus

#

use IO::Socket;

use IO::Select;

use Getopt::Long;

use strict;

my ($result);

my ($localPort, $debug, $result, $message, $flags);

my ($ready, $socket);

my ($x, $c);

$result = GetOptions(‘port=s’ => $localPort,

«debug» => $debug);

si (($result != 1) || !(defined($localPort)))

{

imprimir «nnUso:n»;

imprimir «tperl udpecho.pl -port NÚMERO-DE-PUERTO-LOCAL [-debug]nn»;

salir;

}

if (defined($debug)) { print “local port number is ” . $localPort . “n”; }

my $sock = IO::Socket::INET->new(

Proto => «udp»,

LocalPort => $localPort

) o se produce un error: «No se ha podido crear el socket $!n»;

my $read_set = new IO::Select();

$read_set->add($sock);

$message = “”;

mientras (1)

{

($ready) = IO::Select->select($read_set, undef, undef, 300);

foreach $socket (@$ready)

{

$socket->recv($message, 100, $flags);

if (defined($debug)) { print “Mensaje de ” . $socket->peerhost .

"mensaje: " . $mensaje . "n"; }

$socket->send(“Repetido por udpecho.pl: ” . $message) or die “Error al enviar: $!”

+n»;

}

}

#

# udpecho.pl termina aquí