Showing results for 
Search instead for 
Did you mean: 
Login & Join the DevCentral Connects Group to watch the Recorded LiveStream (May 12) on Basic iControl Security - show notes included.

Problem this snippet solves:

When using ftps with ccc-mode (clear command channel) the ftp-profile on LTM does not seem to translate the respons on the PASV-command correctly. This iRule looks at data coming from the server and replaces the '227 Entering Passive Mode' string for a correct one.

Code :

# This iRule performs NAT on ftps in ccc-mode
# It searches for "227 Entering Passive Mode" in data from
# the server and replaces it with the correct IP-address
# so that the client will connect to the correct address

# Set DEBUG to 1 to get debug-logging of this iRule in /var/log/ltm
when RULE_INIT {
  set static::DEBUG 0

 if { $static::DEBUG } { log local0. "FTP connection from [IP::client_addr]:[TCP::client_port]. \
 Mapped to [serverside {IP::local_addr}]:[serverside {TCP::local_port}] \
-> [IP::server_addr]:[serverside {TCP::remote_port}]" }

  # If in debug mode, log payload of received packet
  if { $static::DEBUG } { log local0. "payload <[TCP::payload]>" }

  # check if payload contains the string we want to replace
  if { [TCP::payload 50] contains "227 Entering Passive Mode" }
     # If in debug mode, log that the payload matched
     if { $static::DEBUG } { log local0. "payload matched" }
     # use a regular expression to save the dataport part of the pasv output
     regexp {[0-9]{1,3},[0-9]{1,3},[0-9]{1,3},[0-9]{1,3},([0-9]{1,5}),([0-9]{1,5})}  [TCP::payload] all first second
     # empty payload entirely so there is no packet to send to the server
     # then fill the packet with the new 227 string
     TCP::payload replace 0 [TCP::payload length] ""
     # edit rule below to match your virtual-server ip address
     set packetdata "227 Entering Passive Mode (xx,xx,xx,xx,$first,$second)\r\n"
     TCP::payload replace 0 0 $packetdata

     # if in debug mode, log the new payload to /var/log/ltm
     if { $static::DEBUG } { log local0. "changed payload <[TCP::payload]>" }
    # release the packet, and collect a new one
Version history
Last update:
‎18-Mar-2015 12:05
Updated by: