【要注意】FortiGate v7.6.3 から全モデルでSSL VPNトンネルモードサポート終了> Membership

A10 Thunder aFleX で仮想サーバのアクセスログを生成しローカルメモリや Syslog サーバに出力する方法

目次

本記事について

本記事では、A10ネットワークス社のロードバランサ製品である Thunder シリーズについて、SLB仮想サーバへクライアントからアクセスがあった際に、クライアントIP/Port、仮想サーバIP/Port、転送先サーバIP/Port 等の情報を含むアクセスログを生成し、システムログとして出力させる方法について説明します。

2025/01/12 08:25:32 |Client| 192.168.200.1:57930 --> 192.168.200.100:53 |LB| 10.1.1.1:24169 --> 10.1.1.10:53 |Server|

本記事は以下のような内容を含んでいます。

  • aFleX とは
  • aFleX の作成方法
  • アクセスログを生成する aFleX の作成方法
  • 仮想サーバへの aFleX の適用方法

動作確認環境

本記事は以下の環境にて動作確認した結果に基づいて作成されています。

  • A10 vThunder
    • version 5.2.1-P11

仮想サーバのアクセスログを生成する

A10 Thunder にて、クライアントから仮想サーバへのアクセス状況を確認する方法としては、リアルタイムにセッション情報、サーバ・サービスグループ・仮想サーバの統計情報(コネクションカウント、パケットカウント)などを確認する方法があります。一方、A10 Thunder の通常の機能ではファイアウォール製品のようにトラフィックログの保存を行うことはできません。

それでも A10 Thunder において仮想サーバのアクセスログを保存したいという場合には、aFleX と呼ばれるスクリプトを作成して仮想サーバに適用することで、アクセスログを生成しシステムログとして出力・保存させることができます。

以下でその設定方法を説明します。

aFleX の概要とその作成方法

aFleX は TCL ベースのスクリプト機能

aFleX とは A10 Thunder にて作成できるスクリプト機能であり、aFleX を使用することで通常の設定では実現できない様々な動作を実現することができます。aFleX はスクリプト言語の TCL をベースにしています。

F5 社のロードバランサ製品である BIG-IP も同様に iRule と呼ばれるスクリプト機能を持っています。

仮想サーバ毎にこの aFleX を適用することができます。アクセスログを生成・出力する内容の aFleX を作成し、対象の仮想サーバに適用することでアクセスログを出力・保存することができます。

aFleX の作成方法

aFleX は GUI または CLI で作成できますが、CLI では新規 aFleX の作成はできても既存 aFleX の編集はできないため、通常は GUI で作成することが多いと思います。ここでは GUI での作成方法のみ説明します。

STEP
aFlex 設定画面の表示

GUI にログインし、画面上のメニューから「ADC > aFleX」をクリックします。

STEP
aFleX 新規作成画面の表示

表示された aFleX 画面の右上にある「+Create」ボタンをクリックします。

STEP
aFleX の作成

以下の画面にて aFleX の内容を設定します。

  • Local / Remote → デフォルトの「Local」のままとします。
  • Name → aFleX の名前です。任意の名前を入力します。記号は「-」「_」のみ使用できます。
  • Definition → スクリプトの内容を入力します。

以上の設定ができたら右下の「Create」ボタンをクリックします。

STEP
aFleX がエラー無く作成されたことを確認

GUI 画面上に以下のように「aFleX was successfully created.」と表示されたことを確認します。

スクリプト内容に構文エラーがあった場合、以下のようにエラーメッセージが表示されます。

リストに作成した aFleX が追加されたことを確認します。

以上で aFleX の作成は完了です。

STEP
【補足】既存 aFleX の内容確認・編集方法

既存の aFleX の内容確認をしたり、編集したりするためには Actions 欄の「Edit」をクリックします。

aFleX の内容はコンフィグ上には表示されません

aFleX の内容はshow running-configの出力には表示されません。このため、aFleX のバックアップのためにはシステムバックアップを取得する必要があります。

またshow aflexコマンドで作成されている aFleX の一覧を表示でき、show aflex <aflex名>コマンドで指定した aFleX のスクリプト内容や統計情報を表示できます。

vThunder#show aflex
Max aFlex file size: 32K
Name                                             Syntax   Virtual port
-----------------------------------------------------------------------
aflex-test                                       Check    No
host_switching                                   Check    No
http_payload_replace                             Check    No
logging-http                                     Check    Bind
logging-tcp                                      Check    Bind
logging-udp                                      Check    Bind
logging_clients                                  Check    No
redirect1                                        Check    No
redirect2                                        Check    No
redirect_rewrite                                 Check    No
Total aFlex number: 10

vThunder#show aflex logging_clients
Name:                    logging_clients
Syntax:                  Check
Virtual port:            No
Statistics:
    Event CLIENT_ACCEPTED      execute 0 times (0 failures, 0 aborts)
    Event SERVER_CONNECTED     execute 0 times (0 failures, 0 aborts)
Content:
# This aFleX logs Client/Server IP/Port information for security when using Source NAT
when CLIENT_ACCEPTED {
  set timestamp [TIME::clock seconds]
  set cip [IP::client_addr]
  set cport [TCP::client_port]
  set vip [IP::local_addr]
  set vport [TCP::local_port]
}

when SERVER_CONNECTED {
  set sip [IP::server_addr]
  set sport [TCP::server_port]
  set snat_ip [IP::local_addr]
  set snat_port [TCP::local_port]

  log "\[$timestamp\] $cip:$cport -> $vip:$vport to $snat_ip:$snat_port -> $sip:$sport"
}

アクセスログを生成する aFleX の作成方法

仮想サーバのアクセスログを生成する aFleX の作成方法について説明します。

aFleX のイベントの基礎知識

aFleX はイベント駆動式のスクリプトです。スクリプト内で指定したイベントが発生したタイミングでスクリプトがトリガーされます。スクリプトで処理したい内容に応じて対象とするイベントを選択する必要があります。

イベントは通信プロトコルごとに用意されていますが、ここでは IP/TCP/UDP、HTTP を対象にして考えます。またプロトコルに関係無く使用できる LB 関連のイベントについても説明します。

IP/TCP/UDP のイベント

IP/TCP/UDP のイベントとしては以下があります。

  • CLIENT_ACCEPTED
    • クライアントが A10 Thunder との接続を確立したとき
      • syn-cookie のない L4 の場合、最初のパケット
      • syn-cookie を使用した L4 および L7 の場合、TCP ハンドシェイクが完了したとき
    • UDP (UDP のみ) の場合、最初に受信された UDP パケットでトリガー
  • CLIENT_CLOSED
    • プロトコルに関係なく、クライアント接続の終了時
  • CLIENT_DATA
    • 接続が収集状態にあるときにクライアントから新しいデータを受信したとき
    • UDP の場合、受信された UDP パケットごとに自動的にトリガー
  • SERVER_CLOSED
    • サーバ側の接続が閉じられたとき
  • SERVER_CONNECTED
    • サーバとの接続が確立されたとき
    • UDP の場合で戻り通信が発生しないタイプの通信の場合はトリガーされない
  • SERVER_DATA
    • 接続が保留状態にあるときにサーバから新しいデータを受信したとき
    • UDP の場合、サーバからの戻りパケットごとに SERVER_DATA イベントがトリガー
      • サーバからの戻り通信が発生しないタイプの通信の場合トリガーされない
    • TCP の場合、TCP::collectを発行する必要があります

HTTP のイベント

HTTP のイベントとしては以下があります。

  • HTTP_RESPONSE_DATA
    • HTTP::collect接続のサーバ側でコマンドの処理が完了したら
    • HTTP::collectコマンドの処理が完了する前にサーバが接続を閉じた場合にもトリガー
  • HTTP_RESPONSE_CONTINUE
    • A10 Thunder がサーバから 100 Continue 応答を受信するたび
  • HTTP_RESPONSE
    • サーバ応答からの応答ステータスとヘッダー行がすべて解析されたとき
    • これは、ロードバランサを通過する SERVER 応答に固有のものであり、ローカルで生成された応答に対してはトリガーされません
  • HTTP_REQUEST_SEND
    • リクエストがサーバに送信される直前
  • HTTP_REQUEST_DATA
    • HTTP::collectコマンドの処理が完了したら
  • HTTP_REQUEST
    • 完全なクライアント要求ヘッダー (メソッド、URI、バージョン、および本文を除くすべてのヘッダー) が解析されるとき

LB 関連のイベント

LB 関連のイベントとしては以下があります。

  • LB_SELECTED
    • 転送先サーバが選択されたタイミングでトリガー
  • LB_FAILED
    • 仮想サーバへのリクエストに対して転送先サーバの選択に失敗した場合にトリガー
      • プールの全てのサーバがダウンしている場合
      • 接続制限に達している場合

アクセスログを生成する aFleX の内容

トリガーや使用変数がプロトコル別に異なるため、ここでは TCP、UDP、HTTP で分けて aFleX を考えます。

ここで説明しているスクリプト内容はあくまで一例です。ログの形式等は自由にカスタマイズすることができます。

TCP 通信のアクセスログを生成する aFleX

ここでは以下の形式のアクセスログを生成することとします。

  • yyyy/mm/dd hh:mm:ss |Client| クライアントIP:Port –> 仮想サーバIP:Port |LB| 転送時送信元IP:Port –> サーバIP:Port |Server|
    • 青字部分は通信毎に変わる変数
2025/01/12 08:25:32 |Client| 192.168.200.1:57930 --> 192.168.200.100:53 |LB| 10.1.1.1:24169 --> 10.1.1.10:53 |Server|

このログを出力する aFleX の内容は以下です。

when CLIENT_ACCEPTED {
        set cli_ip [IP::client_addr]
        set cli_port [TCP::client_port]
        set vs_ip [IP::local_addr]
        set vs_port [TCP::local_port]
}
when SERVER_CONNECTED {
        set cli_ip_nat [IP::local_addr]
        set cli_port_nat [TCP::local_port]
        set sv_ip [LB::server addr]
        set sv_port [LB::server port]

        log "[clock format [TIME::clock seconds] -format {%Y/%m/%d %H:%M:%S}] |Client| $cli_ip:$cli_port --> $vs_ip:$vs_port |LB| $cli_ip_nat:$cli_port_nat --> $sv_ip:$sv_port |Server|"
}

Thunder の CLI でログをshow logで表示した場合、以下のように表示されます。

vThunder#show log length 1
Log Buffer: 30000
Jan 12 2025 08:25:32 Info        [AFLEX]:logging-tcp:2025/01/12 08:25:32 |Client| 192.168.200.1:57930 --> 192.168.200.100:53 |LB| 10.1.1.1:24169 --> 10.1.1.10:53 |Server|

UDP 通信のアクセスログを生成する aFleX

ここでは以下の形式のアクセスログを生成することとします。

  • yyyy/mm/dd hh:mm:ss |Client| クライアントIP:Port –> 仮想サーバIP:Port |LB| –> サーバIP:Port |Server|
    • 青字部分は通信毎に変わる変数
2025/01/19 06:45:07 |Client| 192.168.200.1:52937 --> 192.168.200.100:53 |LB| --> 10.1.1.10:53 |Server|

このログを出力する aFleX の内容は以下です。

when CLIENT_DATA {
        set cli_ip [IP::client_addr]
        set cli_port [UDP::client_port]
        set vs_ip [IP::local_addr]
        set vs_port [UDP::local_port]
}
when LB_SELECTED {
        set sv_ip [LB::server addr]
        set sv_port [LB::server port]

        log "[clock format [TIME::clock seconds] -format {%Y/%m/%d %H:%M:%S}] |Client| $cli_ip:$cli_port --> $vs_ip:$vs_port |LB| --> $sv_ip:$sv_port |Server|"
}

Thunder の CLI でログをshow logで表示した場合、以下のように表示されます。

vThunder#show log length 1
Log Buffer: 30000
Jan 19 2025 06:45:07 Info        [AFLEX]:logging-udp:2025/01/19 06:45:07 |Client| 192.168.200.1:52937 --> 192.168.200.100:53 |LB| --> 10.1.1.10:53 |Server|

HTTP 通信のアクセスログを生成する aFleX

ここでは以下の形式のアクセスログを生成することとします。

  • yyyy/mm/dd hh:mm:ss |Client| クライアントIP:Port –> 仮想サーバIP:Port |LB| 転送時送信元IP:Port –> サーバIP:Port PATH:リクエストパス |Server|
    • 青字部分は通信毎に変わる変数
2025/01/12 08:54:05 |Client| 192.168.200.1:58633 --> 192.168.200.110:80 |LB| 10.1.1.1:24128 --> 10.1.1.10:80 PATH:/page01.html |Server|

このログを出力する aFleX の内容は以下です。

when HTTP_REQUEST {
        set cli_ip [IP::client_addr]
        set cli_port [TCP::client_port]
        set vs_ip [IP::local_addr]
        set vs_port [TCP::local_port]
}
when HTTP_REQUEST_SEND {
        set cli_ip_nat [IP::local_addr]
        set cli_port_nat [TCP::local_port]
        set sv_ip [LB::server addr]
        set sv_port [LB::server port]
        set uri [HTTP::uri]

        log "[clock format [TIME::clock seconds] -format {%Y/%m/%d %H:%M:%S}] |Client| $cli_ip:$cli_port --> $vs_ip:$vs_port |LB| $cli_ip_nat:$cli_port_nat --> $sv_ip:$sv_port PATH:$uri |Server|"
}

Thunder の CLI でログをshow logで表示した場合、以下のように表示されます。

vThunder#show log length 1
Log Buffer: 30000
Jan 12 2025 08:54:05 Info        [AFLEX]:logging-http:2025/01/12 08:54:05 |Client| 192.168.200.1:58633 --> 192.168.200.110:80 |LB| 10.1.1.1:24128 --> 10.1.1.10:80 PATH:/page01.html |Server|

aFleX 内容の解説

各プロトコルにでトリガーとするイベントについては以下の3つを使用しています。

  • クライアント~仮想サーバ(LB)間の通信が発生した際のイベント
  • 仮想サーバ(LB)~リアルサーバ間の通信が発生した際のイベント
    • 本記事の aFleX 例では TCP、HTTP 場合で使用
  • 転送先サーバが選択された際のイベント
    • 本記事の aFleX 例では UDP 場合で使用

それぞれのイベント発生時に、以下の処理を行っています。

クライアント~仮想サーバ(LB)間の通信が発生した際の処理内容

TCP の aFleX を例に説明します。

このタイミングでは以下の処理を行っています。

        set cli_ip [IP::client_addr]
        set cli_port [TCP::client_port]
        set vs_ip [IP::local_addr]
        set vs_port [TCP::local_port]

各行以下の構文となっています。

  • set <変数名> <変数に格納する値>

ここでは以下の値を収集して変数に格納しています。これらは後のログ出力で使用します。

  • [IP::client_addr] → クライアントのIPアドレス
  • [TCP::client_port] → クライアントのポート
  • [IP::local_addr] → 仮想サーバのIPアドレス(クライアントからの宛先IPアドレス)
  • [TCP::local_port] → 仮想サーバのポート(クライアントからの宛先ポート)

仮想サーバ(LB)~リアルサーバ間の通信が発生した際の処理内容

TCP の aFleX を例に説明します。

このタイミングでは以下の処理を行っています。

        set cli_ip_nat [IP::local_addr]
        set cli_port_nat [TCP::local_port]
        set sv_ip [LB::server addr]
        set sv_port [LB::server port]

        log "[clock format [TIME::clock seconds] -format {%Y/%m/%d %H:%M:%S}] |Client| $cli_ip:$cli_port --> $vs_ip:$vs_port |LB| $cli_ip_nat:$cli_port_nat --> $sv_ip:$sv_port |Server|"

最初の4行は以下の構文となっています。

  • set <変数名> <変数に格納する値>

ここでは以下の値を収集して変数に格納しています。これらは後のログ出力で使用します。

  • [IP::local_addr] → リアルサーバとの通信時の送信元IPアドレス
  • [TCP::local_port] → リアルサーバとの通信時の送信元ポート
  • [LB::server addr] → 転送先リアルサーバのIPアドレス(LBからの宛先IPアドレス)
  • [LB::server port] → 転送先リアルサーバのポート(LBからの宛先ポート)

以下の最後の行はログの出力を行う処理です。

aFleXでのログ出力構文
  • log “<出力するログの内容>”

ログの中身については以下の通りです。

  • [clock format [TIME::clock seconds] -format {%Y/%m/%d %H:%M:%S}]
    • イベント発生時の時刻を示しています
  • $<変数名>
    • 指定した変数の値を示しています

転送先サーバが選択された際のイベント

UDP 通信の場合、Syslog や SNMP トラップなどサーバからの戻りの通信が発生しない場合もあります。このため、サーバからの戻りの通信の発生が前提となるイベントを使用することは適切ではない場合があります。

そこで、本記事ではサーバからの戻りの通信が発生しない場合でもトリガーされる LB_SELECTED イベントを使用しています。LB_SELECTED は転送先サーバが選択されたタイミングでトリガーされるため、サーバからの戻りの通信の有無に関係無くトリガーされます。

when LB_SELECTED {
        set sv_ip [LB::server addr]
        set sv_port [LB::server port]

        log "[clock format [TIME::clock seconds] -format {%Y/%m/%d %H:%M:%S}] |Client| $cli_ip:$cli_port --> $vs_ip:$vs_port |LB| --> $sv_ip:$sv_port |Server|"
}

なお、LB_SELECTED イベントの中の処理では、[IP::local_addr] の値としてクライアントからの接続先となる仮想サーバの IP アドレスが取得されます。このためサーバへ転送時に送信元 NAT をしている場合の NAT 後 IP アドレスを [IP::local_addr] で取得することはできないため注意してください。

仮想サーバへの aFleX の適用方法

仮想サーバに対して aFleX を適用します。aFleX は仮想サーバのポート設定毎に設定するため、仮想サーバのポート設定配下で設定します。

仮想サーバへのaFleXの適用設定
  • aflex <aFleX名>
    • 仮想サーバのポート設定配下で設定する
slb virtual-server Apache 192.168.200.110
  port 80 http
    aflex logging-http
    source-nat auto
    service-group Apache-tcp
!
slb virtual-server BIND 192.168.200.100
  port 53 tcp
    aflex logging-tcp
    source-nat auto
    service-group BIND-tcp
  port 53 udp
    aflex logging-udp
    source-nat auto
    service-group BIND-udp

aFleXで生成したアクセスログを Syslog サーバに転送する

aFleX で生成されたログは、システムログとして A10 Thunder のローカルメモリに出力され、通常のシステムログと同様に扱われます。

よって aFleXで生成したアクセスログを Syslog サーバに転送するためには、通常通り Syslog サーバの設定を行えば OK です。

Syslog サーバの設定
  • 転送先 Syslog サーバの設定
    • logging host <Syslog サーバアドレス>
  • Syslog 転送するログレベルの設定
    • logging syslog <ログレベル>
      • emergency (severity=0)
      • alert (severity=1)
      • critical (severity=2)
      • error (severity=3)
      • warning (severity=4)
      • notification (severity=5)
      • information (severity=6)
      • debugging (severity=7)
logging host 192.168.200.1
logging syslog information

aFleX で生成されるログのログレベルは(デフォルトでは)information のため、ログレベルは information または debugging にする必要があります。

aFleX で生成されるログをローカルロギングする場合も同様にローカルのロギングレベル(logging buffered設定)を information または debugging を設定する必要があります。
※デフォルトでは debugging です

aFleX の log コマンドのオプション設定で出力するログのログレベルを変更することも可能です。(後日追記予定)

まとめ

  • A10 Thunder には aFleX と呼ばれるスクリプト機能がある
  • aFleX はイベント駆動式である
  • aFleX を使用して仮想サーバのアクセスログを生成することができる
  • aFleX は仮想サーバのポート毎に適用する
  • aFleX はコンフィグ上には表示されないためバックアップのためにはシステムバックアップを取得する

参考資料


A10 Thunder の設計構築に役立つ関連記事一覧

よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!

コメント

コメントする

日本語が含まれない投稿は無視されますのでご注意ください。(スパム対策)

目次