6月 192013
 

Varnish3.0.4が公開されました。
今回はほとんどBugFixですが、いくつかの機能改善があります。

公式リリースノート(3.0.4)

バグフィックス

CVE-2013-4090 特定条件でACLで想定外のマッチ・マッチ漏れが起こる
#1312
対象は3.0.3までの全てのバージョンです
引っかかる条件は以下だと思います
・CIDR形式の定義が存在(/8,/16,/24を除く)
・単一のIPアドレスを指定している
・その定義範囲が重複している
こんな感じです
VCLコード


acl foo {
  "127.0.0.2";
  "127.0.0.0"/19; //(127.0.0.1 ~ 127.0.31.254で127.0.0.2を含む)
}

Cに変換したコード(3.0.3)


static int
match_acl_named_foo(const struct sess *sp, const void *p)
{
    const unsigned char *a;
    unsigned short fam;

    a = p;
    VRT_memmove(&fam, a + 0, sizeof fam);
    if (fam == 2)
        a += 4;
    else if (fam == 10)
        a += 8;
    else {
        VRT_acl_log(sp, "NO_FAM foo");
        return(0);
    }

    if (fam == 2) {
     if (a[0] == 127) {
      if (a[1] == 0) {
       if (a[2] == 0) {//ここで本来マッチしなくては行けない127.0.1~127.0.31が排除される
        if (a[3] == 2) {
         VRT_acl_log(sp, "MATCH foo " "127.0.0.2");
         return (1);
        }
        VRT_acl_log(sp, "MATCH foo " "127.0.0.0" "/19" );
        return (1);
       }
      }
     }
    }
    VRT_acl_log(sp, "NO_MATCH foo");
    return (0);
}

Cに変換したコード(3.0.4)


static int
match_acl_named_foo(const struct sess *sp, const void *p)
{
        const unsigned char *a;
        unsigned short fam;

        a = p;
        VRT_memmove(&fam, a + 0, sizeof fam);
        if (fam == 2)
                a += 4;
        else if (fam == 10)
                a += 8;
        else {
                VRT_acl_log(sp, "NO_FAM foo");
                return(0);
        }

        if (fam == 2) {
         if (a[0] == 127) {
          if (a[1] == 0) {
           if (a[2] == 0) {
            if (a[3] == 2) {
             VRT_acl_log(sp, "MATCH foo " "127.0.0.2");
             return (1);
            }
           }
           if ((a[2] & 0xe0) == 0) {
            VRT_acl_log(sp, "MATCH foo " "127.0.0.0" "/19" );
            return (1);
           }
          }
         }
        }
        VRT_acl_log(sp, "NO_MATCH foo");
        return (0);
}

影響を受けるかの確認はVCLをCで出してみて
該当のACLマッチ関数(match_acl_named_[ACL名])を見たほうが良いかと思います。

ESI利用時にバックエンドが無効なgzipを送信した場合においてエラーを起こす可能性があった
#1184

バックエンド名が長いとAssertで子プロセスが落ちる
#1224

バグ修正は他にもありますが個人的に気になったのをピックアップしました

ツール改善

varnishncsaのフォーマットで%D,%Tをサポートしました
varnishadmでtabを打つと候補が出るようになりました

パフォーマンス系

TCP_NODELAYを有効にしました(NagleをOffにした)
chunkの時効いてきそうです。

その他

複数のHostヘッダを送られてきた場合はエラーとする
即切断されますのでvcl_recvは呼ばれません(壊れたセッション扱いです)


Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.
GET /test HTTP/1.0
Host: exmple.jp
Host: exmple.jp

Connection closed by foreign host.

varnishncsaログ
★ホストヘッダ1つ
127.0.0.1 - - [18/Jun/2013:22:42:40 +0900] "GET http://exmple.jp/test HTTP/1.0" 404 287 "-" "-"
★ホストヘッダ複数
127.0.0.1 - - [18/Jun/2013:22:42:44 +0900] "GET http://exmple.jp/test HTTP/1.0"  - "-" "-"

ドキュメントが改善されました
ABI変わってるのでvmodのリコンパイルが必要

#vug7の記事書く前にこっちの記事を書くことになるとは・・・(下書きにはあるんですがね)