Forum Discussion

Franck_Marchior's avatar
Franck_Marchior
Icon for Nimbostratus rankNimbostratus
Dec 15, 2016

F5 APM - Google TOTP - How to write into internal data group from irule

Hello,

Can anyone help me to find how we could write into internal datagroup from irule ?

The irule look like this:

when ACCESS_POLICY_AGENT_EVENT {

if { [ACCESS::policy agent_id] eq "ga_add_secretkey" } {

set username [ACCESS::session data get session.logon.last.username]
set secretkey [ACCESS::session data get session.custom.ga_secretkey]

tmsh_modify /ltm data-group internal google_auth_keys records add {
$username { data $secretkey } }
}

}

Thank you,

2 Replies

  • Hi Franck,

    the

    [tmsh::modify]
    and several other config-plane specific commands are not available within iRules.

    But you may use a

    [SIDEBAND]
    connection within an iRule pointing towards your REST-API and then execute a predefined TMSH script that changes the data-group for you as needed.

    Below is a short write up for you to create a working POC...

    Create a TMSH script to change the data-group

    1.) Login to your F5 via SSH

    2.) Execute the following command on TMSH

    load sys config merge from-terminal
    

    3.) Paste the following script into TMSH

    cli script add_totp_key {
        proc script::run {} {
            set cmd "tmsh::modify /ltm data-group internal google_auth_keys \{ records add \{ [lindex $tmsh::argv 1] \{ data [lindex $tmsh::argv 2] \} \} \}"
            tmsh::log "Executing the command: $cmd"
            eval $cmd
        }
    }
    

    Note: You have to make sure that the data-group "google_auth_keys" already exists.

    4.) Hit

    CRTL+D
    to save the config change

    Configure a Layer4 VS:80 that points to the MGMT-ETH:443 of your F5

    1.) Execute the following command on TMSH

    load sys config merge from-terminal
    

    2.) Paste the following config into TMSH

    ltm pool Pool_F5-MGMT-ETH {
        members {
            Node_F5-MGMT-ETH:https {
                address x.x.x.x%1
                session monitor-enabled
                state up
            }
        }
        monitor gateway_icmp 
    }
    
    ltm virtual VS_F5-MGMT-ETH {
        destination 1.1.1.1%1:http
        ip-protocol tcp
        mask 255.255.255.255
        pool Pool_F5-MGMT-ETH
        profiles {
            serverssl {
                context serverside
            }
            tcp { }
        }
        source 0.0.0.0%1/0
        source-address-translation {
            type automap
        }
        translate-address enabled
        translate-port enabled
    }
    

    Note: You have to change the node IP address to match the MGMT-IP of your LTM.

    3.) Hit

    CRTL+D
    to save the config change

    Write a TCL procedure to trigger a SIDEBAND connection towards your REST-API to execute the predefined TMSH script including required parameters (aka. $username and $key).

    1.) Add the following procedure to your existing iRule

    proc add_totp_key { virtual basic_creds username key } {
        set tcp_conn [connect -timeout 2000 -idle 2000 -status tcp_conn_status $virtual]
        if { $tcp_conn_status equals "connected" } then {
            set http_request_body "\{\"command\":\"run\",\"utilCmdArgs\":\"add_totp_key $username $key\"\}"
            set http_request "POST /mgmt/tm/cli/script/ HTTP/1.0\r\nHost: xxx\r\nAuthorization: Basic $basic_creds\r\nContent-Length: [string length $http_request_body]\r\n\r\n$http_request_body"
            send -timeout 2000 -status tcp_sent_status $tcp_conn $http_request
            if { $tcp_sent_status equals "sent" } then {
                set http_response [recv -timeout 2000 $tcp_conn]
                if { $http_response starts_with "HTTP/1.1 200" } then {
                    return "Success"
                } elseif { $http_response equals "" } then {
                    return "Error: Receive Timeout"
                } else {
                    return "Error: API Response = $http_response"
                }
            } else {
                return "Error: Send Status = $tcp_sent_status"
            }
        } else {
            return "Error: Connection Status = $tcp_conn_status"
        }
    }
    

    2.) Modify your existing iRule to call the procedure to finally update the data-group.

    when ACCESS_POLICY_AGENT_EVENT {
        if { [ACCESS::policy agent_id] eq "ga_add_secretkey" } {
            set result [call add_totp_key "VS_F5-MGMT-ETH" "[b64encode "admin:password"]" "[ACCESS::session data get session.logon.last.username]" "[ACCESS::session data get session.custom.ga_secretkey]"]
            log local0.debug "Result: $result"
        }
    }
    

    Note: You have to change the username:password value to match a admin account of your device.

    Hope this helps to get the picture how to change a data-group via an iRule.

    Cheers, Kai

  • Hi

    the

    Error: Receive Timeout
    error message is most likely caused by a malfunctioning Virtual Server / Pool / Node setup.

    You may try to specify the provided IPs without any RD-suffixes (aka.

    %0
    ). If this also fails, then change the IP of your Virtual Server so that you can access this IP:80 via your browser. If the browser can finally access the MGMT-UI then the iRule should be fine too.

    ltm pool Pool_F5-MGMT-ETH {
        members {
            Node_F5-MGMT-ETH:https {
                address 10.13.240.99
                session monitor-enabled
                state up
            }
        }
        monitor gateway_icmp 
    }
    
    ltm virtual VS_F5-MGMT-ETH {
        destination 1.1.1.1:http
        ip-protocol tcp
        mask 255.255.255.255
        pool Pool_F5-MGMT-ETH
        profiles {
            serverssl {
                context serverside
            }
            tcp { }
        }
        source 0.0.0.0/0
        source-address-translation {
            type automap
        }
        translate-address enabled
        translate-port enabled
    }
    

    Cheers, Kai