この記事は CAMPHOR- Advent Calendar 2017 4日目の記事です.
「ネットワークの調子が悪い」という話をしばしば耳にします.このようなときにとりあえず設定をいじってみたり,機器の電源を入れ直してみたりして問題を解決して,根本的な原因がよく分からないままになることがあると思います.また,「ネットワークの調子が悪いのでなんとかしてくれ」と言ったことをよく人に言われて対応するのですが,実際にネットワークが悪いこともあれば,サービスが落ちていることもあったり,クレームを言っている人が設定を間違っていたりなど原因は様々です.
この記事ではネットワークの知識を使って,機器を再起動してしまう前にもう少しまともに原因を究明する方法について紹介します.ネットワークを支えるそれぞれのプロトコルについての説明はよく見られますが,具体的に問題が発生したときに原因を見つける方法が書かれている資料はあまりないように思うので,この記事が皆さんのお役に立てれば幸いです.
注意
この記事の内容は一般的な家庭や研究室程度の小規模なネットワーク (端末数が数十台くらいのもの) を対象にしています.また,基本的に過去に自分が見たことがある事例や,実際に失敗した事例を中心に書いており,内容が偏っている可能性があります.記事中のコマンドは主に Linux や macOS を使って実行した結果を書いています.
はじめに
「ネットワークの調子が悪い」って?
一口に「ネットワークの調子が悪い」といってもそれが意味するところは人によって様々です.例えば「ブラウザで Gmail を開けない」とか「YouTube の動画の読み込みが遅い」とか色々なものがあります.この記事では基本的に「ブラウザで Gmail を開けない (エラーページが表示される)」といった,通信が出来なくなっているケースを主に取り上げます.
また,サービスに障害が発生している場合も「ネットワークの調子が悪い」と言われることがあります.この記事ではサービスに障害が発生している場合も含めて考えます.
調子が悪い原因はいろいろ
ブラウザで Web ページを閲覧するだけでも様々な機器やプロトコルが関わっています.Web ブラウザやサーバーがきちんと動作している必要があることはもちろんのこと,HTTP(S)・TCP・IP 等のプロトコルを使ってきちんと通信できることが必要です.これらのたくさんの要素の内,一つに問題が発生するだけで Web ページを閲覧できない状態になってしまいます.
TCP/IP で通信する際の概念図はおおよそ以下のようになります.
例えば,ブラウザで Web サイトを閲覧する場合,アプリケーション層では HTTP や TLS (SSL),トランスポート層では TCP,インターネット層では IP,リンク層では接続方法によって Ethernet や Wi-Fi が利用されます.もちろん HTTP での通信を始めるまでに DNS を使って名前を解決したり,DHCP で IP アドレス等を設定したりといったことも行われます.
原因を探し始める前に
これから具体的な原因の探し方について書いていくのですが,原因を究明する前に気を付けておくべきことがあります.まず,「この機器は壊れていないはずだ」や「この設定は間違っていないはず」といった思い込みは避けましょう.冷静にコマンドを実行して検証するなどして,原因を絞り込んでいくことが重要です.また,落ち着いて作業することも重要です.障害を直そうとして設定を更に間違ったりすると修正がより大変になります.
直近の変更を疑ってみる
ネットワークの調子が悪いときにまずすべきことは,直近の変更を疑ってみることです.自分の経験では,何も変更をしていないときにネットワークが不調になることは少なく,何かしらの行動が原因で不調になることが多いように思います.
具体的な例を以下にいくつか挙げてみます.
配線を変更した
配線を間違った,ケーブルが断線していた,ケーブルがきちんと刺さっていなかったなどの原因が考えられます.配線をもう一度確認してみましょう.
また,小規模なネットワークでは UTP ケーブルを使った Ethernet がほとんどだと思います.ケーブルが接続されて両端の機器の電源が入っている場合「LINK」と書かれた LED が点灯するようになっているものが多いので,これを確認しましょう.
新しい機器をネットワークに接続した
新しい機器を接続した結果,ネットワークの調子が悪くなった場合は新しい機器の設定ミスなどが考えられます.たとえば新しい機器にすでに他の機器が使用している IP アドレスを設定しまうといった例や,意図せず複数の DHCP サーバーを1つのネットワーク内に立ててしまうといったことが考えられます.このような場合は一旦新しい機器をネットワークから取り外して,冷静に設定を見直すのが良いと思います.
機器の設定を変更した・機器を再起動した
機器の設定を変更した場合は,その設定が間違っている可能性が考えられます.また機器を再起動して問題が発生した場合は,再起動前に設定をきちんと保存しておらず,再起動した際に設定が失われているなどの可能性も考えられます.(例: カーネルパラメータの設定の永続化を忘れる)
自然災害が発生した
地震や火事,落雷などの自然災害が発生した場合は,これが原因で電線が切れたり機器が故障するなどしてネットワークに問題が発生する場合があります.回線事業者などの工事・故障情報などを調べてみると良いでしょう.
自分の経験ですが,家の近くで火事が起こったことがあります.しばらくは問題なくインターネットに接続できていましたが,消火してしばらく経った後,急にインターネットへの接続が出来なくなりました.色々と調べてみたところ,火事で光ファイバーが溶けた可能性があるかなにかで,電柱の間のケーブルの交換作業が行われており,物理的にインターネットへの接続が不可能な状態になっていました.
問題発生箇所を切り分ける
直近の変更箇所を確認しても問題が解決しない場合は,もう少し詳しく問題について調べる必要があります.この節では大まかに問題発生箇所を切り分ける方法について説明します.「ネットワークの調子が悪い」ときの原因は,必ずしも自分のネットワークにあるわけではないからです.
正しくWeb ページを閲覧するためには大雑把に分けて以下の3つの要素がきちんと動作する必要があります.
- 自分の端末とネットワーク (PC や Wi-Fi のアクセスポイント,ルーターなど)
- インターネット (プロバイダの回線や企業・団体などの組織のネットワークなど)
- サービスのネットワークとサーバー
自分が管理している端末やネットワークの問題は自分で直すことが出来ますが,それより先の問題は自分では直すことが出来ません.この点からも,自分の管理している部分に問題があるのか,その外側に問題があるのかを切り分けるのは重要です.
サービス側の問題
自宅のネットワークでも携帯電話のネットワークでもあるサービスが利用できないような場合,これはサービス側に問題が発生している可能性が高いです.また,他のサービスは利用できるが,特定のサービスだけが利用できない場合もサービス側の問題の可能性が高いと考えられます.
メジャーなサービスはステータスを見ることが出来るページや Twitter アカウントなどを用意しているので,それを確認してみるのが良いと思います.GitHub の例:
ステータスページにまだ情報が載っていない場合でも,Twitter などで検索すると同じ現象に遭遇している他の人を見つけられるかもしれません.
最近は AWS・GCP・Azure のようなクラウドを使ってサービスが構築されることが増えています.このようなクラウドのインフラに問題が発生した場合は,同じクラウドサービスを利用している複数のサービスが同時に影響を受けることがあります.
最近の事例としては2017年3月の Amazon S3 の障害などがあります.このときは Slack などのサービスが影響を受けたようです.また,このときは AWS のステータスを表示するページ自体が S3 を利用していたため,ステータスページも正しく表示されなくなるという珍事が発生していました.
端末の問題
同じネットワークに繋がっている端末が複数あり,一つではサービスに接続できるが,他方では接続出来ない場合は接続できない端末に問題があることが考えられます.この場合は問題がある端末について,後述の方法等を使って原因を考える必要があります.
ネットワークの問題
サービス側の問題ではなく,端末の問題でもなければ,ネットワークの問題であることが考えられます.この場合,自分が管理しているネットワークに問題がある可能性があれば,外側のネットワークに問題があることも考えられます.外側のネットワークの問題の例をいくつか挙げてみます.
プロバイダや大学・会社のネットワークの障害
プロバイダや大学等の組織はそれぞれ障害情報を何らかの形で提供してくれているので,そちらを確認することで問題が発生しているかを確認できます.
インターネット全体の障害
インターネット全体の障害の例としては,2017年8月に発生した Google が BGP の経路情報を誤設定したものが記憶に新しいです.この結果,様々なサービスへの接続が困難になるなどの問題が発生しました.
政府がネットワークを制限している
国によっては政府がインターネット接続を行っている場合もあります.中国のものが有名ですが,実際にはそのほかの国でも制限が行われていることがあるようです.
外側のネットワークに問題がないようであれば,自分が管理している端末やネットワークの問題を疑うことになります.
プロトコルスタックを意識して問題を探す
自分が管理している端末やネットワーク問題がありそうということが分かったときに,どのように問題発生箇所を見つけるのが良いでしょうか? 手当たり次第に探しても効率が良くないので,ここでは TCP/IP のプロトコルスタック (スイート) の各階層を意識して探していく方法を紹介します.
Web ページを閲覧するだけでも,前に書いたように アプリケーション層 (HTTP・TLS・DNS)・トランスポート層 (DNS)・インターネット層 (IP)・リンク層 (Ethernet や Wi-Fi) など,様々な層の様々な部分が正しく動作する必要があります.また,ある層できちんと通信できるためには,その層より下側の層が正しく動作している必要があります.(例: トランスポート層の TCP を使うには,インターネット層とリンク層が正しく動作する必要があります.)
問題が発生しているときは,出来る限り要素を減らして検証をすることで原因を見つけやすくなります.たとえば ping を行うためには インターネット層と・リンク層の2層が動作していれば良いので,HTTP での通信を行うより必要な要素が少なくなります.ping は出来るが HTTP では通信が出来ない場合,インターネット層よりも上側の問題であることが疑われます.
この記事では下側の (物理側の) 層から順に見ていきます.
リンク層
リンク層は Ethernet や Wi-Fi (IEEE 802.11) にあたる層です.同じネットワークに Ethernet で接続すれば問題ないが,Wi-Fi で接続したら問題が発生する場合,この層でなにかの問題が発生している可能性があります.
有線でネットワークに接続している場合はケーブルの接続状態を確認したり,ethtool
などのコマンドを使ってみるのも良いでしょう.
$ sudo ethtool enp3s0
Settings for enp3s0:
Supported ports: [ TP MII ]
Supported link modes: 10baseT/Half 10baseT/Full
100baseT/Half 100baseT/Full
1000baseT/Half 1000baseT/Full
Supported pause frame use: No
Supports auto-negotiation: Yes
Advertised link modes: 10baseT/Half 10baseT/Full
100baseT/Half 100baseT/Full
1000baseT/Full
Advertised pause frame use: Symmetric Receive-only
Advertised auto-negotiation: Yes
Link partner advertised link modes: 10baseT/Half 10baseT/Full
100baseT/Half 100baseT/Full
1000baseT/Half 1000baseT/Full
Link partner advertised pause frame use: No
Link partner advertised auto-negotiation: Yes
Speed: 1000Mb/s
Duplex: Full
Port: MII
PHYAD: 0
Transceiver: internal
Auto-negotiation: on
Supports Wake-on: pumbg
Wake-on: g
Current message level: 0x00000033 (51)
drv probe ifdown ifup
Link detected: yes
無線を利用している場合は,電波状況を確認してみるのも一つです.特に 2.4GHz 帯を利用している場合は電子レンジ等の影響を受けやすくなります.
Ethernet では MAC アドレスを使って通信が行われますが,IP アドレスから MAC アドレスへの変換は ARP というプロトコルを使って行われます.ARP によって MAC アドレスが正しく取得できているかは arp
や ip
コマンドを使って確認出来ます:
$ sudo arp -a
gateway (10.229.55.126) at 00:12:xx:xx:xx:xx [ether] on eno1
xxxxx (10.229.55.65) at f4:e9:xx:xx:xx:xx [ether] on eno1
$ ip n
192.168.1.1 dev enp3s0 lladdr 00:a0:xx:xx:xx:xx REACHABLE
192.168.1.60 dev enp3s0 lladdr a0:b3:xx:xx:xx:xx REACHABLE
192.168.1.120 dev enp3s0 FAILED
fe80::xxxx:xxxx:xxxx:xxxx dev enp3s0 lladdr 00:a0:xx:xx:xx:xx router REACHABLE
ネットワーク層
ネットワーク層は IP の層になります.まず IP アドレスやサブネットマスク,ルーティング (デフォルトゲートウェイなど) が適切に設定されているかを確認しましょう.ifconfig
や ip
コマンドを使うのが便利です.
$ ifconfig
lo0: flags=8049<UP,LOOPBACK,RUNNING,MULTICAST> mtu 16384
options=1203<RXCSUM,TXCSUM,TXSTATUS,SW_TIMESTAMP>
inet 127.0.0.1 netmask 0xff000000
inet6 ::1 prefixlen 128
inet6 fe80::1%lo0 prefixlen 64 scopeid 0x1
nd6 options=201<PERFORMNUD,DAD>
en0: flags=8863<UP,BROADCAST,SMART,RUNNING,SIMPLEX,MULTICAST> mtu 1500
ether d0:a6:xx:xx:xx:xx
inet 192.168.1.201 netmask 0xffffff00 broadcast 192.168.1.255
media: autoselect
status: active
$ 1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
inet6 ::1/128 scope host
valid_lft forever preferred_lft forever
2: enp3s0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP group default qlen 1000
link/ether f8:b1:xx:xx:xx:xx brd ff:ff:ff:ff:ff:ff
inet 192.168.1.12/24 brd 192.168.1.255 scope global enp3s0
valid_lft forever preferred_lft forever
inet6 240b:250:8900:xxxx:xxxx:xxxx:xxxx:xxxx/64 scope global dynamic mngtmpaddr
valid_lft 2592000sec preferred_lft 604800sec
inet6 fe80::xxxx:xxxx:xxxx:xxxx/64 scope link
valid_lft forever preferred_lft forever
設定が問題なさそうであれば ping
コマンドを使ってみましょう.ping は IP 上で動作する ICMP というプロトコルを利用します.これが出来ればここまでの各層は正しく動作している可能性が高くなります.
$ ping 192.168.1.1
PING 192.168.1.1 (192.168.1.1) 56(84) bytes of data.
64 bytes from 192.168.1.1: icmp_seq=1 ttl=255 time=0.237 ms
64 bytes from 192.168.1.1: icmp_seq=2 ttl=255 time=0.254 ms
64 bytes from 192.168.1.1: icmp_seq=3 ttl=255 time=0.256 ms
^C
--- 192.168.1.1 ping statistics ---
3 packets transmitted, 3 received, 0% packet loss, time 2004ms
rtt min/avg/max/mdev = 0.237/0.249/0.256/0.008 ms
$ ping 8.8.8.8
PING 8.8.8.8 (8.8.8.8) 56(84) bytes of data.
64 bytes from 8.8.8.8: icmp_seq=1 ttl=58 time=8.30 ms
64 bytes from 8.8.8.8: icmp_seq=2 ttl=58 time=6.43 ms
64 bytes from 8.8.8.8: icmp_seq=3 ttl=58 time=6.80 ms
^C
--- 8.8.8.8 ping statistics ---
3 packets transmitted, 3 received, 0% packet loss, time 2002ms
rtt min/avg/max/mdev = 6.435/7.180/8.304/0.814 ms
ping が失敗する場合は以下のようなことが考えられます.
- 設定が間違っていて通信できない状態になっている
- ping 先のサーバーが ping を返さないようになっている (Google のサーバーは ping を返してくれるのでおすすめです)
- 上位のネットワーク (企業や大学などのネットワーク) が ping を通さないように制限している
IP層まで正しく設定されている場合も,ping が失敗することがあることに注意しましょう.そのネットワークから ping が通るかどうかを普段から把握しておくといざというときに役立ちます.
トランスポート層
TCP や UDP に該当する層です.IP と違ってこの層は特に設定をしなくても動く部分になります.ただしファイアーウォール等を設定していたり,上位のネットワークで特定のポートの通信が制限されていたりすることがあるので注意が必要です.例えば OP25B と呼ばれる,外向けの TCP 25 番ポートへの通信は多くのプロバイダによって制限されていますし,企業などのネットワークでは HTTP などの限られたポートを除いて通信できないように設定されていることもしばしばあります.
ポートスキャンを行うと,どのポートで通信が可能かを確認する助けになります.ポートスキャンを行えるツールとしては nmap が有名です.このブログに HTTPS (TCP 443) で接続できるかどうかは以下のように検証できます:
$ nmap -p 443 blog.ymyzk.com
Starting Nmap 7.60 ( https://nmap.org ) at 2017-12-02 20:52 JST
Nmap scan report for blog.ymyzk.com (160.16.75.53)
Host is up (0.20s latency).
Other addresses for blog.ymyzk.com (not scanned): 2001:e42:102:1513:160:16:75:53
rDNS record for 160.16.75.53: xxxx.ymyzk.com
PORT STATE SERVICE
443/tcp open https
Nmap done: 1 IP address (1 host up) scanned in 0.33 seconds
ポートスキャンはサーバーへの攻撃とも捉えられうるので,自分が管理しているサーバー以外へ行う際には注意が必要になります.
アプリケーション層
HTTP・TLS/SSL・DNS・SSH のようなプロトコルが含まれる層です.この層のプロトコルはアプリケーション毎に様々なものがあり,これまでに紹介した層よりかなり多くのプロトコルが存在します.
この記事では DNS と HTTP について簡単に触れます.アプリケーション層の問題を解決するためには,基本的にサーバーやクライアントのログを読んで問題がないか調査するのが見るのが良いとおもいます.
DNS
DNS は IP アドレスとホスト名の相互の変換を行うプロトコルです.多くのアプリケーションで IP アドレスを直接指定するより,ホスト名を使って指定することが多いため,DNS が正しく動作していることを確認するのは重要です.nslookup
や dig
コマンドを使うと,実際に DNS を使ってホスト名から IP アドレスを引いて正しく引けるか確認することが出来ます.
$ nslookup google.com
Server: 192.168.1.77
Address: 192.168.1.77#53
Non-authoritative answer:
Name: google.com
Address: 216.58.199.238
$ dig google.com
; <<>> DiG 9.11.2 <<>> google.com
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 51434
;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1
;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 4096
;; QUESTION SECTION:
;google.com. IN A
;; ANSWER SECTION:
google.com. 51 IN A 216.58.199.238
;; Query time: 1 msec
;; SERVER: 192.168.1.77#53(192.168.1.77)
;; WHEN: Sat Dec 02 21:56:36 JST 2017
;; MSG SIZE rcvd: 55
DNS サーバーを変えると正しく DNS を引けるようになる場合は,DNS の設定が間違っているか,利用している DNS サーバーの不調が疑われます.
$ dig google.com
; <<>> DiG 9.11.2 <<>> google.com
; (1 server found)
;; global options: +cmd
;; connection timed out; no servers could be reached
$ dig @8.8.8.8 google.com
; <<>> DiG 9.11.2 <<>> @8.8.8.8 google.com
; (1 server found)
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 51505
;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1
;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 512
;; QUESTION SECTION:
;google.com. IN A
;; ANSWER SECTION:
google.com. 299 IN A 172.217.27.174
;; Query time: 47 msec
;; SERVER: 8.8.8.8#53(8.8.8.8)
;; WHEN: Sat Dec 02 21:54:19 JST 2017
;; MSG SIZE rcvd: 55
HTTP(S)
HTTP は Web ページを閲覧するときに利用されるプロトコルです.500 Internal Server Error のようなメッセージが表示される場合は基本的にサーバー側の問題なので,こちらではどうしようもすることが出来ません.HTTP 関係で問題が発生した場合クライアント側で簡単に試せることとしては,Web ブラウザを変更するということがあります.
最近は HTTPS を利用することも増えているため,TLS/SSL についても考える必要があります.TLS/SSL では証明書の有効期限を切らしてしまった結果,障害が発生することがあります.2013年にはこれが原因で Azure のストレージサービスに障害が発生しました.また,クライアント側の機器の時計がずれていると,証明書の有効期限のチェックに失敗するといった問題が発生することもあります.
まとめ
この記事では「ネットワークの調子が悪い」ときの原因の探し方について紹介しました.具体的には,直近の変更点を疑う方法,問題が起こってる箇所を大まかに切り分ける方法,プロトコルスタックを意識して問題を見つける方法の3つを紹介しました.この記事で紹介できた知見は限られていますが,皆さんのお役に立てば幸いです.
CAMPHOR- Advent Calendar 2017 の明日の担当は @ishiy1993 です.お楽しみに!