うまいぼうぶろぐ

linuxとhttpdとperlのメモ

big-ip irule memo

httpとhttpsのpoolをひとつのiruleで処理する

例えば
example.com-http
example.com-https
のようなpoolがある場合

CLIENT_ACCEPTEDではTCP::local_portでportが判別できるので

when CLIENT_ACCEPTED {
  switch -exact [TCP::local_port] {
    80  {  set pool_service "http"   }
    443 {  set pool_service "https"  }
  }
  set pool_prefix "example.com-"
  if ( # 何か条件分岐 ) {
    pool $pool_prefix$pool_service
  }
}

とすればiruleまとめられる

  • irule

pool hogehoge-pool
などを書いた場合、そのpoolが存在していないと構文エラーとなり
iruleを保存できない

ただし、変数などを定義して

set hogehoge "hogehoge-pool"
pool $hogehoge

とした場合はiruleは保存できるか、そのiruleが実行された際にエラーとなり、
iruleはそこで中断する。

set hogehoge "hogehoge-pool"
if { [HTTP::uri] starts_with "/hoge/" } {
  pool $hogehoge
  log local0.info "wryyyyyyyy"
}

hogehoge-poolがない場合、pool $hogehoge の時点でエラーになるため、
log local0.info は実行されずログにwryyyyyyyと出ない。

HTTP_RESPONSE

HTTP::redirect でredirectする場合は
HTTP::header insertなどを書いても無視される

irule の処理を終わらせる

1つのirule内の処理を終える場合
return

iruleが複数ファイルに分かれている場合に、
同じeventの処理を終える場合
event disable

例えば
virtualserver

  • irule1
  • irule2

が適用されていて、HTTP_REQUESTで書かれているとする。
普通に適用すると、irule1の内容のあと、irule2も評価されるけど、
特定の条件があった場合には、irule1でHTTP_REQUESTを終えたい場合、
irule1内にevent disable
と書く

big-ip Web Accelerationでcache

httpコンテンツcacheする場合、だいたいvarnishとかnginx、apacheでやるし、
最近だとCDNもあったりするので、機能としてあるのは知ってたけど使わなかった機能。

とはいえ突発的なアクセスがきて、急に構成変更ができない場合にさくっとできるように調べて見た。

とりあえずまとめ

  • 要http profile
  • cacheはwebacceleration profile毎に個別
  • hostヘッダによっても異なる

f5 document

Local Traffic - Virtual Servers - Profiles - Services - Web Acceleration

defaultのprofileはいぢりだくないので、webaccelerationをparent profile として新規にprofile 作成

webacceleration-test

テスト

2 vip (4 virtualserver)に同一のprofileを適用してテスト

アクセスするとランダムな値を返すアプリを用意

1. 192.168.0.11:80
2. 192.168.0.11:443
3. 192.168.0.12:80
4. 192.168.0.12:443

1と2で同じキャッシュ、3と4で同じキャッシュが返ってきた。

virtualhost

hostsに

192.168.0.11 a.example.com b.example.com

とかいて

にアクセスすると異なるキャッシュが返ってきた。

さらにこのキャッシュが残っている状態で

192.168.0.12 a.example.com b.example.com

に書き換えて192.168.0.12のサーバにアクセスすると

にアクセスすると、↑と同じキャッシュが返ってきた。
(もしくは curl 192.168.0.12 -H 'host: a.example.com')

というわけで、同一webacceleration profileで
hostヘッダをkeyとしてキャッシュを使い分けてるみたい。
まあ、普通にインターネット上に公開している場合、異なるサーバ間で
hostヘッダが同じになることはないので気にしなくてよいかもしれないけど
hostヘッダ偽装により想定外のコンテンツが返る可能性があるので、
virtualserverごとにprofileはわけたほうが無難

sysstat (sadc)にTCP/IPの統計を追加する

sar -n TCP、-n IPなどでTCP/IPの統計も見たい場合sadcに"-S SNMP"オプション追加が必要

man sar

With the TCP keyword, statistics about TCPv4 network traffic are reported. Note that
TCPv4 statistics depend on sadc option "-S SNMP" to be collected. The following val-
ues are displayed (formal SNMP names between square brackets):

/etc/cron.d/sysstatで実行されている/usr/lib64/sa/sa1は内部的にsadcを実行していて、
オプションは

# grep -H SYSCONFIG_DIR /usr/lib64/sa/sa1
/usr/lib64/sa/sa1:SYSCONFIG_DIR=/etc/sysconfig
/usr/lib64/sa/sa1:[ -r ${SYSCONFIG_DIR}/sysstat ] && . ${SYSCONFIG_DIR}/sysstat

のとおり/etc/sysconfig/sysstat を読むのでここに追加する

```
SADC_OPTIONS="-S DISK -S SNMP"
```
RHEL6だと-S DISKは標準で書かれていた。

big-ip rest api

jsonで返ってくるのでjqかなければpython -m json.tool を使うと見易い。

$ curl -s -k --user user:pass https://192.168.0.1/mgmt/tm/ | jq .

URLはこの辺
/tm/net/
/tm/ltm/
/tm/security/
/tm/apm/

ltm

  • node追加
curl --user user:pass -s -k https://192.168.0.1/mgmt/tm/ltm/node \
     -H 'Content-Type: application/json' -X POST \
     -d '{"address": "192.168.0.1", "name": "testnode"}'

responseで帰ってくるの "selfLink": "https://localhost/mgmt/tm/ltm/node/~Common~testnode",
というのこのnodeをapiで操作するurl

  • node削除
curl --user user:pass -s -k https://192.168.0.1/mgmt/tm/ltm/node/~Common~testnode \
     -X DELETE 
  • pool追加

https://192.168.0.1/mgmt/tm/ltm/pool
postパラメータ

'{"name":"testpool-http","monitor":"http","description":"hoge:","members":[{"name":"testnode:80"}]}'

複数monitorを登録する方法は不明

https://192.168.0.1/mgmt/tm/ltm/virtual
postパラメータ

'{"name":"testvirtual-http","destination":"192.168.0.10:80","pool":"testpool-http"}' 

typeがstandardではなくてPerformance(layer 4)になる。。。

afm (security)

  • security address-list一覧

/mgmt/tm/security/firewall/address-list

  • security address-list追加

/mgmt/tm/security/firewall/address-list

'{"name": "hogehoge", "addresses": ["1.1.1.1/32"]}'
  • security address-list変更

PUTメソッドで上書きする
既存の内容を全て上書きするので、追加文だけではなくて既存のものも含める必要がある
/mgmt/tm/security/firewall/address-list/hogehoge -X PUT

'{"addresses": ["1.1.1.1/32", "2.2.2.2/32", "3.3.3.3/32"]}'

ddで書き込み時にキャッシュを使用せず書き込む

このオプションすぐ忘れる
oflag=direct

$ dd if=/dev/zero of=/tmp/hoge.dat bs=1M count=1000 oflag=direct

nginx のproxy_passするときのホスト名指定とresolver

(OS違ったけど詳細忘れた)現象が発生するサーバとしないサーバあったので、これだけが原因じゃないかも。とりあえず心に留めておく。

location /hoge/ {
  proxy_pass "http://example.com/";
} 

これは問題なく動いた。

proxy_pass先でurlまで指定すると

location /hoge/ {
  proxy_pass "http://example.com/hoge/";
} 

"no resolver defined to resolve"というエラーで502 Bad Gatewayが出た。
(もちろんosの/etc/resolv.confにはdns server指定している)

resolver でdns server指定したら動いた

location /hoge/ {
  resolver 8.8.8.8;
  proxy_pass "http://example.com/hoge/";
} 

big-ipで帯域制御 Bandwith ControllerとRate Shaping

Bandwith Controller

Bandwidth controllers のほうが最新機能のようなのでこっちのがいいかも
Rate Shapingの後継機能のようで、共存はできない。
(どこにも割り当てていないRate Shapingの設定すら存在してはいけない)

Acceleration - Bandwith Controller

VirtualServer
advancedにしてBandwith Controllerを選択

dynamicにするとper user で設定できるみたいだけど、
そのbandwidth controller設定はvirtual serverに適用できなかった。

iruleで適用

拡張子で適用する例
https://devcentral.f5.com/wiki/iRules.BWC__policy.ashx

when HTTP_REQUEST {
  if { [HTTP::path] ends_with ".mp4" } {
    BWC::policy attach bandwidth_test1
  }
}

virtualhost名で振り分ける例

  switch -glob [string tolower [HTTP::host]] {
    "www1.example.com" {
      BWC::policy attach bandwidth_test1
    }
    "www2.example.com" {
      BWC::policy attach bandwidth_test2
    }
  }

Rate Shaping

Acceleration - Rate Shaping

http://www.f5networks.co.jp/shared/pdf/BIG-IP_TB_Rate_Shaping.pdf

適用する箇所
VirtualServer
PacketFilter
iRule

一番使うのはVirtualServerかな

VirtualServer
Acceleration - Rate Class

ガチガチに制限せず、バーストトラフィック発生時に少し余裕を持たせるのであれば
Rate 10Mbps
Ceiling 50Mbps
Burst size 5MByte
とかにすれば良さげ?(数字は適当)