はろー64ビット

今日、親切なおにいさんが会社の検証用マシンにdebianをいれてくれました。
なんと、中身をみてびっくり!

$ uname -a
Linux sag15 2.6.18-4-amd64 #1 SMP Mon Mar 26 11:36:53 CEST 2007 x86_64 GNU/Linux

$ gcc -v
Using built-in specs.
Target: x86_64-linux-gnu

をを!!64ビット環境じゃん(笑)
自慢じゃないですが初めてさわります。

で、まず最初にやったこと。

$ vi test.c

#include<stdio.h>

int main(int argc,char *argv[]){

  printf("hello 64bit!!\n");
  printf("char=%d short=%d int=%d long=%d longlong=% double=%d\n",
          sizeof(char),sizeof(short),sizeof(int),sizeof(long),
          sizeof(long long int),sizeof(double));
  return(0);
}

で、

$ gcc -o test test.c
$ ./test
hello 64bit!!
char=1 short=2 int=4 long=8 longlong=8 double=8

ちなみに32ビットの環境だとこうなります。

$ gcc -o test test.c
$ ./test
hello 32bit!!
char=1 short=2 int=4 long=4 longlong=8 double=8

へえ、longが8バイトになってるだけで、他は変わらないんですね。

ipvsのthresholdその後

そういえば、

net/ipv4/ipvs/ip_vs_conn.c をこんな感じにしてみます。

これでESTABLISHEDだけをカウントしてくれるようになるかもです。

http://d.hatena.ne.jp/yasui0906/20070316/p1

とかやってみたんですが、結論書くの忘れてました(^^;
結果から言うとだめでした、はい。

ip_vs_dest_totalconnsを呼んでIP_VS_DEST_F_OVERLOADフラグを落とすのは、コネクションテーブルからエントリを解放するときだけなんですね。つまり、TIME_WAITやFIN_WAITを待たないとIP_VS_DEST_F_OVERLOADフラグを落とす処理には飛ばないわけで、小手先でinactconnsをカウントしないようにしても意味がなかった模様です。

というわけで、別のアプローチでどうにかできないか試行錯誤中です。

SSHのポート番号

sshdが22番ポートで接続を待っていると攻撃を受けまくるので別なポートにするのがいい」って話をよく聞きます。これは闇雲に22番に対して接続を試みる攻撃者に対してはそこそこ有効な手段かもしれません。

ただ「22番ポートの代わりに1024番以上のポートを使うのがいい」って紹介しているところもあるようです。

 SSHはデフォルトでは22番ポートで接続を待っている。攻撃者はポートスキャナを使ってホストがSSHサービスを実行しているかどうかを把握するが、(nmapを含め)大抵のポートスキャナではデフォルトでは1024以上のポート番号のスキャンは行なわれないため、SSH用のポートを1024以上の番号に変更しておくのが賢明だ。

http://opentechpress.jp/security/article.pl?sid=07/04/03/0148224&from=rss

これってどうなんでしょうね。

そもそもポートスキャンする相手に対してポート番号の変更は気休めにしかならないような気がします。「気休めにでもなれば」ってことでポート番号変更するのはいいんですが、気になるのは「1024番以上のポート番号を使う」ってとこ。

1024番未満のポートはウェルノンポート(Well-known Port)として IANAで定義 されていて、rootプロセスしか待機できないことになっています。つまり、1024以上のポートは誰でも待機することができるわけで、もしかすると「どこの誰が作ったかわからんプロセス」が待機してる可能性もあるわけです。
なので、多数のユーザが利用する環境の場合、SSHみたいな大事大事なサービスを1024番以上のポートで提供するのってどうなんだろうと思います。

まあ、「自宅サーバ限定」な話なら関係ないかもしれませんが・・・

他人が管理してて、多数のユーザが利用するようなサーバに対し、レジスタードポートにsshするのはかなりの度胸が必要と感じるのは私だけでしょうか。「じゃあ、どうするの?」っていわれたら、922番あたりを使いますかねえ。まあ、パスワード認証を切って公開鍵認証のみでの運用であれば22番ポートを使うことにためらいはありませんが・・・

l_threshold と u_threshold の使い方

IPVSには設定した接続数を越えると、それ以上の接続を抑止する threshold という機能があります。
これに関連するパラメータは l_threshold と u_threshold のふたつです。
今回はこれらの使い方をおさらいします。

u_threshold

現在の接続数がこの値よりも大きくなると、それ以上の接続をしなくなります。
全サーバがこの状態に陥るとサービス停止となるので要注意です。

net/ipv4/ipvs/ip_vs_conn.c
  if (dest->u_threshold != 0 &&
    ip_vs_dest_totalconns(dest) >= dest->u_threshold)
      dest->flags |= IP_VS_DEST_F_OVERLOAD;

IP_VS_DEST_F_OVERLOADフラグが立っている転送先には新規の接続はされなくなります。

l_threshold

u_thresholdでセットされたIP_VS_DEST_F_OVERLOADフラグをクリアする条件を指定します。
接続数がこの値を下回ったらIP_VS_DEST_F_OVERLOADフラグがクリアされます。
l_thresholdが0の場合は、接続数がu_thresholdの75%を下回ったらクリアされます。

net/ipv4/ipvs/ip_vs_conn.c
  if (dest->l_threshold != 0) {
    if (ip_vs_dest_totalconns(dest) < dest->l_threshold)
      dest->flags &= ~IP_VS_DEST_F_OVERLOAD;
  } else if (dest->u_threshold != 0) {
    if (ip_vs_dest_totalconns(dest) * 4 < dest->u_threshold * 3)
      dest->flags &= ~IP_VS_DEST_F_OVERLOAD;
  } else {

使用例

設定

# ipvsadm -a -t x.x.x.x -r y.y.y.y -s rr -x u_threshold -y l_threshold

参照

# ipvsadm -L -n --thresholds

parallelsでの「カナかなキー」

つい最近、MacBookを買っていろいろ遊んでいるんですが、parallelsすごいすね。
Windowsは気が向いたらインストールするとして、とりあえずDebianいれてデスク
トップ環境を使ってるんですが、速度的にまったく不便を感じません。

ただ一点、日本語入力でちょいと悩んでます。
ぼくは atok大好きな人なので、Linuxでも atokxを使ってるんですが、Macのキー
ボードには「全角・半角キー」がないのでどうやってatokのOn/Offをしようかなあ
と考えています。「カナかなキー」でいいじゃん、と思ったんですが、xevでイベン
トを拾ってもなんにも返ってこないんですね、これ。

とりあえず今は、「コマンドキー」がコード115(LWIN)として認識してくれるので、
/etc/X11/xkb/keycodes/xfree86

alias = ;

alias = ;

に書き換えて「コマンドキー」でOn/Offをやってますが、やっぱしなんか違和感を
感じます。parallels上で「カナかなキー」を認識するにはどうやるんでしょ(^^;;

なにか方法はありそうな気はするんですが・・・

ipvsのthresholdからsorry_serverへ飛ばしたい

ipvsの接続数がthresholdを超えたら「ごめんなさいサーバ」に飛ばせるように試行錯誤中です。
まあ、問題は「ごめんなさいサーバ」をどのように指定してどのように内部で保持するかですかね。

で、なにげに ip_vs_rr.c を眺めててふと思ったんですが、転送先を決定するときは、

・IP_VS_DEST_F_OVERLOADフラグが立っていない
・weightが0より大きい

この両方の条件を満たす転送先を探す訳ですけど、ここを

・IP_VS_DEST_F_OVERLOADフラグが立っていない
・weightが1より大きい

に変えて、weight==1 の転送先を「ごめんなさいサーバ」とみなす事で、構造体に手を加えず
に実現できそうな感じがします。

というわけで、試しに ip_vs_rr.c だけですが、こんな感じで書き換えてみました。

--- linux-2.6.12.6/net/ipv4/ipvs/ip_vs_rr.c     2005-08-30 01:55:27.000000000 +0900
+++ linux-2.6.12.6-sorry/net/ipv4/ipvs/ip_vs_rr.c       2007-03-27 23:19:34.000000000 +0900
@@ -71,11 +71,27 @@
 
                dest = list_entry(q, struct ip_vs_dest, n_list);
                if (!(dest->flags & IP_VS_DEST_F_OVERLOAD) &&
-                   atomic_read(&dest->weight) > 0)
+                   atomic_read(&dest->weight) > 1)
                        /* HIT */
                        goto out;
                q = q->next;
        } while (q != p);
+       /*----- find w==1 -----*/
+       p = (struct list_head *)svc->sched_data;
+       p = p->next;
+       q = p;
+       do {
+               /* skip list head */
+               if (q == &svc->destinations) {
+                       q = q->next;
+                       continue;
+               }
+
+               dest = list_entry(q, struct ip_vs_dest, n_list);
+               if( atomic_read(&dest->weight) == 1 )
+                       goto out;
+               q = q->next;
+       } while (q != p);
        write_unlock(&svc->sched_lock);
        return NULL;

で、keepalived.confはこんな感じにします。

virtual_server 10.37.129.3 {
  delay_loop 6
  lb_algo rr
  lb_kind NAT
  nat_mask 255.255.255.0
  persistence_timeout 0
  protocol TCP
  
  #----- sprry_serverの代わり -----
  real_server 127.0.0.4 22 {
    weight 1
  }
  real_server 127.0.0.2 22 {
    lthreshold 0
    uthreshold 2
    weight 2
  }
  real_server 127.0.0.3 22 {
    lthreshold 0
    uthreshold 2
    weight 2
  }
}

そしてkeepalivedを起動して別のマシンから ssh 10.37.129.3 しまくると・・・

# ipvsadm -Ln             
IP Virtual Server version 1.2.1 (size=4096)
Prot LocalAddress:Port Scheduler Flags
  -> RemoteAddress:Port           Forward Weight ActiveConn InActConn
TCP  10.37.129.3:22 rr
  -> 127.0.0.3:22                 Local   2      3          0         
  -> 127.0.0.2:22                 Local   2      3          0         
  -> 127.0.0.4:22                 Local   1      0          0  

weightが1な127.0.0.4以外の転送先にのみ接続されていることがわかります。
もう一回sshすると、本来はuthresholdいっぱいいっぱいなので蹴られますが、ここでは
127.0.0.4に対して転送されるようになるはずです。

# ipvsadm -Ln
IP Virtual Server version 1.2.1 (size=4096)
Prot LocalAddress:Port Scheduler Flags
  -> RemoteAddress:Port           Forward Weight ActiveConn InActConn
TCP  10.37.129.3:22 rr
  -> 127.0.0.3:22                 Local   2      3          0         
  -> 127.0.0.2:22                 Local   2      3          0         
  -> 127.0.0.4:22                 Local   1      1          0 

おお、いいじゃん(笑
これで、接続数がしきい値を超えた場合に「ごめんなさいサーバ」へ飛ばすという目的は達成できました。
ただまあ、このままweightが1な転送先を「ごめんなさいサーバ」とみなすのもいまいち感が漂うのでもう少
しどうにかにしょうかと思います。