gm300の日記: keepaliveの呪い/「サーバ/インフラを支える技術」を読む。 10
日記 by
gm300
「サーバ/インフラを支える技術」を読んでから ssh でゴニョゴニョしていると、Keepalive に呪われているんじゃないかと思い付く。
keepalive っていろいろあるじゃん。だからその日によって気分が違うんだ。ssh とか、socket の世界で keepalive といったら昔の世界ではheartbeat とか言っていた、生きているよ、接続しているよ という信号だ。接続が継続していることを示すためにときどきなにか信号を送る。
http な世界で keepalive と言ったら、ひとつの接続セッションの中で、複数のトランザクションをこなすことだ。って、用語は正しいのかな?一度 socket を open してそのまま複数回のhttp request を実行する。
数ヵ月前は ssh のほうでそんな便利なフラグがあるとは知らず、適当なことをやっていた。もっと昔はせっかくssh でトンネル工事を行ってもしらないうちにトンネルが消滅していて、めんどうだった。今は、-o serveraliveinterval=400 で処理。
今度は httpd だ。browser は keepalive しているが、httpd のほうは keepalive していない。そのため proxy では片方ずつ対応を変える必要がある。
さらに httpd のほうは、chunk の最後で 0 を返さずに close している。proxy はそんなことを気にせずに browser 方向は keepalive しているので、browser は chunk の次を待ちつづける。
というのが現状分析。じゃどうする?
keepalive っていろいろあるじゃん。だからその日によって気分が違うんだ。ssh とか、socket の世界で keepalive といったら昔の世界ではheartbeat とか言っていた、生きているよ、接続しているよ という信号だ。接続が継続していることを示すためにときどきなにか信号を送る。
http な世界で keepalive と言ったら、ひとつの接続セッションの中で、複数のトランザクションをこなすことだ。って、用語は正しいのかな?一度 socket を open してそのまま複数回のhttp request を実行する。
数ヵ月前は ssh のほうでそんな便利なフラグがあるとは知らず、適当なことをやっていた。もっと昔はせっかくssh でトンネル工事を行ってもしらないうちにトンネルが消滅していて、めんどうだった。今は、-o serveraliveinterval=400 で処理。
今度は httpd だ。browser は keepalive しているが、httpd のほうは keepalive していない。そのため proxy では片方ずつ対応を変える必要がある。
さらに httpd のほうは、chunk の最後で 0 を返さずに close している。proxy はそんなことを気にせずに browser 方向は keepalive しているので、browser は chunk の次を待ちつづける。
というのが現状分析。じゃどうする?
sshのkeepaliveとTCPのkeepaliveが違ったりしてて紛らわしいんだ。これが。 (スコア:1)
Re:sshのkeepaliveとTCPのkeepaliveが違ったりしてて紛らわしいんだ。これが。 (スコア:1)
違う。
sshには TCPKeepAlive と ServerAliveCount/ServerAliveInterval の2つがある。
TCPKeepAliveはコネクションが生きているかどうか「確認するかどうか」を決める。つまり TCPの keepaliveを有効にするかどうか、がこれで決まる。大抵の場合は on でも off でもよい。
TCPKeepAliveをonにすると「reachability」が判る。つまり「サーバがTCP的に生きている」&「あいだの経路が生きている」ことがわかる。が、WANの場合「あいだの経路」は結構切れる(数分のオーダーで)。TCPKeepAliveを使うと、この「経路の不安定さ」に振り回される。だからTCPKeepAliveを嫌がる人は(特に大陸横断でsshしている人なんかは)多い。
TCPKeepAliveは欲しくないが、でもサーバが死んだかどうかは確認したい、と言う人たちのために ServerAliveCount と ServerAliveInterval の変数がある。これも keepalive と同じようなことをするのだが、AliveIntervalとAliveCountを自由に設定できるので、この2つを大きめの値に設定する事で「経路の一時的な切断」に対処できる。
.
もう一つあるのは、TCPkeepaliveは「のっとれる」と言うこと。つまり、第3者が勝手に TCPkeepaliveパケットを投げつけることができる。この部分は暗号化対象外だから。
クライアントからの「セッションクローズパケット」をサーバに到着しないように横取りし、サーバに TCPkeepaliveを投げつけ続けることによって、サーバにsessionを閉じさせない…徐々にsessionが溜まっていって最後にはサーバが新しいコネクションに対応できなくなる…というDoS攻撃がある。
ServerAlive* は暗号化されたパケットの中で ack をやり取りするので、このDoS攻撃がかけられない。
.
ただServerAlive*は重たい。なのでLANでは TCPKeepAlive が、WANでは ServerAlive* を設定するのがお勧め、になる。
fjの教祖様
ServerAliveInterval って重いすか? (スコア:1)
単に ssh 的な nop みたいなのを一分に一回程度投げつけるだけだから
たいしたことないだろ,みたいに考えて(というか深く考えずに)
いつも ServerAliveInterval 指定してたんですが,重いすか?
まぁ切れたとしても screen してるから大したダメージじゃないんですが.
屍体メモ [windy.cx]
Re: ServerAliveInterval って重いすか? (スコア:1)
1) nop 相当のものを
2) 暗号化してから
送る手間分です。TCPkeepaliveは文字通り何も考えずにパケット送るだけですから。
# あくまでも相対的に、って事で。
fjの教祖様
そんな瑣末な違いで「違う」なんて言われてもなー。 (スコア:1)
Re:そんな瑣末な違いで「違う」なんて言われてもなー。 (スコア:1)
生きていることを知らせ続ける。KeepAliveパケットを送る。
確かに、普通にはどっちでも同じようなものかも。っていうかオイラは、同じだと思っていたわけだし。
Re:そんな瑣末な違いで「違う」なんて言われてもなー。 (スコア:1)
fjの教祖様
Re:そんな瑣末な違いで「違う」なんて言われてもなー。 (スコア:1)
別の表現をしよう。keepAliveの偽装にDoS攻撃以上の意味があるのか?そしてDoS攻撃は「本質」か?
もう少し掘り下げるとだ、the netにおいては「全く通信できない」か「完全に通信できる」かのどちらか以外にならない事だけが本質であり、DoS攻撃耐性みたいなものは程度や性能の話であって本質にはなり得ないんだよ。通信路を信用できないというのはそういう事。
Re:そんな瑣末な違いで「違う」なんて言われてもなー。 (スコア:1)
君はsshが何故必要なのか、全く理解していない。それだけのことだ。
fjの教祖様
Re:そんな瑣末な違いで「違う」なんて言われてもなー。 (スコア:1)