こんにちは。yunoです。
普段はインフラエンジニアとして働きながら、Linux・Ansible・ネットワークなどを学習しています。
今回は、Linuxの通信障害でよくある疑問を、実際のUbuntu Serverを使って検証してみました。
「pingは通るのに、なぜWebサイトにはアクセスできないのか?」
Linuxを学習していると、通信確認として最初にpingを使うことがあると思います。
しかし、pingが成功したからといって、Webサービスまで正常に動作しているとは限りません。
今回はVirtualBox上のUbuntu Serverで、Webサーバのnginxを意図的に停止させ、ping・ss・curlを使って原因を切り分けました。
実際に確認できた結果をもとに、障害発生から復旧までの流れを紹介します。
1. この記事でわかること
この記事では、以下の内容を学べます。
-
ping・ss・curlの役割と違い - pingが成功してもWebサイトに接続できない理由
- nginxを停止して通信障害を再現する方法
- TCPの80番ポートが待ち受けているか確認する方法
- curlの接続エラーを確認する方法
- nginxを復旧させてHTTP通信を再確認する方法
Linux初心者の方でも再現できるように、実際に使用したコマンドと結果を順番に紹介します。
2. 検証環境
今回の検証では、以前Ansibleの学習用に構築したVirtualBox環境を再利用しました。
| 項目 | 内容 |
|---|---|
| ホストPC | Mac |
| 仮想化ソフト | VirtualBox |
| OS | Ubuntu Server 24.04 |
| 管理サーバ | controller |
| 検証対象 | tokyo |
| tokyoのIPアドレス | 192.168.56.11 |
| Webサーバ | nginx 1.24.0 |
| 使用コマンド | ping・ss・curl・systemctl |
検証環境にはほかにも複数のUbuntu Serverがありますが、今回はcontrollerとtokyoの2台を使用します。
構成は以下のとおりです。
Mac
└── VirtualBox
├── controller
│ └── 通信確認を実行
│
└── tokyo
├── IP:192.168.56.11
└── nginx:TCP 80番ポート
controllerからtokyoにアクセスし、通信状況を確認します。
IPアドレスの確認
最初に、tokyoサーバのIPアドレスを確認します。
tokyoで以下を実行します。
ip -4 addr show
実際の結果から、以下のアドレスが確認できました。
3: enp0s8: <BROADCAST,MULTICAST,UP,LOWER_UP>
inet 192.168.56.11/24
enp0s8に192.168.56.11/24が設定されています。
今回の検証では、このIPアドレスを接続先として使用します。
なお、以降の手順ではnginxが導入済みであることを前提とします。
3. 正常時の通信状態を確認する
障害を発生させる前に、正常な状態で通信できることを確認します。
今回は以下の順番で調査します。
- pingでIP疎通を確認
- ssで80番ポートの待受状態を確認
- curlでHTTP応答を確認
3-1. pingでIP疎通を確認する
controllerで以下のコマンドを実行します。
ping -c 4 192.168.56.11
-c 4は、ICMP Echo Requestを4回送信するオプションです。
実際の結果は以下のとおりです。
4 packets transmitted, 4 received, 0% packet loss
rtt min/avg/max/mdev =
0.630/0.819/1.126/0.185 ms
4回送信して4回応答があり、パケットロスは0%でした。
この結果から、controllerからtokyoへのICMP通信が成功していることがわかります。
ただし、ここで注意が必要です。
pingが成功しても、Webサービスが正常に動作しているとは限りません。
pingが確認しているのは、ICMPによる疎通です。
HTTP通信が成功するかどうかは、別途確認する必要があります。
3-2. ssで80番ポートを確認する
次に、tokyoで以下を実行します。
sudo ss -lntp | grep ':80'
ssは、Linuxのソケット状態を確認するコマンドです。
今回使用したオプションは以下のとおりです。
| オプション | 意味 |
|---|---|
| -l | 待受状態のソケットを表示 |
| -n | ポート番号などを数値で表示 |
| -t | TCPソケットを表示 |
| -p | ソケットを使用しているプロセスを表示 |
実際の結果では、以下の待受状態を確認できました。
LISTEN 0 511 0.0.0.0:80 0.0.0.0:* users:(("nginx",...))
LISTEN 0 511 [::]:80 [::]:* users:(("nginx",...))
ここで重要なのは、LISTENという表示です。
これは、nginxがTCPの80番ポートで接続を待ち受けていることを意味します。
0.0.0.0:80は、すべてのIPv4ローカルアドレスで80番ポートを待ち受けている状態を示しています。
ただし、待受状態が確認できても、HTTPリクエストに正常な応答を返すとは限りません。
そこで、次にcurlを使います。
3-3. curlでHTTP応答を確認する
controllerで以下を実行します。
curl -I http://192.168.56.11
curlはHTTPなどの通信を行うコマンドです。
今回使用した-Iは、HTTPのHEADリクエストを送信し、レスポンスヘッダーを取得するオプションです。
実際の結果は以下のとおりです。
HTTP/1.1 200 OK
Server: nginx/1.24.0 (Ubuntu)
Content-Type: text/html
Content-Length: 454
HTTP/1.1 200 OKが返ってきました。
これにより、controllerからtokyoのnginxへHTTPリクエストを送信し、正常な応答を受信できたことを確認できました。
正常時の確認結果
ここまでの結果を整理します。
| コマンド | 確認内容 | 結果 |
|---|---|---|
| ping | ICMPによる疎通 | 成功 |
| ss | TCP 80番ポートの待受 | LISTEN |
| curl | HTTP応答 | 200 OK |
これで、障害発生前の正常な状態を確認できました。
4. nginxを停止して通信障害を再現する
ここから、意図的に通信障害を発生させます。
今回はtokyoのnginxを停止させます。
注意:この操作はWebサービスを停止させるため、本番環境では実行しないでください。必ず検証環境で行ってください。
tokyoで以下を実行します。
sudo systemctl stop nginx
実際の検証では、エラー表示なくコマンドが終了しました。
この状態で、先ほどと同じ順番で通信を確認していきます。
5. 障害発生後の通信状態を確認する
5-1. pingで疎通を確認する
まず、controllerで再びpingを実行します。
ping -c 4 192.168.56.11
結果は以下のとおりでした。
4 packets transmitted, 4 received, 0% packet loss
rtt min/avg/max/mdev =
0.594/0.731/1.007/0.161 ms
なんと、nginxを停止した後でもpingは成功しました。
これは、nginxを停止してもLinuxサーバ自体は稼働しており、ICMPによる通信には応答できるためです。
つまり、pingの成功だけではWebサービスの障害を検知できない場合があるということです。
5-2. ssで80番ポートを確認する
次に、tokyoで以下を実行します。
sudo ss -lntp | grep ':80'
正常時にはnginxのLISTEN状態が表示されていました。
しかし、今回は何も表示されませんでした。
tokyo@tokyo:~$
この結果から、今回の環境では80番ポートの待受を確認できなくなったことがわかります。
つまり、pingは成功しているものの、Webサーバが接続を受け付ける状態ではなくなっています。
なお、grep ':80'は文字列による検索です。実運用では、ポートを厳密に指定するために次のような確認方法も利用できます。
sudo ss -lntp '( sport = :80 )'
こちらは補足コマンドであり、今回の実機検証では実行していません。
5-3. curlでHTTP接続を確認する
続いて、controllerでcurlを実行します。
curl -I http://192.168.56.11
結果は以下のとおりでした。
curl: (7) Failed to connect to 192.168.56.11 port 80 after 1 ms: Couldn't connect to server
正常時にはHTTP/1.1 200 OKが返っていましたが、今回は接続エラーになりました。
curl: (7)は、接続先への接続確立に失敗したことを示すエラーコードです。
今回の結果を整理すると、以下のようになります。
| 確認項目 | nginx停止前 | nginx停止後 |
|---|---|---|
| ping | 成功 | 成功 |
| ss | 80番 LISTEN | 表示なし |
| curl | HTTP 200 OK | 接続失敗 |
これで、「pingは通るのにWebサイトにはつながらない」という現象を実機で再現できました。
6. 原因を整理する
今回の障害を、調査の流れに沿って整理します。
現象
controllerからtokyoへのpingは成功するものの、HTTP接続は失敗する。
原因候補
一般的に、このような現象が発生した場合は、次のような原因が考えられます。
- Webサーバが停止している
- TCP 80番ポートで待ち受けていない
- ファイアウォールによって通信が遮断されている
- 接続先のIPアドレスやポート番号が間違っている
- Webサーバの設定に問題がある
切り分け
今回は以下の結果を確認しました。
ping:成功
ICMPによるIP疎通は正常でした。
ss:80番ポートのLISTENなし
Webサーバが待ち受けていない状態でした。
curl:接続失敗
HTTP接続を確立できませんでした。
さらに、直前にnginxを停止させているため、今回の原因はnginxの停止による80番ポートの待受消失と判断できます。
なお、実際の障害では同じ症状でも原因が異なることがあります。
今回の結果だけで、すべての通信障害の原因をnginx停止と判断できるわけではありません。
7. nginxを復旧する
原因を確認できたので、nginxを復旧させます。
tokyoで以下を実行しました。
sudo systemctl start nginx
続いて、サービスの稼働状態を確認します。
systemctl is-active nginx
結果は以下のとおりでした。
active
nginxが再び稼働していることを確認できました。
ただし、サービスがactiveであっても、HTTP通信まで正常とは限りません。
最後に、実際のHTTP応答を確認します。
8. 復旧後のHTTP通信を確認する
controllerで再び以下を実行します。
curl -I http://192.168.56.11
結果は以下のとおりでした。
HTTP/1.1 200 OK
Server: nginx/1.24.0 (Ubuntu)
Content-Type: text/html
Content-Length: 454
HTTP/1.1 200 OKが返ってきました。
これで、nginxを再起動することでHTTP通信が復旧したことを確認できました。
今回の一連の検証結果は以下のとおりです。
| 確認項目 | 正常時 | 障害時 | 復旧後 |
|---|---|---|---|
| ping | 成功 | 成功 | 未実施 |
| ss | LISTEN | 表示なし | 未実施 |
| curl | 200 OK | 接続失敗 | 200 OK |
| nginx | 稼働 | 停止操作 | active |
復旧後のpingとssは実施していませんが、nginxの稼働状態とHTTP応答の復旧を確認できています。
9. 今回の検証で学んだこと
今回、実際にUbuntu Serverでnginxを停止させてみて、改めて理解できたことがあります。
それは、通信できるかどうかを1つのコマンドだけで判断してはいけないということです。
それぞれのコマンドには、確認できる範囲があります。
| コマンド | 主に確認できること |
|---|---|
| ping | ICMPによるIP疎通 |
| ss | TCPポートの待受状態 |
| curl | HTTP通信の結果 |
例えば、pingが成功してもWebサイトにアクセスできない場合は、次のように調査できます。
Webサイトにつながらない
|
v
pingでIP疎通を確認
|
+-- 失敗
| └── IP設定・経路・ICMP制御などを調査
|
+-- 成功
|
v
ssで待受状態を確認
|
+-- LISTENなし
| └── サービス状態や設定を調査
|
+-- LISTENあり
└── curlなどでHTTP応答を確認
※ この図は基本的な調査例です。pingの成否だけでTCP通信の可否が確定するわけではありません。また、ssは原則として対象サーバ側で確認します。
今回の検証では、pingが成功してもnginxが停止していればHTTP接続が失敗することを確認できました。
コマンドを覚えるだけでなく、何を確認するためにそのコマンドを実行するのかを理解することが重要だと感じました。
10. まとめ
今回は、VirtualBox上のUbuntu Server 24.04を使用して、Webサーバの通信障害を再現しました。
検証の流れは以下のとおりです。
- 正常時にping・ss・curlで通信状態を確認
- nginxを停止して障害を発生させる
- pingが成功することを確認
- ssで80番ポートの待受がなくなったことを確認
- curlでHTTP接続が失敗することを確認
- nginxを起動して復旧
- curlでHTTP 200 OKに戻ったことを確認
今回の検証で、pingが成功していても、Webサービスが正常に動作しているとは限らないことを実際に確認できました。
Linuxの障害調査では、複数のコマンドを組み合わせて、問題がどこにあるのかを順番に切り分けることが重要です。
今後もLinux・ネットワーク・Ansibleなどを実際に操作しながら、学んだ内容を発信していきたいと思います。
関連記事・学習記録
今回のようなLinux・ネットワークの実機検証を継続しています。
X|インフラ学び直し記録
Xでは、Linux・ネットワーク・Ansibleなどの学習内容を、初心者にもわかりやすい図解とともに発信しています。
今回の記事のきっかけになった「ping → ss → curl」の切り分けについても投稿しています。
note|Linux・Ansibleの実機検証
noteでは、VirtualBoxを使ったLinux環境構築や、Ansibleによる複数サーバの管理・自動化など、実際に手を動かして学んだ内容を公開しています。
今回の通信障害についても、実際に再現しながら学べる演習教材を制作しています。
今後も、実際に試して理解できたことを中心に発信していきます。
最後まで読んでいただき、ありがとうございました。
また次のQiita記事でお会いしましょう!










