【Linux】Webアプリ開発における簡単なトラブルシューティング

Tech

2023.9.1

Topics

はじめに

こんにちは、いかがお過ごしでしょうか?

開発をしているなかでうまくいかないことはたくさんあると思いますが、その中でも厄介なのが「発生場所がわからないトラブル」ではないでしょうか?トラブルの発生場所さえ分かれば公式ドキュメントを読んだり、誰かに聞いたりと、いくらでも調べようがありますからね。
というわけで、Webアプリ開発初心者を対象に”どこでトラブルが起こっているのかについて、ある程度自力で把握する力をつける“を目標に本記事を書きました。ぜひ最後まで読んでいただくとともに、お手元の環境で実際に実行してみてください。

それではイギリスの作家、ギルバート・ケイス・チェスタトンの名言と共に「Webアプリケーション開発における簡単なトラブルシューティング」、始めていきます!

解決策がわからないのではない。問題がわかっていないのだ。

 

トラブルシューティングにおいて大切なこと

まず初めに、トラブルシューティングにおいて大切なことは何でしょうか?色々な回答があると思いますが、私は「原因を効率的に素早く特定する」ということが最も基本的で最も大切なことだと思っています。ではどのようにすれば、効率的に問題が発生している原因を見つける事ができるのでしょうか。

例として洗濯機が突然動かなくなったというシチュエーションで一度考えてみましょう。ボタンの接触が悪いのでしょうか。中のモーターが壊れてしまったのでしょうか。
原因はどこで起こっているかわかりませんが、洗濯機を分解する前にまずは電源が刺さっているか(電源コードが破損していないか)を確認しますよね?分解して確認したあとに、電源ケーブルが抜けていることが原因で動かないとわかったら多くの時間や手間を無駄にかけてしまったことになります。

コンピューターネットワークのトラブルにおいても同じことがいえます。正しい順番と正しい確認方法でトラブルシューティングを行うことによって、より効率的にトラブルの原因を見つけることができるのです。
ではコンピューターネットワークにおける正しい調査の順番とは何でしょうか?それについて知るために、次の章ではOSI参照モデルとTCP/IP階層モデルについて紹介していきます。

 

OSI参照モデルとTCP/IP階層モデル

コンピュータでなにかをしようとするとき、大抵の場合はネットワークでつながれ、様々な種類のデータをやりとりしなければいけません。その際に、コンピュータの種類によって別々の通信方針を持っていたらどうでしょうか?これでは非常に不便です。
よってどんな機器であってもスムーズなデータ通信を実現するために定められたネットワーク構造の基本的な設計方針が必要です。そうですそれこそがOSI参照モデルとTCP/IP階層モデルです。
OSI参照モデルは「通信プロトコルに必要な機能はなにか」を中心に考えてモデル化されているのに対して、TCP/IPの階層モデルは「プロトコルをコンピュータに実装するにはどのようにプログラミングしたらよいか」を中心に考えてモデル化されています。

つまり、より実用的なのはTCP/IP階層モデルということになります。それではTCP/IP階層モデルの各層について、簡単に解説していきます。

図 OSI参照モデルとTCP/IPモデル

ハードウェア層

最下位層として物理的にデータを転送してくれるハードウェア層がある。イーサネット電話回線などが代表的なプロトコルとなっている。使用する通信方式はケーブルでも無線でもよく、通信する上での決まりなども特にない。なぜならTCP/IP階層モデルは、ネットワークで接続された装置間で通信できることを前提にして作られているプロトコルだからである。

ネットワークインターフェース層

ネットワークインターフェース層は、イーサネットなどのデータリンクを使用し、通信するためのインターフェースとなる階層。コンピュータの周辺機器や拡張カードなどは、OSが認識して利用できるように設定する必要がある。例としてNIC(ネットワークインターフェースコントローラ)を動かすための「デバイスドライバ」だと考えると非常にわかりやすい。OSとハードウェアを橋渡しするソフトウェアである。

インターネット層

インターネット層ではIPという通信プロトコルが使われる。最も馴染みのある名前では無いだろうか。IPはIPアドレスをもとにパケットを転送することで、インターネットでページを閲覧することができる。

トランスポート層

TCPUDPという通信プロトコルが代表的である。アプリケーションプログラム間の通信を実現している。コンピュータの内部では複数のプログラムが同時に動いており、通信を識別する必要がある。その識別にはポート番号という識別子が使われている。

アプリケーション層

ユーザーが利用するアプリケーションに対して、ネットワークサービスを提供する層である。有名なものだとHTTPなどがある。

ざっくりとでも、TCP/IP階層モデルの概要を理解できたでしょうか。ここまで理解してもらった上で、下記が正しい調査の順番の答えとなります。正しい調査の順番がわかったところで、次の章では各層での調査に使えるLinuxコマンドを紹介していきたいと思います。

・トラブルシューティングにおいては、TCP/IP階層モデルでいう下位層から上位層に向けて調査していく
※クラウドサービスなどを使用している場合は、下位層を確認できない場合も多いことに注意

 

実践的なトラブルシューティング手法

今回はハードウェア層やネットワークインターフェース層に関しては、問題がないと仮定してインターネット層から確認していきたいと思います。(各方面の技術の進歩により、Webアプリ開発においてハードウェア層やネットワークインターフェース層で問題が発生するケースは低くなっています)

まずはなにはともあれpingコマンドを打ちましょう。このコマンドはパケットを送り、きちんと届いて帰ってきているか調べることができます。(架空のサイトXXXX.com・YYYY.comをそれぞれ調査)
※インターネットに公開されているサーバーにはセキュリティ上の都合で反応を返さないように設定されているものや、ICMPパケットを遮断しているものもあるので、こちらのコマンドが使用できない場合もあります

・反応あり

 
root@test:~$ ping XXXX.com 

PING XXXX.com (142.251.222.14) 56(84) bytes of data. 
64 bytes from nrt13s71-in-f14.1e100.net (142.251.222.14): icmp_seq=1 ttl=114 time=10.3 ms 
64 bytes from nrt13s71-in-f14.1e100.net (142.251.222.14): icmp_seq=2 ttl=114 time=11.3 ms 
64 bytes from nrt13s71-in-f14.1e100.net (142.251.222.14): icmp_seq=3 ttl=114 time=12.6 ms 
64 bytes from nrt13s71-in-f14.1e100.net (142.251.222.14): icmp_seq=4 ttl=114 time=10.0 ms 
64 bytes from nrt13s71-in-f14.1e100.net (142.251.222.14): icmp_seq=5 ttl=114 time=10.2 ms 
64 bytes from nrt13s71-in-f14.1e100.net (142.251.222.14): icmp_seq=6 ttl=114 time=14.8 ms 

・反応なし

 
root@test:~$ ping YYYY.com

ping: cannot resolve YYYY.com: Unknown host
 

 

この時点で疎通が確認できない場合、TCP/IPモデル3層以下で問題が発生しています。オンプレミスの場合、LANケーブルなどの物理的からルーティングの設定などに問題があることが多いです。

pingで疎通が確認できたら徐々に上の層に向かって確認していきましょう。telnetコマンドではTCP/UDP(トランスポート層)でポートの反応があるのかを知ることができます。ご自身の環境でしたら、設定したポートが正しく待機しているかどうかをしらべることができます。
今回はXXXX.comの80・9898番ポートの反応をそれぞれ見てみましょう。

・反応あり

root@test:~$ telnet XXXX.com 80

Trying 54.239.28.85...
Connected to XXXX.com.
Escape character is '^]'.

・反応なし

 root@terraform:~$ telnet XXXX.com 9898 

Trying 54.239.28.85... 
Trying 205.251.242.103... 
Trying 52.94.236.248... 
telnet: Unable to connect to remote host: Connection refused 

80番ではポートが設定されてることがわかりましたが、9898番ではポートは開かれて(受け付けて)いないようです。

実はこのポート番号、プロトコルごとにポート番号が決め打ちされています。(もちろん故意に変更を加えることができます)
先程調べた80番ポートはHTTP通信プロトコルで使用されるポートでした。他にも代表的なプロトコルはポート番号が決められているため、調べてみると勉強になるかもしれません。

さて、ここまで問題がなければTCPでの疎通が確認できたということになります。ということはTCP/IP階層モデルで4層までは問題ないことが確認できました。最後にアプリケーション層を調査してみましょう。
opensslコマンドでSSL/TLSで指定のサーバーにアクセスしてみたいと思います。(SSL/TLSとは、セキュアな接続の上でHTTP通信をするためのプロトコルです)

XXXX.com・YYYY.comの443番ポートにそれぞれアクセスしてみます。

・反応あり

root@test:~$ openssl s_client -connect XXXX.com:443

(省略)
---
No client certificate CA names sent
Peer signing digest: SHA512
Peer signature type: RSA
Server Temp Key: ECDH, prime256v1, 256 bits
---
SSL handshake has read 5558 bytes and written 438 bytes
Verification: OK
---
New, TLSv1.2, Cipher is ECDHE-RSA-AES128-GCM-SHA256
Server public key is 2048 bit
Secure Renegotiation IS supported
Compression: NONE
Expansion: NONE
No ALPN negotiated
SSL-Session:
    Protocol  : TLSv1.2
    Cipher    : ECDHE-RSA-AES128-GCM-SHA256
    Session-ID: F97CC4574B4349A3A09DA94EB542527FDC612799D24AA656C8BC7C0C39997AC7
    Session-ID-ctx:
    Master-Key: 4E64D078BB332A00472ECB2121E47BBD2A7F8F273D3C37268BB28096CC8285A438329B66BB6D7B63232390D83B8941DA
    PSK identity: None
    PSK identity hint: None
    SRP username: None
    Start Time: 1692945334
    Timeout   : 7200 (sec)
    Verify return code: 0 (ok)
    Extended master secret: no
---

・反応なし

root@test:~$ openssl s_client -connect XXXX.com:443

00DE45F001000000:error:10080002:BIO routines:BIO_lookup_ex:system lib:crypto/bio/bio_addr.c:738:nodename nor servname provided, or not known
connect:errno=0

疎通が確認できましたでしょうか?接続に成功していたら、出力された文章の下部にSSL証明書というものの情報が載っているはずです。
ご自身で作成した環境に対してコマンドを打っている場合は、表示されているSSL証明書がご自身が設定したものと同じかを確認してみてください。

 

その他の便利なコマンド

ここまで3つの代表的なトラブルシューティングに使えるコマンドを紹介してきました。3つはどれも必須級のコマンドですので、なにか動かないときはとりあえず打ってみるようにするといいかもしれません。また、Linuxコマンドはサブコマンドやオプションによって取得できる情報を変えることもできるので、ぜひ気になったコマンドについて詳しく調べてみてください。

実際のトラブルシューティングでは、紹介したコマンド以外のコマンドも組み合わせて原因を特定していきます。前提として全てに万能なコマンドはありません。なにを確認したいのか、現在の環境(コマンドが使えるのかどうか)などによっても適切なコマンドを取捨選択する必要があります。
簡単に代表的なコマンドをまとめましたのでぜひお手元の環境で一通り打ってみてください。


root@test:~$ nslookup XXXX.com
Server: 127.0.0.53
Address: 127.0.0.53#53

Non-authoritative answer:
Name: XXXX.com
Address: 17X.2X7.17X.110
Name: XXXX.com
Address: 2404:6800:4004:818::200e

nslookupコマンド
・DNSサーバーにホスト名からIPアドレス、IPアドレスからホスト名などの名前解決の問い合わせをするコマンド
・主にドメイン名からIPアドレスを知りたい(正引きといいます)ときや、その逆にIPアドレスからドメイン名を知りたいとき(逆引きといいます)に使用する

root@test:~$ dig XXXX.com

; <<>> DiG 9.18.12-0ubuntu0.22.04.2-Ubuntu <<>> XXXX.com
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 54756
;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 65494
;; QUESTION SECTION:
;XXXX.com.			IN	A

;; ANSWER SECTION:
XXXX.com.		377	IN	A	172.2X7.X75.110

digコマンド
・DNSサーバにDNSサーバ/ドメイン名/検索タイプなどを問い合わせる
・使い方は基本的には上のnslookupと同様だが、nslookupと違いdigは取得した情報を加工せずにそのまま表示させる(文量は長くなるが詳細な情報が得られる)

root@test:~$ whois XXXX.com

   Domain Name: XXXX.COM
   Registry Domain ID: 2138514_DOMAIN_COM-VRSN
   Registrar WHOIS Server: whois.markmonitor.com
   Registrar URL: http://www.markmonitor.com
   Updated Date: 2019-09-09T15:39:04Z
   Creation Date: 1997-09-15T04:00:00Z
   Registry Expiry Date: 2028-09-14T04:00:00Z
   Registrar: MarkMonitor Inc.
   Registrar IANA ID: 292
   Registrar Abuse Contact Email: XXXX@markmonitor.com
   Registrar Abuse Contact Phone: +1.20X68X1750

whoisコマンド
whoisサービスのクライアント。ドメインの所有者や技術連絡先を調べるのに利用する
・類似ドメインが存在しないかの確認や、技術的な問題が発生した場合の連絡などに使われる

 

まとめ

お疲れ様でした。本記事は、初心者向けということもあり、どうしても広く浅い情報が多くなってしまいました。腑に落ちない箇所や、気になった箇所はぜひどんどん調べていっていただけると良いかと思います。
最後にまとめとして、Webアプリケーション開発におけるトラブルシューティングでは下記2点が大切でした。

・正しい順番(TCP/IP階層モデルで下層から上層へ)で原因を調査していく

・知りたい情報に合わせて適切なコマンドを取捨選択する

トラブルシューティングの際は、とにかく丁寧に原因を正しい順番で切り分けていく必要があります。本記事が環境構築やWeb開発のトラブルシューティングの際に微力でも力になることができたら幸いです。

 

python開発環境構築はこちら▼

関連記事
pyenvによるPythonの開発環境構築【Mac】
Dr.K

2023年度新卒入社。DevOpsエンジニア。「好きなことで生きていく」

Recommends

こちらもおすすめ

Special Topics

注目記事はこちら