インフラストラクチャの運用において、「Pingは通るが、サーバーへの接続(SSHやHTTPなど)が失敗する」という事象は頻繁に発生します。ICMPによるL3レベルの疎通確認のみに依存し、L4以上のトランスポート層やL7アプリケーション層の検証を怠ることは、障害復旧の遅延や誤った原因特定を招く要因となります。
ICMPエコーテストは低レイテンシかつパケットロス0%で成功している状態を示します。
$ ping 192.168.10.100
PING 192.168.10.100 (192.168.10.100) 56(84) bytes of data.
64 bytes from 192.168.10.100: icmp_seq=1 ttl=64 time=0.3 ms
64 bytes from 192.168.10.100: icmp_seq=2 ttl=64 time=0.2 ms
しかし、SSHセッションやHTTPリクエストを開始すると、接続に失敗します。
$ ssh 192.168.10.100
ssh: connect to host 192.168.10.100 port 22: Connection refused
あるいは、接続試行時にタイムアウトが発生します。
$ curl http://192.168.10.100:8080
curl: (7) Failed to connect to 192.168.10.100 port 8080: Connection timed out
「Pingが成功したためネットワークは正常であり、接続失敗はサーバー自体の破損を意味する」という仮定は、技術的に誤りです。ICMPはネットワーク層(L3)で動作するのに対し、SSH、HTTP、HTTPS、PostgreSQL、MySQL、Redisなどの主要なアプリケーションプロトコルは、特定のポート番号にバインドされたトランスポート層(L4)のTCPソケットに依存しているためです。
本稿では、この境界ギャップを体系的に分解し、Linuxの3つのコアユーティリティである ss、nc、tcpdump を中心とした診断手法を確立します。
1. ネットワーク層の抽象化とサービスマッピング
💡 通信のボトルネックを効果的に特定するために、対象サービスをOSI参照モデルの各レイヤーとトランスポートメカニズムにマッピングします。
- ICMP:
pingなどの診断および制御メッセージングにのみ使用されます(トランスポートポートは存在しません)。 - SSH: TCP ポート
22 - HTTP: TCP ポート
80 - HTTPS: TCP ポート
443 - PostgreSQL: TCP ポート
5432 - MySQL / MariaDB: TCP ポート
3306 - Redis: TCP ポート
6379
ICMPはL4のTCPリスニングソケットとは独立して動作するため、ICMPエコーリクエストに対する応答があっても、TCPポートが開放されている、あるいは到達可能である保証はありません。
2. ping の低レイヤーメカニズム
ping 192.168.10.100 を実行すると、宛先ホストに対して ICMP Echo Request パケット(Type 8)が送信され、宛先ホストは ICMP Echo Reply パケット(Type 0)を返します。
+------------------------+ +------------------------+
| Client: 192.168.10.50 | | Server: 192.168.10.100 |
+------------------------+ +------------------------+
| |
|------------ ICMP Echo Request (Type 8) ------------->|
| |
|<----------- ICMP Echo Reply (Type 0) ----------------|
| |
Ping of 成功は、クライアントからローカルルーティング、ゲートウェイ、物理ネットワーク、ターゲットのIPスタックを経て、ICMP応答が戻るパスが正常であることを確認するに留まります。ファイアウォールルールがTCPフレームを許可しているか、あるいはホスト上のアプリケーションデーモンがアクティブにソケットを処理しているかは検証できません。
3. TCP 3-Way ハンドシェイクの構造
TCPベースのサービス接続を開始する際、オペレーティングシステムのカーネルは、まず TCP 3-Way ハンドシェイク を介してステートフルな接続を確立する必要があります。
Client (192.168.10.50) Server (192.168.10.100:22)
| |
|----------------------- 1. SYN ------------------------------>|
| |
|<------------------- 2. SYN-ACK ------------------------------|
| |
|----------------------- 3. ACK ------------------------------>|
| |
[ ESTABLISHED ] [ ESTABLISHED ]
- SYN: クライアントは接続開始を要求するために、
SYNフラグを設定したTCPフレームを送信します。 - SYN-ACK: サーバーは
SYNを受信すると、ポート22でリスニングしているソケットを確認し、接続状態バッファを割り当ててSYN-ACKで応答します。 - ACK: クライアントは
ACKで応答し、両方のエンドポイントがESTABLISHED状態に移行します。
アプリケーションプロトコルが機能するためには、このL4シーケンスが正常に完了する必要があります。
4. 「Ping疎通可能 + TCP接続失敗」の診断
初期の診断状態を定義します。
$ ping 192.168.10.100
# 成功 (パケットロス 0%)
$ nc -zv 192.168.10.100 22
# 失敗
この不一致により、障害ドメインを即座に絞り込むことができます。ICMPが機能していることはL3ルーティングと物理リンクが正常であることを示し、TCPの失敗はL4ソケット、ファイアウォール、またはサービスデーモンの障害を示します。
5. nc (Netcat) によるトランスポート層のプロービング
Netcat (nc) は、TCPおよびUDPの接続アナライザーとして機能します。実務環境における主なユースケースは、特定のソケットアドレスに対する生のTCP到達性を検証することです。
Netcatの実行には、ポートスキャン用のオプションを指定します。
$ nc -zv 192.168.10.100 22
-z`: Zero-I/Oモード(ペイロードデータを送信せずにリスニングデーモンをスキャン)。
-v: 詳細出力モード。
接続テストの実行結果から、ネットワークの状態を判定します。
ハンドシェイク成功:
Connection to 192.168.10.100 22 port [tcp/ssh] succeeded!失敗パターン A:
nc: connect to 192.168.10.100 port 22 failed: Connection refused失敗パターン B:
nc: connect to 192.168.10.100 port 22 failed: Connection timed out
Connection Refused と Connection Timed Out の違いを理解することは、根本原因の特定において極めて重要です。
6. Connection Refused と Connection Timeout のメカニズム
Connection Refused の仕組み
⚠️ Connection refused エラーは、クライアントの SYN パケットが宛先ホストのカーネルに到達したものの、ホストが明示的に接続を拒否し、TCP Reset (RST) フレームを返したことを示します。
Client Server
| |
|--------------------------- SYN ---------------------------->| (宛先ホストに到達)
| | (リスニング中のプロセスなし)
|<------------------------ TCP RST ---------------------------|
主な原因:
- サービスデーモンの停止: プロセス(
sshd、nginx、mysqldなど)が起動していません。 - 誤ったサービスポート: アプリケーションがデフォルト以外のポート(例:
22ではなく2222)でリスニングしています。 - バインドインターフェースの不整合: デーモンが
0.0.0.0ではなく127.0.0.1のみにバインドされています。 - アクティブなパケットフィルタリング: ローカルホストのファイアウォールが、パケットを破棄(DROP)するのではなく、明示的にTCP Resetパケットを返す(REJECT)ように設定されています。
Connection Timeout の仕組み
Connection timed out エラーは、クライアントが SYN パケットを送信したものの、ソケットのタイムアウトしきい値が経過するまでに応答が一切返ってこなかった場合に発生します。
Client Network / Firewall / Target
| |
|--------------------------- SYN ---------------------------->|
| | ===> [ 破棄 / ブロック ]
| (応答なし) |
| ... タイムアウト ... |
主な原因:
- ネットワークセキュリティによる破棄: クラウドのセキュリティグループ、ネットワークACL、またはハードウェアファイアウォールがインバウンドトラフィックをサイレントに破棄しています。
- ホストレベルのファイアウォールによる破棄:
iptables、firewalld、またはnftablesがDROPアクションで設定されています。 - ルーティング障害: 中間ネットワークスイッチやルーターにおけるデフォルトルーティングの誤り、または静的ルートの欠落。
- 非対称ルーティング / 戻りパスの失敗: サーバーは
SYNを受信してSYN-ACKを送信したものの、戻りパスのルーティングでパケットが破棄または誤送信されています。
7. ss によるローカルソケットの検査
ss (Socket Statistics) ユーティリティは、Linuxプラットフォーム上のアクティブな内部ソケットを検査し、従来の netstat ツールに代わるものとして使用されます。
ソケットの状態を確認するための診断コマンドを実行します。
$ sudo ss -lntp
フラグ仕様:
-l: リスニング(LISTEN)状態のソケットのみを表示。-n: 数値アドレスとポートを表示(DNSやサービス名の解決によるオーバーヘッドを防止)。-t: TCPソケットを表示。-p: ソケットに関連付けられたプロセスIDと名前を表示(rootまたはsudo権限が必要)。
コマンドの実行により、以下のようなソケット情報が出力されます。
State Recv-Q Send-Q Local Address:Port Peer Address:Port Process
LISTEN 0 128 0.0.0.0:22 0.0.0.0:* users:(("sshd",pid=1234,fd=3))
LISTEN 0 128 0.0.0.0:80 0.0.0.0:* users:(("nginx",pid=1500,fd=6))
LISTEN 0 128 127.0.0.1:8080 0.0.0.0:* users:(("java",pid=2000,fd=20))
8. バインドアドレスの分析: 127.0.0.1 vs 0.0.0.0
Local Address:Port のバインド設定は、外部からの到達性を決定します。
ループバック隔離ケース (127.0.0.1:8080)
ソケットがループバックアドレスにのみバインドされている状態を示します。
LISTEN 0 128 127.0.0.1:8080 0.0.0.0:*
アプリケーションプロセス(java)は ループバックインターフェース(lo) にのみバインドされています。
[ 外部クライアント ] [ ターゲットサーバー ]
192.168.10.50 192.168.10.100
| |
|--- 192.168.10.100:8080 へのHTTPリクエスト ------>| [ 物理インターフェース ]
| |
| (ブロック / ソケットなし)
| v
| [ ループバックインターフェース ]
| 127.0.0.1:8080 (Javaデーモン)
ローカル検証: サーバー上で curl http://127.0.0.1:8080 を実行すると成功します。
- リモート検証: 外部クライアントから
curl http://192.168.10.100:8080を実行すると失敗します。
ワイルドカードIPv4バインド (0.0.0.0:8080)
ソケットがすべてのインターフェースにバインドされている状態を示します。
LISTEN 0 128 0.0.0.0:8080 0.0.0.0:*
ソケットは、ホストに割り当てられたすべてのアクティブなIPv4ネットワークインターフェース(例:IP 192.168.10.100 を持つ ens160)を介したインバウンドTCPトラフィックを受け入れます。ファイアウォールが許可していれば、外部クライアントからの接続が可能です。
+-------------------------------------------------------------+
| Server: 192.168.10.100 |
| |
| Interface ens160 [ 192.168.10.100 ] <--- [ 外部リクエスト ] |
| | |
| v |
| 0.0.0.0:8080 にバインドされたサービス (全インターフェースで受診) |
+-------------------------------------------------------------+
9. 実務におけるトラブルシューティング事例
事例 1: Pingは通るが、SSHが失敗する (Connection Refused)
環境構成:
- クライアント:
192.168.10.50 - サーバー:
192.168.10.100 - 対象サービス: SSH (TCP ポート
22)
ステップ 1: クライアント側での診断
$ ping 192.168.10.100
# 結果: 64 bytes from 192.168.10.100: icmp_seq=1 ttl=64 time=0.3 ms (成功)
$ nc -zv 192.168.10.100 22
# 結果: nc: connect to 192.168.10.100 port 22 failed: Connection refused
ステップ 2: サーバー側でのソケット検査
サーバーのローカルコンソールまたは帯域外(OOB)管理インターフェースにログインします。
$ sudo ss -lntp
# 出力結果:
# LISTEN 0 128 0.0.0.0:80 0.0.0.0:* users:(("nginx",pid=1500,fd=6))
TCPポート22がリスナーテーブルに存在しません。*
ステップ 3: サービス状態の確認と解決
$ sudo systemctl status sshd
# 出力: Active: inactive (dead)
$ sudo systemctl start sshd
$ sudo systemctl enable sshd
$ sudo ss -lntp | grep ':22'
# 出力: LISTEN 0 128 0.0.0.0:22 0.0.0.0:* users:(("sshd",pid=3102,fd=3))
クライアント側で再度 nc -zv 192.168.10.100 22 を実行すると、接続が成功します。
事例 2: プロセスは起動しているが、外部アクセスが失敗する (Bind Mismatch)
診断状態:
アプリケーションサーバー上で ss -lntp を実行すると、以下の結果が得られます。
LISTEN 0 128 127.0.0.1:8080 0.0.0.0:* users:(("node",pid=4211,fd=18))
疎通テスト:
- ターゲットサーバーから:
curl http://127.0.0.1:8080$\longrightarrow$ 200 OK - リモートクライアントから:
curl http://192.168.10.100:8080$\longrightarrow$ 接続拒否 (Refused)
診断と解決策:
アプリケーション(Node.js、Spring Boot、Nginxなど)の設定が localhost に制限されています。ホストの設定(例:server.host = 0.0.0.0 または LISTEN 0.0.0.0:8080)を変更し、サービスを再起動してソケットを外部インターフェースに公開します。
事例 3: サービスはバインドされているが、外部接続がタイムアウトする
診断状態:
サーバーのソケットテーブルは正常に公開されています。
$ sudo ss -lntp | grep ':8080'
LISTEN 0 128 0.0.0.0:8080 0.0.0.0:* users:(("java",pid=8820,fd=7))
しかし、クライアント側での実行は失敗します。
$ nc -zv 192.168.10.100 8080
nc: connect to 192.168.10.100 port 8080 failed: Connection timed out
ファイアウォールの検査:
出力が Refused ではなく Timeout であるため、インラインネットワークデバイスまたはホストのファイアウォールルールがパケットをサイレントに破棄しています。
ローカルホストのルールを確認します。
$ sudo firewall-cmd --list-all
# サービスおよびポートセクションに '8080/tcp' が存在するか確認
$ sudo nft list ruleset
firewalld でICMPがグローバルに許可されていても、ポート8080が除外されている場合、ping` は通過しますが、ポート8080へのL4 TCPトラフィックは破棄されます。
Client (192.168.10.50) Server (192.168.10.100)
| |
|----------------------- TCP SYN ---------------------------->|
| |
| [ Host Firewall (nftables) ]
| [ Action: DROP Port 8080 ]
| |
| <=== Timeout (SYN-ACKが送信されない) ========================|
10. tcpdump によるディープパケット診断
nc は接続結果を報告し、ss はソケットのリスニング状態を示します。しかし、tcpdump は実際のパケットの動きをキャプチャし、フレームレベルでの状態遷移を明らかにします。
ターゲットサーバーでパケットキャプチャを実行します。
$ sudo tcpdump -nn -i ens160 tcp port 8080
-n`: ホスト名を解決しない。
-nn: ホスト名およびポート名を解決しない(数値IPとポートを表示)。-i ens160: 対象ネットワークインターフェースens160のトラフィックを監視。tcp port 8080: ポート8080を通過するTCPパケットのみをフィルタリング。
11. tcpdump によるパケットパターンの分析
シナリオ A: 正常な TCP 3-Way ハンドシェイク
10:00:01.001 IP 192.168.10.50.52344 > 192.168.10.100.8080: Flags [S], seq 1001
10:00:01.002 IP 192.168.10.100.8080 > 192.168.10.50.52344: Flags [S.], seq 2001, ack 1002
10:00:01.003 IP 192.168.10.50.52344 > 192.168.10.100.8080: Flags [.], seq 1002, ack 2002
Flags [S]`: クライアントからの初期 SYN フレーム。
Flags [S.]: サーバーからの SYN-ACK 応答。Flags [.]: クライアントからの ACK フレーム。- 診断: L4ハンドシェイクが完了し、接続が確立(ESTABLISHED)されています。
シナリオ B: 応答のないインバウンド SYN の継続
10:00:01.001 IP 192.168.10.50.52344 > 192.168.10.100.8080: Flags [S], seq 1001
10:00:04.005 IP 192.168.10.50.52344 > 192.168.10.100.8080: Flags [S], seq 1001
10:00:10.009 IP 192.168.10.50.52344 > 192.168.10.100.8080: Flags [S], seq 1001
観察: クライアントが TCP SYN を再送信しています。サーバーのインターフェースはパケットを受信していますが、アウトバウンドの SYN-ACK ([S.]) が送信されていません。
- 診断: ホストレベルのセキュリティメカニズム(
iptables、nftables、SELinux、またはカーネルレベルのIPフィルタリング)が、ネットワークインターフェース層への流入直後にパケットを破棄しています。
シナリオ C: サーバーは SYN-ACK を送信するが、クライアントが SYN を再送する
10:00:01.001 IP 192.168.10.50.52344 > 192.168.10.100.8080: Flags [S]
10:00:01.002 IP 192.168.10.100.8080 > 192.168.10.50.52344: Flags [S.]
10:00:04.005 IP 192.168.10.50.52344 > 192.168.10.100.8080: Flags [S]
観察: サーバーはインバウンド SYN を処理して SYN-ACK を送信していますが、クライアントは応答を受信していないかのように SYN フレームを送信し続けています。
- 診断: サーバーとクライアント間の戻りパスのルーティング障害、または送信元方向へのエグレスファイアウォールによるフィルタリングが発生しています。
Client (192.168.10.50) Server (192.168.10.100)
| |
|----------------------- 1. SYN ----------------------------->|
| |
| X <=== [ 戻りルーティング障害 / エグレスブロック ] ---------| (SYN-ACKを送信)
主な原因:
- ターゲットサーバー上のローカルデフォルトゲートウェイの設定誤り。
- 非対称ルーティングポリシーによる戻りパスの破棄。
- NATテーブルの状態喪失。
シナリオ D: 即時のリセット (SYN 直後の RST)
10:00:01.001 IP 192.168.10.50.52344 > 192.168.10.100.8080: Flags [S]
10:00:01.001 IP 192.168.10.100.8080 > 192.168.10.50.52344: Flags [R.]
観察: サーバーが即座にリセットフレーム([R.])を返しています。
- 診断: パケットはホストのファイアウォールを通過しましたが、カーネルは TCP ポート 8080 でリスニングしているプロセスを見つけられませんでした。
ss -lntpでデーモンの状態を確認してください。
12. カーネルカウンタによるソケット状態の追跡
ss -ant を実行して、アクティブなソケット全体の接続状態の割り当てを確認します。
$ sudo ss -ant
State Recv-Q Send-Q Local Address:Port Peer Address:Port
LISTEN 0 128 0.0.0.0:8080 0.0.0.0:*
ESTAB 0 0 192.168.10.100:8080 192.168.10.50:52344
SYN-RECV 0 0 192.168.10.100:8080 192.168.10.50:52345
重要なソケット状態と異常値:
SYN-SENTの累積 (クライアント側):$ ss -ant state syn-sent
意味*: クライアントアプリケーションが SYN フレームを送信しましたが、SYN-ACK を受信していません。アウトバウンドのブロックまたは経路上の破棄を示します。
SYN-RECVの累積 (サーバー側):$ ss -ant state syn-recv
意味*: サーバーが SYN を受信して SYN-ACK を送信しましたが、クライアントからの最終的な ACK を待機したまま停止しています。クライアント側のインバウンドブロック、非対称ルーティング、またはSYNフラッド攻撃を示します。
13. 上位レイヤーの診断: PingとTCPは成功するが、アプリケーションが失敗する
さらに高度な障害状態を定義します。
$ ping 192.168.10.100
# 成功 (L3正常)
$ nc -zv 192.168.10.100 8080
# 成功 (L4 TCP接続正常)
$ curl http://192.168.10.100:8080/
# 失敗 / エラー / HTTP 5xx / 応答なし
このシナリオは、ネットワーク層(L3)およびトランスポート層(L4)が完全に機能していることを証明しています。
curl によるアプリケーション層のデバッグ
詳細なHTTP操作を実行して、ハンドシェイクとプロトコルのセマンティクスをキャプチャします。
$ curl -v http://192.168.10.100:8080/
詳細な実行トレースの例を示します。
* Trying 192.168.10.100:8080...
* Connected to 192.168.10.100 (192.168.10.100) port 8080 (#0)
> GET / HTTP/1.1
> Host: 192.168.10.100:8080
> User-Agent: curl/7.76.1
> Accept: */*
>
< HTTP/1.1 504 Gateway Timeout
< Server: nginx/1.20.1
< Date: Mon, 10 Nov 2025 10:00:00 GMT
< Content-Type: text/html
L7障害の主な原因カテゴリ:
- リバースプロキシの上流タイムアウト: Nginxはポート8080で接続を受け入れますが、ローカルで動作するバックエンド(例:
127.0.0.1:8000のNode/Javaアプリ)への到達に失敗し、HTTP504 Gateway Timeoutまたは502 Bad Gatewayを返します。 - HTTPホストヘッダーの拒否: アプリケーションの仮想ホストフィルタが、有効な
Host:リクエストヘッダーを欠くリクエストを破棄しています。 - アプリケーションのスレッドロック: データベース接続プールの枯渇や内部デッドロックにより、L4ソケットハンドシェイクが確立されているにもかかわらず、アプリケーション層がペイロードフレームを送信できません。
- TLS/SSLハンドシェイクの失敗: 暗号スイートの不一致、証明書の期限切れ、またはSNIの誤設定により、ポート443でのTCP初期化直後に接続が切断されます。
14. UDPプロトコル診断における注意点
TCPとは異なり、UDPはコネクションレスです。セットアップフラグ(SYN、ACK)や状態マシンのチェックはありません。
nc を使用してUDPの到達性をテストするには、-u フラグが必要です。
$ nc -zvu 192.168.10.100 53
診断上の課題:
- UDPスキャナーは0バイトのパケットを送信します。
ICMP Port Unreachableフレームが戻ってこない場合、ncはポートが「開いている」または「開いているかフィルタされている」と判断します。 - 誤検知が非常に多いため、信頼性の高いUDPテストには、アクティブなパケットキャプチャと並行して、プロトコル固有のクエリツール(例:DNS UDP 53には
dig、SNMP UDP 161にはsnmpwalk)を使用する必要があります。
$ sudo tcpdump -nn -i ens160 udp port 53
15. システムエンジニアのためのツールマトリクス
これらの診断ツールを統合された運用ワークフローに組み込みます。
| ユーティリティ | 対象レイヤー | コア機能 | 主な診断価値 |
|---|---|---|---|
ping | L3 (ネットワーク) | 生のICMP到達性とリンクレイテンシの評価 | 基本的なIPルーティングと物理的接続性の検証 |
nc | L4 (トランスポート) | エンドツーエンドのTCP/UDPソケット可用性テスト | Connection Refused と Timeout の識別 |
ss | ホストカーネルソケット | ローカルインターフェースバインドとソケット状態の検査 | デーモンプロセスが正常に起動しバインドされているかの確認 |
tcpdump | ワイヤプロトコル | 生のネットワークインターフェースにおけるTCPフレームの監視 | シーケンスフラグ(SYN、SYN-ACK、RST)の分析による障害箇所の特定 |
curl | L7 (アプリケーション) | HTTP/Sアプリケーションプロトコルトランザクションの検証 | Webサーバーエラー、プロキシ設定ミス、バックエンドタイムアウトの特定 |
16. 体系的なトラブルシューティングフロー
🛠️ 「Pingは通るが、サービスアクセスが失敗する」事象に遭遇した場合は、以下の論理フローに従って診断を進めます。
[ 事象発生: Pingは通るがサービスアクセスが失敗する ]
|
v
実行: nc -zv <server_ip> <port>
|
+-----------------------------------+-----------------------------------+
| | |
v v v
[ Connection Refused ] [ Connection Timed Out ] [ Succeeded ]
| | |
v v v
ターゲットサーバーにログイン サーバーでパケットキャプチャを実行: L3/L4レイヤーは正常。
実行: ss -lntp tcpdump -nn -i <nic> port <port> L7アプリケーション層を検証。
| | 実行: curl -v http://<ip>:<port>
+---------------+ +---------------+ |
| | | | v
v v v v アプリ/プロキシログを確認:
[ ポートが未表示 ] [ 127.0.0.1 にバインド ] [ SYNが未到達 ] [ SYN到達、SYN-ACKなし ] - Systemdステータス
| | | | - Nginx / アプリ例外
v v v v - DB接続プール
デーモンの起動: アプリ設定の修正 ネットワークパスの確認: ホストファイアウォールの確認:
systemctl start 0.0.0.0:<port> - ネットワークFW - firewall-cmd
<service> アプリ再起動 - セキュリティグループ - nftablesルール
- ルーター設定 - カーネルIPフィルタリング
17. 運用CLIクイックリファレンス
L3 診断コマンド:
# リンク到達性をテストするために4つのICMPパケットを送信
$ ping -c 4 192.168.10.100
L4 ソケットプロービングコマンド (nc):
# 標準的な管理およびWebサービスのTCPポートを調査
$ nc -zv 192.168.10.100 22
$ nc -zv 192.168.10.100 80
$ nc -zv 192.168.10.100 443
$ nc -zv 192.168.10.100 8080
# UDPドメイン名解決サービスを調査
$ nc -zvu 192.168.10.100 53
ローカルソケット検査コマンド (ss):
# プロセス詳細を含むすべてのアクティブなリスニングTCPポートを一覧表示
$ sudo ss -lntp
# 特定のターゲットソケットリスナーをフィルタリング
$ sudo ss -lntp | grep ':8080'
# 状態に関係なく、すべての数値TCP接続を表示
$ sudo ss -ant
# SYN-SENTまたはSYN-RECV状態の接続を分離
$ sudo ss -ant state syn-sent
$ sudo ss -ant state syn-recv
パケット分析コマンド (tcpdump):
# 特定のインターフェースでTCPポート8080を監視
$ sudo tcpdump -nn -i ens160 tcp port 8080
# 生のSYN接続初期化リクエストをグローバルにキャプチャ
$ sudo tcpdump -nn -i ens160 'tcp[tcpflags] & tcp-syn != 0'
# 特定のホストIPアドレスに関連するすべてのトラフィックをキャプチャ
$ sudo tcpdump -nn -i ens160 host 192.168.10.50
# ICMP制御パケットとターゲットTCPアプリケーショントラフィックを多重追跡
$ sudo tcpdump -nn -i ens160 'tcp port 8080 or icmp'
ホストファイアウォール操作 (firewalld / nftables):
# 現在のfirewalld設定を検査
$ sudo firewall-cmd --list-all
# TCP 8080の許可を永続的に追加
$ sudo firewall-cmd --add-port=8080/tcp --permanent
$ sudo firewall-cmd --reload
# 低レベルのnftablesルールセットバインディングを検査
$ sudo nft list ruleset
Lessons Learned
- Pingの成功はサービスの健全性を保証しない: ICMP Echo応答は、レイヤー3のインターフェース到達性とルーティングの正常性のみを証明します。レイヤー4のポート状態やレイヤー7のアプリケーション機能は検証されません。
- エラーメッセージの正確な解釈:
Connection refusedは、パケットがホストに到達したものの、アクティブなリスナーがないか、明示的にRST拒否されたことを示します。ホストのソケットバインド (ss -lntp) を確認してください。Connection timed outは、送信または戻りの経路でフレームが消失したことを示します。ファイアウォール、セキュリティグループ、ルーティングループを確認してください。
- ワイヤキャプチャによるパケットパスの追跡:
tcpdumpを使用して、「初期SYNフレームがインフラストラクチャスタックのどこまで到達したか」という根本的な問いに答えます。 - レイヤー範囲の段階的な分離: L3(
ping)からL4(nc)へ順次テストし、ローカルのリスニング状態(ss)を検査し、ワイヤ上の生のフレーム(tcpdump)を検証し、最後にL7(curl)で確認を行います。</server_ip>