ある日のこと
Aさん「んー?切り出したサーバがpingすら上手く通らない。。。Firewall絡みかな?」
自分「telnetでつなげて対向先サーバでtcpdumpしてパケットは来てる?」
Aさん「来ていますね」
自分「iptablesは?」
Aさん「落としてます」
自分「んー・・・?デフォゲも設定&疎通出来ているされているしな・・・はて・・・」
先日こんなことがあったのですが、
わかると単純なんですがハマってしまって解決するのに30分ほどかかってしまいました。
恐らくわかる方はすぐわかってしまうかと思います。
自戒をこめて今回書き記しておこうと思います。
状況を整理すると以下の通り。
接続イメージ
Xサーバ(データ送信元) -> 🔥Firewall🔥 -> Zサーバ(データ送信先)
聞き取り調査状況
- XとZサーバはNWセグメントは別
- XからZサーバへpingを投げても応答を返さない。また、その逆のZからXサーバも応答が返ってこない。
- Xサーバからtelnet接続するとtcpdumpで見る限りパケットはZサーバに問題なく来ている
- ZサーバでiptablesはOFFにしている
- X及びZサーバのデフォルトゲートウェイ(以下DG)は適切に設定されている。また、DGに対してpingは返ってくる
- Zサーバでtsharkでパケットの中身を眺めてみても異常はなさそう
その後...
自分「んー・・・iptablesは切ってるし、そもそもパケットフィルタが原因ならtcpdump上は返すように見えると思うんだよなぁ」
自分「そもそも自分のパケットと認識していないような挙動だし・・・」
Xサーバ以外のNWからpingを投げてみたら応答が返ってきました。
ここまでを振り返ると、どうやらFirewallやpingそのものがおかしいわけではなさそうでした。
ふと何気なくルーティングを見ていたら、
自分「ん?XサーバのNWアドレスとバッティングしたNWアドレスがZサーバ内のブリッジに向けてある・・・なんだこりゃ」
ex. XサーバのNWアドレス(192.168.0.0/24)、Zサーバ内のルーティング(192.168.0.0/16)のようなイメージ
ということで、
応答を返さない原因はルーティングテーブルが原因でした。
後にAさんに事情を聞いてみたところ、
どうやらコンテナを設定するのに以前使っていたのが残ったままになってしまっていたようでした。
既に使っていなかったようで、削除してもらったら無事に疎通出来るようになりました。
ここまでは単なるルーティングミスのおはなしですが、
ふと思いました。
時間かけすぎてしまった、と。
ここからは、どうしたらもっと早く気がつけたのか振り返ってみようと思います。
振り返り
- DGの設定確認したときに、ルーティングテーブルもきちんと見るべきだった
- FWやiptables等のパケットフィルタは調査当初から問題なさそうという認識はあったが、いまいち断言しきれずにtsharkでパケットの中身を見ることを優先しすぎてしまった
- パケットが着信しているにもかかわらず自分のものと認識していないのはアプリレイヤの設定に何かあるのかと壮大な勘違いをしていた
正直1を徹底するにつきてしまうのですが、
3も個人的に結構な反省点だと思っています。
もっとパケットの気持ちになって
デバイス -> Kernel -> ユーザランドでどういう風にデータが流れていくのか、
そもそも、パケットフィルタとルーティングの処理される位置関係がどうだったのか
再認識してみようとおもいます。
Linux Kernel Networkingについて
www.slideshare.net
こちらのスライドのp.40を見るとデバイスに着信してから上位レイヤに渡されるまでの概要が記載されています。
せっかくですので、linux-3.10.105のip_input.cの中身を追いかけて書いていたのですが、
別のブログで既に整理して記載がありましたのでここではご紹介に留めておこうと思います。
ip_input.cを見てからブログを拝見するとスッキリしました。
その他参考
- FrontPage - Linuxカーネルメモ
- Linux Kernel 2.6系ですが、フィルタのフック処理概要など参考にさせていただきました。