[NetBSD]

ルーター、クラッシュ / 2006-02-14 (火)

ルーターに使ってた NetBSD/i386 の HDD が吹っ飛びまして、半日ぐらい全て不通になってました。

気づいたのは夕方で、手持ちの 10G HDD にディスク交換、NetBSD 3.0 をインストールして以前の設定のバックアップを引っ張り出し、とりあえず復旧をしました。最新のconfig ファイルのバックアップを忘れてたので GENERIC カーネルなのが気に入らないけど、これはおいおいビルドし直しますか。バックアップがあってもどのみち、以前のカーネルは 1.6 で、今回入れたのは 3.0 なので色々手直しする羽目になってでしょうけど。

そもそも、1.6 でピン留めされてたのは 2.0 を使うと ipnat での MSS clump がうまくいかなかったり、ipfilter が挙動不審なふるまいをしたりしてくれたせいだったりします。そういう意味では、何も考えず 3.0 いれて素直に動いてくれたのは、結果的に OS のアップグレードが出来たのは怪我の功名というか不幸中の幸いです。

3.0 はいまのところいい感じなのですが、NetBSD の、特に -release のクオリティには色々疑念を持ってたのも事実。てか、-current あらずんば NetBSD あらず の風潮がキツくて先が思いやられます。先を考えるなら FreeBSD に移行する方がいいんだろう。5 は酷い出来でしたが、6 はかなり期待できそうなので。しかし、2.x で FreeBSD を捨てて NetBSD に移行した身としては今更戻って色々覚え直すのも辛いのよね。

この記事のリンク元 | 1 | 1 | 1 |

この記事のリンク用URL&トラックバックURL : http://x.nest.jp/NetBSD/060214_0630.htm

...

[NetBSD]

宴会 / 2004-12-21 (火)

去年もそうだったが、冬になるとどうしてもマレーチャンのスチームボートという鍋が食いたくなるのだ。という訳で、去年に続きことしもはた迷惑に知己にメールを出しまくって勝手に忘年会を開催する。その場でも言われたのだが、やっぱり FreeBSD は楽だって事。pf + mpd がとっても楽だそうで、なんか話を聞いているだけで NetBSD を使い続ける気力がどんどん萎えてくる。pf いいなー。

まぁ、それでも SMP にちょっと期待なので 2.1 までは我慢して待ってみるか?

この記事のリンク元 | 1 | 1 |

この記事のリンク用URL&トラックバックURL : http://x.nest.jp/NetBSD/041221_0029.htm

...

[NetBSD]

(続) MTU blackhole 問題 / 2004-12-16 (木)

MTU blackhole 問題 の続き

一時期 代替機として NetBSD2.0RC5 を使ってましたが、こいつだと何故か ipnat を有効にすると TCPのセッションが切られてしまうという問題があり、だましだまし使いつつ、以前のNetBSD1.6.2 をいれたマシンに戻した訳です。

ちゃんと動いているから安心してたら、知己からうちで預かってる Web サイトのページが見れないと悲鳴が上がりまして。

で、調査がこれ。DMZ 側のインターフェイス ex0 で tcpdump で採取しました。

20:16:46.353879 xxx.xxx.xxx.xx.35252 > sepia.front.nest.or.jp.www: S 4062547751:4062547751(0) win 5840 <mss 1460,sackOK,timestamp 2403195649 0,nop,wscale 0> (DF)
20:16:46.354995 sepia.front.nest.or.jp.www > xxx.xxx.xxx.xx.35252: S 2616774323:2616774323(0) ack 4062547752 win 24616 <nop,nop,timestamp 114090451 2403195649,nop,wscale 0,nop,nop,sackOK,mss 1460>

問題は一つめのパケット。こいつは pppoe0 から入ってきて DMZ 側の ex0 から出力される訳ですが、mss が 1460 のままである。

戻りも 1460 になってるけど、これは pppoe0 を通る時点で mssclamp されて ipnat.conf で指定した mss である事の 1360 にされます。

そして、ちと設定ミスでこの sepia というマシン (Solaris8 で動いてます)は MTU Path Discovery が off になってました。

このため、sepia -> xxx.xxx.xxx.xx の経路で MTU1460 のパケットが飛び、NetBSD1.6.2 なルータが悲鳴を上げて(ICMPで MTU サイズの変更をお願いして)、通常ならそれを受けて MTU を 1360 に落とすところが MTU Path Discovery が off になっているせいかこれを受け取らず、そして blackhole が発生したという訳です。

( なお、この悲鳴を上げて mss を下げる効果が sysctl でせっていする mss_ifmtu で発生すると、いう事みたいです。 )

とりあえず対処したのですが、問題は 「MTU path blackhole?(4)」で述べたパッチを当てたカーネルであるということです。このため、pppoe0 から出て行くパケットだけではなく、入ってくるSYNパケットの mss も mssclamp するはずなのですが、してくれておりません。

ここまでが昨日の夜の話。

今日、さっきの昼休みに追試をしたところ

「DMZ のマシン -> お外のマシン 」という通信の場合、pppoe0 を通って出て行く場合、それから相手から帰ってきて pppoe0 から入ってくる場合双方とも mssclamp がかかって mss が1360 になってました。これは (4) の結果と合致します。

しかし、「お外のマシン -> DMZ のマシン」という通信の場合は、外から pppoe0 を通って入っていくときに mssclamp がなされません。これは上の問題と合致します。

つまり、私が直したコードは不完全で、内部から外部への通信の場合にしか clamp がされてないみたいです。

じゃあ外部から発信された場合も直せばいいじゃん、と思ったのですが...、うう、ip_nat.c のソース見たってわっかんねーよ(涙)

素養がない状態でのコード追っかけには限度があるみたいです Orz...。

なお、通常の map に加えて


map ex0 0.0.0.0/0 -> 0/0 mssclamp 1360

という設定を追加すれば「ex0 を通るときに mssclamp がかかって SYNパケット内の mss が1360 に書き換えられる」のですが...美しくねぇので却下気味(--;;;

(なお、bimap は mssclamp オプションを受け付けない模様)

なので、あと考えられるのは、1.6.2 標準の ipfilter (2.4.29 ベース)を使うのではなく3.4.35 ないしは 4.1.3 にそこだけアップデートするというのが一つ、もう一つは NetBSD2.0 (release)を試してみる、って事ですか。

何が嫌って、試すたびにサービス落とす羽目になること、かな。

この記事のリンク元 | 5 |

この記事のリンク用URL&トラックバックURL : http://x.nest.jp/NetBSD/041216_1716.htm

...

[NetBSD]

MTU blackhole 問題 / 2004-12-16 (木)

10月頃の話。

うちでは NetBSD1.6.2 を積んだ PCにオンボード含めネットワークインターフェイスを三つつけてルータにしており、PPPoE で FletsADSL に接続、内部マシンへの NA(P)Tを提供しておりました。

ところが、あるマシンからだけ何故かWebのフォームで大容量のテキストを送ろうとすると通信に失敗するという問題がありました。以下はその調査結果です。

結局、よーわからんので週末持ち越し。会社から PowerBook を持って帰ってきて比較検証をやってみる。

対象は mixi の日記の書き込み。

これが正常な PowerBook

21:43:18.058803 IP dhcp09.core.nest.or.jp.49307 > sumbawa.mixi.jp.http: S 3598307457:3598307457(0) win 65535 <mss 1460,nop,wscale 0,nop,nop,timestamp 4277980427 0> 
21:43:18.075370 IP sumbawa.mixi.jp.http > dhcp09.core.nest.or.jp.49307: S 1217852595:1217852595(0) ack 3598307458 win 5792 <mss 1460,nop,nop,timestamp 758981033 4277980427,nop,wscale 0> 
21:43:18.075523 IP dhcp09.core.nest.or.jp.49307 > sumbawa.mixi.jp.http: . ack 1 win 65535 <nop,nop,timestamp 4277980427 758981033> 
21:43:18.075790 IP dhcp09.core.nest.or.jp.49307 > sumbawa.mixi.jp.http: . 1:1449(1448) ack 1 win 65535 <nop,nop,timestamp 4277980427 758981033> 
21:43:18.092521 IP puresnow.core.nest.or.jp > dhcp09.core.nest.or.jp: icmp 36: sumbawa.mixi.jp unreachable - need to frag (mtu 1400) 
21:43:18.092653 IP dhcp09.core.nest.or.jp.49307 > sumbawa.mixi.jp.http: . 1:1349(1348) ack 1 win 65535 <nop,nop,timestamp 4277980427 758981033> 
3way handshake の時の MSSに注目。PowerBook が 1460 を送るのはともかくとして帰ってきたパケットも 1460 とほざいてやがる。で、安心して1446 バイト突っ込んで送ったら ICMP で「MTUは1400までにしてくれ」と泣きをいれて、でもって 1348 バイトにまけてやらぁと流れていく訳です。

で、問題の方。

sumbawa.mixi.jp.http: S 139593446:139593446(0) win 65535 <mss 1460,nop,wscale 0,nop,nop,timestamp 761340946 0> 
21:46:51.442298 IP sumbawa.mixi.jp.http > dhcp03.core.nest.or.jp.49217: S 1438025936:1438025936(0) ack 139593447 win 5792 <mss 1460,nop,nop,timestamp 759193408 761340946,nop,wscale 0> 
21:46:51.442483 IP dhcp03.core.nest.or.jp.49217 > sumbawa.mixi.jp.http: . ack 1 win 65535 <nop,nop,timestamp 761340946 759193408> 
(中略) 
21:46:51.464313 IP dhcp03.core.nest.or.jp.49217 > sumbawa.mixi.jp.http: . 668:2116(1448) ack 1 win 65535 <nop,nop,timestamp 761340946 759193428> 
21:46:51.464417 IP dhcp03.core.nest.or.jp.49217 > sumbawa.mixi.jp.http: . 2116:3564(1448) ack 1 win 65535 <nop,nop,timestamp 761340946 759193428> 
21:46:51.466627 IP puresnow.core.nest.or.jp > dhcp03.core.nest.or.jp: icmp 36: sumbawa.mixi.jp unreachable - need to frag (mtu 1400) 
21:46:51.466917 IP puresnow.core.nest.or.jp > dhcp03.core.nest.or.jp: icmp 36: sumbawa.mixi.jp unreachable - need to frag (mtu 1400) 
21:46:52.922657 IP dhcp03.core.nest.or.jp.49217 > sumbawa.mixi.jp.http: . 668:2116(1448) ack 1 win 65535 <nop,nop,timestamp 761340948 759193428> 

最初の 3 way handshake はまぁいいとしよう、 問題は次だ。1448バイト詰めたところでやっぱり泣きが入るが、こいつ泣いてきてもMSSを直さない!

だからここで通信が途絶え、MTU path black hole っぽい挙動になるのでした。

まぁ、後者の ICMP を聞かないのはバグだろう(なおこいつ、ファイアーウォールは切ってます)。これは報告するとして、もう一つ気にかかるのは puresnow( NetBSD1.6.2 )が MSSが1460 なやりとりを看過している事だ。ipnat で mssclamp しているのだからここで小さくすべきじゃないのか?

で、実はそこら辺、今日の昼休みに食後の気分転換でソースを読んでたのだ。対象は NetBSD1.6.2 の ip_nat.c と ipfilter 4.3.35 のソース。なお、NetBSD1.6.2 の ipfilter は 3.4.29ベースとあるがipfilterでは mssclamp は3.4.30 から実装となっている事から分かるように、ipfilter 本体で未実装の技術が先行投入されている。(ipfilter の作者は NetBSD の comitter らしいので、まぁそういう事なんだろう)

そして、この二つをざーっとみくらべて気がついて、以下のパッチを当ててカーネルを再構築、で、治りましたとさ。

puresnow# diff -rcN /sys/netinet/ip_nat.c.orig /sys/netinet/ip_nat.c 
*** /sys/netinet/ip_nat.c.orig Wed Dec 31 06:21:18 2003 
--- /sys/netinet/ip_nat.c Fri Oct 1 21:49:18 2004 
*************** 
*** 2804,2809 **** 
--- 2803,2817 ---- 
*/ 
if (nat->nat_age == fr_tcpclosed) 
nat->nat_age = fr_tcplastack; 
+ #if 1 /* added shiro */ 
+ /* 
+ * Do a MSS CLAMPING on a SYN packet, 
+ * only deal IPv4 for now. 
+ */ 
+ if (nat->nat_mssclamp && 
+ (tcp->th_flags & TH_SYN) != 0) 
+ tcp_mss_clamp(tcp, nat->nat_mssclamp, fin, csump); 
+ #endif 
MUTEX_EXIT(&nat->nat_lock); 
} else if (fin->fin_p == IPPROTO_UDP) { 
udphdr_t *udp = (udphdr_t *)tcp; 

断片だけだと分からんだろうからざっと説明すると、tcp_mss_clamp() がパケット内部の MSS がmssclamp で指定した値よりも大きい場合にその値に fix する関数。で、この修正は

ip_natin() 関数に追加している。ソースのコメントからだすと

* ip_natout() - changes ip_src and if required, sport

* - creates a new mapping, if required.

* ip_natin() - changes ip_dst and if required, dport

*

とある。で、対になる外部から内部へのパケットをやりとりする ip_natout() ではこの tcp_mss_clamp() が記載されているにもかかわらず内部から外部へのパケットを処理する ip_natin() ではそれが記載されてなかったため追加したという訳。これで外部からの返事も「clamp」されて、mssclamp で指定された値以上が出ないようになる。

え、なんでこれでうまくいくかって?

これは pppoe0 でとった 3 way handshake の

22:53:30.600441 PPPoE [ses 0x4a58] 61.199.200.64.10104 > sumbawa.mixi.jp.www: S 3935919247:3935919247(0) win 65535 <mss 1360,nop,wscale 0,nop,nop,timestamp 761348944 0> (DF) 
22:53:30.613527 PPPoE [ses 0x4a58] sumbawa.mixi.jp.www > 61.199.200.64.10104: S 1374318826:1374318826(0) ack 3935919248 win 5792 <mss 1460,nop,nop,timestamp 763194281 761348944,nop,wscale 0> (DF) 
22:53:30.617697 PPPoE [ses 0x4a58] 61.199.200.64.10104 > sumbawa.mixi.jp.www: . ack 1 win 65535 <nop,nop,timestamp 761348944 763194281> (DF) 

ここではお互いのmss を通知しているのだが、中から外に行く時は確かに「clamp」されて 1360 になってるけど、帰りは 1460 が通ってしまう。中のマシンは外部にパケットが流れる時に「clamp」されたと分かる訳がないので 1460 を信じちゃう訳だ。

通常、これは実際にパケットを流したところで ICMPで泣きが入るのでけりがつくのだが、泣きを無視するOSの場合、ここで信じちゃうのが致命傷になる訳だ。

なお、この修正は ipfilter 3.4.35 でははいっている。つまりこの問題を ipfilter の作者はしっているという訳だ。NetBSD 2.0 では ipfilter は 4.x ベースになるそうだし、NetBSD1.6.3 がでるとしたらこの修正は入るだろうから、NetBSD.org には報告しなくていいかなっと思っているけど...、しかし、ぐぐっても同じ問題を誰も報告してないところを見ると、NetBSD1.6.2 なんて誰も使ってないのかも知れない。ううぅ、-current に移行すべきなのかなぁ、私も(;______;)

まぁ、これにてこの問題は解決、っと。

この記事のリンク用URL&トラックバックURL : http://x.nest.jp/NetBSD/041216_1702.htm

...