BIG-IP APMとPassLogicを連携させて端末固有情報の登録を自動化する方法

Technorati タグ: APM,BIG-IP,iRules

SSLVPN利用基盤の構築においてクライアント証明書を用いずにデバイスの制限を簡易な運用で実現できる仕組みを検討されており、下記のような要件があったとします。

・SSLVPNを利用したい
・リスト型攻撃によるアカウント乗っ取りを防ぐ目的でワンタイムパスワードを利用したい
・メールを受信する形のワンタイムパスワードはそもそもメールを受信するシステムへのログインに使用するなど、メールが受信できない環境でのログインができないため今回は検討対象外
・ユーザーに許可したデバイス以外からのアクセスは禁止したい
・デバイス登録のためにデバイス固有情報を1台1台調べて登録する作業は防ぎたい
・デバイスの特定のためにクライアント証明書による認証はSSLを終端するタイプのProxy経由でのアクセスもあることと、運用管理がより煩雑になるため行いたくない
・1ユーザーが使用するデバイスはひとり1台ではなくMac, Windows, Linux, iOS, Androidがあり最大5台(うちiOS/Androidは最大2台)
・ユーザーに紐づけるデバイスではなく、あらかじめ登録してある共有用デバイス (PC, Windows, iOS, Android)からのログインは無条件に認めたい
・ジェイルブレイクされたiOS端末、Android端末の登録は許可しない

BIG-IP Access Policy Manager (以下APM)とパスロジ社のPassLogic Enterprise Edition 2.3.0(以下PassLogic)、そして本記事で紹介するAPMのAccess ProfileとiRulesでPassLogicのAPIと連携することでこれらの要件を満たすことができます。

システム要件
PassLogic Enterprise Edition 2.3.0
BIG-IP Access Policy Manager (APM) v12.0 HF1

このiRulesでは、Sideband Connectionを使用してAPMセッション変数のPassLogicのRADIUS Attribute登録を実現しています。

Technorati タグ: Japan

本設定サンプルでは、各OSで取得可能なデバイス固有情報

・(任意の)NICのMACアドレス (Windows, Mac, Linux)
session.machine_info.last.net_adapter.list.[0].mac_address

・マザーボードのシリアル番号 (Windowsのみ)
session.machine_info.last.motherboard.sn

・(任意の)ハードディスクドライブのシリアル番号 (Windowsのみ)
session.machine_info.last.hdd.list.[0].sn
詳しくは
About Machine Info
https://support.f5.com/kb/en-us/products/big-ip_apm/manuals/product/apm-visual-policy-editor-12-0-0/4.html
も合わせてご参照ください。

・iOSのUDID
session.client.unique_id
詳しくは
Support for using the BIG-IP Edge Client to check identifying information from Apple iOS client devices https://support.f5.com/kb/en-us/solutions/public/12000/700/sol12749.html
も合わせてご参照ください。

・AndroidのUnique ID
session.client.unique_id
詳しくは
Overview of session variable support for BIG-IP Edge Client for Android devices https://support.f5.com/kb/en-us/solutions/public/13000/700/sol13731.html
も合わせてご参照ください。

APMでは下記のようなポリシーを作成し、Access ProfileからiRulesイベントを呼び出します。

iRulesではAPMセッション変数を使用してPassLogicのRADIUS Attributeへ情報を登録します。

when RULE_INIT {
# Set the IP:Port of PassLogic Enterprise Edition
set static::passlogicip "192.168.10.201"
set static::passlogicport 7080
}

when ACCESS_POLICY_AGENT_EVENT {

#   Check Shared Device (Required to set HW Info to DataGroup SharedDevices HWInfo:=DeviceKind)
    if { [ACCESS::policy agent_id] eq "IsSharedDevice" } {
        set uname [ACCESS::session data get session.logon.last.username]
        set hwinfo [ACCESS::session data get session.passlogic.hwinfo]
        set devkind0 [ACCESS::session data get session.passlogic.devicekind]
        if { [class match -value $hwinfo eq SharedDevices] eq $devkind0 } {
            log local0. "User $uname is accessed with shared device kind=$devkind ($hwinfo)"
            ACCESS::session data set session.isshareddevice "yes"
        } else {
            log local0. "User $uname is accessed with non-shared device kind=$devkind0 ($hwinfo)"
            ACCESS::session data set session.isshareddevice "no"
        }            
    }

#   Device HW Information will be registed to PassLogic RADIUS Attribute
    if { [ACCESS::policy agent_id] eq "RegistHWInfoToPassLogic" } {
        # Get APM session variables
        set uname [ACCESS::session data get session.logon.last.username]
        set dom [ACCESS::session data get session.logon.last.domain]
        set rattr [ACCESS::session data get session.passlogic.attr]
        set devkind [ACCESS::session data get session.passlogic.devicekind]
        set hwinfo [ACCESS::session data get session.passlogic.hwinfo]
        set rewrite9 [ACCESS::session data get session.passlogi.setrewrite9]
        set newattr ""
        log local0. "username = $uname device=$devkind hw=$hwinfo"
        log local0. "Old Attribute = $rattr"

        if { $rewrite9 eq "yes" } {
            log local0. "Rewrite not device kind ($devkind) but any device (9)"
            set devkind 9
        }
        # flag for change attribute
        set addd 0
        foreach i [split $rattr |] {
            if { $i eq $devkind } {
                if { $addd == 0 } {
                    # Generate new attribute data for regist new device
                    set tstr $newattr
                    set newattr "$tstr$hwinfo|"
                    set addd 1
                } else {
                    set tstr $newattr
                    set newattr "$tstr$i|"
                }
            } else {
                    set tstr $newattr
                    set newattr "$tstr$i|"
            }
        }
        if { $addd == 1 } {
            log local0. "New DeviceID ($hwinfo) for user $uname will be registered to PassLogic. New RADIUS Attribute=$newattr"
            set conn [connect -timeout 3000 -idle 30 -status conn_status $static::passlogicip $static::passlogicport ]
            log local0. "Connect returns: <$conn> and conn status: <$conn_status> "
            set conn_info [connect info -idle -status $conn]
            log local0. "Connect info: <$conn_info>"
            set data "GET /passlogic/api/admin?mode=useredit&uid=$uname&domain=$dom&attribute1=$newattr HTTP/1.0\r\n\r\n"
            set send_info [send -timeout 3000 -status send_status $conn $data]
            log local0. "Sent <$send_info> bytes and send status: <$send_status>"
            set recv_data [recv -timeout 3000 -status recv_status 1024 $conn]
            log local0. "Recv data: <$recv_data> and recv status: <$recv_status>"
            close $conn
            log local0. "Closed; conn info: <[connect info -status $conn]>"
            log local0. "PassLogic response is correct."

            if { $recv_data contains "PassLogic" } {
                set ret [string range [findstr $recv_data "
" 0 "
"] 6 10] log local0. "Result Code = $ret" ACCESS::session data set session.passlogic.result $ret switch $ret { "50300"{ ACCESS::session data set session.passlogic.error "PassLogic Error: err Invalid input data." log local0. "PassLogic Error: err Invalid input data." } "50301"{ ACCESS::session data set session.passlogic.error "PassLogic Error: err The user does not exist." log local0. "PassLogic Error: err The user does not exist." } "50302"{ ACCESS::session data set session.passlogic.error "PassLogic Error: err Update parameter is required." log local0. "PassLogic Error: err Update parameter is required." } "50400"{ ACCESS::session data set session.passlogic.error "PassLogic Information: notice User information has updated successfully. New DeviceID ($hwinfo) for user $uname was registered." log local0. "PassLogic Information: notice User information has updated successfully. New DeviceID ($hwinfo) for user $uname was registered." } "50499"{ ACCESS::session data set session.passlogic.error "PassLogic Error: crit System error occurred." log local0. "PassLogic Error: crit System error occurred." } } } } else { ACCESS::session data set session.passlogic.result "NG" } } }

詳しい設定手順やAccess Profile、iRulesサンプルは下記よりダウンロードできます。

https://f5.com/Portals/1/PDF/JAPAN/devcentral/PassLogic230_APM12_AP_iRule_v1.zip

Updated Jun 06, 2023
Version 2.0
No CommentsBe the first to comment