1

Similar documents
1

1.2. ご 利 用 環 境 推 奨 ブラウザ Internet Explorer Google Chrome(バージョン 32 時 点 で 動 作 確 認 済 み) Mozilla Firefox(バージョン 26 時 点 で 動 作 確 認 済 み) Safari 7

KINGSOFT Office 2016 動 作 環 境 対 応 日 本 語 版 版 共 通 利 用 上 記 動 作 以 上 以 上 空 容 量 以 上 他 接 続 環 境 推 奨 必 要 2

<4D F736F F D20819C486F70658F6F93588ED297708AC7979D89E696CA837D836A B E A2E646F63>

PowerPoint プレゼンテーション

目 次 1. Web メールのご 利 用 について Web メール 画 面 のフロー 図 Web メールへのアクセス ログイン 画 面 ログイン 後 (メール 一 覧 画 面 ) 画 面 共 通 項 目

(3) 小 単 元 の 指 導 と 評 価 の 計 画 小 単 元 第 11 章 税 のあらまし の 指 導 と 評 価 の 計 画 ( 四 次 確 定 申 告 制 度 抜 粋 ) 関 心 意 欲 態 度 思 考 判 断 技 能 表 現 知 識 理 解 小 単 元 の 評 価 規 準 税 に 関 す

Ver 改 訂 日 付 改 訂 内 容 1

「給与・年金の方」からの確定申告書作成編

Microsoft Word - 第3章.doc

続 に 基 づく 一 般 競 争 ( 指 名 競 争 ) 参 加 資 格 の 再 認 定 を 受 けていること ) c) 会 社 更 生 法 に 基 づき 更 生 手 続 開 始 の 申 立 てがなされている 者 又 は 民 事 再 生 法 に 基 づき 再 生 手 続 開 始 の 申 立 てがなさ

<4D F736F F D2090C389AA8CA72D92F18F6F2D D F ED28CFC82AF91808DEC837D836A B E838B A815B816A2E646F6378>


入 札 参 加 資 格 申 請 システム 操 作 マニュアル 入 札 参 加 資 格 の 資 格 有 効 ( 変 更 ) 日 を 迎 えると 追 加 届 の 登 録 ができるようになります ( 入 札 参 加 資 格 申 請 の 定 時 受 付 では いずれかの 申 請 先 団 体 から 入 札 参

<4D F736F F D208ED089EF95DB8CAF89C193FC8FF38BB CC8EC091D492B28DB88C8B89CA82C982C282A282C42E646F63>

迷惑メールフィルタリングコントロールパネル利用者マニュアル

<4D F736F F D AC90D1955D92E CC82CC895E DD8C D2816A2E646F63>

している 5. これに 対 して 親 会 社 の 持 分 変 動 による 差 額 を 資 本 剰 余 金 として 処 理 した 結 果 資 本 剰 余 金 残 高 が 負 の 値 となるような 場 合 の 取 扱 いの 明 確 化 を 求 めるコメントが 複 数 寄 せられた 6. コメントでは 親

エ CarotDAV が 起 動 すると 次 のようなウィンドウが 表 示 されます メニューバーにある File から New Connection の WebDAV を 選 択 します オ 次 のような 設 定 画 面 が 表 示 されたら General タブでネットワークアドレスなどを 設

WEBメールシステム 操作手順書

R4財務対応障害一覧

[2] 控 除 限 度 額 繰 越 欠 損 金 を 有 する 法 人 において 欠 損 金 発 生 事 業 年 度 の 翌 事 業 年 度 以 後 の 欠 損 金 の 繰 越 控 除 にあ たっては 平 成 27 年 度 税 制 改 正 により 次 ページ 以 降 で 解 説 する の 特 例 (

スライド 1

電子申告簡易マニュアル【所得税実践編】

( 別 途 調 査 様 式 1) 減 損 損 失 を 認 識 するに 至 った 経 緯 等 1 列 2 列 3 列 4 列 5 列 6 列 7 列 8 列 9 列 10 列 11 列 12 列 13 列 14 列 15 列 16 列 17 列 18 列 19 列 20 列 21 列 22 列 固 定

富士山チェックリスト

PowerPoint プレゼンテーション

( 別 紙 ) 以 下 法 とあるのは 改 正 法 第 5 条 の 規 定 による 改 正 後 の 健 康 保 険 法 を 指 す ( 施 行 期 日 は 平 成 28 年 4 月 1 日 ) 1. 標 準 報 酬 月 額 の 等 級 区 分 の 追 加 について 問 1 法 改 正 により 追 加

変 更 履 歴 日 付 Document ver. 変 更 箇 所 変 更 内 容 2015/3/ 新 規 追 加 2015/9/24 誤 字 修 正 2016/2/ 動 作 環 境 最 新 のものへ 変 更 全 体 オペレーター の 表 記 を 削 除 2016/5/

01_07_01 データのインポート_エクスポート_1

4 応 募 者 向 けメニュー 画 面 が 表 示 されます 応 募 者 向 けメニュー 画 面 で [ 交 付 内 定 時 の 手 続 を 行 う] [ 交 付 決 定 後 の 手 続 を 行 う]をクリックします 10

注 雇 促 進 税 制 と 本 制 度 のどちらかを 利 する 可 能 性 があるが あらかじめどちらの 制 度 を 利 するか 判 断 できない という 場 合 雇 促 進 税 制 の 事 前 届 出 ( 雇 促 進 計 画 の 提 出 )をした 上 で 申 告 の 際 にどちらを 利 するかご

改 定 履 歴 改 訂 日 改 訂 理 由 及 び 内 容 承 認 者 確 認 者 改 訂 者 05/8/7 新 版 発 行 05/0/5 推 奨 動 作 環 境 を 追 記

研究者情報データベース

< 目 次 > 8. 雇 用 保 険 高 年 齢 雇 用 継 続 給 付 27 ( 育 児 休 業 給 付 介 護 休 業 給 付 ) 8.1 高 年 齢 雇 用 継 続 給 付 画 面 のマイナンバー 設 定 高 年 齢 雇 用 継 続 給 付 の 電 子 申 請 高

 

ご 利 用 の 前 に 手 順 初 回 ご 利 用 時 に 必 ずご 確 認 ください ご 利 用 の 前 に (ご 利 用 環 境 の 確 認 ) P アクセス 方 法 (IMAGE WORKSサイトへアクセス) P 初 期 設 定 (JREのインストール) P

PowerPoint プレゼンテーション

< 現 在 の 我 が 国 D&O 保 険 の 基 本 的 な 設 計 (イメージ)> < 一 般 的 な 補 償 の 範 囲 の 概 要 > 請 求 の 形 態 会 社 の 役 員 会 社 による 請 求 に 対 する 損 免 責 事 由 の 場 合 に 害 賠 償 請 求 は 補 償 されず(

計算式の取り扱い

2016 年 度 情 報 リテラシー 三 科 目 合 計 の 算 出 関 数 を 用 いて 各 教 科 の 平 均 点 と 最 高 点 を 求 めることにする この2つの 計 算 は [ホーム]タブのコマ ンドにも 用 意 されているが 今 回 は 関 数 として 作 成 する まず 表 に 三 科

データコピーとは データコピーは 古 い NAS のデータを 新 しい HDL-Z シリーズに 簡 単 にコピーできます 環 境 例 本 製 品 は 以 下 の 用 途 の 際 に 最 適 です 古 い HDL-Z シリーズから 新 しい HDL-Z シリーズへのコピー 古 い HDL-Z シリーズ

4 承 認 コミュニティ 組 織 は 市 長 若 しくはその 委 任 を 受 けた 者 又 は 監 査 委 員 の 監 査 に 応 じなければ ならない ( 状 況 報 告 ) 第 7 条 承 認 コミュニティ 組 織 は 市 長 が 必 要 と 認 めるときは 交 付 金 事 業 の 遂 行 の


- INDEX - 1 ご 利 用 時 間 1 2 メニュー 1 3 ご 利 用 になる 前 に 行 っていただきたいこと 3 (1) 所 在 地 沿 線 設 定 3 (2) 会 員 情 報 の 管 理 ( 自 社 情 報 の 設 定 ) 5 4 物 件 情 報 の 登 録 8 (1) 操 作 概

MetaMoJi ClassRoom/ゼミナール 授業実施ガイド

C.1 共 有 フォルダ 接 続 操 作 の 概 要 アクセスが 許 可 されている 研 究 データ 交 換 システムの 個 人 用 共 有 フォルダまたは メーリングリストの 共 有 フォルダに 接 続 して フォルダを 作 成 したり ファイル をアップロードまたはダウンロードしたりすることがで

Microsoft Word - ML_ListManager_10j.doc

税金読本(8-5)特定口座と確定申告

2. データを 検 索 する なごやコレクションのデータを 検 索 するための 方 法 として キーワード 検 索 詳 細 検 索 の 二 通 りの 検 索 方 法 が あります 2.1. キーワードから 探 す キーワードを 入 力 する トップページの 入 力 ボックスに 検 索

PowerPoint プレゼンテーション

贈与税 faq

V-CUBE One

Microsoft Word - 不正アクセス行為の禁止等に関する法律等に基づく公安

「1 所得税及び復興特別所得税の確定申告書データをお持ちの方」からの更正の請求書・修正申告書作成編

(Microsoft Word - Excel\211\236\227p2\217\315.docx)

あいち電子調達共同システム

戦略担当者のための

0 目 次 1. 畑 のあしあとの 使 い 方 P.3 2.オプション P.6 3.モバイルデバイスより 履 歴 取 得 P.8 4. 基 本 情 報 管 理 P 栽 培 計 画 P.22 6.ドキュメント 出 力 P 栽 培 履 歴 管 理 P.28 8.モバイルでの 栽

<4D F736F F D C97F195CF8AB DEC90E096BE8F912091E6312E313294C52E646F63>

Microsoft Word - 311Tools_END

Taro-2220(修正).jtd

改 訂 履 歴 版 概 要 区 分 更 新 日 1.0 新 規 作 成 新 規 2014/06/26 2

スライド 1

目 次 必 ずお 読 みください 接 続 方 法 WEB ブラウザ 操 作 方 法 閲 覧 用 PC で 直 接 ZERO 本 体 と 接 続 する 場 合 各 ページについて 発 電 状 況 画 面 表 示... 3

2 課 題 管 理 ( 科 学 研 究 費 補 助 金 ) 画 面 が 表 示 されます 補 助 事 業 期 間 終 了 後 欄 の[ 入 力 ] をクリックします [ 入 力 ]ボタンが 表 示 されていない 場 合 には 所 属 する 研 究 機 関 の 事 務 局 等 へお 問 い 合 わせく

内 容 1. はじめに メールのログイン 初 めてのログイン メールの 受 信 / 送 信 メールの 受 信 メールの 作 成 と 送 信 メールの 新 規 作 成 メー

<4D F736F F D F93878CA797708F4390B3816A819A95CA8B4C976C8EAE91E682538B4C8DDA97E12E646F6378>

事前チェック提出用現況報告書作成ツール入力マニュアル(法人用)

スライド 1

検 索 しよう... 1 結 果 を 見 よう ~ 検 索 結 果 一 覧 ~... 2 結 果 を 見 よう ~ 検 索 結 果 詳 細 ( 図 書 )~... 3 結 果 を 見 よう ~ 検 索 結 果 詳 細 ( 雑 誌 )~... 4 ログインしよう... 5 私 の 本 棚 を 活 用

は 固 定 流 動 及 び 繰 延 に 区 分 することとし 減 価 償 却 を 行 うべき 固 定 の 取 得 又 は 改 良 に 充 てるための 補 助 金 等 の 交 付 を 受 けた 場 合 にお いては その 交 付 を 受 けた 金 額 に 相 当 する 額 を 長 期 前 受 金 とし

1. 表 から 値 を 抽 出 する 説 明 1.1. 表 から 値 を 抽 出 するための 関 数 について 説 明 します LOOKUP VLOOKUP HLOOKUP 関 数 は 検 索 値 に 対 応 する 値 を 検 索 値 を 含 む 一 覧 表 から 抽 出 し てくれる 関 数 です

(1)1オールゼロ 記 録 ケース 厚 生 年 金 期 間 A B 及 びCに 係 る 旧 厚 生 年 金 保 険 法 の 老 齢 年 金 ( 以 下 旧 厚 老 という )の 受 給 者 に 時 効 特 例 法 施 行 後 厚 生 年 金 期 間 Dが 判 明 した Bは 事 業 所 記 号 が

目 次 1. 積 算 内 訳 書 に 関 する 留 意 事 項 1 ページ 2. 積 算 内 訳 書 のダウンロード 3 ページ 3. 積 算 内 訳 書 の 作 成 (Excel 2003の 場 合 ) 6 ページ 4. 積 算 内 訳 書 の 作 成 (Excel 2007の 場 合 ) 13

事 業 税 の 外 形 標 準 課 税 事 業 税 は 都 道 府 県 が 所 得 ( 利 益 )に 対 して 課 税 します 1. 個 人 事 業 税 業 種 区 分 税 率 ( 標 準 税 率 ) 第 1 種 事 業 ( 物 品 販 売 業 製 造 業 金 銭 貸 付 業 飲 食 店 業 不 動

2.4 箇 条 書 のスタイルを 変 更 する 右 クリックして 箇 条 書 と 番 号 付 け を 選 択 する. あとは 少 し 遊 べば, このようなことをやりたい 人 は 理 解 できると 思 います 3 いろいろな 入 力 ワープロを 使 う 上 で 肝 心 な 点 は, 空 白 調 整

目 次. WEB メールへのログイン.... メール 送 信 手 順.... メール 受 信 手 順 アドレス 帳 の 操 作 手 順 フォルダーの 操 作 手 順 メール 発 信 者 登 録 署 名 登 録 手 順 基 本 的 な 設 定

目 次 ログインする 前 に... 4 メンバー 管 理 編 ( 管 理 者 )... 5 ログインする... 6 トップページについて... 7 メンバー 管 理 をする... 8 メンバー 管 理 画 面 について 医 療 機 関 指 定 新 規 追 加 指 定...

CSV_Backup_Guide

操 作 の 手 順 : 個 人 住 民 税 一 括 納 付 / 新 規 依 頼 修 正 複 写 個 人 住 民 税 一 括 納 付 メニュー 個 人 住 民 税 一 括 納 付 新 規 依 頼 修 正 複 写 依 頼 / 委 託 者 情 報 入 力 (P100) 依 頼 修 正 / 委 託 者 情

治 験 実 施 管 理 システム NMGCP 向 け Excel 形 式 プロトコール 作 成 手 順 書 V4.0.3 対 応 版 第 1 版 株 式 会 社 富 士 通 アドバンストエンジニアリング All Rights Reserved,Copyright 株 式 会 社 富 士 通 アドバン

5-2.操作説明書(支店連携)_xlsx

入札公告 機動装備センター

もくじ はじめに 本 書 はスマートフォンやタブレットのアプリ LINE の 設 定 を 行 うためのマニュアルとなります 詳 しい 操 作 方 法 については メーカーホームページ 上 の 基 本 的 な 使 い 方 を 参 照 ください LINE 基 本 的 な 使 い 方

メール 受 信 画 面 のレイアウトを 変 更 することができます ここでは 初 期 設 定 のレイアウトで 表 示 されているボタ ンやマークについて 解 説 します メール 一 覧 画 面 には 受 信 したメールが 一 覧 表 示 されます メール 受 信 タブをクリックすると 受 信 箱 フ

電子申告直前研修会(所得税編)

<4D F736F F F696E74202D2082C882E982D982C DD8ED88EE688F882CC82B582AD82DD C668DDA9770>


Taro13-01_表紙目次.jtd

同 期 を 開 始 する( 初 期 設 定 ) 2 1 Remote Link PC Sync を 起 動 する 2 1 接 続 機 器 の [PIN コード ] [ ユーザー 名 ] [ パスワード ] を 入 力 する [PIN コード ] などの 情 報 は 接 続 機 器 の 設 定 画 面

WEB版「新・相続対策マスター」(ご利用の手引き)

以 下 に 手 順 の 流 れを 記 載 します 3ページ 以 降 で 各 項 目 の 手 順 を 説 明 します ( をクリックすると 該 当 ページにジャンプします ) また 4ページに 汎 用 データ 受 入 に 関 するよくあるお 問 い 合 わせをご 紹 介 しています Step (3ペー

募集新株予約権(有償ストック・オプション)の発行に関するお知らせ


養 老 保 険 の 減 額 払 済 保 険 への 変 更 1. 設 例 会 社 が 役 員 を 被 保 険 者 とし 死 亡 保 険 金 及 び 満 期 保 険 金 のいずれも 会 社 を 受 取 人 とする 養 老 保 険 に 加 入 してい る 場 合 を 解 説 します 資 金 繰 りの 都

研究者総覧システム

2 科 学 研 究 費 助 成 事 業 のトップページ 画 面 が 表 示 されます [ 研 究 者 ログイン]をクリック します 掲 載 している 画 面 は 例 示 です 随 時 変 更 されます 3 科 研 費 電 子 申 請 システムの 応 募 者 ログイン 画 面 が 表 示 されます e

Ⅰ 調 査 の 概 要 1 目 的 義 務 教 育 の 機 会 均 等 その 水 準 の 維 持 向 上 の 観 点 から 的 な 児 童 生 徒 の 学 力 や 学 習 状 況 を 把 握 分 析 し 教 育 施 策 の 成 果 課 題 を 検 証 し その 改 善 を 図 るもに 学 校 におけ

年末調整

Transcription:

irules 設 定 ガイド(V11.5.1 対 応 ) 初 級 & 中 級 編 F5 Networks Japan V1.0

目 次 1. irules とは... 4 1.1. irules の 構 成... 4 2. TCL 動 作 確 認 の 準 備 (tclsh の 利 用 )... 5 2.1. BIG-IP への SSH アクセス... 5 2.2. tclsh を 使 う... 6 3. TCL の 基 礎... 7 3.1. 基 本 のコマンド 行... 7 3.2. コマンド 行 の 終 わり... 7 3.3. expr ( 計 算 )... 8 単 純 な 計 算... 8 計 算 式 を()でまとめる... 8 真 偽 の 計 算... 8 [ 参 考 ] TCL の 演 算 子 の 一 覧... 9 3.4. ドル 記 号 $ ( 変 数 置 換 ) [その 1]... 10 3.5. ブレス 記 号 :{ ( 無 効 化 )... 11 3.6. ドル 記 号 $ ( 変 数 置 換 ) [その 2]... 12 3.7. ブラケット 記 号 [ ] (コマンド 置 換 )... 13 3.8. ダブルクォーテーション 記 号 " "... 14 3.9. ブレス{ の 中 身 をコマンド 内 部 で 評 価 するもの... 15 expr... 15 if... 16 while... 17 for... 18 3.10. if, else, elseif... 19 3.11. switch... 20 switch の 基 本 サンプル... 20 switch のオプション... 20 switch の glob オプションの 例... 21 3.12. 配 列 変 数... 22 3.13. 文 字 列 操 作... 24 string... 24 split... 25 join... 25 append... 25 concat... 25 3.14. リスト 操 作... 26 list... 26 lindex... 26 llength... 26 lappend... 26 linsert... 27 lrange... 27 lreplace... 27 lsearch... 27 lsort... 28 3.15. foreach... 29 3.16. TCL のマニュアル... 29 4. irules の 概 要... 30 4.1. イベント... 30 4.2. 変 数 (variables) について... 31 ローカル 変 数 (Local variables)... 31 グローバル 変 数 (Global variables)... 32 irules 間 で 読 み 書 き 可 能 な 変 数 :Table コマンド... 33 irules の 変 数 一 覧... 34 4.3. 演 算 子 ( Operators )... 35 Ⅹ

4.4. ファンクション... 36 4.5. ステートメント... 37 4.6. コマンド... 38 出 現 頻 度 の 高 いコマンド... 38 コマンドの 注 意 点... 40 5. irules 動 作 確 認 用 のネットワーク 構 成 サンプル... 41 6. LTM の 設 定... 42 6.1. Platform 設 定... 42 6.2. VLAN 設 定... 42 6.3. Self IP 設 定... 43 6.4. Routing 設 定... 43 6.5. Pool の 設 定... 44 http-pool... 44 A-pool... 45 B-pool... 45 6.6. Virtual Server の 設 定... 46 Web-vs (Port:80)... 46 Secure-vs (Port:443)... 47 7. irules の 使 い 方... 48 7.1. [パターン 1] irule Editor を 使 う... 48 7.2. [パターン 2] BIG-IP の Web GUI を 使 う... 50 irule の 適 用... 51 出 力 されるログの 確 認... 52 8. irules の 具 体 例... 53 8.1. よく 使 う EVENT の 例... 53 CLIENT_ACCEPTED... 53 CLIENT_DATA... 54 HTTP_REQUEST... 55 HTTP_RESPONSE... 56 RULE_INIT... 57 LB_FAILED... 59 9. Class / Data-Group の 使 い 方... 61 Data-Group のデータの Type... 62 Internal Data-Group... 63 External Data-Group (その 1:String 形 式 )... 66 External Data-Group (その 2:Address 形 式 )... 68 9.2. table の 使 い 方... 71 10. irule 作 成 のテクニック... 74 10.1. デバッグのやり 方... 74 本 番 環 境 でのロギング 有 効 化 / 無 効 化... 74 10.2. irule による CPU 使 用 率 の 測 定... 76 2 つの irule で CPU 使 用 率 を 比 較... 76 irule の CPU 使 用 率 の 計 算... 78 10.3. irule を 最 適 化 する... 79 11. おわりに... 84 12. Appendix... 85 12.1. EVENT 発 動 のタイミング... 85 EVENT のフロー... 85 EVENT 発 動 を 確 認 するためだけの irule... 86 出 力 されたログ... 87 12.2. コマンド 一 覧 (2015/6 現 在 )... 89 Ⅹ

1. irules とは irule は BIG-IP 上 で 動 作 する パワフルでフレキシブルな 機 能 です irule は VirtualServer( 以 下 VS)に 関 連 付 けられるオブジェクトの 1 つで VS に 到 着 または VS から 出 力 される IP アプリケーショントラフィックに 対 して 記 述 されたスクリプトの 内 容 をもとに インターセプト( 割 込 ) インスペクト( 調 査 ) トランスフォーム( 変 換 )などの 様 々な 処 理 を 行 うことが 可 能 です 処 理 されたパケットは VS に 設 定 される Default pool だけではなく irule で 書 かれた pool や node へ 送 ること もできます また irule はパーシステンスでも 使 用 でき 更 に 認 証 にも 使 用 されます irule は TCL(Tool Command Language)を 用 いており 汎 用 性 の 高 い 実 装 を 行 っているので 様 々な 用 途 に 使 用 で きます 1.1. irules の 構 成 irule は 1 つ 以 上 の event と その event が 発 動 した 際 に 実 行 される TCL コードから 構 成 されます < 基 本 的 なシンタックス> when EVENT { if { 条 件 式 ( 比 較 演 算 など) { コマンド EVENT が irule 発 動 のトリガーとなり 条 件 式 が True なら コマンド を 実 行 します 例 えば http://www.foobar.com/test.txt のような "txt"で 終 わる URI は"Pool1"に 振 り 分 け それ 以 外 の HTTP リクエストは"Pool2"に 振 り 分 けたい という 要 件 があったとします 以 下 が この 要 件 を 実 現 する irule です when HTTP_REQUEST { 1 if { [HTTP::uri] ends_with "txt" { 2 pool pool1 3 else { 4 pool pool2 5 1 HTTP リクエストを 受 信 したとき 2 その HTTP リクエストの URI が txt で 終 わるのならば 3 Pool1 へ 送 る 4 それ 以 外 は 5 Pool2 へ 送 る 以 降 詳 細 解 説 に 入 ります 4

2. TCL 動 作 確 認 の 準 備 (tclsh の 利 用 ) 以 降 で TCL コマンドの 動 きを 確 かめることを 目 的 として BIG-IP へ SSH でログインし CLI 画 面 の bash で"tclsh"を 実 行 します tclsh は TCL インタプリタのためのシンプルなシェルで BIG-IP に 限 らず 多 くの Linux ディストリビュー ションで 標 準 搭 載 またはインストールして 利 用 することができます 例 )CentOS の 場 合 のインストール 方 法 : # yum -y install tcl 2.1. BIG-IP への SSH アクセス SSH クライアント( 例 :TeraTerm)を 使 って BIG-IP へ SSH でアクセスします (1) SSH でログインします BIG-IP のマネージメント IP アドレス (2) User name に root を 入 力 し Use challenge/response to log in をチェックします 5

(3) パスワードを 入 力 します (デフォルト 状 態 のパスワードは default です) (4) 以 下 のようなコマンドプロンプトが 表 示 されます [root@big208:active:in Sync] config # 2.2. tclsh を 使 う この bash で tclsh を 実 行 します [root@big208:active:in Sync] config #tclsh % 以 降 で 出 てくる TCL コマンド(%が 先 頭 についているものが 目 印 です)を この tclsh で 実 行 してその 結 果 を 確 認 してみてください tclsh を 終 了 する 際 は % exit を 入 力 または Ctrl + D キーを 押 してください 6

3. TCL の 基 礎 TCL(Tool Command Language)はスクリプト 言 語 で ティクルと 読 みます インタプリタ 言 語 リスト 処 理 連 想 配 列 などの 特 長 を 持 ち アプリケーション 開 発 のためのスクリプト 言 語 として 設 計 拡 張 されてきた 言 語 です irules は TCL で 記 述 されるので irules を 作 成 するには まず TCL の 基 本 を 理 解 する 必 要 があります TCL の 基 本 を 理 解 することで irule サンプルスクリプトもグッと 読 み 取 りやすくなります 本 セクションでは TCL について 解 説 します 3.1. 基 本 のコマンド 行 TCL は 以 下 のようなリスト 構 造 (= 要 素 をブランクで 区 切 って 並 べたもの)になっています リストの 先 頭 要 素 が コマンド で 残 りの 要 素 は アーギュメント( 引 数 ) です コマンド アーギュメント 1 アーギュメント 2 上 記 のような 形 で コマンドの 後 にブランクで 区 切 られたアーギュメントが 続 きます TCL はこのようなリスト 構 造 をとっているため ブランクやタブは リストを 構 成 する 要 素 の 区 切 り 文 字 として 重 要 な 意 味 を 持 つ という 点 に 注 意 が 必 要 です 3.2. コマンド 行 の 終 わり コマンド 行 の 終 わりは 改 行 によって 示 されます もうひとつは ; (セミコロン) です ; を 使 うと 複 数 のコマンド 行 を 続 けて 1 行 に 書 くことができます コマンド アーギュメント 1 アーギュメント 2; コマンド アーギュメント 3 アーギュメント 4 7

3.3. expr ( 計 算 ) まず TCL で 計 算 を 行 う 際 に 使 う expr コマンドにについて 触 れておきます expr は 数 式 を 解 釈 して 計 算 した 結 果 を 返 します 計 算 式 は オペランド と 演 算 子 (+ - * / < > == 等 )の 組 み 合 わせで 構 成 されます オペランドとは 演 算 の 対 象 となる 値 や 文 字 列 のこと 尚 TCL でのブランクやタブは リストを 構 成 する 要 素 の 区 切 り 文 字 として 重 要 な 意 味 を 持 つ とお 伝 えしましたが 式 のなかのブランクに 関 しては 無 視 されます 単 純 な 計 算 % expr 1 + 2 + 3 + 4 + 5 15 が 返 されます 計 算 式 を()でまとめる ( 丸 カッコ )は 計 算 と 論 理 変 数 をまとめるときに 使 います % expr 2 * 3 / 3 + 3 5 が 返 されます % expr 2 * 3 / (3 + 3) 1 が 返 されます 真 偽 の 計 算 expr コマンドで 対 象 比 較 演 算 子 (< > <= >=)や 等 値 比 較 演 算 子 (==!=)などを 利 用 することで 真 偽 の 計 算 が できます % expr 1 > 1 0 = " 偽 "という 値 が 返 されます % expr 1 == 1 1 = " 真 "という 値 が 返 されます 8

[ 参 考 ] TCL の 演 算 子 の 一 覧 TCL では 以 下 のような 演 算 子 を 使 うことができます 演 算 子 - + ~! * / % 説 明 単 項 のマイナス プラス ビット 毎 の 否 定 論 理 否 定 いずれも 文 字 列 に 対 しては 使 えない ビット 毎 の 否 定 は 整 数 に 対 してのみ 適 用 可 能 乗 算 除 算 剰 余 の 2 項 演 算 子 いずれも 文 字 列 に 対 しては 使 えない 剰 余 演 算 子 (%)は 整 数 に 対 してのみ 適 用 可 能 + - 加 算 および 減 算 (2 項 演 算 子 ) オペランドが 数 値 ならば 使 用 可 能 << >> 左 シフトおよび 右 シフト 演 算 子 オペランドは 整 数 のみ 可 能 < > <= >= ==!= 大 小 比 較 演 算 子 比 較 結 果 が 真 なら 1 を 偽 なら 0 を 返 す オペランドは 数 値 だけではなく 文 字 列 で もよい 等 値 比 較 演 算 子 結 果 が 真 なら 1 を 偽 なら 0 を 返 す オペランドは 数 値 だけではなく 文 字 列 でもよ い eq ne 文 字 列 専 用 の 等 値 比 較 演 算 子 eq は 等 しいときに 1 を 返 し ne は 等 しくないときに 1 を 返 す & ^ ビット 毎 の and 演 算 子 オペランドは 整 数 のみ ビット 毎 の exor 演 算 子 オペランドは 整 数 のみ ビット 毎 の or 演 算 子 オペランドは 整 数 のみ && 論 理 的 な "and" 演 算 子 2つのオペランドがともに 非 ゼロなら 1 を 返 し そうでなければ 0 を 返 す オペランドはブーリアンタイプかまたは 数 値 論 理 的 な "or" 演 算 子 2つのオペランドがともにゼロなら 0 を 返 し そうでなければ 1 を 返 す オペランドはブーリアンタイプかまたは 数 値 x? y : z C 言 語 と 同 様 の3 項 演 算 子 で x が 非 ゼロなら y を そうでなければ z を 返 す x はブーリアンタイプか または 数 値 9

3.4. ドル 記 号 $ ( 変 数 置 換 ) [その 1] TCL の 重 要 な 機 能 のひとつに 変 数 があります この 変 数 機 能 の 提 供 により コマンド 間 でのデータの 受 け 渡 しが 可 能 になります 変 数 は set コマンドにより 生 成 されます TCL パーサー は $ 記 号 が 先 頭 に 付 いた 要 素 を 変 数 名 とみなし その 変 数 をその 実 体 に 置 き 換 えてからコマンドを 実 行 します これが 変 数 置 換 です % set a 100 % puts $a 100 が 返 されます TCL パーサーが $a (= 変 数 ) を 100 (= 実 体 ) に 変 数 置 換 した 結 果 です (ちなみに"puts"は ディスプレイへの 標 準 出 力 を 行 うコマンドです ) [ 参 考 ] TCL パーサー(Parser)とは パーサー(Parser)は 一 般 的 には 構 文 解 析 を 行 うためのプログラムの 総 称 です TCL においてもパーサーが 存 在 しており TCL 言 語 で 記 載 されたスクリプトを 解 析 するプログラム とお 考 えくださ い 以 降 の 解 説 でも TCL パーサーという 言 葉 を 使 います 10

3.5. ブレス 記 号 :{ ( 無 効 化 ) アーギュメントをブレス{ で 囲 むことで 囲 まれた 部 分 に 含 まれるあらゆる 特 殊 文 字 の 機 能 を 無 効 化 しま す なので ブレス{ 内 はバックスラッシュ(\)=エスケープなしで 改 行 できますし ブランクやタブを 要 素 の 中 に 含 めることもできます 以 下 の 文 字 列 は 3 つの 要 素 からなるリストです "a f5 fan"はブランクを 含 んでいますが { によって 無 効 化 さ れ ひとつの 要 素 として 扱 われます You are {a f5 fan コマンドも 一 つの 要 素 です したがって 以 下 の 文 字 列 は 3 つの 要 素 からなる 一 つのリストです if {$a > 0 {set a 0 ブレス{ 内 は 改 行 文 字 も 無 効 化 されるので 以 下 の 形 が 成 り 立 ちます if {$a > 0 { set a 0 しかし 以 下 の 形 は 成 り 立 ちません if {$a > 0 { set a 0 これが 成 り 立 たないのは ブレス{ の 制 限 ではなく if コマンドの 制 限 によるものです if コマンドに 続 く 第 1 アーギュメントの 直 後 で 改 行 されているので そこでコマンド 行 の 終 了 を 意 味 します よって if コマンドが 求 める 第 2 アーギュメントがコマンド 行 に 存 在 しない という 理 由 で このコマンドが 成 り 立 たな くなります 以 下 3 つを tclsh で 実 行 してみてください (1) サンプル 1 % set a 100 % if {$a > 0 {set a 0 (2) サンプル 2 % set a 100 % if {$a > 0 { set a 0 (3) サンプル 3 % set a 100 % if {$a > 0 ここでエラーになります { set a 0 11

3.6. ドル 記 号 $ ( 変 数 置 換 ) [その 2] 変 数 について もう 少 し 踏 み 込 んで 解 説 します (1) 変 数 置 換 とブレス{ 前 項 でブレス{ について 触 れましたので 変 数 置 換 とブレス{ の 関 係 についても 触 れておきます 以 下 のような 文 字 列 もブレス{ に 囲 まれると 一 つの 要 素 となるので これも 変 数 に 取 込 むことができます % set a {You are a f5 fan. % puts $a You are a f5 fan. が 返 されます これは TCL パーサーが $a (= 変 数 ) を You are a f5 fan. (= 実 体 ) に 変 数 置 換 した 結 果 です 尚 TCL パーサーによる 変 数 置 換 は 1 回 しか 実 行 されない という 点 に 注 意 してください よって 変 数 置 換 結 果 に $ が 含 まれていても 再 置 換 が 行 われることはありません % set a {You are a $a fan. % puts $a You are a $a fan. が 返 されます また 変 数 置 換 後 の 結 果 にブランクが 含 まれていても 複 数 のアーギュメントとしてみなされることはなく ブランクが 含 まれた 1 つのアーギュメントと 判 断 されます ( 上 記 例 のとおりです ) これは 変 数 置 換 を 行 った 後 では ブランク 区 切 りによるリスト 構 造 の 認 識 は 行 われない ということを 意 味 します その 他 少 し 変 則 的 な 変 数 の 使 い 方 を 以 下 2 つ 紹 介 しておきます (2) $をつけない 変 数 変 数 の 値 を 直 接 処 理 するコマンドの 場 合 変 数 の 先 頭 に"$"を 付 けずに 利 用 する 場 合 が 多 いです 以 下 は 変 数 int に"1"を 加 える 例 です("1"は 省 略 されています) % set int 1 % incr int 2 が 返 されます (3) 変 数 と 文 字 を 繋 げたい(ブランクで 区 切 りたくない) 場 合 変 数 の 文 字 部 分 ($を 含 まない)をブレス{ で 囲 むことで 変 数 と 連 続 したキャラクタ(ブランクで 区 切 らないキャラク タ)を 繋 げることができます 以 下 は int の 実 体 が 数 字 であり その 数 字 の 後 ろに"th"をつけることで 日 付 を 表 現 する 例 です % set int 5 % puts "Today's date is the ${intth" Today's date is the 5th が 返 されます 12

3.7. ブラケット 記 号 [ ] (コマンド 置 換 ) TCL は リストの 先 頭 要 素 を 常 にコマンド 名 として 認 識 します それ 以 外 の 要 素 はコマンドに 渡 すべきアーギュメントとして 認 識 します しかし そのアーギュメント 要 素 がブラケット[ ]で 挟 まれていると TCL パーサーはその 中 身 をコマンド 行 と 認 識 し それを 実 行 して 本 来 のアーギュメント 値 に 置 き 換 えてくれます コマンドを 実 体 値 に 置 き 換 える これが コマンド 置 換 です % set a [expr 1000 * 5] % puts $a 5000 が 返 されます 上 記 の 行 は TCL パーサーが[ ]の 中 を 計 算 して 5000 に 置 き 換 えているので set a 5000 という 指 定 をしているのと 同 じ 結 果 になります また コマンド 置 換 は 以 下 のようにネストすることも 可 能 です % set b 3 % set a [expr 5 + [expr $b * 70]] % puts $a 215 が 返 されます 13

3.8. ダブルクォーテーション 記 号 " " 既 述 のように ブレス{ は 改 行 コードなどの 特 殊 文 字 の 機 能 を 無 効 化 します この 法 則 はコマンド 置 換 子 であるブラケット[ ]や 変 数 置 換 子 である$ 記 号 に 対 しても 同 様 です そのため 下 記 のコードではコマンド 置 換 も 変 数 置 換 も 行 われません % set num 5 % puts {[expr 100 * $num] Yen よって この 実 行 結 果 として 出 力 される 文 字 列 は 以 下 です [expr 100 * $num] Yen コマンド 置 換 も 変 数 置 換 も 機 能 させ かつブランクを 含 む 文 字 列 をひとつのアーギュメントとして puts コマンドに 渡 したい 場 合 には ブレスの 代 わりにダブルクォーテーション(")で 挟 みます % set num 5 % puts "[expr 100 * $num] Yen" このコマンドの 実 行 結 果 として 500 Yen が 出 力 されます このように ダブルクォーテーションの 機 能 は コマンド 置 換 と 変 数 置 換 を 許 すところが ブレス{ と 異 なる 点 です 14

3.9. ブレス{ の 中 身 をコマンド 内 部 で 評 価 するもの ブレス{ で 囲 むと 特 殊 文 字 の 機 能 が 無 効 化 されてしまうのであれば { で 囲 むと 何 も 実 行 されなくなるのではな いか?と 思 われたかもしれません ある 意 味 では 正 しいです 事 実 として 例 えば 既 述 の set や puts コマンドでは { 内 のコマンド 置 換 や 変 数 置 換 は 実 施 されず { はただ 単 に 文 字 列 として 返 されました % set a {You are a $a fan. % puts $a You are a $a fan. が 返 されます 変 数 置 換 が 行 われません %puts {[expr 100 * $num] Yen [expr 100 * $num] Yen が 返 されます 変 数 置 換 もコマンド 置 換 も 行 われません しかし コマンドによっては TCL パーサーがそのブレス{ で 囲 まれたアーギュメントをコマンドに 引 渡 し そのコマン ドが 内 部 で 評 価 を 行 う (=コマンド 置 換 や 変 数 置 換 する) ものがあります その 代 表 が expr や if や while や for コマンドなどです expr 算 術 演 算 を 行 う expr コマンドは アーギュメントをコマンド 内 部 で 評 価 します よって 以 下 の 2 つのコマンド (1 と 2) は 同 じ 結 果 を 返 します % set a 11 % set b 22 % expr $a * $b 1 % expr { $a * $b 2 1も2も 242 が 返 されます 上 記 2に 関 しては ブレス{ で 囲 まれている 部 分 は 無 効 化 されているので TCL パーサーは 変 数 置 換 を 行 いませ ん しかし TCL パーサーが 変 数 置 換 を 行 ってくれなくても expr がコマンドの 内 部 でブレス{ 内 の 変 数 置 換 を 実 行 す るので 同 じ 結 果 が 得 られる ということです 上 記 1の 場 合 TCL パーサーによる 変 数 置 換 の 後 に expr 内 で 計 算 を 行 う という 2 回 の 処 理 に 対 し 2は expr 内 で 一 度 に 処 理 するので 2の 方 が 効 率 は 良 い といえます 15

if if は その 第 1 アーギュメントが 真 なら 第 2 アーギュメントをコマンド 内 部 で 評 価 する というコマンドです また if コマンドは 第 1 アーギュメントをコマンド 内 部 で expr によって 評 価 し その 結 果 を 使 います % set val 1 % if $val { set a 111 TCL パーサーは if コマンド 行 の 第 1 アーギュメントの $val を 評 価 して 1 に 書 き 換 えます( 変 数 置 換 ) 同 様 に TCL パーサーは 第 2 アーギュメントの{ set a 111 を 評 価 し ブレス{ で 囲 まれているので 文 字 列 とし て 処 理 し 以 下 のようにします % if 1 { set a 111 TCL バーサーはこの 後 1 と set a 111 を if コマンドに 渡 します if コマンド 側 は 受 け 取 った 第 1 アーギュメントの 文 字 列 を expr コマンドに [expr 1] として 渡 し その 結 果 が 真 なので 第 2 アーギュメントの set a 111 を 処 理 します 第 1 アーギュメントをブレス{ で 囲 んでも 同 じ 結 果 が 得 られます % set val 1 % if {$val { set a 111 この 場 合 TCL パーサーは if コマンド 行 の 第 1 アーギュメントを $val という 4 文 字 の 文 字 列 として 処 理 し 第 2 アーギュメントも set a 111 を 文 字 列 として 処 理 し if コマンドに 渡 します if コマンド 側 は 受 け 取 った 文 字 列 を expr コマンドに [expr {$val] として 渡 し その 結 果 が 真 なので set a 111 を 処 理 します if のように コマンドがアーギュメントを 内 部 で 評 価 してくれるならば そのアーギュメントはブレス{ で 挟 んで 渡 し た 方 が 効 率 がよくなります このことで TCL パーサーと if コマンドによる 計 2 回 の 評 価 処 理 を 1 回 に 減 らすことができるからです 16

while while コマンドも if コマンドと 同 様 に 第 1 アーギュメントとして 与 えられた 文 字 列 を while コマンド 内 部 で expr に よって 評 価 し その 結 果 を 使 います while は 第 1 アーギュメントが 真 の 場 合 に 第 2 アーギュメントを 処 理 する というところまでは if と 同 じです if と 異 なるのは 第 2 アーギュメントを 処 理 し 終 えると 再 び 第 1 アーギュメントを 評 価 し それが 真 なら 再 び 第 2 ア ーギュメントの 処 理 を 行 う という 繰 り 返 し 実 行 がなされる 点 です したがって 以 下 の 形 では 問 題 が 発 生 します % set val 1 % while $val { set a 111 TCL パーサーが 変 数 置 換 を 行 うので $val は 1 です よって while 行 は 実 質 以 下 の 形 になっています % while 1 { set a 111 この 状 態 だと 常 に 真 であるため 永 遠 に set a 111 が 繰 り 返 される 無 限 ループに 陥 ります 例 えば 以 下 のような 形 は 無 限 ループに 陥 ります % set a 100 % set val 1 % while $val { if {$a > 0 { set val 0 puts $val 5 行 目 で set val 0 を 実 行 しても while のあとの$val は 1 のままなので 0 の 出 力 が 延 々と 続 きます この 無 限 ループを 回 避 するためには while の 後 ろの$val をブレス{ で 囲 みます % set a 100 % set val 1 % while {$val { if {$a > 0 { set val 0 puts $val このことによって ブレス{ 内 は TCL パーサーによる 変 数 置 換 が 無 効 化 され while コマンドに$val という 文 字 列 として 渡 されます while が 1 回 目 の 処 理 を 終 え 2 回 目 の 処 理 に 入 る 際 に$val が while コマンド 内 で 再 評 価 ( 変 数 置 換 ) されるの で $val は 0 = 偽 となり while 処 理 が 終 了 します よって このような 無 限 ループを 回 避 するためには 第 1 アーギュメントをブレス{ で 囲 む 必 要 があります 17

for for ループは while ループと 似 ていますが ループに 入 る 前 の 初 期 化 (カウンタ 用 の 変 数 の 初 期 化 を 行 なう)を 含 む 点 が while ループとは 異 なります for {init {test {next {body (1) {init ループに 入 る 前 に 一 度 だけ 実 行 される 初 期 化 と 呼 ばれる 処 理 です 例 : set i 1 最 初 だけ 変 数 i に 1 をセットする (2) {test 終 了 条 件 を 判 断 するものです もし test が 真 ならば {bodyの 中 が 実 行 されます test が 偽 ならループから 抜 け 出 します 例 : $i<=3 $i が 3 以 下 ならば {bodyを 実 行 する (3) {next {bodyの 中 が 実 行 された 後 で 実 行 されるもので 一 般 的 には 増 分 を 指 定 します 例 : incr i {bodyの 処 理 が 終 わったら $i の 値 を 1 ずつ 増 やす % for {set i 1 {$i<=3 {incr i { puts $i 出 力 結 果 は 1, 2, 3 です "for"の 場 合 {testを for コマンドの 内 部 で 評 価 するように 作 られており {initおよび{nextはそれぞれ 構 文 で 指 定 することから 全 てをブレス{ で 囲 む 必 要 があります これらの 理 由 から if, while, for コマンドのアーギュメントは 常 にブレス{ で 挟 んでおくことで 不 要 なエラー を 避 けることができます 18

3.10. if, else, elseif if, else, elseif を 使 って 複 雑 な 条 件 分 岐 を 行 うことができます (1) サンプル 1 $var の 値 が 1 なら 変 数 a に 値 123 をセットします % set var に 1 または 1 以 外 を 入 力 % if {$var == 1 { set a 123 (2) サンプル 2 $var の 値 が 1 なら 変 数 a に 値 123 をセット それ 以 外 であれば 変 数 a に 値 456 をセットします % set var に 1 または 1 以 外 を 入 力 % if {$var == 1 { set a 123 else { set a 456 (3) サンプル 3 $var の 値 が 1 なら 変 数 a に 値 123 をセット $var の 値 が 2 なら 変 数 a に 値 456 をセット それ 以 外 であれば 変 数 a に 値 777 をセットします % set var に 1 または 1 以 外 を 入 力 % if {$var == 1 { set a 123 elseif {$var == 2 { set a 456 else { set a 777 19

3.11. switch switch コマンドは 複 数 の 分 岐 条 件 の 中 から 一 致 する 条 件 を 見 つけ 出 し そこに 指 定 された 処 理 を 実 行 します switch コマンドは 以 下 のような 構 文 になっています switch string { pattern1 {body-1 pattern2 {body-2 default {body-default switch コマンドは 最 初 のアーギュメント (String) を 後 続 のアーギュメント (pattern1, pattern2) と 比 較 しま す string にマッチする pattern を 見 つけると その pattern に 続 く body を TCL パーサーに 渡 し その 実 行 結 果 を 返 します 最 後 の pattern を"default"で 指 定 すると 前 行 のどの pattern にもマッチしなかった 場 合 に default の body を 実 行 します もし どの pattern もマッチせず "default"も 設 定 していない 場 合 switch コマンドは 空 の string を 返 します switch の 基 本 サンプル % set fruit "Lemon" % switch $fruit { "Apple" {puts "RED" "Grape" {puts "PURPLE" "Lemon" {puts "YELLOW" default {puts "What color is that fruit?" YELLOW が 返 されます switch のオプション Switch コマンドに 続 くアーギュメントが - (ハイフン)で 始 まっている 場 合 は オプションとして 扱 われます switch コマンドには 以 下 のようなオプションが 用 意 されています; (1) -exact string と pattern の 文 字 が 一 字 一 句 完 全 に 一 致 しなければなりません これがデフォルトの 動 作 です (2) -glob String と pattern を 比 較 するときに 正 規 表 現 の glob スタイルを 使 います (3) -regexp String と pattern を 比 較 するときに 正 規 表 現 が 使 われます 20

[ 参 考 ] glob と regexp の 違 い 正 規 表 現 には glob スタイルと regexp スタイルがあり 両 者 の 違 いは 以 下 の 通 りです glob のほうが 比 較 的 シンプルに 作 られています glob スタイル regexp スタイル * 0 文 字 以 上 の 文 字 にマッチ * 0 文 字 以 上 の 文 字 にマッチ? 1 文 字 にマッチ. 1 文 字 にマッチ + + 1 文 字 以 上 にマッチ? 0 または 1 文 字 にマッチ ^ 行 の 先 頭 にマッチ $ 行 の 最 後 にマッチ [chars] chars の 1 文 字 にマッチ [a-z]などが 使 える [chars] chars の 1 文 字 にマッチ [a-z]などが 使 える x 文 字 x にマッチ x 文 字 x にマッチ {a,b,... a,b 等 文 字 列 にマッチ {a,b,... a,b 等 文 字 列 にマッチ exp1 exp2 選 択 ( exp ) 部 分 パターン (その 他 省 略 ) switch の glob オプションの 例 (1) "?"を 使 ってみる % set fruit "Lemon" % switch -glob $fruit { "Ap*" {puts "RED" "Gr???" {puts "PURPLE" "Le???" {puts "YELLOW" Le に 3 文 字 続 く 必 要 があるが どのような 文 字 でもよい default {puts "What color is that fruit?" YELLOW が 返 されます (2) [a-za-z]を 使 ってみる % set fruit "Lemon" % switch -glob $fruit { "Ap*" {puts "RED" "Gr???" {puts "PURPLE" "Lem[a-zA-Z][a-zA-Z]" {puts "YELLOW" default {puts "What color is that fruit?" Lem に 続 く 2 文 字 が a~z か A~Z のいずれか YELLOW が 返 されます 21

3.12. 配 列 変 数 TCL でも 配 列 を 扱 うことができます TCL での 配 列 変 数 は 変 数 名 ( 添 え 字 ) で 表 されます 配 列 変 数 としての 宣 言 や 要 素 数 の 指 定 は 必 要 なく ()が 付 いた 変 数 に 値 がセットされるときに 配 列 変 数 とし て 認 識 登 録 されます % set i 0 % while {$i < 3 { set abc($i) $i puts "abc($i) = $abc($i)" incr i 出 力 結 果 は 以 下 です abc(0) = 0 abc(1) = 1 abc(2) = 2 要 素 を, や. で 区 切 って 複 数 記 述 することによって 多 次 元 配 列 を 使 用 できます % set i 0 % set k 0 % while {$i < 3 { while {$k < 3 { set abc($i.$k) [expr $i+$k] puts "abc($i.$k) = $abc($i.$k)" incr k incr i set k 0 出 力 結 果 は 以 下 です abc(0.0) = 0 abc(0.1) = 1 abc(0.2) = 2 abc(1.0) = 1 abc(1.1) = 2 abc(1.2) = 3 abc(2.0) = 2 abc(2.1) = 3 abc(2.2) = 4 22

以 下 のように 同 名 の 通 常 変 数 と 配 列 変 数 を 同 一 のスクリプト 内 で 使 用 することはできません 使 うとエラーになります % set a 300 % set a(1) 400 can't set "a(1)": variable isn't array また 要 素 数 は 数 字 である 必 要 は 無 く 文 字 列 も 使 用 できます % unset -nocomplain a 一 旦 変 数 "a"を 削 除 % set a(jkl) 200 ただし 利 用 の 利 便 性 を 考 えると 数 字 を 使 用 するのが 一 般 的 です 23

3.13. 文 字 列 操 作 以 下 のコマンドで 文 字 列 操 作 が 行 えます string (1) string compare string1 string2 文 字 列 の 比 較 を 行 います 文 字 列 string1 と string2 を 文 字 毎 に 比 較 して -1 0 1 のいずれかを 返 します string1 と string2 等 しければ 0 を 返 します 辞 書 順 で 比 較 するので string1 の 方 が string2 よりも 辞 書 順 で 前 に 出 現 する 文 字 列 なら -1 を 後 で 出 現 す る 文 字 列 なら 1 を 返 し 返 します % string compare abc abc 0 が 返 されます % string compare abc def -1 が 返 されます % string compare abc ABC 1 が 返 されます (2) string toupper 小 文 字 を 大 文 字 に 変 換 します % string toupper AbCdEfgHiJkLmN ABCDEFGHIJKLMN が 返 されます (3) string tolower 大 文 字 を 小 文 字 に 変 換 します % string tolower AbCdEfgHiJkLmN abcdefghijklmn が 返 されます (4) string length 文 字 列 の 長 さを 返 します % string length AbCdEfgHiJkLmN 14 が 返 されます 24

split 文 字 列 を 決 められたデリミタで 区 切 ったリストを 返 します % split "abcxdefxghixjkl" X abc def ghi jkl が 返 されます join リストを 決 められたデリミタで 文 字 列 として 結 合 して 返 します % join "abc def ghi jkl" # abc#def#ghi#jkl が 返 されます append 既 に 存 在 する 変 数 にデータを 付 け 足 す 時 に 使 います (Note: もし 変 数 が 存 在 していなければ このコマンドが 変 数 を 作 ります ) % set var 0 % for {set i 1 {$i<=10 {incr i { append var "," $i % puts $var 0,1,2,3,4,5,6,7,8,9,10 が 返 されます ( 変 数 の 値 を 直 接 処 理 するコマンドなので 変 数 var の 前 に$をつけません ) concat 各 アーギュメントの 先 頭 と 末 尾 のスペースをカットし 全 てのアーギュメントをスペースで 連 結 します アーギュメントの 個 数 はいくつでもかまいません 以 下 は 3 つのアーギュメントです % concat " a b {c " d " e f " a b {c d e f が 返 されます 25

3.14. リスト 操 作 以 下 のコマンドで リスト( 要 素 を 並 べたもの)の 操 作 が 行 えます list 変 数 群 $val1, $val2 を 要 素 としたリストを 返 します list $val1 $val2 % list AAAA BBBB "CCCC DDDD" EEE AAAA BBBB {CCCC DDDD EEE が 返 されます lindex リストから$index 番 目 の 要 素 を 取 り 出 します lindex $list $index % set LIST [list AAAA BBBB "CCCC DDDD" EEE] % lindex $LIST 1 BBBB が 返 されます llength リストの 要 素 の 数 を 返 します llength $list % set LIST [list AAAA BBBB "CCCC DDDD" EEE] % llength $LIST 4 が 返 されます lappend 変 数 に 対 してリスト 要 素 の 追 加 し その 結 果 のリストを 返 します lappend variable $var1 $var2 % set LIST [list AAAA BBBB "CCCC DDDD" EEE] % lappend LIST 111 222 333 AAAA BBBB {CCCC DDDD EEE 111 222 333 が 返 されます ( 変 数 の 値 を 直 接 処 理 するコマンドなので 変 数 LIST の 前 に$をつけません ) 26

linsert リストの$index 番 目 の 要 素 の 前 に 要 素 $val1, $val2, を 挿 入 したリストを 返 します linsert $list $index $val1 $val2 % set LIST [list AAAA BBBB "CCCC DDDD" EEE] % linsert $LIST 0 111 222 333 111 222 333 AAAA BBBB {CCCC DDDD EEE が 返 されます lrange リスト$list の$index_s 番 目 から$index_e 番 目 までの 要 素 をリストとして 返 します 最 後 までの 場 合 は$last の 中 身 を 文 字 列 end にします lrange $list $index_s $index_e % set LIST [list AAAA BBBB "CCCC DDDD" EEE] % lrange $LIST 1 3 BBBB {CCCC DDDD EEE が 返 されます lreplace リスト$list の$s 番 目 から$e 番 目 までの 連 続 した 要 素 をすべての 要 素 $val1, $val2, で 置 き 換 え 新 しいリス トを 返 します lreplace $list $s $e $val1 $val2 % set LIST [list AAAA BBBB "CCCC DDDD" EEE] % lreplace $LIST 1 3 QQQ PP AAAA QQQ PPP が 返 されます lsearch リスト$list から $sw で 任 意 で 与 えられたパターンマッチング 方 式 で $pattern に 合 致 する 最 初 の 要 素 のインデ ックスを 返 します $sw は-glob( 方 式 ) exact( 完 全 一 致 ) regexp( 正 表 現 )などが 用 意 されます lsearch $sw $list $pattern % set LIST [list AAAA BBBB "CCCC DDDD" EEE] % lsearch -glob $LIST E?? 3 が 返 されます 27

lsort リスト$list の 要 素 をソートしたリストを 返 します $switch には -ascii(ascii コード 順 ) -integer( 数 字 順 ) などが 用 意 されています lsort $switch $list % set LIST [list CCCC QQQQ 108Z AAAA LLLL 3333 5555 2222 4444 1111] % lsort -ascii $LIST 1111 2222 3333 4444 5555 AAAA CCCC LLLL QQQQ 108Z が 返 されます 28

3.15. foreach foreach コマンドは リストを 使 ったループです リストの 要 素 を 左 から 一 つずつ 変 数 に 代 入 して ループの 処 理 を 実 行 します 書 式 は 次 のようになります foreach valname $list {body $list から 要 素 を 一 つずつ 取 り 出 し 変 数 valname に 順 番 に 代 入 し body を 実 行 します この 処 理 を 要 素 数 の 分 だけ 繰 り 返 し 行 います % set LIST [list AAAA BBBB "CCCC DDDD" EEE] % foreach item $LIST { puts "item is $item" 出 力 結 果 は 以 下 です item is AAAA item is BBBB item is CCCC DDDD item is EEE 3.16. TCL のマニュアル TCL はこの 他 にも 多 数 のコマンドを 持 っています また コマンドによっては ここに 紹 介 したもの 以 外 にも 多 数 のオプションを 持 っているものがあります 実 際 の TCL コマンド 利 用 に 際 しては 以 下 リンクを 参 照 して より 要 件 にあうコマンドやオプション 指 定 がないかを 確 認 してください 英 語 : http://www.tcl.tk/ 日 本 語 : http://www.freesoftnet.co.jp/tclkits/doc/tclcmdref/tcl_contents_jp.htm 29

4. irules の 概 要 ここからは irules の 特 徴 について 解 説 します 尚 irules のより 詳 細 な 情 報 や 多 数 のサンプルは F5 の DevCentral サイトに 掲 載 していますので 必 要 に 応 じてこ ちらもご 参 照 ください [DevCentral] https://devcentral.f5.com/wiki/irules.homepage.ashx 4.1. イベント EVENT は F5 が 追 加 した TCL 拡 張 です あるコネクションが TMOS に 入 力 されてから 出 力 されるまでの 間 に BIG-IP 内 部 で ある 一 連 の 複 数 の 内 部 状 態 の 変 化 が 発 生 します これらそれぞれの 状 態 と irule の EVENT とが 一 致 するように 作 られており この EVENT が irule を 発 動 するトリガ ーになります 例 えば CLIENT_ACCEPTED は どのような Profile が Virtual Servers に 割 当 てられているかに 関 わらず 全 ての TCP コネクションに 対 して 利 用 することができます その 他 の 状 態 ( 例 :HTTP_REQUEST, CLIENTSSL_CLIENTCERT, RTSP_RESPONSE,...)に 達 することができるのは 必 要 な profile が Virtual Server に 割 当 てられる 場 合 に 限 られる 場 合 もあります 例 えば HTTP_REQUEST イベントが 利 用 できるのは Virtual Server に HTTP Profile が 割 り 当 てられている 場 合 に 限 られます Event は f5 が 独 自 に 追 加 した when ステートメントを 使 って 以 下 のような 形 で 宣 言 されます when EVENT 名 { TCL コード EVENT 名 で 指 定 されたイベントが 発 動 すると そこに 指 定 された TCL コードだけが 実 行 されるので このイ ベントを 内 部 ステートの 一 連 の 流 れ 通 りに 記 載 する 必 要 はなく 順 番 が 異 なってもかまいません よく 使 うイベント: イベント CLIENT_ACCEPTED CLIENT_DATA HTTP_REQUEST HTTP_RESPONSE RULE_INIT LB_FAILED 概 要 クライアントがコネクションを 確 立 したときにトリガーされる コネクションが TCP::collecct(TCP データを 取 得 する) 状 態 にあるとき クライアントから 新 し いデータを 受 け 取 るたびにトリガーされる クライアントからの HTTP リクエストヘッダを 解 析 できる 状 態 (HTTP Profile が 有 効 になってい る 状 態 )にあって HTTP リクエストを 受 信 したときにトリガーされる サーバからの HTTP レスポンスのステータス 及 びヘッダを 解 析 できる 状 態 (HTTP Profile が 有 効 になっている 状 態 )にあって サーバからの HTTP レスポンスを 受 信 したときにトリガーされ る irule が 追 加 されたとき または 変 更 されたときにトリガーされる pool または pool member の 選 択 に 失 敗 したときにトリガーされる または 選 択 した node,pool member に 到 達 できないときにもトリガーされる これらの EVENT については irule の 具 体 例 のセクションにて サンプルを 使 って 説 明 します 30

4.2. 変 数 (variables) について 変 数 には 大 きく 以 下 の 3 つのタイプがあります 1 ローカル 変 数 2 グローバル 変 数 3 コネクション 間 で 読 み 書 き 可 能 な 変 数 ローカル 変 数 (Local variables) ローカル 変 数 は irule 内 だけで 有 効 な 変 数 です すべての irules はセッション 毎 に 動 作 するので ローカル 変 数 もまた 同 じくセッション 毎 に 有 効 です よって あるセッションに 与 えられた irules のローカル 変 数 やデータに 対 してのメモリ 領 域 は そのセッションによっ て 決 定 されることを 意 味 しています 例 えば コネクション 1 が BIG-IP に 到 達 し ある irule が 実 行 され 5 つのローカル 変 数 が 生 成 されたとします これらの 変 数 は そのコネクションが 閉 じられるまでの 間 だけしか 存 続 しません コネクションが 閉 じられた 後 そのコネクションに 割 当 てられたメモリは 解 放 され irule がそのコネクションのために 生 成 した 5 つのローカル 変 数 は 使 えなくなります このように ローカル 変 数 は コネクション(またはセッション)が 終 了 すればメモリは 自 動 的 に 解 放 されるので メモリ 管 理 を 気 にする 必 要 はありません ローカル 変 数 の 使 い 方 は TCL の 基 礎 の 説 明 に 何 度 も 出 現 した 方 法 と 同 じです 例 :HTTP リクエストの Host ヘッダ 値 を 取 り 出 してログに 出 力 when HTTP_REQUEST { set host [HTTP::host] log "HOST header of HTTP Request is $host" 逆 に 複 数 の irules で 同 じ 変 数 を 共 用 したい 場 合 ローカル 変 数 は 使 えません その 場 合 は 以 降 で 紹 介 するグローバル 変 数 または table コマンドによる 変 数 を 使 います 31

グローバル 変 数 (Global variables) グローバル 変 数 は 各 irules が 共 通 で 利 用 できる 変 数 です 例 えば 複 数 の irules を 設 定 する 予 定 があり それら 全 ての irules のログは 共 通 のロギングサーバへ 出 力 した い という 要 件 があるとします 一 つ 一 つの irule にそのロギングサーバの IP アドレスを 設 定 していくのは 非 効 率 なので 全 irules で 共 有 できる 変 数 にその IP アドレスを 持 たせて その 変 数 を 利 用 したい というような 要 望 はあると 思 います このような 要 件 を 解 決 するのがグローバル 変 数 です TCL 自 身 にもグローバル 変 数 は 用 意 されていますが TCL のグローバル 変 数 を 使 うためには 各 CPU コアが 利 用 で きる 共 有 メモリに 保 存 する 必 要 があります しかし BIG-IP は CMP(Clusterd Multi Processing)テクノロジーを 使 っています sol14358: Overview of Clustered Multiprocessing (11.3.0 and later) http://support.f5.com/kb/en-us/solutions/public/14000/300/sol14358.html CMP は 複 数 の CPU コアにタスクを 分 配 してスケールすることを 可 能 にするテクノロジーであり それぞれの CPU コア が 独 立 したメモリを 持 っています CMP では 各 CPU コア 同 士 が 使 える 共 有 メモリを 持 たないので TCL のグローバル 変 数 を 使 うとなると CMP を 無 効 化 し シングルコアで 処 理 する 必 要 があります これはパフォーマンスの 妨 げとなります そこで F5 は static:: ネームスペースと 呼 ばれる 新 しいネームスペースを 用 意 しています このことによって CMP を 無 効 化 しない=パフォーマンスを 犠 牲 にしないで グローバル 変 数 を 利 用 することが 可 能 に なります RULE_INIT イベントの 中 で static:: 変 数 名 として 設 定 することで ロードの 際 に 各 CPU 用 のメモリ 領 域 に 読 み 込 まれ 変 数 として 利 用 することができます この 変 数 は コンフィグが 再 読 み 込 みされるまで 消 えません 例 : RULE_INIT で コンフィグをリロードまで 存 続 する Static 変 数 に Syslog サーバの IP アドレスを 設 定 その Static 変 数 を irule 内 で 利 用 して その Syslog サーバへログを 出 力 する when RULE_INIT { set static::logserver "10.10.1.145" when HTTP_REQUEST { log $static::logserver "Got HTTP Request now." [Tips] 実 は Static:: 変 数 で 指 定 された Global 変 数 の 値 は RULE_INIT の 外 であっても set コマンドを 使 うことで 書 き 換 えることができてしまいます しかし この 書 き 換 えられた 値 は その 書 換 えが 実 行 された TMM 内 だけで 有 効 であり 他 TMM へ 伝 播 されないので TMM 間 で 不 整 合 が 起 きた 状 態 になってしまい 期 待 する 動 作 が 得 られない 場 合 が 考 えられます よって F5 では RULE_INIT の 外 での Static:: 変 数 の 書 換 えは 行 わないことを 強 く 推 奨 しています sol13033: Constructing CMP-compatible irules http://support.f5.com/kb/en-us/solutions/public/13000/000/sol13033.html TMM 間 で 共 有 する 必 要 のある 変 数 で 書 換 えを 行 いたい 場 合 には 以 下 の table コマンドの 利 用 を 推 奨 します 32

irules 間 で 読 み 書 き 可 能 な 変 数 :Table コマンド Table は 読 み 書 き 可 能 なメモリ 構 造 であり コネクション 間 で 共 有 できる というのが 特 徴 的 です irules のローカル 変 数 のような コネクション 毎 にしか 利 用 できないものとは 違 い Table には 持 続 する 必 要 がある データを 格 納 できる という 特 徴 があります Table には key:value ( 変 数 : 値 ) という 複 数 のレコードを リストとして 保 存 することができます また sub tables という 機 能 を 使 うことで 1 つのフラットなリストを 作 るだけでなく 名 前 つきのリストを 個 別 に 作 るこ とができるので その 名 前 ごとにデータを 分 離 することができます さらに コンフィグ 可 能 な timeout と lifetime オプションがあり これらによって メモリ 管 理 または Table をプログ ラム 的 にクリーンアップする 心 配 は 必 要 なくなります timeout: レコードの 最 終 更 新 からの 秒 数 アイドルタイムアウト 的 lifetime: レコードが 作 成 されてからの 秒 数 更 新 されたかどうかは 関 係 ない ------- <Session コマンドについて> ------- Table コマンドがリリースされる 以 前 (v10.1 より 前 )から 同 様 の 動 作 を 行 う Session コマンドが 存 在 しています Table コマンドは この Session コマンドの 使 い 難 さを 改 善 することを 目 的 としてリリースされました Session コマンドは 以 下 のようなシンタックスになっています session add <mode> <key> <data> [<timeout>] session lookup <mode> <key> session delete <mode> <key> <mode>については v10 以 降 は 実 質 的 な 意 味 を 持 っておらず "uie"という 値 だけが 使 われます また <key>については 以 下 のようなやや 奇 妙 なシンタックスになっていますが v10 からは key がこのような 形 に なっている 意 味 はありません session add uie "$key any pool any virtual" $data 180 session lookup uie "$key any pool" session delete uie "$key" 古 くから irules に 親 しみのあるユーザでなければ uie って 何? なぜ key に Pool を 指 定 するの? となって しまうと 思 います そもそも session というコマンド 名 が session とどのように 関 係 しているの? と 思 ってしまうので 混 乱 を 招 きや すいネーミングであることも 否 めません このような 使 い 難 さを 改 善 するために v10.1 で Table コマンドがリリースされました ---------------------------------------- Table は 以 下 のようなシンタックスになっています table set $key $data 180 table lookup $key table delete $key Table については irule の 具 体 例 のセクションにて サンプルを 使 って 説 明 します 33

irules の 変 数 一 覧 irules で 利 用 可 能 な 変 数 の 一 覧 です これらのうち 本 ガイドの 具 体 例 では 推 奨 フィールドに がついた 変 数 のみ 利 用 します 推 奨 変 数 CMP 対 応 Global TCL 形 式 設 定 ( 生 成 読 出 し 削 除 ) set ::<key> <value> $::<key> unset ::<key> Global static:: set static::<key> <value> $static::<key> Local set <key> <value> $key unset <key> session :v 9.0 session add uie <key> <value> :v10.0 session lookup uie <key> session delete uid <key> Table table set <key> <value> table lookup <key> table delete <key> 変 数 の 解 除 Standby 最 小 への Mirror Version Unset コマンド v9.0 できない v9.7 1)Unset コマンド 2)コネクションの 終 了 1)Timeout 2)session delete コマンド 1)Timeout 2)table delete コマンド v9.0 v9.0 v10.1 34

4.3. 演 算 子 ( Operators ) irules では 演 算 子 (Operators)は 2 つの 値 を 比 較 したい 場 合 によく 利 用 されます TCL が 標 準 で 持 つ 演 算 子 (==, <=, >=,...)に 加 えて F5 は starts_with, contains, ends_with のような 比 較 補 助 のための 演 算 子 を 追 加 しています 演 算 子 "A" contains "B" "A" ends_with "B" "A" equals "B" "A" matches_glob "B" "A" matches_regex "B" "A" starts_with "B" "A" and "B" "A" not "B" "A" or "B" 解 説 "A" 文 字 列 が "B" 文 字 列 を 含 むかどうか "A" 文 字 列 が "B" 文 字 列 で 終 わるかどうか "A" 文 字 列 と"B" 文 字 列 が 一 致 するかどうか "A" 文 字 列 と"B" 文 字 列 が glob 形 式 での 比 較 で 一 致 するかどうか "A" 文 字 列 と"B" 文 字 列 が regex 形 式 での 比 較 で 一 致 するかどうか "A" 文 字 列 が "B" 文 字 列 で 始 まるかどうか "A"と"B"の 値 を AND 条 件 で 評 価 する ( 例 : "A"と"B"の 両 方 が 真 ならば 次 のアクション) "A"と"B"の 値 を NOT 条 件 で 評 価 する ( 例 : "A"と"B"の 値 が 異 なるのならば 次 のアクション) "A"と"B"の 値 を OR 条 件 で 評 価 する ( 例 : "A"または"B"の 値 が 真 ならば 次 のアクション) 35

4.4. ファンクション ファンクション(Functions)は 検 索 した 結 果 の 値 を 返 すのに 役 立 つコマンドです 大 きく 以 下 2 つに 分 類 されます (1) Class ファンクション 事 前 に 作 成 した key:value タイプのデータベースから 情 報 を 検 索 して 値 を 戻 します Class については 後 述 します (2) 文 字 列 ファンクション ある 文 字 列 から 値 を 返 す 操 作 を 行 います F5 では 以 下 のような 独 自 の 文 字 列 ファンクションを 用 意 しています ファンクション findstr substr getfield domain 解 説 findstr <string> <search_string> [<skip_count> [<terminator count or string>]] <string>の 文 字 列 から <search_string>の 文 字 を 見 つけ 出 し 見 つけ 出 した 文 字 の 先 頭 から<skip_count> 分 オフセットしたところを 始 点 とした 文 字 を 返 す また <terminator count or string>を 指 定 すると その 手 前 までの 文 字 を 返 す 例 : findstr www.sub.my.domain.com sub 7.com 結 果 : domain substr <string> <skip_count> [<terminator>] <string>の 文 字 列 の 先 頭 から<skip_count>で 指 定 した 文 字 数 分 をスキップし <terminator>で 指 定 した 文 字 で 終 わるまでの 文 字 を 返 す 例 : substr www.sub.my.domain.com 11.com 結 果 : domain getfield <string> <split> <field_number> <string>の 文 字 列 を <split>で 指 定 した 文 字 で 分 割 し <field_number>で 指 定 したフ ィールドの 文 字 を 返 す 例 : getfield www.sub.my.domain.com. 4 結 果 : domain domain <string> <count> "."で 区 切 られたドメイン 名 :<string>を"." 単 位 で 区 切 って <count> 指 定 した 数 の 後 ろからの 区 切 り 数 分 の 文 字 を 返 す 例 : domain www.sub.my.domain.com 2 結 果 : domain.com 36

4.5. ステートメント ステートメント (Statements) は 一 般 的 には 何 かを 実 行 する ものであり 値 を 戻 さないコマンドです 例 えば TCL では 条 件 分 岐 を 行 う if switch while for などがステートメントに 該 当 します f5 では 独 自 に 以 下 のようなステートメントを 用 意 しています ステートメント 解 説 when irule のイベントを 指 定 する 場 合 に 使 う log syslog-ng ユーティリティへ ログを 出 力 する pool モニターステータスに 関 わらず 指 定 した Pool へロードバランスまたは Pool Member へ トラフィックを 送 る node 指 定 されたサーバノードへ 直 接 トラフィックを 送 る persist 指 定 したパーシステンスを 使 う snat 指 定 した 変 換 アドレスを コネクションの 送 信 元 IP アドレスに 割 当 てる snatpool 指 定 した SNAT Pool 内 の IP アドレスのいずれかを コネクションの 送 信 元 IP アドレス に 割 当 てる また SNAT Pool 内 の member を 指 定 することもできる discard コネクションやパケットを Drop/Disacard する drop コマンドと 同 じ drop コネクションやパケットを Drop/Disacard する discard コマンドと 同 じ reject コネクションをリジェクトする(TCP RST を 返 す) forward LTM のルーティングテーブルにしたがって パケットを 転 送 する nexthop BIG-IP からサーバ 側 への Nexthop を 指 定 する lasthop クライアントへパケットを 戻 す 際 の lasthop(mac または IP アドレス)を 指 定 する rateclass パケット 転 送 時 に 指 定 した Rate Class を 使 う clone モニターステータスに 関 係 なく 指 定 した Pool または Pool Member にトラフィックをク ローン(コピー)する event このコネクションで ある irule イベント(または 全 ての irule イベント)の 評 価 を 有 効 化 / 無 効 化 する clientside 指 定 した irule コマンドを BIG-IP から 見 てクライアント 側 の 情 報 (IP アドレス/ポート 番 号 等 )に 基 づいて 実 行 する serverside 指 定 した irule コマンドを BIG-IP から 見 てクライアント 側 の 情 報 (IP アドレス/ポート 番 号 等 )に 基 づいて 実 行 する peer コンテキストの 反 対 側 (サーバ 側 ならクライアント 側 またはその 逆 )で 指 定 された irule コマンドを 実 行 する ( 例 外 的 に 値 を 返 すもの) TCL_platform プラットフォームの 情 報 (OS Version など)を 返 す cpu あるインターバルにおける TMM CPU の 平 均 負 荷 値 を 返 す 37

4.6. コマンド Commands は TCL 内 で 利 用 できる 制 御 構 造 です 例 えば HTTP::uri を 使 うことで HTTP リクエストの URI を 取 得 できますし AES::encrypt によって AES 鍵 を 使 って 暗 号 化 を 実 行 する というようなことが 可 能 です 標 準 TCL のコマンドセットに 加 えて F5 はグローバルな 範 囲 で 使 えるコマンド(TCP::client_port, IP::addr など) や 特 定 の Profile で 使 えるコマンド(HTTP::uri,SSL::sessionid 等 )を 追 加 しています 出 現 頻 度 の 高 いコマンド かなり 多 くのコマンドが 存 在 しますので ここでは 以 降 のサンプルで 現 れるコマンド 及 び 比 較 的 出 現 頻 度 の 高 いコ マンドについて 紹 介 します (1) IP IP 概 要 IP::client_addr クライアント IP アドレスを 返 す IP::server_addr サーバの IP アドレスを 返 す IP::remote_addr BIG-IP から 見 てリモートの IP アドレスを 返 す (クライアント IP の 場 合 もあれば サーバ IP の 場 合 もある ) IP::local_addr クライアントまたはサーバから 接 続 される BIG-IP が 持 つ IP アドレス(Virtual Server の IP または Self-IP)を 返 す または サーバ 側 では クライアント IP を SNAT 変 換 しないで 出 力 する 場 合 はその アドレスを SNAT する 場 合 には SNAT アドレスが 該 当 する IP::addr IP アドレス/サブネット と IP アドレス/サブネットの 比 較 を 行 い 真 偽 を 返 す 例 :[IP::addr [IP::client_addr]/8 equals 10.0.0.0] (2) TCP TCP 概 要 TCP::client_port クライアント 側 の TCP コネクションの クライアント PC のポート 番 号 を 返 す TCP::server_port サーバ 側 の TCP コネクションの サーバの TCP ポート 番 号 を 返 す TCP::local_port TCP コネクションの BIG-IP 側 の TCP ポート 番 号 を 返 す TCP::remote_port クライアント/サーバ 側 両 方 の BIG-IP から 見 てリモートの TCP ポート 番 号 を 返 す TCP::collect 指 定 したバイト 数 のコンテンツデータを 収 集 する TCP::payload TCP::collect 取 得 した TCP データコンテンツを 変 更 or 返 す TCP::release TCP::collect で 収 集 したデータを 消 去 &リリースし 処 理 を 再 開 する TCP::bandwidth 対 向 端 との 帯 域 幅 を 返 す TCP::respond 対 向 端 へ 特 定 データを 直 接 送 る TCP::close TCP コネクションを 閉 じる (3) HTTP HTTP 概 要 HTTP::request HTTP リクエストのヘッダを 全 て 返 す HTTP::header HTTP ヘッダのいずれかを 指 定 し その 値 を 取 得 または 変 更 する HTTP::uri HTTP リクエストの URI 部 分 を 返 す or セットする 例 :http://www.example.com:8080/main/index.jsp?user=test&login=check URI は /main/index.jsp?user=test&login=check HTTP::host HTTP ホストヘッダの 値 を 返 す HTTP::cookie HTTP リクエスト 及 びレスポンスに 対 して Cookie の 挿 入 削 除 値 の 取 得 といっ た 操 作 を 行 う Usage 例 : HTTP::cookie namestlc の List 形 式 で HTTP ヘッダ 内 にある 全 Cookie 名 を 返 す HTTP::cookie insert name <name> value <value> <name>と<vaule>の 組 合 せの Cookie を 挿 入 する 38

HTTP::path HTTP リクエストの Path 部 分 を 返 す or セットする ("?" 以 降 のクエリ 文 字 列 は 含 まない ) 例 :http://www.example.com:8080/main/index.jsp?user=test&login=check Path は /main/index.jsp HTTP::query HTTP リクエストのクエリ 文 字 列 部 分 を 返 す 例 :http://www.example.com:8080/main/index.jsp?user=test&login=check Query は user=test&login=check HTTP::collect HTTP ボディデータの 指 定 したバイト 数 分 を 収 集 する HTTP::release HTTP::collect で 集 めたデータをリリースする HTTP::payload Queries for or manipulates HTTP payload information. HTTP ペイロード 情 報 の 要 求 or ペイロード 情 報 を 操 作 する Usage 例 : HTTP::payload <length> HTTP::collect コマンドが 収 集 したコンテンツを 指 定 した byte 数 分 返 す HTTP::payload length HTTP::collect コマンドが 収 集 したコンテンツの 長 さを 返 す HTTP::redirect HTTP リクエストを 受 けたとき またはレスポンスを 返 すときに 指 定 した URL へリ ダイレクトさせる HTTP::respond まるでサーバからレスポンスが 来 たかのように HTTP レスポンスを 生 成 してクライ アントに 返 す HTTP::status HTTP レスポンスのステータスコードを 返 す (4) AES AES AES::key AES::decrypt AES::encrypt 概 要 データを 暗 号 化 / 複 合 化 するための AES Key を 生 成 する 事 前 に 生 成 された AES Key を 使 ってデータを 複 合 化 する 事 前 に 生 成 された AES Key を 使 ってデータを 暗 号 化 する (5) LB LB 概 要 LB::detach サーバ 側 コネクションを 切 断 する LB::down node または pool member のステータスを Down 状 態 にセットする LB::mode ロードバランシングモードをセットする LB::persist パーシステンスレコードの 検 索 を 強 制 し 結 果 を 返 す LB::reselect ロードバランシング 先 を 再 選 択 する LB::select ロードバランシングセレクションを 強 制 し 結 果 を 返 す LB::server 今 選 ばれたサーバについての 情 報 を 返 す LB::snat Virtual Server の SNAT コンフィグレーションについての 情 報 を 返 す LB::status node アドレスまたは pool member のステータスを 返 す LB::up node または pool member のステータスを Up 状 態 にする 39

コマンドの 注 意 点 コマンドについての 注 意 点 について 触 れておきます (1) コマンド 毎 に 利 用 できる Event と 利 用 できない Event が 存 在 コマンドによって どの Event 内 なら 利 用 できるかが 決 まっています 例 ) 以 下 は DevCentral 上 の HTTP::url のマニュアル 画 面 です https://devcentral.f5.com/wiki/irules.http uri.ashx ~ 略 ~ 利 用 できる Event この HTTP::uri コマンドは 上 記 の Valid Events: に 記 載 された Event 内 だけで 有 効 であり これら 以 外 の Event では 利 用 できません 利 用 したいコマンドが 利 用 したい Event との 組 合 せで 利 用 できるかどうかが 明 確 ではない 場 合 には DevCentral のマニュアルを 参 照 して 確 認 してください https://devcentral.f5.com/wiki/irules.commands.ashx (2) 無 効 化 された TCL コマンド TCL 言 語 が 標 準 で 持 っているいくつかの Commands は irules 実 装 の 中 では 無 効 にされています 一 般 的 に トラフィックフローの 中 で 予 期 しない 停 止 を 引 き 起 こす 可 能 性 のあるコマンド( 例 :file IO socket call 等 )が 取 り 除 かれています 利 用 できない TCL コマンドについては 以 下 を 参 照 ください https://devcentral.f5.com/wiki/irules.disabledtclcommands.ashx 40

5. irules 動 作 確 認 用 のネットワーク 構 成 サンプル 以 下 のネットワーク 構 成 を 使 って 以 降 のセクションで 紹 介 する irules の 動 作 を 確 認 します web-vs/secure-vs ともに デフォルトの Pool は http-pool(10.99.100.216)として 設 定 します A-pool B-pool も 設 定 しておきます VS との 紐 付 けは 行 いません Node(10.99.100.211,10.99.100.213)は LTM 上 での 設 定 は 不 要 ですが サンプル irule で 利 用 します 41

6. LTM の 設 定 LTM 設 定 のより 詳 細 は LTM かんたんセットアップガイド を 参 照 ください ここでは 以 降 の irule サンプルを 動 作 させるために 必 要 な LTM の 設 定 箇 所 を 示 します 6.1. Platform 設 定 以 下 は 初 期 ウィザードの 流 れの 中 で 設 定 します 設 定 した 内 容 は System Platform で 確 認 できます ホスト 名 FQDN 形 式 で 指 定 Asia/Tokyo を 選 択 CLI アクセス 用 root アカウントの パスワード WebUI アクセス 用 admin アカウントの パスワード 6.2. VLAN 設 定 Network VLANs で 以 下 の 状 態 になるように 設 定 します 42

6.3. Self IP 設 定 Network Self IPs で 以 下 の 状 態 になるように 設 定 します 6.4. Routing 設 定 Network Routes で 以 下 の 状 態 になるように 設 定 します 43

6.5. Pool の 設 定 Local Traffic Pools で 設 定 します http-pool 任 意 の 名 前 を 入 力 ヘルスモニター(http)を 設 定 Pool Member のアドレスと Port 番 号 を 入 力 して Add ボタンを 押 す 44

A-pool 任 意 の 名 前 を 入 力 ヘルスモニター(http)を 設 定 Pool Member のアドレスと Port 番 号 を 入 力 して Add ボタンを 押 す B-pool 任 意 の 名 前 を 入 力 ヘルスモニター(http)を 設 定 Pool Member のアドレスと Port 番 号 を 入 力 して Add ボタンを 押 す 45

6.6. Virtual Server の 設 定 Web-vs (Port:80) 任 意 の 名 前 を 入 力 IP アドレスとポート 番 号 を 入 力 HTTP Profile を 選 択 環 境 に 応 じて 設 定 ~ 略 ~ 設 定 済 みの http-pool を 選 択 46

Secure-vs (Port:443) 任 意 の 名 前 を 入 力 IP アドレスとポート 番 号 を 入 力 HTTP Profile を 選 択 本 ガイドでは 簡 易 的 に デフォルトで 用 意 されている clientssl を 選 択 環 境 に 応 じて 設 定 ~ 略 ~ 設 定 済 みの http-pool を 選 択 47

7. irules の 使 い 方 irules の 設 定 方 法 に 慣 れるために 簡 易 的 に 以 下 のような irule を 設 定 してみます HTTP リクエストに 含 まれる User-Agent ヘッダ 情 報 をログへ 出 力 する 具 体 的 には 2 つのブラウザ: Internet Explorer と Firefox を 使 って Virtual Server にアクセスし それ らのブラウザの User-Agent ヘッダの 情 報 が BIG-IP 内 部 へログが 出 力 されることを 確 認 します irules の 作 成 方 法 には 大 きく 以 下 の 2 パターンがあります 7.1. [パターン 1] irule Editor を 使 う irule Editor は DevCentral から 無 償 でダウンロードできるエディタです irule Editor のダウンロード 用 リンク: https://devcentral.f5.com/d/tag/irules%20editor このエディタは irule の 構 文 チェック コマンドの 補 完 コマンドをクリックすることで DevCentral のオンラインマニ ュアルページへアクセスしてくれるなど irules 作 成 のための 支 援 機 能 を 備 えたエディタです BIG-IP の Web-GUI からも irule 作 成 は 可 能 ですが このエディタを 使 うほうが irule は 作 りやすいと 思 います 本 エディタは 不 定 期 に Version Up がなされるので できるだけ 最 新 版 をご 利 用 ください (1) PC で irule Editor を 起 動 し 以 下 の 赤 点 線 部 分 をクリックします (2) 以 下 のように 値 を 入 力 し OK を 押 します 1 BIG-IP のマネージメント IP を 入 力 2 Admin のパスワードを 入 力 3 OK をクリック 48

(3) 以 下 の 赤 点 線 部 分 をクリックします (4) irule の 名 前 を 入 力 します irule の 名 称 ( 任 意 )を 入 力 (5) User-Agent を ログファイルへ 出 力 する irule を 入 力 します 設 定 後 save ボタンを 押 します Save ボタン 上 記 の irule: when HTTP_REQUEST { log local0. "USER-AGENT is [string tolower [HTTP::header "User-Agent"]]" 49

7.2. [パターン 2] BIG-IP の Web GUI を 使 う BIG-IP の Web GUI インタフェースから 直 接 irule を 作 成 編 集 することも 可 能 です Local Traffic irules で 表 示 された 画 面 右 上 の Create ボタンを 押 して 表 示 された 画 面 で 以 下 のように 設 定 します irule の 名 称 ( 任 意 )を 入 力 irule を 入 力 50

irule の 適 用 作 成 した irule を Virtual Server へ 適 用 します (1) Local Traffic Virtual Server で 表 示 された 設 定 済 みの Virtual Server:Web-vs を 選 択 し 画 面 の 上 に 表 示 された Resources タブをクリックします irules の 部 分 の Manage ボタンを 押 します (2) 作 成 した irule を 選 択 し << ボタンを 押 します (3) 以 下 の 状 態 になります 51

出 力 されるログの 確 認 irule で 出 力 されるログは 以 下 の 手 順 で BIG-IP に SSH でアクセスし コマンドラインで 確 認 します (1) 以 下 のコマンドを 実 行 します [root@big208:active:in Sync] config #tail f /var/log/ltm (2) irule を 設 定 した Virutal Server へ クライアント PC から 以 下 の 2 つのブラウザを 使 ってアクセスしてみま す 1 FireFox 2 Internet Explorer (3) /var/log/ltm に 以 下 のようなログが 出 力 されます 1 Firefox Aug 26 03:04:05 big208 info tmm1[11991]: Rule /Common/User-Agent_check <HTTP_REQUEST>: USER-AGENT is mozilla/5.0 (windows nt 6.1; rv:30.0) gecko/20100101 firefox/30.0 2 Internet Explorer Aug 26 03:04:21 big208 info tmm3[11991]: Rule /Common/User-Agent_check <HTTP_REQUEST>: USER-AGENT is mozilla/5.0 (windows nt 6.1; trident/7.0; rv:11.0) like gecko 以 上 が irule の 基 本 的 な 使 い 方 です 52

8. irules の 具 体 例 具 体 的 な irule のサンプルを 紹 介 します 8.1. よく 使 う EVENT の 例 irule には 多 くのイベントが 存 在 しますが このセクションでは よく 利 用 するイベントを 使 ったサンプルを 紹 介 しま す 尚 EVENT 発 動 のタイミングの 詳 細 は Appendix に 記 載 しましたので 必 要 に 応 じて 参 照 ください CLIENT_ACCEPTED あるエントリが BIG-IP のコネクションテーブルに 挿 入 されたときに このイベントが 発 動 します TCP の 場 合 は 3WAY ハンドシェーク 完 了 時 に 発 動 します (1) サンプル irule の 動 作 概 要 以 下 のサンプルは クライアントと BIG-IP の 間 で TCP コネクションが 確 立 された 時 刻 をログ 出 力 する というもので す No. 1 2 3 4 サンプル irule when CLIENT_ACCEPTED { set curtime [clock seconds] set formattedtime [clock format $curtime -format {%H:%M:%S ] log "the time is: $formattedtime" 1 TCP 3WAY ハンドシェークが 完 了 したとき 2 その 時 刻 を 変 数 にセットし 3 時 刻 のフォーマットを 人 が 読 み 取 りやすい 形 に 整 形 し 4 それをログとして 出 力 する (2) この irule を web-vs に 適 用 してください ( irule の 使 い 方 のセクションを 参 照 ) (3) /var/log/ltm へ 出 力 されるログが 確 認 できる 状 態 にしてください ( irule の 使 い 方 のセクションを 参 照 ) (4) クライアントから web-vs(http://10.99.1.108)へブラウザでアクセスしてください (5) ブラウザと BIG-IP の 間 で 確 立 される TCP コネクション 数 分 のログが 出 力 されます 例 : May 18 18:42:44 big208 info tmm[13467]: 01220002:6: Rule /Common/current_time <CLIENT_ACCEPTED>: the time is: 18:42:44 May 18 18:42:44 big208 info tmm1[13467]: 01220002:6: Rule /Common/current_time <CLIENT_ACCEPTED>: the time is: 18:42:44 [ 参 考 ] UDP の 場 合 は TCP のようなハンドシェークは 存 在 しないので コネクションテーブルにエントリされたタイミングで 発 動 され その UDP のエントリは アイドルタイムアウトになる(デフォルト 60 秒 )まで 存 続 し 続 けます よって タイムアウトまでの 間 にそのエントリと 同 じ 情 報 を 持 つ UDP パケットが 到 達 しても このイベントは 新 規 と 見 な されないため 発 動 しません 53

CLIENT_DATA ある TCP コネクションが TCP::collect の 状 態 にあるとき クライアントから 新 しいデータを 受 け 取 るたびにこの CLIENT_DATA イベントが 発 動 します (1) サンプル irule の 動 作 概 要 以 下 のサンプルは Web ブラウザの 種 類 に 応 じて 振 り 分 ける Pool を 変 える というものです 具 体 的 には Firefox なら A-Pool それ 以 外 なら B-Pool という 振 り 分 けにしています No. 1 2 3 4 5 6 7 8 9 サンプル irule when CLIENT_ACCEPTED { TCP::collect when CLIENT_DATA { if { [TCP::payload] contains " Firefox" { log local0. "PAYLOAD is [TCP::payload]" pool A-pool else { pool B-pool TCP::release 1 3WAY ハンドシェークが 完 了 したとき 2 その TCP データを 収 集 する 3 2で TCP データを 受 け 取 ったので このイベントが 発 動 4 そのデータ(Payload)が Firefox を 含 んでいたら 5 その Payload 部 分 をログ 出 力 し 6 A-Pool に 送 る 7 それ 以 外 は 8 B-Pool に 送 る 9 そして 取 得 した TCP データを 開 放 する (2) この irule を web-vs に 適 用 してください ( irule の 使 い 方 のセクションを 参 照 ) (3) /var/log/ltm へ 出 力 されるログが 確 認 できる 状 態 にしてください ( irule の 使 い 方 のセクションを 参 照 ) (4) クライアントから web-vs(http://10.99.1.108)へ Firefox ブラウザでアクセスしてください "A-pool"からのレスポンスを 受 け 取 ります (5) クライアントから web-vs(http://10.99.1.108)へ Internet Explorer ブラウザでアクセスしてください "B-pool"からのレスポンスを 受 け 取 ります [ 参 考 ] UDP の 場 合 は UDP セグメントを 受 け 取 るたびに 発 動 します また UDP の 場 合 は TCP のような collect コマンドによるデータ 取 得 は 必 要 ありません 54

HTTP_REQUEST HTTP リクエストを 受 け 取 ったときに 発 動 します (1) サンプル irule の 動 作 概 要 以 下 のサンプルは URI に 応 じて SSL の Virtual Server へリダイレクトする というものです 具 体 的 には "secure"という URI の 場 合 に HTTPS の VS にリダイレクトさせます No. 1 2 3 4 サンプル irule when HTTP_REQUEST { if { [HTTP::uri] contains "secure" { log local0. "URI is [HTTP::uri]" HTTP::redirect https://[http::host] 1 HTTP リクエストを 受 け 取 ったとき 2 URI が"secure"の 文 字 を 含 んでいたら 3 URI をログ 出 力 し 4 SSL の Virtual Server(HTTPS)へリダイレクトさせる (2) この irule を web-vs に 適 用 してください ( irule の 使 い 方 のセクションを 参 照 ) (3) /var/log/ltm へ 出 力 されるログが 確 認 できる 状 態 にしてください ( irule の 使 い 方 のセクションを 参 照 ) (4) クライアントのブラウザから web-vs へ http://10.99.1.108/secure でアクセスしてください (5) https://10.99.1.108 へリダイレクトされます 55

HTTP_RESPONSE HTTP レスポンスを 受 け 取 ったときに 発 動 します (1) サンプル irule の 動 作 概 要 以 下 のサンプルは レスポンスのステータスコードが 404 なら クライアントとの TCP コネクションを 切 断 する というも のです No. 1 2 3 4 5 サンプル irule when HTTP_RESPONSE { if { [HTTP::status] == 404 { log local0. "HTTP Status is [HTTP::status]" HTTP::collect reject 1 HTTP レスポンスを 受 け 取 ったとき 2 HTTP のステータスコードが 404(Not Found)だったら 3 そのステータスコードをログ 出 力 し 4 HTTP データを 収 集 して 5 TCP を 切 断 する [ Tips] このイベントの 中 で HTTP::collect を 使 わないで reject コマンドを 使 った 場 合 には BIG-IP はサーバが 生 成 した HTTP ヘッダをクライアントに 送 ってから TCP リセットを 送 ります HTTP ヘッダを 送 らずに TCP リセットを 送 りたい 場 合 には reject コマンドの 前 に HTTP::collect が 必 要 です HTTP::collect がなくても 結 果 は 同 じように 見 えます しかし 例 えば 404 で 返 される HTTP リクエストヘッダの 中 に 攻 撃 者 が 攻 撃 を 成 立 させるための 手 がかりになる 情 報 が 入 っているかもしれません そのような 場 合 に 備 え 404 レスポンスの 場 合 にはクライアントに 何 も 返 さない という ことを 想 定 した irule になっています (2) まず この irule を 適 用 する 前 に クライアントのブラウザから web-vs へ http://10.99.1.108/xxx ( 存 在 し ない URI)でアクセスして ブラウザ 上 に 404 の 表 示 があることを 確 認 してください 例 :IE の 場 合 (3) この irule を web-vs に 適 用 してください ( irule の 使 い 方 のセクションを 参 照 ) (4) /var/log/ltm へ 出 力 されるログが 確 認 できる 状 態 にしてください ( irule の 使 い 方 のセクションを 参 照 ) (5) クライアントのブラウザを 再 起 動 してから 再 度 web-vs へ http://10.99.1.108/xxx ( 存 在 しない URI)でアク セスしてください (6) 今 度 はブラウザの 画 面 上 に 404 の 表 示 が 無 い 状 態 で 切 断 されます 56

RULE_INIT このイベントは irules の 中 で 使 われる static 変 数 を 初 期 化 するために 使 います この RULE_INIT で 指 定 した 変 数 は 全 ての Virtual Server で 共 通 で 利 用 できます このイベントは 以 下 の 状 態 の 時 に 発 動 します このイベントを 使 った irule が save されたとき デバイスが 起 動 したとき ソフトウェアが 再 起 動 されたとき (1) サンプル irule の 動 作 概 要 以 下 のサンプルは サーバから 発 行 された Cookie( 平 文 )を クライアントと BIG-IP の 間 は 暗 号 化 する というもの です 本 ガイドで 使 っている Web サーバの Cookie 変 数 名 は"SESSION"です 環 境 に 応 じて 変 更 してください No. 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 サンプル irule when RULE_INIT { set static::key [AES::key 256] when HTTP_RESPONSE { if {[HTTP::cookie exists "SESSION"] { set decrypted [HTTP::cookie "SESSION"] HTTP::cookie remove "SESSION" set encrypted [b64encode [AES::encrypt $static::key $decrypted]] HTTP::cookie insert name "SESSION" value $encrypted log local0. "DEC=$decrypted, ENC=$encrypted" when HTTP_REQUEST { if {[HTTP::cookie exists "SESSION"] { set encrypted [HTTP::cookie "SESSION"] HTTP::cookie remove "SESSION" set decrypted [AES::decrypt $static::key [b64decode $encrypted]] HTTP::cookie insert name "SESSION" value $decrypted log local0. "DEC=$decrypted, ENC=$encrypted" 57

1 この irule が save されたとき 2 256bit の AES 鍵 を 変 数 (static::key)に 入 れる 3 HTTP レスポンスを 受 信 したとき 4 もし SESSION という 名 前 の Cookie が 存 在 していたら 5 変 数 :decrypted にその Cookie の 値 を 入 れ 6 一 旦 その Cookie(SESSION)を 削 除 する 7 $decrypted に 入 った Cookie 値 を $static::key の AES 鍵 で 暗 号 化 &base64 に 変 換 し 変 数 :encrypted に 入 れる 8 暗 号 化 したその Cookie 値 ($encrypted)を SESSION という 名 の Cookie として HTTP レスポンスに 付 け 加 える 9 暗 号 前 の 値 および 暗 号 後 の 値 をログ 出 力 する 10 HTTP リクエストを 受 信 したとき 11 もし SESSION という 名 前 の Cookie が 存 在 していたら 12 変 数 :encrypted にその Cookie の 値 を 入 れ 13 一 旦 その Cookie(SESSION)を 削 除 する 14 $encrypted に 入 った Cookie 値 を base64 でデコード$static::key の AES 鍵 で 複 合 化 し 変 数 :decrypted に 入 れる 15 複 合 化 したその Cookie 値 ($decrypted)を SESSION という 名 の Cookie として HTTP レスポンスに 付 け 加 える 16 複 合 後 の 値 および 複 合 前 の 値 をログ 出 力 する (2) この irule を web-vs に 適 用 してください ( irule の 使 い 方 のセクションを 参 照 ) (3) /var/log/ltm へ 出 力 されるログが 確 認 できる 状 態 にしてください ( irule の 使 い 方 のセクションを 参 照 ) (4) Web ブラウザから web-vs(http://10.99.1.108)に 初 めてアクセスします もし 以 下 の Error に 遭 遇 したら 一 旦 Web ブラウザを 再 起 動 して アクセスし 直 して 下 さい この Error は Web ブラウザが 始 めてこの Web ページにアクセスするのではなく 以 前 に 既 にアクセスしたことが あって そのときの 暗 号 化 されてない Cookie が Web ブラウザに 残 っていることが 原 因 です May 22 10:00:50 big208 err tmm[10621]: 01220001:3: TCL error: /Common/RULE_INIT <HTTP_REQUEST> - conversion error (line 1) invoked from within "b64decode $encrypted" (5) HTTP レスポンスで Web サーバから SESSION Cooike が 発 行 されます これが DEC=に 入 った 値 です これを この irule を 使 って AES 鍵 で 暗 号 化 したものが ENC=に 入 った 値 で これが Web ブラウザに 渡 されます May 22 10:00:55 big208 info tmm[13467]: Rule /Common/RULE_INIT <HTTP_RESPONSE>: DEC=fhfuk4jn79kql0e0lhtjdleu55, ENC=TbiL4Kh2c7EMfOggwnOd4kx+rkRc+EDp2X28PPvD5EC8YvORYoTaDR57dncmUVmf1+ixuEpLl11YTHzluytOxgAAAAE= (6) この web アプリケーションのフォームに username と password を 入 れてログインすると HTTP リクエストに SESSION Cookie として ENC=の 値 でログインします これを この irule を 使 って AES 鍵 で 複 合 化 したのが DEC=に 入 った 値 です DEC= ENC= のどちらの 値 も(4) 同 じになっています May 22 10:01:07 big208 info tmm[13467]: Rule /Common/RULE_INIT <HTTP_REQUEST>: DEC=fhfuk4jn79kql0e0lhtjdleu55, ENC=TbiL4Kh2c7EMfOggwnOd4kx+rkRc+EDp2X28PPvD5EC8YvORYoTaDR57dncmUVmf1+ixuEpLl11YTHzluytOxgAAAAE= 58

LB_FAILED このイベントは LTM が Pool Member にリクエストを 送 る 準 備 ができたときに その Pool Member へ 以 下 のような 理 由 でそのリクエストを 送 れないときに 発 動 します Pool Member に 到 達 できなかった 場 合 ( 例 : 経 路 ダウン/ルーティング 設 定 ミス) Pool Member から TCP SYN への 反 応 が 無 かった 場 合 ( 例 :Pool Member が 停 止 している) BIG-IP が Pool または Pool Member を 選 択 できなかった 場 合 ( 例 :pool コマンドの 設 定 ミス) もし ヘルスモニターが 設 定 されていない 状 態 で irule が pool または member を 選 んだ 場 合 や node コマンドを 使 って モニターしてない 宛 先 へトラフィックを 送 った 場 合 には 選 択 された 宛 先 は そのリクエストに 対 して 返 答 できる 状 態 ではないかもしれません そのケースでは "LB_FAILED"イベントがトリガーされ その 状 況 を 処 理 するようにロジックを 組 むことができます (1) サンプル irule の 動 作 概 要 以 下 のサンプルは URI が"/admin"で 始 まるリクエストは 10.99.100.211 のアドレスを 持 つサーバに 送 るが その サーバが 返 答 しなかった 場 合 に 次 の 候 補 のノードに 送 る というものです No. 1 2 3 4 5 6 7 8 9 10 11 12 (a) (b) (c) (d) (e) (f) 13 サンプル irule when HTTP_REQUEST { if { [HTTP::uri] starts_with "/admin" { set admin 1 node 10.99.100.211 80 else { set admin 0 pool http-pool when LB_FAILED { switch $admin { 1 { log local0. "Server 10.99.100.211:80 not responding" LB::reselect node 10.99.100.215 80 2 { log local0. "Server 10.99.100.215:80 not responding" LB::reselect node 10.99.100.217 80 3 { log local0. "Server 10.99.100.217:80 not responding" reject incr admin 1 HTTP リクエストを 受 け 取 ったとき 2 URI が"/admin"の 文 字 で 始 まっていたら 3 変 数 :admin に"1"をセットし 4 10.99.100.211:80 に この HTTP リクエストを 送 る 5 URI が"/admin" 以 外 なら 59

6 変 数 :admin に"0"をセットし 7 http-pool に 送 る 8 サーバが 応 答 しなかった 場 合 この LB_FAILED イベントが 発 動 9 $admin に"1"がセットされていたら 10 この"1 { 処 理 "が 実 行 される 11 "1 { 処 理 "の 1 行 目 :サーバが 応 答 しなかったことをログ 出 力 する 12 "1 { 処 理 "の 2 行 目 :10.99.100.215:80 へ 送 る 13 $admin に 1 を 加 算 する (=$admin は"2") もし 12の 10.99.100.215:80 も 応 答 しなかったら 再 び8の LB_FAILED が 発 動 上 記 13で $admin には"2"がセットされているので (a) この"2 { 処 理 "が 実 行 される (b) "2 { 処 理 "の 1 行 目 :サーバが 応 答 しなかったことをログ 出 力 する (c) "2 { 処 理 "の 2 行 目 :10.99.100.217:80 へ 送 る 再 び13で $admin に 1 を 加 算 する (=$admin は"3") もし (c)の 10.99.100.217:80 も 応 答 しなかったら 再 び8の LB_FAILED が 発 動 上 記 13で $admin には"3"がセットされているので (d) この"3 { 処 理 "が 実 行 される (e) "3 { 処 理 "の 1 行 目 :サーバが 応 答 しなかったことをログ 出 力 する (f) "3 { 処 理 "の 2 行 目 :コネクションを RST で 切 断 する (2) この irule を web-vs に 適 用 してください ( irule の 使 い 方 のセクションを 参 照 ) (3) /var/log/ltm へ 出 力 されるログが 確 認 できる 状 態 にしてください ( irule の 使 い 方 のセクションを 参 照 ) (4) Web ブラウザで http://10.99.1.108/admin にアクセスし 10.99.100.211 からのレスポンスが 得 られることを 確 認 してください (5) 10.99.100.211 が 停 止 した という 形 を 模 擬 します irule の4の 行 を 存 在 しないアドレス( 例 :10.99.100.111)に 変 更 して save してください ( 存 在 しないアドレスに 変 更 することで 停 止 したことと 同 じ 結 果 になります ) (6) Web ブラウザで http://10.99.1.108/admin にアクセスし 10.99.100.215 からのレスポンスが 得 られることを 確 認 してください (7) 10.99.100.215 も 停 止 した という 形 を 模 擬 します irule の12の 行 を 存 在 しないアドレス( 例 :10.99.100.115)に 変 更 して save してください ( 存 在 しないアドレスに 変 更 することで 停 止 したことと 同 じ 結 果 になります ) (8) Web ブラウザで http://10.99.1.108/admin にアクセスし 10.99.100.217 からのレスポンスが 得 られることを 確 認 してください 60

9. Class / Data-Group の 使 い 方 irules を 使 うときに 検 索 可 能 なリストがほしい 場 合 があります 例 えば HTTP リクエストの URI を 見 て あるリストの 中 からヒットする URI の 文 字 列 を 見 つけ そこに 指 定 されたプー ルに 振 り 分 ける というような 場 合 です このような 場 合 に Class/Data-Group が 役 に 立 ちます F5 が 言 う "class" と"Data-Group"には 明 確 な 違 いはありません GUI では Data-Group(s) と 呼 ばれ irules コマンドでは Class(es) と 呼 ばれています 本 ガイドでは 便 宜 上 リストを Data-Group そのデータを 呼 び 出 す irule コマンドを Class と 呼 ぶことにします Data-Group の 種 類 には 2 つあります Internal Data-Group:BIG-IP のコンフィグファイル(bigip.conf) 内 に 設 定 する 場 合 External Data-Group: 外 部 ファイルとして 保 存 する 場 合 (=Host 側 (Linux 側 )のファイルとして 保 存 する 場 合 ) External Data-Group は V11.4 から 実 装 された 機 能 です Internal Data-Group は 多 くても 100,000 エントリ 程 度 が 限 界 でしたが External Data-Group を 使 うことで 2,000,000~3,000,000 のエントリまで 扱 うことができるように 拡 張 されています 以 降 Data-Group の Type 及 びこれら 2 つの 方 式 それぞれの 利 用 方 法 を 解 説 します 61

Data-Group のデータの Type Data-Group のデータ(エントリ)には 以 下 のような Type が 存 在 します (1) String ( 文 字 列 ) 最 も 一 般 的 なタイプです string( 文 字 列 )フォーマットのあらゆるタイプのデータをストアすることができるので URL スイッチングのようなこと を 実 行 する 場 合 に 高 い 頻 度 で 使 われます 例 : /admin := 10.99.100.215, /user := 10.99.100.217, (2) IP IP アドレスやアドレスレンジをストアできるタイプです 例 えば 送 信 元 IP アドレス 毎 に 振 分 け 先 の Pool を 変 更 したいような 場 合 に 便 利 なタイプです 例 : host 10.99.4.19 := "1", host 10.99.4.228 := "2", network 10.99.4.0/24 := "0", (3) Integer ( 数 値 ) 整 数 値 をストアすることを 可 能 にするタイプです 何 らかのコマンド 実 行 結 果 が 数 値 となる 場 合 ( 例 えば 演 算 や 何 かをカウントする 場 合 )に 便 利 です 例 : 1 := "test 1", 2 := "test 2", 62

Internal Data-Group BIG-IP のコンフィグレーションファイル(bigip.conf) 内 に Data-Group を 作 り それを 参 照 する 方 法 です このサンプルでは まず 以 下 の Data-Group を 作 ります Type は String です /admin := 10.99.100.215, /user := 10.99.100.217, そして 以 下 のような irule を 作 ります HTTP リクエストを 受 信 したら その URI と 上 記 の Data-Group を 比 較 URI と Data-Group 内 の 文 字 列 が 一 致 したら そこに 指 定 された IP アドレスへその HTTP リクエストを 送 る 具 体 的 には URI が /admin なら 10.99.100.215 へその HTTP リクエストを 送 る URI が /user なら 10.99.100.217 へその HTTP リクエストを 送 る となる irule を 作 ります 63

9.1.2.1. Internal Data-Group の 作 成 BIG-IP のコンフィグファイル(bigip.conf) 内 に Data-Group を 作 ります (1) tmsh の 場 合 は 以 下 のコマンドで Data-Group を 生 成 できます (tmos)# create ltm data-group internal TEST_Class { records add { /admin { data 10.99.100.215 /user { data 10.99.100.217 type string (2) 以 下 のコマンドで Data-Group の 設 定 内 容 を 確 認 できます (tmos)# list ltm data-group ltm Data-Group internal TEST_Class { records { /admin { data 10.99.100.215 /user { data 10.99.100.217 type string (3) GUI からも 作 成 / 編 集 できます 以 下 は Local Traffic irules Data Group List で 上 記 tmsh で 作 った Data-Group を 選 択 した 画 面 です ここで 編 集 が 可 能 です 64

9.1.2.2. Internal Data-Group を 使 った irules 作 成 した Data-Group を irule で 参 照 するには "class"コマンドを 使 います (1) サンプル irule の 動 作 概 要 本 サンプルは HTTP リクエスト 内 の URL と Data-Group を 比 較 し ヒットしたら そこに 記 載 された IP アドレスへその リクエストを 送 る というものです No. 1 2 3 4 5 サンプル irule when HTTP_REQUEST { if {[class match [HTTP::uri] contains TEST_Class] { set NODE [class match -value [HTTP::uri] contains TEST_Class] log local0. "$NODE" node $NODE 80 1 HTTP リクエストを 受 け 取 ったとき 2 URI が Data-Group の TEST_Class 内 の 文 字 にヒットしたら 3 NODE 変 数 に ヒットした URI に 記 載 された 値 (IP アドレス)を 格 納 し 4 その IP アドレスをログ 出 力 し 5 NODE の 80 番 ポートに 送 る (2) コマンドの 解 説 class match このコマンドは 特 定 の 検 索 パラメータが 正 確 にマッチする Member を Data-Group list から 検 索 し マッチが 成 功 したかどうかを 示 す True/False 値 (0/1)を 返 します class match -value このコマンドは Class 内 の Key/value の vaule を 返 答 することができます 例 えば class に URI と Pool が key と value として 記 載 されたものがあるとします Class の 行 が /admin := 10.99.100.215 であった 場 合 検 索 値 (key)が /admin であれば その 2 番 目 の 値 (value):10.99.100.215 を 戻 り 値 とします (3) この irule を web-vs に 適 用 してください ( irule の 使 い 方 のセクションを 参 照 ) (4) /var/log/ltm へ 出 力 されるログが 確 認 できる 状 態 にしてください ( irule の 使 い 方 のセクションを 参 照 ) (5) Web ブラウザで http://10.99.1.108/admin にアクセスし 10.99.100.215 からのレスポンスが 得 られることを 確 認 してください (6) Web ブラウザで http://10.99.1.108/user にアクセスし 10.99.100.217 からのレスポンスが 得 られることを 確 認 してください 65

External Data-Group (その 1:String 形 式 ) 今 度 は BIG-IP のコンフィグ 内 ではなく BIG-IP の Host 側 (Linux 側 )に 保 存 されたファイルを Data-Group として 利 用 する 方 法 を 示 します まずは Internal Data-Group と 同 様 に String 形 式 で 作 成 してみます 9.1.3.1. External Data-Group 用 ファイルの 作 成 BIG-IP の Host 側 (Linux 側 )に Data-Group 用 の 外 部 ファイルを 作 成 します ファイルを 保 存 するディレクトリはどこでもかまいません よって 本 ガイドでは /var/tmp ディレクトリに 保 存 することにします [root@big208:active:in Sync] config # cd /var/tmp vi エディタなどを 利 用 して 以 下 の 2 行 を 追 加 してください [root@big208:active:in Sync] tmp # vi ext_test_class.file /admin := 10.99.100.211, /user := 10.99.100.213, 注 意 点 : 改 行 コードは LF のみ に 対 応 しています Windows の CRLF などは 読 み 込 みエラーとなります よって Windows のテキストエディタで 作 成 した Data-Group をそのまま 貼 り 付 けても エラーとなる 場 合 があります のでご 注 意 ください 9.1.3.2. External Data-Group ファイルの 読 み 込 み 以 下 の TMSH コマンドで 外 部 ファイルをオブジェクトとして 読 み 込 みます (tmos)# create sys file data-group ext_test_class_object type string source-path file:/var/tmp/ext_test_class.file Copying file "file:/var/tmp/ext_test_class.file"... % Total % Received % Xferd Average Speed Time Time Time Current Dload Upload Total Spent Left Speed 0 49 0 49 0 0 92627 0 --:--:-- --:--:-- --:--:-- 0 9.1.3.3. External Data-Group の 作 成 以 下 のコマンドで 上 記 で 生 成 したオブジェクトを irule が 参 照 できる Data-Group に 変 換 します (tmos)# create ltm data-group external ext_test_class external-file-name ext_test_class_object 以 下 のコマンドで 参 照 先 を 確 認 できます (tmos)# list ltm data-group external ltm data-group external ext_test_class { external-file-name ext_test_class_object type string 66

9.1.3.4. External Data-Group を 使 った irule (1) サンプル irule の 概 要 以 下 の irule は internal Data-Group の 場 合 と 同 じ 動 作 を 行 うルールです 参 照 する 先 が bigip.conf 内 ではなく 外 部 ファイルから 生 成 した Data-Group になる と 点 だけが 異 なります No. 1 2 3 4 5 サンプル irule when HTTP_REQUEST { if {[class match [HTTP::uri] contains ext_test_class] { set NODE [class match -value [HTTP::uri] contains ext_test_class] log local0. "$NODE" node $NODE 80 (2) この irule を web-vs に 適 用 してください ( irule の 使 い 方 のセクションを 参 照 ) (3) /var/log/ltm へ 出 力 されるログが 確 認 できる 状 態 にしてください ( irule の 使 い 方 のセクションを 参 照 ) (4) Web ブラウザで http://10.99.1.108/admin にアクセスし 10.99.100.211 からのレスポンスが 得 られることを 確 認 してください (5) Web ブラウザで http://10.99.1.108/user にアクセスし 10.99.100.213 からのレスポンスが 得 られることを 確 認 してください (6) 外 部 ファイルの 内 容 を 変 更 して Data-Group に 反 映 させてみます vi エディタなどを 使 って 外 部 ファイルを 変 更 してください [root@big208:active:in Sync] tmp # vi ext_test_class.file /admin := 10.99.100.215, /user := 10.99.100.217, 変 更 後 tmsh で 以 下 のコマンドを 実 行 することで Data-Group に 反 映 できます (tmos)# modify sys file data-group ext_test_class_object source-path file:/var/tmp/ext_test_class.file (7) Web ブラウザで http://10.99.1.108/admin にアクセスし 10.99.100.215 からのレスポンスが 得 られることを 確 認 してください (8) Web ブラウザで http://10.99.1.108/user にアクセスし 10.99.100.217 からのレスポンスが 得 られることを 確 認 してください 67

External Data-Group (その 2:Address 形 式 ) 今 度 は データ Type を Address 形 式 で 作 成 したものを 使 って 動 作 を 確 認 します 9.1.4.1. External Data-Group ファイルの 作 成 BIG-IP の Host 側 (Linux 側 )に Data-Group 用 の 外 部 ファイルを 作 成 します vi エディタなどを 利 用 して 以 下 の 3 行 を 追 加 してください [root@big208:active:in Sync] tmp # vi ext_test_ip_class.file host 10.99.4.19 := "1", host 10.99.4.228 := "2", network 10.99.4.0/24 := "0", 9.1.4.2. External Data-Group ファイルの 読 み 込 み 以 下 の TMSH コマンドで 外 部 ファイルをオブジェクトとして 読 み 込 みます (tmos)# create sys file data-group ext_test_ip_class_object type ip source-path file:/var/tmp/ext_test_ip_class.file Copying file "file:/var/tmp/ext_test_ip_class.file"... % Total % Received % Xferd Average Speed Time Time Time Current Dload Upload Total Spent Left Speed 0 78 0 78 0 0 108k 0 --:--:-- --:--:-- --:--:-- 0 9.1.4.3. External Data-Group の 作 成 以 下 のコマンドで 上 記 で 生 成 したオブジェクトを irule が 参 照 できる Data-Group に 変 換 します (tmos)# create ltm Data-Group external ext_test_ip_class external-file-name ext_test_ip_class_object 以 下 のコマンドで 参 照 先 を 確 認 できます (tmos)# list ltm data-group external ext_test_ip_class ltm Data-Group external ext_test_ip_class { external-file-name ext_test_ip_class_object type ip 68

9.1.4.4. External Data-Group を 使 った irule (1) サンプル irule の 概 要 クライアントの IP アドレスに 応 じて 利 用 する Pool Member を 変 える というルールです No. 1 2 3 4 5 6 サンプル irule when CLIENT_ACCEPTED { switch [class match -value [IP::client_addr] equals ext_test_ip_class] { "0" { reject "1" { node 10.99.100.213 80 "2" { node 10.99.100.215 80 default { log local0. "Address not found or invalid value." 1 クライアント 側 の TCP コネクションが 確 立 されたとき 2 クライアントの IP アドレスで ext_test_ip_class 内 を 検 索 し 3 戻 り 値 が"0"なら TCP RST を 送 る 4 戻 り 値 が"1"なら 10.99.100.213:80 へ 5 戻 り 値 が"2"なら 10.99.100.215:80 へ 6 何 もヒットしなければ ログを 出 力 (2) この irule を web-vs に 適 用 してください ( irule の 使 い 方 のセクションを 参 照 ) (3) /var/log/ltm へ 出 力 されるログが 確 認 できる 状 態 にしてください ( irule の 使 い 方 のセクションを 参 照 ) (4) Web ブラウザで http://10.99.1.108 にアクセスし 10.99.100.213 からのレスポンスのみが 得 られることを 確 認 してください (5) Web ブラウザを Forward Proxy(Squid) 経 由 (=10.99.4.228 から BIG-IP へアクセス)に 変 更 します 例 )Internet Explorer の 場 合 : ツール インターネットオプション 接 続 タブ LAN の 設 定 ボタンを 押 す 69

サンプルネットワーク 構 成 図 中 の Proxy(Squid)サーバのアドレス / ポート=10.99.4.228 / 3128 を 入 力 (6) Web ブラウザで http://10.99.1.108 にアクセスし 10.99.100.215 からのレスポンスのみが 得 られることを 確 認 してください (7) Web ブラウザの Forward Proxy(Squid) 経 由 を 解 除 します (8) 外 部 ファイルの 内 容 を 変 更 して Data-Group に 反 映 させてみます vi エディタなどを 使 って 例 えば 外 部 ファイルを 以 下 のように 変 更 してください [root@big208:active:in Sync] tmp # vi ext_test_ip_class.file host 10.99.4.19 := "2", host 10.99.4.228 := "1", network 10.99.4.0/24 := "0", 変 更 後 tmsh で 以 下 のコマンドを 実 行 することで Data-Group に 反 映 できます (tmos)# modify sys file data-group ext_test_ip_class_object source-path file:/var/tmp/ext_test_ip_class.file (9) Web ブラウザで http://10.99.1.108 にアクセスし 10.99.100.215 からのレスポンスのみが 得 られることを 確 認 してください (10) Web ブラウザを Proxy(Squid) 経 由 に 変 更 します http://10.99.1.108 にアクセスし 10.99.100.213 からのレスポンスのみが 得 られることを 確 認 してください 70

9.2. table の 使 い 方 table コマンドは メモリ 内 に 小 さなデータベースに 相 当 するもの を 作 成 してくれます table を 使 うことで 例 えば 送 信 元 IP アドレス 単 位 にアクセス 数 をカウントし ある IP アドレスからのコネクションが 一 定 数 を 超 えたら その IP アドレスからのアクセスはドロップする というような よりきめ 細 かい 単 位 での 制 御 が 可 能 になります (1) サンプル irule の 動 作 概 要 本 サンプルは 1 秒 間 に 100 以 上 のアクセス(TCP コネクション)が 発 生 する IP アドレスは 一 定 時 間 ブロックする と いう irule です 上 図 を 簡 単 に 解 説 します 1.1.1.1 と 2.2.2.2 のクライアントからのアクセスがあり それぞれの IP アドレス 単 位 に 1 秒 間 に 発 生 するコネク ション 数 を table を 使 ってカウントします 2.2.2.2 からのアクセスは 100/ 秒 を 超 えたので Subtable:blacklist にレコードを 追 加 します そのレコードの Lifetime( 生 存 時 間 )は 20 秒 にセットされます この 後 2.2.2.2 からの 後 続 のアクセスは 20 秒 の 間 ブロックされ 続 けます このような 動 作 イメージのルールを 作 成 します No. 1 2 3 4 5 6 7 8 9 10 11 12 サンプル irule when RULE_INIT { set static::maxquery 100 set static::holdtime 20 when CLIENT_ACCEPTED { set srcip [IP::remote_addr] if { [table lookup -subtable "blacklist" $srcip]!= "" { log local0. "BList $srcip is: [table lookup -subtable "blacklist" $srcip]" drop return else { set curtime [clock second] set key "count:$srcip:$curtime" 71

13 14 15 16 17 18 19 20 set count [table incr $key] table lifetime $key 1 log local0. "COUNT/sec of $key is: $count" if { $count >= $static::maxquery { table add -subtable "blacklist" $srcip "blocked" indef $static::holdtime table delete $key drop return 1 この irule が save されたとき 2 Static 変 数 (static::maxquery)に 100 を 入 れる ( 最 大 コネクション 数 ) 3 Static 変 数 (static::holdtime)に 20 を 入 れる (ブラックリストとなったレコードの 生 存 時 間 ) 4 クライアントとの TCP コネクションが 確 立 されたとき 5 変 数 (srcip)に クライアントの IP アドレスを 入 れる 6 もし "blacklist"という 名 の subtable に $srcip の IP アドレスが 存 在 していたら 7 その IP アドレスのログを 出 力 し 8 その IP アドレスからのパケットをドロップし 9 この 処 理 から 抜 ける 10 もし 6ではなかったら(=ブラックリストに IP アドレスが 存 在 しなかったら) 11 変 数 (curtime)に 現 在 時 刻 を 入 れ 12 変 数 (key)に"count:ip アドレス: 現 在 時 刻 "の 形 で 値 を 入 れ 13 テーブルに$key のレコードを 追 加 & $key の 値 を 1 つ 増 加 & その 値 を 変 数 (count)に 入 れ 14 テーブルの$key レコードのライフタイムを 1 秒 にセット 15 $key の 1 秒 あたりのコネクション 数 をログ 出 力 秒 間 のコネクション 数 が 100 に 達 するまでは 10~15が 繰 り 返 される ( 厳 密 には10~16が 繰 り 返 されるが 16の if 条 件 には 合 致 しないので それ 以 降 の 処 理 は 行 われない ) 16 $count が 100(static::maxquery の 値 )に 達 したら 17 "blacklist"という 名 のサブテーブルに 以 下 を 追 加 (ア) $srcip(クライアントの IP アドレス)を Key に (イ) "blocked"を Value に (ウ) timeout(アイドルタイムアウト)は 無 限 に (エ) lifetime(このレコードが 作 られてからの 生 存 時 間 )は 20 秒 (static::holdtime)に 18 13の$key レコードは 削 除 (コネクションが 100 になるまでカウントするための 一 時 的 なレコードであるため ) 19 クライアントからのパケットはドロップ 20 この 処 理 から 抜 ける 72

(2) コマンド 解 説 table incr <key> - table 上 にある 指 定 された Key の Value に 1 を 加 えます もし table 上 に Key が 存 在 していなかったら デフォルト value には"0"が 使 われ そのエントリが 追 加 され ます - incr 処 理 が 完 了 すると そのエントリ(key)の 値 を 返 します table add -subtable <name> <key> <value> <timeout> <lifetime> - <name>に 指 定 された" 名 前 つきテーブル"=subtable を 生 成 します - そのサブテーブルのレコードとして <key> <value>の 形 でエントリされます - <timeout>に indef が 指 定 されると アイドルタイムアウトは 発 生 しなくなります - <lifetime>には このレコードが 生 成 された 時 刻 から 何 秒 後 に 消 去 するかを 指 定 します table lookup -subtable <name> <key> - <name>に 指 定 された" 名 前 つきテーブル"=subtable 内 を<key>で 検 索 し それに 紐 付 く value を 返 します table lifetime <key> <value> - table 内 の <key>の lifetime(レコードが 作 成 されてから 消 去 するまでの 時 間 )を <value>に 指 定 された 秒 数 にセットします table delete <key> - table 内 の<key>のレコードを 削 除 します (3) この irule を web-vs に 適 用 してください ( irule の 使 い 方 のセクションを 参 照 ) (4) /var/log/ltm へ 出 力 されるログが 確 認 できる 状 態 にしてください ( irule の 使 い 方 のセクションを 参 照 ) (5) 10.99.4.228(Linux)で 以 下 のコマンド(Apache Bench)を 実 行 してください # ab n 999999 c 100 http://10.99.1.108/ [ 参 考 :Apache Bench] https://httpd.apache.org/docs/2.2/programs/ab.html (6) /var/log/ltm を 見 ていると 100 コネクションに 達 したとき 以 下 のログが 出 力 されます Jun 11 19:27:20 big208 info tmm1[11003]: Rule /Common/TABLE <CLIENT_ACCEPTED>: COUNT/sec of count:10.99.4.228:1434018440 is: 99 Jun 11 19:27:20 big208 info tmm[11003]: Rule /Common/TABLE <CLIENT_ACCEPTED>: COUNT/sec of count:10.99.4.228:1434018440 is: 100 Jun 11 19:27:20 big208 info tmm1[11003]: Rule /Common/TABLE <CLIENT_ACCEPTED>: BList 10.99.4.228 is: blocked (7) blacklist テーブル 上 のレコードは 通 信 の 有 無 に 関 係 なく 20 秒 で 消 えますので もう 一 度 実 行 する 場 合 には 20 秒 待 ってから 実 施 してください 73

10. irule 作 成 のテクニック 10.1. デバッグのやり 方 irule は 多 様 な 機 能 を 持 つので 要 件 によってはコードが 複 雑 になる 場 合 があります 複 雑 なコードはエラーを 誘 発 しやすくなるので デバッグが 必 要 になることがあると 思 います デバッグ 手 段 として 有 効 なのは とにもかくにもログ 出 力 することです 以 下 の 要 領 で 各 所 にロギングの 行 を 挿 入 し 変 数 の 値 が 想 定 どおりにセットされているか またはコマンド の 実 行 結 果 や 戻 り 値 が 想 定 通 りか 等 をチェックします when HTTP_REQUEST { log local0. "section1, a is $a" もちろん 変 数 に 限 らず コマンドを 記 述 することもできます when CLIENT_ACCEPTED { log local0. "section1, Bandwidth is [TCP::bandwidth]" 本 番 環 境 でのロギング 有 効 化 / 無 効 化 デバッグロギングは アプリケーションのテストを 行 うときや 本 番 サーバの 問 題 を 修 正 するような 場 合 に 有 効 なツー ルです しかし ロギングによる CPU 負 荷 は 比 較 的 高 く またロギングし 続 けると かなり 大 きな Syslog サーバのディ スクが 必 要 となる 場 合 があります よって 多 くのケースでは 不 具 合 修 正 ができた 後 では デバッグログは 無 効 化 しておくことが 推 奨 されます 無 効 化 の 方 法 には 以 下 のようにいくつかの 方 法 が 存 在 します 10.1.1.1. irule 内 からログコマンドを 削 除 する これは 最 も 簡 単 な 方 法 です log の 行 を 削 除 して 保 存 するだけです 10.1.1.2. irule 内 の log 行 をコメントアウトする log コマンド 行 の 先 頭 に#をつけてコメントアウトする 方 法 です この 方 法 であれば log 設 定 を 簡 単 に 復 活 できるので アプリケーションの 新 しい 問 題 が 発 生 した 場 合 にも 直 ぐにロ ギングできます 10.1.1.3. 変 数 を 使 った 条 件 つきロギングを 行 う "if"コマンドを 使 って 変 数 の 値 をチェックすることで ログ 行 を 有 効 化 / 無 効 化 する 方 法 です 変 数 値 を 変 えるだけで シンプルにロギングの ON/OFF ができます 例 えば LB_FAILED イベントのサンプルで 使 った irule に この 方 法 を 適 用 してみます 74

No. 1 2 3 サンプル irule when HTTP_REQUEST { set DEBUG 1 if { $DEBUG { log local0. "Request: [HTTP::uri]" if { [HTTP::uri] starts_with "/admin" { set admin 1 node 10.99.100.211 80 else { set admin 0 pool http-pool when LB_FAILED { switch $admin { 1 { if { $DEBUG {log local0. "Server 10.99.100.211:80 not responding" LB::reselect node 10.99.100.215 80 2 { if { $DEBUG {log local0. "Server 10.99.100.215:80 not responding" LB::reselect node 10.99.100.217 80 3 { if { $DEBUG {log local0. "Server 10.99.100.217:80 not responding" reject incr admin (1) この irule を web-vs に 適 用 してください ( irule の 使 い 方 のセクションを 参 照 ) (2) /var/log/ltm へ 出 力 されるログが 確 認 できる 状 態 にしてください ( irule の 使 い 方 のセクションを 参 照 ) (3) Web ブラウザで http://10.99.1.108/admin にアクセスし 10.99.100.211 からのレスポンスが 得 られることを 確 認 してください 期 待 するログが 出 力 されていることを 確 認 してください (4) 以 下 2 つの 方 法 のどちらかを 実 施 してください 10.99.100.211 を 停 止 停 止 できない 場 合 irule の3の 行 を 存 在 しないアドレス( 例 :10.99.100.111)に 変 更 ( 存 在 しないアドレスに 変 更 することで 停 止 したことと 同 じ 結 果 になります ) 期 待 するログが 出 力 されていることを 確 認 してください (5) Web ブラウザで http://10.99.1.108/admin にアクセスし 10.99.100.215 からのレスポンスが 得 られることを 確 認 してください 期 待 するログが 出 力 されていることを 確 認 してください (6) 1の set DEBUG 1 を set DEBUG 0 に 変 更 し 同 様 の 動 作 確 認 を 行 ってください ログが 出 力 されなくなることを 確 認 してください 75

10.2. irule による CPU 使 用 率 の 測 定 irule を 設 定 した 際 には どの 程 度 のパフォーマンス 劣 化 が 発 生 するのかが 気 になる 場 合 があります そのような 場 合 には "timing"コマンドを 使 うことによって irule がどの 程 度 CPU サイクルを 使 っているのかを 確 認 することができます 2 つの irule で CPU 使 用 率 を 比 較 TCL の 基 礎 の 章 で 計 算 式 をブレス{ で 囲 むか 囲 まないかで 計 算 効 率 が 変 わる という 点 に 少 し 触 れました どれぐらい 違 うのか 2 つを 比 べてみます (1) expr {$a*$b 以 下 は HTTP リクエストを 受 信 したときに 2 つ 数 を 計 算 する という irule です 変 数 を 使 った 計 算 式 を{ で 囲 むことで 効 率 的 に 計 算 を 行 うパターンです No. 1 2 3 4 サンプル irule 名 :TMINIG_TEST when HTTP_REQUEST timing on { set a 100000 set b 100000 set c [expr {$a*$b] 以 下 のコマンドで この irule が 使 用 した CPU サイクルを 確 認 できます root@(big208)(cfg-sync In Sync)(Active)(/Common)(tmos)# show ltm rule TIMING_TEST raw (raw) ----------------------------------------- Ltm::Rule Event: TIMING_TEST:HTTP_REQUEST ----------------------------------------- Priority 500 Executions Total 49998 Failures 0 Aborts 0 CPU Cycles on Executing Average 19951 Maximum 569256 Minimum 0 以 下 のコマンドで 上 記 の Statistics を 消 去 できます (tmos)# reset-stats ltm rule TIMING_TEST 76

(2) expr $a*$b 変 数 を 使 った 計 算 式 をブレス{ で 囲 まないパターンです {で 囲 まないので TCL パーサーによる 変 数 置 換 が 実 施 された 後 に 計 算 する という 2 つの 処 理 が 入 るため 効 率 が 悪 くなります No. 1 2 3 4 サンプル irule when HTTP_REQUEST timing on { set a 100000 set b 100000 set c [expr $a*$b] 以 下 のコマンドで この irule が 使 用 した CPU サイクルを 確 認 できます root@(big208)(cfg-sync In Sync)(Active)(/Common)(tmos)# show ltm rule TIMING_TEST raw (raw) ----------------------------------------- Ltm::Rule Event: TIMING_TEST:HTTP_REQUEST ----------------------------------------- Priority 500 Executions Total 100003 Failures 0 Aborts 0 CPU Cycles on Executing Average 34972 Maximum 23861033 Minimum 12407 { で 囲 んだ 場 合 と 比 べると 平 均 値 で 約 1.7 倍 の CPU サイクルを 使 用 していることがわかります 77

irule の CPU 使 用 率 の 計 算 利 用 する 予 定 の irule がどの 程 度 CPU へインパクトを 与 えるのかを 知 りたい 場 合 があります その 場 合 の 計 算 方 法 を 示 します 厳 密 な 計 算 は 難 しいですが 目 安 にはなりえます 10.2.2.1. プラットフォームの CPU クロック 数 を 求 める まず プラットフォームの CPU を 調 べます 本 ガイドで 利 用 している BIG-IP は Virtual Edition であり CPU を 2 個 使 っています root@(big208)(cfg-sync In Sync)(Active)(/Common)(tmos)# show sys hardware Chassis Information Maximum MAC Count 1 Registration Key - Hardware Version Information Name cpus Type base-board Model Intel(R) Xeon(R) CPU E5540 @ 2.53GHz Parameters -- -- cache size 8192 KB cores 2 cpu MHz 2527.000 Platform Name BIOS Revision Base MAC ~ 省 略 ~ BIG-IP Virtual Edition 00:50:56:bd:a4:0b 10.2.2.2. 計 算 Timing コマンドで 出 力 された CPU サイクルを CPU クロックの 合 計 値 で 割 る という 単 純 計 算 です 1 つの HTTP リクエストが 発 生 した 際 の CPU 使 用 率 という 値 となります CPU クロックの 合 計 : 2,527,000,000 Hz * 2 Core = 5,054,000,000Hz (1) expr {$a*$bの 場 合 19951 / 5,054,000,000Hz 0.0003948% (2) expr $a*$b の 場 合 34972 / 5,054,000,000Hz 0.0006920% 例 えば(2)の 場 合 は 10,000 リクエスト/ 秒 のアクセスがあれば CPU は 6% 上 昇 する と 見 込 まれます 78

10.3. irule を 最 適 化 する irule を 最 適 に 利 用 するために 考 慮 すべきポイントについてまとめました (1) irule を 使 う 前 にまず Profile でできないかを 確 認 する irule は 様 々なことが 行 える 強 力 なスクリプトですが BIG-IP に 標 準 で 実 装 されている 機 能 に 比 べると オーバーヘ ッドが 大 きくなりがちです よって 何 でも irule で 実 装 してしまう 前 に BIG-IP に 標 準 実 装 されている Profile の 設 定 で 実 施 できないかを 調 査 し Profile でできるのならば それを 利 用 するほうがパフォーマンスへのインパクトは 少 なくすみます 例 : HTTP header insert and erase HTTP fallback HTTP compress uri <exclude include> HTTP redirect rewrite HTTP insert X-Forwarded-For HTTP ramcache uri <exclude include pinned> Stream profile for content replacement Class profile for URI matching. (2) 最 適 な 制 御 ステートメントを 利 用 する (if/elseif/else,switch,class/data-group) 条 件 分 岐 を 行 う 制 御 ステートメントは if,switch など 複 数 存 在 します それぞれの 制 御 ステートメントには 得 手 / 不 得 手 な 部 分 があるので それぞれを 見 極 めて 利 用 することによって 不 要 な CPU リソースを 消 費 しないようすることが 望 ましいです if/elseif を 使 うよりもまず switch または Class/Data-Group を 使 うことを 考 える - 100 エントリ 以 下 の 条 件 分 岐 なら Switch を 使 う - 100 エントリ 以 上 の 条 件 分 岐 なら Class/Data-Group を 使 う しかし if/elseif のほうが switch や Class よりも 柔 軟 性 が 高 いので 適 材 適 所 で 利 用 する 79

if の 連 続 使 用 よりも if/elseif を 使 う 例 えば 以 下 2 つの irule は 同 じ 結 果 を 導 き 出 します if/if/if if/elseif/elseif when HTTP_REQUEST { set uri [HTTP::uri] if { $uri equals "/" { pool http-pool if { $uri contains "admin" { pool A-pool if { $uri contains "user" { pool B-pool when HTTP_REQUEST { set uri [HTTP::uri] if { $uri equals "/" { pool http-pool elseif { $uri contains "admin" { pool A-pool elseif { $uri contains "user" { pool B-pool しかし if/if/if の 場 合 は 例 えば 1 つ 目 の if で 条 件 がヒットして Pool 選 択 ができた(http-pool の 選 択 ができ た) 場 合 でも 後 続 の 2 つの if が 同 様 の 処 理 を 実 施 する というムダが 生 じます 一 方 if/elseif/elseif の 方 は 最 初 の if の 条 件 がヒットしなかった 場 合 にのみ 以 降 の elseif を 実 行 するの で if/if/if のルールよりも 効 率 が 良 くなります このことは どの 条 件 にヒットする 割 合 が 大 きいかによっても 影 響 があると 考 えられます もし B-Pool が 選 ばれる 条 件 が 9 割 以 上 という 場 合 には 両 者 の 効 率 は 大 差 ないかもしれません (3) for よりも foreach の 利 用 を 考 える 以 下 の for と foreach は それぞれ 同 じ 結 果 を 導 き 出 します for when HTTP_REQUEST { set domains [bob.com ted.com domain.com] set countdomains [llength $domains] for {set i 0 { $i < $countdomains {incr i { set domain [lindex $domains $i] foreach when HTTP_REQUEST { set domains [bob.com ted.com domain.com] foreach domain $domains { # This is faster, and more elegant # This is slower しかし 条 件 を 多 数 指 定 する for に 対 し foreach は 1 つの 行 で 同 じ 形 を 実 現 できます よって foreach で 要 件 を 見 たせるならばその 方 が 効 率 はよく また 見 た 目 も 美 しくなります 80

(4) 最 適 なオペレータの 利 用 (contains, equals) "contains"よりも"equals"を 使 う contains ではなく equals で 要 件 を 満 たせるなら 検 索 ロジックが 少 ない equals を 使 ったほうが CPU リソースの 消 費 は 少 ないです (5) 正 規 表 現 の 利 用 は 極 力 避 ける 正 規 表 現 (Regular Expressions)は 非 常 に 便 利 な 機 能 である 反 面 メモリや CPU リソースを 多 く 消 費 しがちです 多 くのケースで 正 規 表 現 を 使 わずとも 要 件 を 満 たせるコマンドがあるはずなので 極 力 そちらを 利 用 することを 検 討 すべきです "string match"や"switch -glob"を 使 う "string match"や"switch -glob"のほうが 正 規 表 現 よりも CPU 負 荷 が 軽 いので これらで 要 件 が 満 たせるなら ば 正 規 表 現 は 極 力 使 うことを 避 けるべきです "regex"よりも"start_with" 悪 い 例 : when HTTP_REQUEST { if { [regexp {^/admin [HTTP::uri]] { regsub {/admin [HTTP::uri] "/UserPortal" newuri log local0. "$newuri" HTTP::uri $newuri よい 例 : when HTTP_REQUEST { if { [HTTP::uri] starts_with "/adimin" { set newuri [string map {admin UserPortal [HTTP::uri]] HTTP::uri $newuri 81

(6) 変 数 を 使 わないほうがいい 場 合 変 数 は 比 較 的 オーバーヘッドの 大 きい 機 能 です よって 変 数 を 使 わずに 実 装 できるならば 使 わないほうがよい 場 合 があります 例 えば 以 下 のように ただ 単 にコマンド 出 力 結 果 を 変 数 に 入 れるだけならば 変 数 を 使 わないほうが 効 率 がよいで す 変 数 を 使 う 効 率 がよくない 例 : when HTTP_REQUEST { set host [HTTP::host] set uri [HTTP::uri] if { $host equals "bob.com" { log "Host = $host; URI = $uri" pool http_pool1 上 記 と 同 じことは 変 数 を 使 わない 以 下 の irule でも 実 施 できます when HTTP_REQUEST { if { [HTTP::host] equals "bob.com" { log "Host = [HTTP::host]; URI = [HTTP::uri]" pool http_pool1 (7) 変 数 を 使 ったほうがいい 場 合 一 方 何 度 も 同 じコマンドを 実 行 するのならば 変 数 を 使 ったほうが 効 率 がよくなります 悪 い 例 : 繰 り 返 し 同 じ 処 理 をすると メモリ 消 費 が 多 くなる when HTTP_REQUEST { if { [string tolower [HTTP::uri]] starts_with "/img" { pool imagepool elseif { ([string tolower [HTTP::uri]] ends_with ".gif") ([string tolower [HTTP::uri]] ends_with ".jpg") { pool imagepool 良 い 例 : 変 数 を 使 って 同 じ 処 理 を 繰 り 返 し 実 施 しないようにする when HTTP_REQUEST { set uri [string tolower [HTTP::uri]] if { $uri starts_with "/img" { pool imagepool elseif { ($uri ends_with ".gif") ($uri ends_with ".jpg") { pool imagepool 82

(8) 変 数 名 は 短 めに 以 下 は 上 記 と 同 じ 事 を 行 う irule ですが 変 数 名 が 長 い 悪 い 例 です TCL は Lookup 用 テーブルに 変 数 を 格 納 するので 長 い 名 前 はオーバーヘッドが 多 くなります できるだけ 短 い 変 数 名 にすることをお 勧 めします 悪 い 例 : when HTTP_REQUEST { set theurithatiammatchinginthisirule [string tolower [HTTP::uri]] if { $theurithatiammatchinginthisirule starts_with "/img" { pool imagepool elseif { ($theurithatiammatchinginthisirule ends_with ".gif") ($theurithatiammatchinginthisirule ends_with ".jpg") { pool imagepool (9) オペレータの 注 意 点 これは 最 適 化 というよりも 注 意 点 です 比 較 演 算 子 (オペレータ)には 文 字 列 に 適 したものと 数 字 に 適 したものが 存 在 します これらを 適 切 に 利 用 しないと 誤 った 判 断 になる 場 合 が 発 生 します 文 字 列 の 比 較 には eq や ne を 使 う 数 字 の 比 較 には == や!= を 使 う 例 えば "5"と"05"の 比 較 の 結 果 を 同 じとしたい(= 数 字 として 比 較 したい)のか 違 うものとして 扱 いたい( 文 字 列 と して 扱 いたい)のかによって 利 用 すべきオペレータは 異 なります set x 5 if { $x == 5 { if { $x eq 5 { if { $x == 05 { if { $x eq 05 { # evaluates to true # evaluates to true # evaluates to true # evaluates to false よって 要 件 に 応 じて 適 切 なオペレータを 使 い 分 けるようにしてください 83

11. おわりに 基 本 的 な irules セットアップに 関 しては 以 上 で 終 了 となります BIG-IP シリーズ 製 品 ラインナップにおいては ソフトウェアモジュールライセンスを 追 加 することで サーバ 負 荷 分 散 はもちろんのこと 広 域 負 荷 分 散 やリモートアクセス 機 能 ネットワークファイアウォール 機 能 など アプリケーションア クセスを 最 適 化 する 為 の 多 彩 な 機 能 が 使 用 できるようになります 詳 細 は 各 種 WEB サイトにてご 確 認 いただくか 購 入 元 にお 問 い 合 わせください <F5 ネットワークス WEB サイトの 紹 介 > F5 ネットワークスジャパン 総 合 サイト https://f5.com/jp/homepage F5 Tech Depot:エンジニア 向 け 製 品 関 連 情 報 サイト http://www.f5networks.co.jp/depot/ AskF5:ナレッジベース 総 合 サイト( 英 語 ) http://support.f5.com/kb/en-us.html DevCentral:F5 ユーザコミュニティサイト( 英 語 :アカウント 登 録 が 必 要 です) https://devcentral.f5.com/ 以 上 引 用 文 献 : ウィキペディア:Tcl/Tk http://ja.wikipedia.org/wiki/tcl/tk F5 ネットワークスジャパン 合 同 会 社 107-0052 東 京 都 港 区 赤 坂 4-15-1 赤 坂 ガーデンシティ 19 階 本 資 料 は F5 ネットワークスジャパンのエンジニアが 特 定 のソフトウェアバージョンの 動 作 仕 様 に 基 づいて 作 成 した 構 築 設 計 を 補 助 するための 資 料 であり メーカー 公 式 資 料 とは 異 なります 資 料 の 記 載 内 容 に 誤 りがあった 際 には 指 摘 に 基 づいて 修 正 を 行 いますが 内 容 についての 責 任 は 一 切 負 いません また 修 正 変 更 改 訂 は 予 告 無 く 行 われます 84

12. Appendix 12.1. EVENT 発 動 のタイミング EVENT のフロー 85