FTP Session Logging

Problem this snippet solves:

This iRule logs FTP connections and username information. By default connection mapping from client through BIG-IP to server is logged as well as the username entered by the client. Optionally you can log the entire FTP session by uncommenting the log message in CLIENT_DATA.

Code :

# This iRule logs FTP connections and username information.
# By default connection mapping from client through BIG-IP to server is logged
# as well as the username entered by the client. Optionally you can log the 
# entire FTP session by uncommenting the log message in CLIENT_DATA.

when CLIENT_ACCEPTED {
    set vip [IP::local_addr]:[TCP::local_port]
    set user "unknown"
}

when CLIENT_DATA {
    # uncomment for full session logging
    #log local0. "[IP::client_addr]:[TCP::client_port]: collected payload ([TCP::payload length]): [TCP::payload]"
    
    # check if payload contains the string we want to replace
    if { [TCP::payload] contains "USER" } {
        # use a regular expression to save the user name
        ## regex modified by arkashik
        regexp "USER \(\[a-zA-Z0-9_-]+)"  [TCP::payload] all user

        # log connection mapping from client through BIG-IP to server
        log local0. "FTP connection from $client. Mapped to $inside -> $node, user $user"
        TCP::release
        TCP::collect
    } else {
        TCP::release
        TCP::collect
    }
}

when SERVER_CONNECTED {
    set client "[IP::client_addr]:[TCP::client_port]"
    set node "[IP::server_addr]:[TCP::server_port]"
    set inside "[serverside {IP::local_addr}]:[serverside {TCP::local_port}]"
    TCP::collect
}
 
when SERVER_DATA {
    TCP::release
    clientside { TCP::collect }
}
Published Mar 17, 2015
Version 1.0
  • I'm not good with TCL, is there a way to change the way the logging is done? I want to send it through HSL like I do for HTTP?

     

  • The regex doesn't work to capture a username with a dot or other special characters in it. And, regex can be expensive cpu wise.

    This irule seems to work well by just matching on the payload containing USER and printing that, then you don't even need the regex. Also lets you capture if someone is trying to brute force with other special characters.

    Rule /Common/log_ftp_sessions : FTP 10.0.0.0:60469: collected payload (30): USER S:LDEFJ:SLDFJS:DLFJ@@%

     check if payload contains the string we want to log
    if { [TCP::payload] contains "USER" } {
        log local0. "FTP Client IP [IP::client_addr]:[TCP::client_port]: ([TCP::payload length]): [TCP::payload]"
    

    Although of course, if the user's password is USER, it'll capture the password.. but you're using stricter password requirements than that, right? 😉

  • Hello there,

     

    I'm used this Irule to log every ftp session. At the moment works perfectly for me, but i realized that some things are not being logged. For example:

     

    When a client get a file from the ftp behind the F5, last log shows " RETR filename ", that is ok, but I would like to add when the transfer has been completed and finally when the client disconnect.

     

    Could be possible? Regards

     

  • I tried this irule but it logs the password in plain text. How to mask the password or remove it from logging.