4月 132012
 

How do ACL match to req.http.X-Forwarded-For? (this is string!!)
I tried to make a vmod.

inet_pton(BOOL ipv6 , STRING str , STRING defaultstr)

example 1


import campur_xcir;

set resp.http.v6 = campur_xcir.inet_pton(true,"2001:0db8:bd05:01d2:288a:1fc0:0001:10ee","1982:db8:20:3:1000:100:20:3");
set resp.http.v4 = campur_xcir.inet_pton(false,"1.1.1.1","2.2.2.2");
set resp.http.v6ng = campur_xcir.inet_pton(true,"2001:0db8:bd05:01d2:288a:1fc0:0001:10eeHOGE","1982:db8:20:3:1000:100:20:3");//NG pattern
set resp.http.v4ng = campur_xcir.inet_pton(false,"1.1.1.1HOGE","2.2.2.2");//NG pattern

//result
v6: 2001:db8:bd05:1d2:288a:1fc0:1:10ee
v4: 1.1.1.1
v6ng: 1982:db8:20:3:1000:100:20:3
v4ng: 2.2.2.2

example 2


import campur_xcir;

//acl
acl local {
    "192.168.1.0"/24;
    !"0.0.0.0";
}

sub vcl_recv{
  if(campur_xcir.inet_pton(false , req.http.X-Forwarded-For , "0.0.0.0") ~ local){
      //acl ok
      ...
  }
}

I hope that this code is of help to you.
libvmod-campur_xcir

this module is my motley function.
Others, get varnish generated hash etc…

this vmod’s function is increase at times. 🙂


4月 132012
 

ちょっとdai_yamashitaさんに聞かれたのでつくってみたものですがせっかくなので記事にします。

よくクライアントのIPアドレスをACLと突き合わせて処理をする・しないをやるかと思いますが
上位に他のProxyがいるなど(たとえばNginx)で、X-Forwarded-ForをACLと付き合わせてみたいときはどうすればよいでしょうか?
通常の方法ではできないのでVMOD作ってみました。

campur_xcir.inet_pton(ipv6かどうか , 変換したいIPアドレスな文字列 , 失敗した場合のデフォルトのIPアドレスな文字列)


import campur_xcir;

set resp.http.v6 = campur_xcir.inet_pton(true,"2001:0db8:bd05:01d2:288a:1fc0:0001:10ee","1982:db8:20:3:1000:100:20:3");
set resp.http.v4 = campur_xcir.inet_pton(false,"1.1.1.1","2.2.2.2");
set resp.http.v6ng = campur_xcir.inet_pton(true,"2001:0db8:bd05:01d2:288a:1fc0:0001:10eeHOGE","1982:db8:20:3:1000:100:20:3");//失敗パタン
set resp.http.v4ng = campur_xcir.inet_pton(false,"1.1.1.1HOGE","2.2.2.2");//失敗パタン

//結果
v6: 2001:db8:bd05:1d2:288a:1fc0:1:10ee
v4: 1.1.1.1
v6ng: 1982:db8:20:3:1000:100:20:3
v4ng: 2.2.2.2

実際はこんな感じの使い方を想定しています


import campur_xcir;

//acl
acl local {
    "192.168.1.0"/24;
    !"0.0.0.0";
}

sub vcl_recv{
  if(campur_xcir.inet_pton(false , req.http.X-Forwarded-For , "0.0.0.0") ~ local){
      //acl ok
      ...
  }
}

もしよかったら使ってみてください
libvmod-campur_xcir

ちなみにこのモジュールは僕が試しに作ったものを突っ込んでるものです
他にはMLで質問してた人向けに作ったVarnishのhash値を取得するものとかが入ってます
たまに増えたりすると思います


3月 302012
 

oranieさんが主催しているWebサーバ勉強会という
全員何かしら発表するという勉強会でESIについて発表してきました。

ESIについては結構前にqpstudyでもLTしているのですが
Varnishのバージョンも上がり、いろいろ使いやすくなったので、ここでもう一回とおもいこのテーマで発表しました。
Varnishの利点はやはりその柔軟な設定(VCL)にあると思うので
その利点を生かして、単純に静的ファイルをキャッシュさせるだけではなく
ESIのように複雑なキャッシュをさせるのもいいんじゃないかなと思っています。

また他の方の発表を聞いてfluentdはやっぱり使いたい!と思った所存です。
JSONにどうしてもなるのかなぁと思っていたのですがrawで収集できるようにしたよ!という発表もあり既存とも組み合わせしやすくこれはいいなと考えています。
Apacheについても2.4.1が出た際に僕はEvent MPMばっかに目が言ってたのですが他にも魅力的な機能がありもう一回じっくり見てみようかなと考えています。

非常に刺激を受けた勉強会でした。
また機会があれば是非参加したいと考えています。
参加者の皆様、主催者のoranieさん本当にありがとうございました。


3月 202012
 

To save the split log for every host([hostname].access_log), Apache is easy.
I want the same action in varnishncsa. What should I do?

Use the options -m [tag:regex], -w [file], -a and -D.

-m perform a regex match to the tag’s log entry.
-w write log to a file.
-a append log. Will be overwritten if you do not specify.
-D Daemonize.

exec varnishncsa(host is a.example.net and b.example.net)


varnishncsa -m "RxHeader:^Host: a.example.net$" -a -w /var/log/varnish/a.example.net.access_log -D
varnishncsa -m "RxHeader:^Host: b.example.net$" -a -w /var/log/varnish/b.example.net.access_log -D

after request


cat a.example.net.access_log
192.168.1.199 - - [20/Mar/2012:12:51:50 +0900] "GET http://a.example.net/a HTTP/1.0" 200 280 "-" "Wget/1.12 (linux-gnu)"

cat b.example.net.access_log
192.168.1.199 - - [20/Mar/2012:12:51:59 +0900] "GET http://b.example.net/a HTTP/1.0" 200 280 "-" "Wget/1.12 (linux-gnu)"

work as expected.

If you want to log rotate, please send the SIGHUP.


3月 202012
 

Apacheでvirtualhostを切って複数のホストで運用する場合
よくログファイル名に[hostname].access_logとかつけるとおもいます。
ではvarnishncsaで似たようなことをするにはどうすればいいでしょうか?

-m [tag:regex]と-w [file] -D -aオプションを使うことで可能です。
このオプションはログエントリの指定されたタグ(RxHeaderなど)の内容(Host: c.example.netなど)を正規表現でマッチさせて
引っかかったものを対象にするオプションです
タグについてはvarnishlogを眺めてる時に出てくるのを見ればわかると思います


        ↓ここがタグ      ↓ここが内容
   12 RxHeader     c Host: c.example.net

-wは出力先のファイル名を指定して、-Dを指定するとデーモンとして動きます
-aはログの追記です。指定しないとログが存在する場合上書きされてしまいます。

今回はテストでa.example.netとb.example.netでそれぞれログを出力します
こんな感じで指定します


varnishncsa -m "RxHeader:^Host: a.example.net$" -a -w /var/log/varnish/a.example.net.access_log -D
varnishncsa -m "RxHeader:^Host: b.example.net$" -a -w /var/log/varnish/b.example.net.access_log -D

それぞれwgetを投げてみて出力されたのが以下です。


cat a.example.net.access_log
192.168.1.199 - - [20/Mar/2012:12:51:50 +0900] "GET http://a.example.net/a HTTP/1.0" 200 280 "-" "Wget/1.12 (linux-gnu)"

cat b.example.net.access_log
192.168.1.199 - - [20/Mar/2012:12:51:59 +0900] "GET http://b.example.net/a HTTP/1.0" 200 280 "-" "Wget/1.12 (linux-gnu)"

きちんと分かれているのがわかります。

またvarnishncsaはSIGHUPを受け取るとファイルを開き直すので
ローテーションする場合はSIGHUPを使ってください


3月 122012
 

varnishlogtrans version up(mapping from vcl_trace to vcl source)

Past Articles:convert varnishlog output to easy

Changes

  • Feature: mapping from vcl_trace to vcl source(line).(request from @perbu)
  • Feature: show backend status.(request from @dai_yamashita)
  • Change: Add run option.
  • Experimental: mapping from vcl_trace to vcl source(all).
  • mapping from vcl_trace to vcl source(line).

    if you set to -f option, replace vcl_trace to VCL code
    before.

    
             | trace  | vrt_count:1 vcl_line:55 vcl_pos:1
    
    

    after(use -f and -e option)

    
             | trace  | set req.http.X-TEST1=campur_xcir.gethash();
             |        | ^ (vrt_count:1 vcl_line:55 vcl_pos:1 src_name:input)
    
    
    

    show backend status.

    show backend status.
    past status is window 4times.

    
    backend status
    ------------------------------------------------------------
    
    name    | status  | past status
    default | healthy | YY
    
    

    Add run option.

    -f [vcl file]

    if you set, you can mapping from vcl_trace to vcl source.

    -e [varnishd]

    if you set, you can mapping from vcl_trace to vcl source.

    -cc_command [cc_command]

    if you set in the -f option and varnish’s cc_command option ,please setting.

    –(backend|action|variable) [on|off]

    if you want to disable (backend|action|variable) info , set to off. (default is on)

    mapping from vcl_trace to vcl source(all).

    this function is unstable.
    if you want use this function.
    it need change value and set option(–src=on -f=[vclfile] -e=[varnishd]).

    before

    
    define('experimental' , false);
    
    

    after

    
    define('experimental' , true);
    
    

    output

    
    ############################################################
    vcl trace
    [exec]      /* "input"*/
    [exec]  /*
    
    ...
    
    [exec]  sub vcl_recv {
    [exec]      if (req.restarts == 0) {
    [exec]          if (req.http.x-forwarded-for) {
                        set req.http.X-Forwarded-For =
                            req.http.X-Forwarded-For + ", " + client.ip;
    [exec]          } else {
    [exec]              set req.http.X-Forwarded-For = client.ip;
    [exec]          }
    [exec]      }
    [exec]      if (req.request != "GET" &&
    [exec]        req.request != "HEAD" &&
    [exec]        req.request != "PUT" &&
    [exec]        req.request != "POST" &&
    
    ...
    
    

    I hope that this code is of help to you.

    download here.
    varnishlogTrans


    3月 122012
     

    この前作ったvarnishlogを見やすくするツールですが
    機能強化しました。

    追加機能は

  • vcl_traceの値をVCLソースで表示(@perbuさんからのリクエスト)
  • バックエンドの状態を表示(@dai_yamashitaさんからのリクエスト)
  • です

    vcl_traceの値をVCLソースで表示

    今までvcl_traceの結果は味気ない表示で出していましたが。-fオプションでVCLファイルを指定することで実際のソースコードを表示するようにしました。

    
             | trace  | vrt_count:1 vcl_line:55 vcl_pos:1
    
    

    
             | trace  | set req.http.X-TEST1=campur_xcir.gethash();
             |        | ^ (vrt_count:1 vcl_line:55 vcl_pos:1 src_name:input)
    
    
    

    バックエンドの状態を表示

    バックエンドのヘルスチェックの状態を表示するようになりました。
    過去の履歴はとりあえずwindowの4倍です

    
    backend status
    ------------------------------------------------------------
    
    name    | status  | past status
    default | healthy | YY
    
    

    起動オプション

    またこれらの機能を実現するために起動オプションが追加されました。

    -f [vcl file]

    VCLを指定します。これによりvcl_traceを解決できます。

    -e [varnishd]

    varnishdを指定します。vcl_traceの解決に必要です。

    -cc_command [cc_command]

    varnishのcc_commandで共有ライブラリを使っている場合は指定してください。
    vcl_traceの解決がいらない場合は不要です。

    –(backend|action|variable) [on|off]

    それぞれの情報の表示のon/offができます。
    デフォルトは全てonです

    また機能的に安定しなくてONにはしてないのですが

    
    define('experimental' , false);
    
    

    
    define('experimental' , true);
    
    

    にして
    起動時に–src=onと-f=[vclfile]と-e=[varnishd]を指定するとVCLファイルで実際に通った場所が表示されます([exec])

    
    ############################################################
    vcl trace
    [exec]      /* "input"*/
    [exec]  /*
    
    ~中略~
    
    [exec]  sub vcl_recv {
    [exec]      if (req.restarts == 0) {
    [exec]          if (req.http.x-forwarded-for) {
                        set req.http.X-Forwarded-For =
                            req.http.X-Forwarded-For + ", " + client.ip;
    [exec]          } else {
    [exec]              set req.http.X-Forwarded-For = client.ip;
    [exec]          }
    [exec]      }
    [exec]      if (req.request != "GET" &&
    [exec]        req.request != "HEAD" &&
    [exec]        req.request != "PUT" &&
    [exec]        req.request != "POST" &&
    
    ~後略~
    
    

    良かったら使ってみてください
    varnishlogTrans


    2月 092012
     

    Do you use a Varnish? I’ve been using.
    I think to using varnishlog for VCL debugging.

    For example, the output of the varnishlog that include ESI request.

    varnishlog(include ESI)

    
       13 BackendOpen  b default 192.168.1.199 36011 192.168.1.199 81  ★Open backend here.
       13 TxRequest    b GET
       13 TxURL        b /test2.html
       13 TxProtocol   b HTTP/1.1
       13 TxHeader     b User-Agent: Wget/1.12 (linux-gnu)
       13 TxHeader     b Accept: */*
       13 TxHeader     b Host: 192.168.1.199:6081
       13 TxHeader     b X-Varnish: 171551254
       13 TxHeader     b Accept-Encoding: gzip
       13 RxProtocol   b HTTP/1.1
       13 RxStatus     b 200
       13 RxResponse   b OK
       13 RxHeader     b Date: Sat, 28 Jan 2012 05:05:59 GMT
       13 RxHeader     b Server: Apache/2.2.15 (Scientific Linux)
       13 RxHeader     b Last-Modified: Sat, 23 Jul 2011 08:09:05 GMT
       13 RxHeader     b ETag: "5a28-51-4a8b8187f8177"
       13 RxHeader     b Accept-Ranges: bytes
       13 RxHeader     b Content-Length: 81
       13 RxHeader     b Connection: close
       13 RxHeader     b Content-Type: text/html; charset=UTF-8
       13 Fetch_Body   b 4(length) cls 0 mklen 1
       13 Length       b 81
       13 BackendClose b default  ★Close backend here.
       13 BackendOpen  b default 192.168.1.199 36012 192.168.1.199 81  ★Open backend for ESI request here.
       13 TxRequest    b GET
       13 TxURL        b /test3.html
       13 TxProtocol   b HTTP/1.1
       13 TxHeader     b User-Agent: Wget/1.12 (linux-gnu)
       13 TxHeader     b Accept: */*
       13 TxHeader     b Host: 192.168.1.199:6081
       13 TxHeader     b X-Varnish: 171551254
       13 TxHeader     b Accept-Encoding: gzip
       13 RxProtocol   b HTTP/1.1
       13 RxStatus     b 200
       13 RxResponse   b OK
       13 RxHeader     b Date: Sat, 28 Jan 2012 05:05:59 GMT
       13 RxHeader     b Server: Apache/2.2.15 (Scientific Linux)
       13 RxHeader     b Last-Modified: Sat, 23 Jul 2011 08:08:59 GMT
       13 RxHeader     b ETag: "5a29-14-4a8b81829c835"
       13 RxHeader     b Accept-Ranges: bytes
       13 RxHeader     b Content-Length: 20
       13 RxHeader     b Connection: close
       13 RxHeader     b Content-Type: text/html; charset=UTF-8
       13 Fetch_Body   b 4(length) cls 0 mklen 1
       13 Length       b 20
       13 BackendClose b default  ★Close backend here.
       12 SessionOpen  c 192.168.1.199 55115 :6081
       12 ReqStart     c 192.168.1.199 55115 171551254 ★Start Request (/test2.html)
       12 RxRequest    c GET
       12 RxURL        c /test2.html
       12 RxProtocol   c HTTP/1.0
       12 RxHeader     c User-Agent: Wget/1.12 (linux-gnu)
       12 RxHeader     c Accept: */*
       12 RxHeader     c Host: 192.168.1.199:6081
       12 RxHeader     c Connection: Keep-Alive
       12 VCL_call     c recv 1 7.1
       12 VCL_Log      c a
       12 VCL_trace    c 2 9.1
       12 VCL_Log      c b
       12 VCL_trace    c 3 11.1
       12 VCL_Log      c a
       12 VCL_return   c lookup
       12 VCL_call     c hash 18 85.5
       12 Hash         c /test2.html
       12 VCL_trace    c 19 87.9
       12 Hash         c 192.168.1.199:6081
       12 VCL_return   c hash
       12 VCL_call     c miss 22 99.5 fetch
       12 Backend      c 13 default default ★Call backend.
       12 TTL          c 171551254 RFC 120 -1 -1 1327727160 0 1327727159 0 0
       12 VCL_call     c fetch 4 18.1 deliver
       12 ObjProtocol  c HTTP/1.1
       12 ObjResponse  c OK
       12 ObjHeader    c Date: Sat, 28 Jan 2012 05:05:59 GMT
       12 ObjHeader    c Server: Apache/2.2.15 (Scientific Linux)
       12 ObjHeader    c Last-Modified: Sat, 23 Jul 2011 08:09:05 GMT
       12 ObjHeader    c ETag: "5a28-51-4a8b8187f8177"
       12 ObjHeader    c Content-Type: text/html; charset=UTF-8
       12 VCL_call     c deliver 26 116.5 deliver
       12 TxProtocol   c HTTP/1.1
       12 TxStatus     c 200
       12 TxResponse   c OK
       12 TxHeader     c Server: Apache/2.2.15 (Scientific Linux)
       12 TxHeader     c Last-Modified: Sat, 23 Jul 2011 08:09:05 GMT
       12 TxHeader     c ETag: "5a28-51-4a8b8187f8177"
       12 TxHeader     c Content-Type: text/html; charset=UTF-8
       12 TxHeader     c Date: Sat, 28 Jan 2012 05:05:59 GMT
       12 TxHeader     c X-Varnish: 171551254
       12 TxHeader     c Age: 0
       12 TxHeader     c Via: 1.1 varnish
       12 TxHeader     c Connection: close
       12 VCL_call     c recv 1 7.1  ★Start ESI log.
       12 VCL_Log      c a
       12 VCL_trace    c 2 9.1
       12 VCL_Log      c b
       12 VCL_trace    c 3 11.1
       12 VCL_Log      c a
       12 VCL_return   c lookup
       12 VCL_call     c hash 18 85.5
       12 Hash         c /test3.html
       12 VCL_trace    c 19 87.9
       12 Hash         c 192.168.1.199:6081
       12 VCL_return   c hash
       12 VCL_call     c miss 22 99.5 fetch
       12 Backend      c 13 default default
       12 TTL          c 171551254 RFC 120 -1 -1 1327727160 0 1327727159 0 0
       12 VCL_call     c fetch 4 18.1 deliver
       12 ObjProtocol  c HTTP/1.1
       12 ObjResponse  c OK
       12 ObjHeader    c Date: Sat, 28 Jan 2012 05:05:59 GMT
       12 ObjHeader    c Server: Apache/2.2.15 (Scientific Linux)
       12 ObjHeader    c Last-Modified: Sat, 23 Jul 2011 08:08:59 GMT
       12 ObjHeader    c ETag: "5a29-14-4a8b81829c835"
       12 ObjHeader    c Content-Type: text/html; charset=UTF-8
       12 VCL_call     c deliver 26 116.5 deliver
       12 Length       c 20
       12 ReqEnd       c 171551254 1327727159.889132023 1327727159.890880346 -0.001736164 nan nan  ★Request end.
       12 SessionClose c EOF mode
       12 StatSess     c 192.168.1.199 55115 0 1 1 0 0 2 282 20
        0 CLI          - Rd ping
        0 CLI          - Wr 200 19 PONG 1327727160 1.0
    
    

    little too difficult for me.
    Therefore, I tried to make a tool to format and display.
    Continue reading »


    2月 052012
     

    Varnish redirect is pain.

    
    sub vcl_recv {
      if (req.http.user-agent ~ "iP(hone|od)") {
        error 750 "Moved Temporarily";
      }
    }
    
    sub vcl_error {
      if (obj.status == 750) {
        set obj.http.Location = "http://www.example.com/iphoneversion/";
        set obj.status = 302;
        return(deliver);
      }
    }
    
    

    (via:Redirecting using VCL)
    I just want to redirect. but should write code in two action.
    This is it lack of maintenance, and I do not like.
    I tried to make a vmod_redirect can be easily redirect.
    Continue reading »


    2月 052012
     

    Varnishでリダイレクトを行うのは結構めんどくさいです。
    たとえばuser-agentにiphoneかipodを含む場合にそれ用のページにリダイレクトする場合は以下のようになります

    
    sub vcl_recv {
      if (req.http.user-agent ~ "iP(hone|od)") {
        error 750 "Moved Temporarily";
      }
    }
    
    sub vcl_error {
      if (obj.status == 750) {
        set obj.http.Location = "http://www.example.com/iphoneversion/";
        set obj.status = 302;
        return(deliver);
      }
    }
    
    

    (via:Redirecting using VCL)

    ただリダイレクトしたいだけなのに二箇所のアクションでコードを書かなくてはいけません。
    これは保守性に欠けると思いますし個人的にあまり好みではありません。

    そこで簡単にリダイレクトができるvmod_redirectを作って見ました。
    Continue reading »