#1. 問題判別で最初に行うこと
事前に環境について十分な知識を持っていない人が、「動かないので調べて」と言われてすぐに問題判別に取り掛かれることはありません。問題が発生した際に最初にやらなければいけないことは、今起こっている問題について余すところなく説明する準備をすることです。この問題の記述なしには、原因調査をどこから始めればよいのか分からないでしょう。問題の本質を整理し、スムーズな支援を受けたり次のアクションを決めるためには、まずは以下の内容を整理して周りと共有することから開始するべきです。
- 問題は何ですか?
2. 誰(何)が問題を報告していますか?
3. 問題の症状は何ですか?
4. この問題はどのようなビジネス・インパクトがありますか?当面の回避策はありますか? - 問題が発生している環境を説明できますか?
6. 構成図やネットワーク図を使って説明できますか?
7. 不明な箇所の環境は誰ならば知っていますか?その人を問題判別のために巻き込むことは可能ですか? - 問題はどのような状況で発生しますか?
8. いつも発生していますか?それとも特定の時間帯だけですか?
9. いつからこの問題が発生していますか?(過去に一度でも成功したことはありますか?最近何かやりましたか?)
10. 問題が発生するのは、他にも何か実行している時だけですか? - 問題は再現可能ですか?
9. 同一の問題を再現できる開発環境はありますか?
10. ログインして情報を収集することは可能ですか?
11. よりシンプルな構成で問題を再現できますか?(問題の本質を抽出し、再現環境構築の敷居を下げるため)
#2. ネットワーク問題分析ツールの導入方法(CentOS/Redhat系の場合)
問題が発生していざ判別しようとしたら「ツールが導入されていない!でも今更本番環境に手を入れられない!」なんていう話はよく聞きます。シャーロックホームズの有名な台詞(When you have eliminated the impossible, whatever remains, however improbable, must be the truth.)ではありませんが、一見当たり前で問題がないと思っていたことに思わぬ見落としがあり、実は巡りめぐって分かった結果、初歩的がミスが原因でした、、、という経験をされた方もいらっしゃるのではないでしょうか。こうした状況を防ぐためには「問題がない」と判断した根拠は、仮に当たり前だと思うことでもしっかりと記録しておく必要があります。そのためには、システム設計の段階で、トラブル発生時にどこからどういう手段で問題判別を行うのかを十分に考慮し、予め構築段階から最低限の問題判別に必要なツールを導入しておき、ツールの利用法の確認や正常時のデータの収集を行っておくことは重要なことです。
# yum install -y mtr
# yum install -y traceroute
# yum install -y whois
# yum install -y nmap
# yum install -y tcpdump
#3. ping/mtr/traceroute/tracertの基本と注意点
- pingはICMPを利用。
- 以下は頻出。多分正常のステータスコードを0にしたかったからecho replyが0になっているのだと思われる。
- echo reply(Type 0)
- destination unreachable(Type 3)
- code 1: host unreachable
- code 3: port unreachable
- code 4: packet too big
- echo request(Type 8)
- time exceeded(Type 11)
- iptablesでいうと、pingの宛先サーバーにて、以下の設定相当の設定が存在しないとその宛先サーバーはICMPパケットを受信しない、もしくは応答しない。
-A INPUT -p icmp --icmp-type 8 -j ACCEPT
-A OUTPUT -p icmp --icmp-type 0 -j ACCEPT
- ICMPはTCPでもUDPでもないのでポート番号は存在しない。「あれー、それだったらNAPTできないんじゃないの?」と思うのは当然だが、実際pingでNAPT越えできてしまうケースに遭遇することは多い(だからこそ、ICMPがTCPやUDPの一種であるかのような誤解をしている人も多いのだが)。その場合は、ICMP系にはIdentifierフィールドというものが存在し、これでポート番号のフィールドの代用として実装されている。
- 以下は頻出。多分正常のステータスコードを0にしたかったからecho replyが0になっているのだと思われる。
- mtrはICMPがデフォルト。TCPやUDPを使うように変更することが可能なので、Firewallの設定によってはICMPを通さない構成になっていてもレポートを取得することが可能。private NWを利用している時はホスト名解決は試行する意味がないので-nオプションを必ずつけること。使い方は次項参照。
- traceroute(Linux)はUDPがデフォルトでポート番号は特に定まっていない。ICMP(-Iオプション)やTCP(-T -p 80でポート80番を指定)に変更可能。private NWを利用している時はホスト名解決は試行する意味がないので-nオプションを必ずつけること。他に、-Aとか-eオプションも有効なので、以下も参照のこと。
- tracert(Windows)はICMPを利用(変更不可)。WindowsとLinuxで挙動が違う!って騒ぐ前に、そもそも利用しているプロトコルのデフォルトが異なることに注意。
- DNSによるホスト名解決が不要である場合(インターネットに接続されていないネットワーク経路等)であれば、-dオプションを利用するとよい。tracertが遅い!と騒いでいる人の原因の殆どが-dオプションを付けていないことが原因。
- ルーターを通る度にIPヘッダのTTLmtr/traceroute/tracertなどは、基本的にはIPヘッダのTTL(ルータを通過できる最大回数)値が1のパケットを送出、TTL=2のパケットを送出、、、とコマンドを発行した端末から送出し、TTL値が0になった時点でルーターはパケットを破棄してICMP Time Exceed(Type 11)を返すという仕組み。途中経路のルーターがICMP Time Exceeded(Type 11)の送信をブロックしていれば、当然そのルーターからの情報は得られない。
- mtrやtracerouteにてICMP/TCP/UDPのいずれのプロトコルを使ったとしても、経路途中のルーターからの返りのパケットはICMP Time Exceeded(Type 11)になる。よって、iptablesでいうと、
-A INPUT -p icmp --icmp-type 11 -j ACCEPT
相当の設定がコマンド送信元に存在しないとICMP Time Exceeded(Type 11)を受け取れない。 - 最終到達先から送信元が受信するパケットは、ICMP Time Exceeded(Type 11)ではない。それぞれのプロトコル使用時に応じて、ICMP echo reply(Type 0)およびTCP/UDPで指定したそれぞれのポートからの応答になる。
- 各コマンドにて出力される時間は、このRTT(Round Trip Trime)に他ならない。つまり、送信元からパケットを投げてICMP Time Exceeded(Type 11)が返って来るまでの時間を指す。
- 「あれ?送信元ではICMPによる外部からのアクセスは全部遮断している筈なのにちゃんとmtrとかtracerouteは実行できているよ?」という人は、おそらく定番のように入れている
-A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
のおかげの可能性が高い。iptablesのmanには以下のように記載されている。- ESTABLISHED: meaning that the packet is associated with a connection which has seen packets in both directions
- RELATED: meaning that the packet is starting a new connection, but is associated with an existing connection, such as an FTP data transfer, or an ICMP error.
- Firewallなどが原因で、ある中継ルーターや最終宛先から先の応答を全く受け取れない場合は、送信元端末からTTLを1つずつ増やして試行しても全部NGとなる結果になってしまうので、出力結果にアスタリスク(*)がTTL最大試行値まで続くことになる。
- mtrやtracerouteにてICMP/TCP/UDPのいずれのプロトコルを使ったとしても、経路途中のルーターからの返りのパケットはICMP Time Exceeded(Type 11)になる。よって、iptablesでいうと、
#4. 接続できない・接続が不安定!?実例を通して見てみよう。
インターネット上の2拠点間における経路はよく変更されるだけでなく、行きの経路(往路)と帰りの経路(復路)が異なることも多く存在します。ネットワーク通信問題は、往路・復路の双方に問題が存在する可能性があるため、SoftLayerにネットワーク通信問題のチケットを起票した際には、サポートにEnd to endでの双方向のmtr(bidirectional mtr)を求められます。数回レベルだとたまたまドロップしていたという可能性もあるので、十分な数の施行を鑑みると、まずは-c 100
ぐらいで取得するのが推奨です。
mtrのオプション方法例
- -r: report形式
- -w: ホスト名を短縮せずに表示
- -n: ホスト名ではなくIPアドレスのみ表示(DNS lookupによるホスト名出力が意味がない環境では推奨。特にインターネットを経由しない環境ではホスト名による名前解決は意味がないのだから、多くのケースで付ける方が良い)
- -b: ホスト名とIPアドレスの両方を表示
- -c: pingの転送数。デフォルトは10回。SoftLayerにレポートする時には100回ぐらいにしておくことを推奨。
- -T -P 80: -TでTCPを-Pでport番号を指定(この例だとport番号80を指定)。
#サーバーA(161.202.xx.xx) -> サーバーB(169.47.xx.xx)へのmtrレポート
#今回はインターネット接続なのでホスト名解決ができることを期待して-nの代わりに-bを利用。
# mtr -rwb -c 100 169.47.xx.xx
Start: Tue Feb 14 02:03:30 2017
HOST: powertokyo.softlayer.com Loss% Snt Last Avg Best Wrst StDev
1.|-- xx.xx.xxxx.ip4.static.sl-reverse.com (161.202.xx.xx) 0.0% 100 0.7 0.7 0.5 3.7 0.3
2.|-- ae11.dar02.tok02.networklayer.com (161.202.118.132) 0.0% 100 0.3 0.5 0.3 7.8 0.9
3.|-- ae9.bbr01.eq01.tok01.networklayer.com (50.97.19.134) 0.0% 100 0.8 0.9 0.7 4.6 0.4
4.|-- ae2.bbr02.eq01.sjc02.networklayer.com (50.97.18.160) 0.0% 100 99.3 97.1 96.2 100.4 0.7
5.|-- ae6.cbs02.eq01.sjc02.networklayer.com (50.97.17.78) 8.0% 100 98.0 98.4 95.7 100.9 0.9
6.|-- ae0.cbs02.cs01.lax01.networklayer.com (50.97.17.86) 2.0% 100 103.6 104.0 102.5 111.9 1.1
7.|-- ae7.cbs01.cs01.lax01.networklayer.com (50.97.17.60) 44.0% 100 103.0 104.3 103.0 113.0 1.4
8.|-- ae0.cbs01.eq01.dal03.networklayer.com (50.97.17.81) 64.0% 100 132.2 132.1 131.1 134.1 0.5
9.|-- ae0.dar01.dal10.networklayer.com (50.97.17.9) 0.0% 100 130.1 131.3 129.9 154.4 2.9
10.|-- ae0.ppr04.dal10.networklayer.com (169.46.118.135) 0.0% 100 134.0 134.3 133.0 136.1 0.6
11.|-- po4.fcr01b.dal10.networklayer.com (169.46.118.171) 0.0% 100 132.5 133.3 132.4 137.9 0.8
12.|-- xx.xx.xxxx.ip4.static.sl-reverse.com (169.47.xx.xx) 0.0% 100 130.4 130.8 130.1 132.4 0.5
#サーバーB(169.47.xx.xx) -> サーバーA(161.202.xx.xx)へのmtrレポート
# mtr -rwb -c 100 161.202.xx.xx
Start: Tue Feb 14 02:08:07 2017
HOST: powerdallas.softlayer.com Loss% Snt Last Avg Best Wrst StDev
1.|-- ??? 100.0 100 0.0 0.0 0.0 0.0 0.0
2.|-- ae103.ppr02.dal10.networklayer.com (169.46.118.158) 0.0% 100 2.5 2.2 1.5 2.9 0.0
3.|-- ae3.dar01.dal10.networklayer.com (169.46.118.130) 0.0% 100 0.5 1.2 0.4 26.0 3.4
4.|-- ae10.cbs01.eq01.dal03.networklayer.com (50.97.17.8) 76.0% 100 3.0 3.1 2.2 6.8 0.8
5.|-- ae0.cbs01.cs01.lax01.networklayer.com (50.97.17.80) 21.0% 100 31.8 31.5 30.4 48.5 1.9
6.|-- ae7.cbs02.cs01.lax01.networklayer.com (50.97.17.61) 21.0% 100 31.4 31.7 30.6 51.7 3.0
7.|-- ae0.cbs02.eq01.sjc02.networklayer.com (50.97.17.87) 14.0% 100 38.5 38.4 37.5 40.0 0.2
8.|-- ae24.bbr02.eq01.sjc02.networklayer.com (50.97.17.79) 0.0% 100 53.4 39.3 35.9 121.6 11.0
9.|-- ae0.bbr01.eq01.tok01.networklayer.com (50.97.18.161) 0.0% 100 131.6 131.8 131.4 135.0 0.4
10.|-- ae5.dar01.tok02.networklayer.com (50.97.19.133) 0.0% 100 132.8 132.0 131.8 137.1 0.5
11.|-- po1.fcr01a.tok02.networklayer.com (161.202.118.131) 0.0% 100 132.0 130.8 129.9 132.3 0.7
12.|-- xx.xx.xxxx.ip4.static.sl-reverse.com (161.202.xx.xx) 0.0% 100 130.3 130.3 129.9 130.7 0.0
Loss%: パケットの消失率(返ってこなかった率)
Snt: パケットを送信した回数
Last/Avg/Best/Wrst: 最新/平均/最良/最悪のRTT(Round-Trip Time:パケットがコマンド発行元端末から行って返ってくる時間)。単位はms。
StDev: 標準偏差。平均値周辺に値が偏っているかどうかの指標。値が大きいほどバラツキが多い。
- 上記の解釈
- DAR(Datacenter Aggregation Router)やFCR(Frontend Customer Router)などの意味を知りたければ、SoftLayerのNW構成図としては、http://www.softlayer.com/NETWORK やhttp://knowledgelayer.softlayer.com/procedure/direct-link-connectivity-options に添付されているpdfファイルが参考になる。もしこうした用語に慣れていなければ、この構成図を一度よく読んでみるとよい。(注:CBSはCore Backbone Switch、PPRはPod to Pod Routerらしい。)
- mtrレポートは、行きの経路(往路)を表示しているが帰りの経路(復路)は表示してしない。行きの経路と帰りの経路は全く異なる可能性もあるため、双方向のmtrレポートは重要。
-
ICMPパケットの通信量をわざと制限(ICMP rate limiting)しているプロバイダーもいるため、一見パケットロスが発生していたり、大きな遅延が発生しているように見えても次のhopでLoss%が0であったりLatencyが改善されていれば問題なしとみなしてよい。
- 例えば上記のmtrの例において、途中で一見パケットロスが発生しているように見える(lax01やdal03の辺り)が、より後段でICMPパケットを100回送って全部到達できている(Loss%=0)ので問題なし。
- 最初のhopはFCRだが、ICMPに反応してくれるDCとそうでないDCがあるみたい。TOK02では反応してくれているみたいだが、DAL10では反応してくれないみたい。どちらの場合であっても、その後段のhopでパケットロスしていないので、ネットワーク的には問題なし。
- Latencyの時間が増えた場所は、一般的にはそこで遠くにパケットが転送されたと考えると自然。この例だと、tok01とsjc02の間(100msec程度)や、lax01とdal03(30msec程度)の間はそれなりに離れていることが予想される。
- 途中経路のIPアドレスの所有組織は誰かを調べるためには、
whoisコマンド
が有効。
# whois 161.202.118.132
(途中略)
organisation: ORG-STI12-RIPE
org-name: SoftLayer Technologies, Inc.
org-type: LIR
address: 14001 N.Dallas Parkway,Suite M100
address: 75240
address: Dallas TX
address: UNITED STATES
(途中略)
#5. Bluemix Infrastructure(SoftLayer)でのあるある問題の事例
##5.1 SoftLayer所有のネットワーク(BBRやDAR)にパケットが全く到達できない
- SoftLayerにDDOS防御でサーバーに割り振られている該当IPへの接続がフィルタリングされていた(DDOSは不特定多数からの攻撃なので、接続先で絞る)。
- SoftLayerにTicketを起票して、NOC(Network Operation Center)から確認を得る。
- SoftLayerにSPAM防御で特定のIPアドレスレンジからの接続がフィルタリングされていた(接続元を絞る)。
- SoftLayerにTicketを起票して、NOC(Network Operation Center)から確認を得る。
- 世の中的に該当IPがSPAMとして認定されているかどうかは、spamhausの情報が参考になる。https://www.spamhaus.org/lookup/
##5.2 SoftLayerからパケットが全く届かない
- SoftLayerは原則Outboundをフィルタリングしませんが、唯一の例外としてOP25B(Outbound Port 25 Blocking)対策として25番ポートへのOutbound通信はブロックしています。メールを送信する際には、submission portとして25番以外を利用しているSendGridなどのサービスを利用しましょう。
##5.3 サーバーまでパケットが全く到達できない
- Firewallでフィルタリングされていた。
- Linuxであれば
iptables -L -v -n
などでフィルタリング情報を確認可能。 - nmapなどで外部からポートスキャンをかけてポートの開閉確認可能。
- Linuxであれば
- OS付属のFirewallでフィルタリングされていた
- WindowsでMcAfee VirusScanを導入している場合には、Access Protection機能によって必要なポートがブロックされていることがある。
- Private VLAN間の通信や同一Private VLAN内でも異なるサブネット間の通信は、VLAN Spanning=ONにするかVRFの有効化が必要。
##5.4 届く時もあるが時間帯によっては届かない時もある場合の例
- SoftLayerのBackbone networkのケーブルが切れており、迂回経路を通っていた
- 既知の障害情報をチェックする
- SoftLayer内のVLAN/経路情報が正しくなかった(表示上は正しくても、実機で片系にしか正しく構成されていない場合は、repushが必要)
- SoftLayerにTicketを起票して、VLAN構成をrepushしてもらう
- DDoS攻撃を受けて、kernel内部の処理が追いつかずパケットが落ちてしまっている。
- DDoS攻撃を受けていてもパケットが小さいのでCPU使用率はそれほど上昇しないことが多い。また、DDoSを受けている間は、もし処理が追いついていなければ、tcpdumpや/var/log/messageも、全てのパケットを拾えていない可能性もあるし、記録されている時刻にもズレが生じている可能性がある。
- zone firewallはdeny判断までに要するルールが多くなり、outboundまでチェックするので、kernel内部の処理が重くなり本事象が起こりやすい。可能であればinterfaceベースのfirewallに変更することが推奨。ただし、vRouter 5600ではiptablesベースではないので、事象が改善している可能性はある。
- Vyattaの
table-size
,hash-size
,expect-table-size
のデフォルト値はまだ余裕があるのでより大きな値(まずは倍にしてみましょう)に変更することで、(DDoSまで含めて)より多くのコネクションを受け止められる可能性がある。
#6. より細部の切り分けのためには
該当サーバーにて
- パケットが本当に届いているのか?
- どういうパケットが届いているのか?
- どういうパケットを送信しているのか?
を確認するためには、実際にパケットをキャプチャーするのが一番です。Linuxではtcpdumpなどでパケットキャプチャーを取得すると良いでしょう。
tcpdumpでよく使うオプション
- -i: 指定しないと(eth0/eth1/eth2/eth3と4つあっても)eth0のような一番若い番号のインターフェースしかモニタリングしない。パケットの挙動を疑う場合はany指定をする
- -nn: IPアドレス/ポート番号で表示
- host: 該当のIPを含むパケットのみを表示
- port: 該当のポート番号のみを表示
- -s: キャプチャーするサイズを指定。-s0はすべて。
- -A: パケットの中身をASCII表示。HTTPアクセスの時に重宝することがある。
# tcpdump -i any -nn icmp
# tcpdump -i any -nn host xx.xx.xx.xx
# tcpdump -i eth1 -nn net 183.79.0.0/16
#以下だとTCPもUDPもどちらのポートも確認可能
# tcpdump -i eth0 -nn 'icmp or port 80 or port 443'
#パケットの中身を省略なしでASCIIで表示
# tcpdump -i any -nn -s0 -A port 80