メインコンテンツへスキップ
アプリケーションがバックエンドデータベースサーバー(172.16.1.116)への接続に問題があると報告している場合、あるいは新規アプリケーションの設定時にバックエンドデータベースサーバーへの接続を確認したい場合。 最初に思い浮かぶツールはpingですが、多くのホストはもはやICMPエコー(ping)リクエストに応答せず、応答するホストでもネットワークファイアウォールがpingリクエストまたは応答をブロックする可能性が高いです。pingがタイムアウトした場合(図1)、ネットワーク接続性をテストする他の方法があります。
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
図1 – pingのタイムアウト
接続先のホストがTCP(UDPではなく)ベースのサービスを実行していると仮定すると、単にそのホストにtelnet接続し、サービスのポート番号を指定すればよい。返される応答は4種類あり、接続成功(図2)、接続拒否(図6)、何らかの異常の表示(図7および図8)、タイムアウト(図9)である。
telnet 172.16.1.116 1830
Trying...
Connected to 172.16.1.116.
Escape character is '^]'.
図2 – 接続
「接続済み」というメッセージは、ホストに接続されていることを示しています(おそらく)。一部のWANアクセラレータは接続を中継し、プロキシとして動作します。接続後に数秒で切断される場合、アクセラレータに接続したものの、アクセラレータが最終的な宛先に接続できず、あなたとの接続を切断した可能性があります。 もちろん、実際のホストに接続したもののアプリケーションがクラッシュした可能性もあります。アクセラレータハードウェアを使用しているかどうか、またその動作を正確に把握しておくことが重要です。
切断するには、telnet> プロンプトで Control-] と「quit」を入力してください。
telnet 172.16.1.116 1830
Trying...
Connected to 172.16.1.116.
Escape character is '^]'.
telnet> quit
図3 – 接続済みセッションの切断
ターゲットホスト上で正しいサービスが確実に実行されていることを確認する唯一の方法は、そのサービスが接続要求に対して何らかのバナーメッセージで応答することです。例えば、ホストを識別するログインプロンプトなどです。ターゲットホストにアクセスでき、かつそのホストにPerlがインストールされている場合、tcplisten Perlスクリプトを実行できます。このスクリプトは接続を受け入れる際に指定されたバナーメッセージを送信します。
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
図4 OpenVOSクライアントを実行Linux tcplisten.plを実行
OpenVOSのtelnetクライアントは接続終了時に端末ウィンドウをクリアするため、接続メッセージを確認するには端末タイプをasciiに設定する必要があるでしょう。
OpenVOS上でもtcplistenを実行できます(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 ~]$
図5 OpenVOSシステム上でtcplisten.plを実行し、Linux を接続する
「拒否されました」というメッセージは、ターゲットホストには到達したものの、そのポートでリスニングしているサービスが存在しなかったことを示しています。おそらく。
telnet 172.16.1.116 1830
Trying...
telnet: Unable to connect to remote host: The connection was refused.
ready 12:31:28
図6 – 拒否
一部のファイアウォールは、承認されていない接続要求に対してリセットを送信する場合があります。少なくともクライアント側からは、どちらのシナリオが発生しているかを判別することは非常に困難、あるいは不可能です。
telnetがネットワーク(図7)またはホスト(図8)に到達できないという通知を受信した場合、その旨を報告します。 「ネットワーク…に到達不可」というメッセージは、OpenVOSが対象ネットワークへの経路を持たないか、ネットワーク途中のルーターが宛先ネットワークに到達できなかったことを示します。「ホストへの経路なし」というメッセージは、宛先ネットワークに接続されたルーターが対象ホストに到達できなかったことを示します。これはおそらく、対象ホストがダウンしていることを意味します。
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
図7 – OpenVOSのtelnetクライアントがネットワークに到達できないことを報告している。
telnet 172.16.1.116 1830
Trying...
telnet: Unable to connect to remote host: No route to host.
ready 12:55:44
図8 – OpenVOSのtelnetクライアントがホストに到達できないことを報告している
Telnetはこれらのエラーの原因を報告しません。同じIPアドレスとポート番号を指定したtuc.pl(テストUDP接続)Perlスクリプトは、送信元IPアドレスを報告します(UDPテストに関する以下の説明を参照)。
タイムアウトは、おそらくホストに到達できないことを示します。ほとんどのホストは接続応答または拒否応答を返しますが、ホストベースのファイアウォールが設定されている場合、応答せずにリクエストを破棄することがあります。同様に、ネットワークベースのファイアウォールも応答せずにリクエストを破棄することがあります。また、ルーターやホストから送信されたICMPメッセージも、別のルーターやファイアウォールによって破棄される可能性があります。
telnet 172.16.1.116 1830
Trying...
telnet: Unable to connect to remote host: The operation timed out.
図9 – タイムアウトを報告するOpenVOS telnetクライアント
要約すると、5つの結果が考えられます
メッセージ
意味
接続済み(バナー付き)
ホストとアプリケーションに到達可能
接続済み(バナーなし)
ホストとアプリケーションに到達可能 – おそらく
拒否された
ホストには到達できるがアプリケーションには到達できない – おそらく
到達不能
ホストに到達できません
タイムアウト
ホストに到達できません – おそらく
図10 – TCP接続の結果と解釈のまとめ
アプリケーションがUDPポートを使用する場合、状況はより複雑になります。まず、OpenVOSにはUDPデータグラムを送信するための標準ユーティリティが存在しません。 次に、応答はUDPデータグラムまたはICMPメッセージのいずれかの形式で返ってくる可能性があります。tuc.pl(テストUDP接続)Perlスクリプトは、指定されたホストとポートに現在の日時を含むデータグラムを送信します。その後、UDPデータグラムまたはICMPメッセージのいずれかを待機します。理想的には、アプリケーションがメッセージを返すと、それが表示されます。図11は、リスニングアプリケーションがスクリプトから送信されたメッセージをエコーしたことを示しています。
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
図11 – UDPサーバーアプリケーションは受信したメッセージをエコーする
サーバーが対象ポートでリスニングしていない場合、「宛先ポートに到達できません」というメッセージを返すべきです。このメッセージが対象IPアドレスから受信されたと仮定すると、サーバーには到達したものの、アプリケーションがリスニングしていなかったことを意味します。
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
図12 – ポート到達不能メッセージを送信するターゲットホスト
telnetテストと同様に、ネットワークやホストの問題を示すICMPメッセージを取得できます。また、前述したように送信元のIPアドレスも取得できるため、調査を開始するためのより明確な出発点を得られます。
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
図13 – ネットワークおよびホスト到達不能メッセージ
上記のエラーはおそらく最も一般的な2つです。別のエラーはルーティングループを示しています
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
図14 – ルーティングループを示すICMPメッセージ
他にも多くのエラーが存在し、その中にはパケットの流通を防ぐための管理上の措置を示すものもあります。これらのメッセージは、ファイアウォールがあなたのパケットをブロックしていることを示しているとほぼ確実に言えます。
ただし、多くのアプリケーションは特定の形式のメッセージを期待します。その場合、おそらく応答が得られないでしょう。デフォルトでは、スクリプトは5秒後にタイムアウトし、「応答なし」と報告します。
perl tuc.pl -i 172.16.1.116 -p 1830
No response was received from 172.16.1.116
ready 16:43:26
図15 – 応答なし
より長く(または短く)待機したい場合は「-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
図16 – デフォルトのタイムアウトを変更する
沈黙は必ずしも悪いことではありません。ターゲットホストに到達し、ターゲットポートでリスニングしているものの、送信されたテストメッセージを気に入らなかっただけかもしれません。 残念ながら、テストパケットがターゲットホストに到達せず、その旨を示すICMPメッセージがブロックされた可能性も考えられます。サーバーへのアクセス権がある場合は、udpecho.pl Perlスクリプトを実行できます。このスクリプトは自身のヘッダーを追加し、送信された内容をそのまま返します(図11)。
要約すると
メッセージ
意味
アプリケーションバナーメッセージ
ホストとアプリケーションに到達可能
ICMPネットワーク/ホストメッセージ
ホストに到達できません
ホストからのICMPポートメッセージ
ホストには到達できるが、アプリケーションには到達できない
応答なし、アプリケーションはバナーメッセージを送信します
ホストに到達できません
応答なし、アプリケーションはバナーメッセージを送信しません
ホストに到達できる場合とできない場合がある
図17 – UCP接続に関する結果と解釈のまとめ

tcplisten.pl

# tcplisten.pl begins here

#

# バージョン 1.00 2010年7月30日

# このスクリプトは以下でテスト済みです

# Open VOS 17.0.2ah を実行中、Perl v5.8.0 (i686-vos 向けにビルド済み)

# MicrosoftWindows Service Pack 3 が実行中

# ActiveState Perl v5.10.0 (MSWin32-x86-マルチスレッド用ビルド)

# Red HatLinux .5 を実行中

# Perl v5.8.5linux 向けにビルド済み

#

# [email protected]

#

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);

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

{

print "nn使用方法:n";

print "tperl tcplisten.pl -port PORT-NUMBER [-message MESSAGE]";

終了;

}

if (!defined ($message))

{

print "メッセージが指定されていません – メッセージを作成中";

$message = "tcplisten が実行中のホスト名で接続を受け付けました" . hostname;

}

print "perl tcplisten.pl -port $localPort -message '" . $message . "'\n";

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

Proto => ‘tcp’,

ローカルポート => $localPort,

LocalAddr => '0.0.0.0',

聴く => 1,

) または die “ポート $localPort のソケットを作成できませんでした: $!n”;

while (1)

{

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

print "接続要求を受諾しました。接続元: " . $newSock->peerhost .

” at ” . localtime() . “n”;

print $newSock $message . "\n";

$newSock -> shutdown(2);

$sock->read($data, 1024); # 終了を示すシグナルを受信するまで待機 */

$newSock->close();

}

#

# tcplisten.pl はここで終了します

tuc.pl

# tuc.pl begins here

#

# バージョン 1.00 2010年7月30日

# このスクリプトは以下でテスト済みです

# Open VOS 17.0.2ah を実行中、Perl v5.8.0 (i686-vos 向けにビルド済み)

# MicrosoftWindows Service Pack 3 が実行中

# ActiveState Perl v5.10.0 (MSWin32-x86-マルチスレッド用ビルド)

# Red HatLinux .5 を実行中

# Perl v5.8.5linux 向けにビルド済み

#

# [email protected]

#

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);

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

{

print "nn使用方法:n";

print "tperl tuc.pl -ip 宛先IPアドレス " .

「-ポート 宛先ポート番号nn」;

終了;

}

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

elsif ($timeout > 15) { print "OK, but " . $timeout .

”は不合理に長いように思える。n”; }

$message = "tuc.pl により送信されました。時刻: " . localtime();

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

Proto => ‘udp’

PeerPort => $destPort,

PeerAddr => $destIP

) または die “宛先 $destIP のソケットを作成できませんでした: $!n”;

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

Proto => 'icmp');

$sock->send($message) または die "送信エラー: $!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;

if ($socket == $sock)

{

$x = "UDPソケットから受信した返信";

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

if ($icmpAlready == 0)

{

if (length($message) > 0)

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

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

}

}

else # icmpメッセージ受信

{

$icmpAlready = 1;

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

if (length($message) > 98)

{ print "予想外に長い (" . length($message) .

「」からのICMPメッセージ。$socket->peerhost

” message: ” . $message . “\n”; }

elsif (length ($message) < 52)

{ print "予想外に短い(" . length($message) .

") ICMPメッセージ送信元: " . $socket->peerhost . ""; }

else # 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));

if ($port != $destPort)

{ print "予期しないICMPメッセージを受信しました。送信元は " .

$socket->peerhost . " メッセージ : " . substr($message, 20) .

“n”; }

それ以外の場合、# icmpメッセージは正常です

{

if ($type == 3)

{

if ($code == 0) { print "ICMP 宛先ネットワーク " .

「受信不能なメッセージを受信しました」

$socket->peerhost . "n"; }

elsif ($code == 1) { print "ICMP 宛先ホスト " .

「受信不能なメッセージを受信しました」

$socket->peerhost . "n"; }

elsif ($code == 3) { print "ICMP 宛先ポート " .

「受信不能なメッセージを受信しました」

$socket->peerhost . "n"; }

elsif ($code == 6) { print "ICMP 宛先ネットワーク " .

「不明なメッセージを受信しました」

$socket->peerhost . "n"; }

elsif ($code == 7) { print "ICMP 宛先ホスト不明 " .

「メッセージ受信元:」 . $socket->peerhost . 「n」; }

elsif ($code == 8) { print "ICMP 送信元ホストが隔離されました " .

「メッセージを受信しました」

$socket->peerhost . "n"; }

elsif ($code == 9) { print "ICMP Network administratively " .

「禁止されたメッセージを受信しました」

$socket->peerhost . "n"; }

elsif ($code == 10) { print "ICMP ホスト管理上利用不可" .

「禁止されたメッセージを受信しました」

$socket->peerhost . "n"; }

elsif ($code == 11) { print "ICMP ネットワーク到達不可: " .

「TOSメッセージ受信元」

$socket->peerhost . "n"; }

elsif ($code == 12) { print "ICMP ホスト到達不能: " .

「TOSメッセージ受信元」

$socket->peerhost . "n"; }

elsif ($code == 13) { print "ICMP 通信 " .

「管理上禁止されたメッセージを受信しました」

$socket->peerhost . "n"; }

else { print "予期しないICMPメッセージを受信しました タイプ = " .

$type . "、コード = " . $code . "、送信元 " .

$socket->peerhost . "n"; }

} # if ($type == 3)

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

{ print "ICMP タイムアウト、TTL が転送中に期限切れ" .

「メッセージ受信元:」 . $socket->peerhost . 「n」; }

else { print "予期しないICMPメッセージを受信しました タイプ = " .

$type . "、コード = " . $code . "、送信元 " .

$socket->peerhost . "n"; }

} # それ以外の場合 # icmpメッセージは正常

} # それ以外の場合 # icmpメッセージを処理する

} # それ以外の場合 #ICMPメッセージ受信

} # foreach $socket (@$ready)

if ($c == 0) { print "応答が受信されませんでした。 " .

$sock->peerhost . "n"; }

#

# tuc.pl はここで終了します

udpecho.pl

# udpecho.pl begins here

#

# バージョン 1.00 2010年7月30日

# このスクリプトは以下でテスト済みです

# Open VOS 17.0.2ah を実行中、Perl v5.8.0 (i686-vos 向けにビルド済み)

# MicrosoftWindows Service Pack 3 が実行中

# ActiveState Perl v5.10.0 (MSWin32-x86-マルチスレッド用ビルド)

# Red HatLinux .5 を実行中

# Perl v5.8.5linux 向けにビルド済み

#

# [email protected]

#

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);

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

{

print "nn使用方法:n";

print "tperl udpecho.pl -port LOCAL-PORT-NUMBER [-debug]nn";

終了;

}

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

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

Proto => ‘udp’

ローカルポート => $localPort

) または die “ソケット $!n を作成できませんでした”;

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

$read_set->add($sock);

$message = "";

while (1)

{

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

foreach $socket (@$ready)

{

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

if (defined ($debug)) { print "Message from " . $socket->peerhost .

” message: ” . $message . “\n”; }

$socket->send("udpecho.pl によるエコー: " . $message) or die "送信エラー: $!"

+n”;

}

}

#

# udpecho.pl はここで終了します

© 2024 ストラタス・テクノロジーズ