HAProxyでHTTPヘッダーを操作する。(リクエスト編)

今回はHAProxyでHTTPヘッダーを操作してみます。主にHTTPリクエストヘッダーの方です。

reqadd

HTTPリクエストのヘッダーを追加します。

設定例:"X-Greeding"ヘッダーを追加します。

backend web1
       mode http
       server web1 172.16.1.129:80 check rise 1 fall 3
       option httpchk
       reqadd X-Greeding:\ Hello\ World

reqaddキーワードでHTTPリクエストヘッダーを追加することができます。
バックスラッシュはその次の文字をエスケープします。バックスラッシュがないとHAPoxyの構文エラーになってしまいます。

以下は、http://172.16.1.129:8080/test.php へブラウザでアクセスした表示結果です。※test.phpは、すべてのヘッダーを出力するプログラムです。

== HTTP headers ==
Host: 172.16.1.129:8080
User-Agent: Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10.6; ja-JP-mac; rv:1.9.2.8) Gecko/20100722 Firefox/3.6.8
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: ja,en-us;q=0.7,en;q=0.3
Accept-Encoding: gzip,deflate
Accept-Charset: Shift_JIS,utf-8;q=0.7,*;q=0.7
Keep-Alive: 115
Connection: keep-alive
Cache-Control: max-age=0
X-Greeding: Hello World

ちゃんとX-Greedingが追加されていました。

reqdel, reqidel

指定した正規表現にマッチするHTTPリクエストヘッダーを削除します。
reqidelは大文字小文字を無視します。(ignore case)

設定例:ヘッダーUser-Agentを削除します。

backend web1
       mode http
       server web1 172.16.1.129:80 check rise 1 fall 3
       option httpchk
       reqidel ^User-Agent:.*


以下は、http://172.16.1.129:8080/test.php へブラウザでアクセスした表示結果です。

== HTTP headers ==
Host: 172.16.1.129:8080
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: ja,en-us;q=0.7,en;q=0.3
Accept-Encoding: gzip,deflate
Accept-Charset: Shift_JIS,utf-8;q=0.7,*;q=0.7
Keep-Alive: 115
Connection: keep-alive
Cache-Control: max-age=0

ちゃんとUser-Agentが削除されています。

reqallow, reqiallow, reqdeny, reqideny

指定した文字列がリクエストラインとヘッダーにマッチするものをアクセス許可(reqallow)、不許可(reqdeny)にします。
reqiallow, reqidenyは大文字小文字を無視します。

設定例:publicディレクトリ以下に対してはアクセスを許可する。secretディレクトリ以下に対してはアクセスを許可しない。

backend web1
       mode http
       server web1 172.16.1.129:80 check rise 1 fall 3
       option httpchk
       reqdeny .*/secret/.*
       reqallow .*/public/.*

secretディレクトリへアクセスしようとすると、以下のメッセージがブラウザに表示されました。

403 Forbidden
Request forbidden by administrative rules. 

reqrep, reqirep

HTTPヘッダー、リクエストライン内で指定した文字列がマッチする部分を置換します。
reqirep は大文字小文字を無視します。

設定例:User-Agentを"foobar"に変更する。

backend web1
       mode http
       server web1 172.16.1.129:80 check rise 1 fall 3
       option httpchk
       reqrep ^(User-Agent:)(.*) \1foobar

Firefoxでアクセスしてみると、以下のヘッダーが出力されました。

== HTTP headers ==
Host: 172.16.1.129:8080
User-Agent: foobar
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: ja,en-us;q=0.7,en;q=0.3
Accept-Encoding: gzip,deflate
Accept-Charset: Shift_JIS,utf-8;q=0.7,*;q=0.7
Keep-Alive: 115
Connection: keep-alive
Cache-Control: max-age=0

User-Agentが変更されていました。

reqtarpit, reqitarpit

HTTPヘッダー、リクエストライン内で指定した文字列がマッチする場合ターピットによるスパム対策を施せます。
reqitarpit は大文字小文字を無視します。

設定例:特定のIP(172.16.1.1)はターピットで動作を遅らせる。

backend web1
       mode http
       server web1 172.16.1.129:80 check rise 1 fall 3
       option httpchk
       acl robot src 172.16.1.1
       reqtarpit . if robot

172.16.1.1のクライアントでアクセスすると5秒待たされた後に、500エラーが返却されました。


上の例でACLと絡めましたが、その他の例でもACLと一緒に使用することができます。
その他に、reqpass,reqipass というのがあるんだけど、思ったように動作してくれん・・・。