Forum Discussion

sistemaspcs_851's avatar
sistemaspcs_851
Icon for Nimbostratus rankNimbostratus
May 19, 2016

virtual command not working

Hello,

I hope you could help me (I'm sorry if my question is too simple, i am a begginer in F5 world):

I am trying to make it work the solution offered by Colin in this topic:

ftps-offload-via-irules

I 've followed the steps, but by the moment it doesn't work and now I'm completely stuck

The thing is, it seems like the 'virtual' command in the first iRule is not calling the second iRule. I inserted some log commands in the iRules, and the process stops in the first iRule, and never reaches the second one. I also can see that in the statistics for the second Virtual Server, that are totally zeroed

This is the first VS (VS-PRE-FTPS_1):

ltm virtual VS-PRE-FTPS_1 {
destination X.X.X.X:ftp
ip-protocol tcp
mask 255.255.255.255
persist {
    source_addr_FTPS {
        default yes
    }
}
profiles {
    Profile-WildcardPCS-2014-2016-SHA1 {
        context clientside
    }
    ftp { }
    tcp { }
}
rules {
    irule_FTPS_1
}
source 0.0.0.0/0
source-address-translation {
    type automap
}
vs-index 81

}

This is the first VS iRule (irule_FTPS_1):

when CLIENT_ACCEPTED {
log local0. "client accepted"
SSL::disable
TCP::respond "220 My ftp server\r\n"
TCP::collect
}
when CLIENT_DATA {
log local0. "client data"
TCP::respond "234 AUTH TLS Successful\r\n"
TCP::payload replace 0 [TCP::payload length] ""
virtual VS-PRE-FTPS_2
SSL::enable
TCP::release
log local0. "TCP Release Completed"
}

This is the second VS (VS-PRE-FTPS_2):

ltm virtual VS-PRE-FTPS_2 {
destination any:any
internal
ip-protocol tcp
mask any
persist {
    source_addr_FTPS {
        default yes
    }
}
pool pool-preweb-ftp
profiles {
    tcp { }
}
rules {
    irule_FTPS_2
}
source 0.0.0.0/0
source-address-translation {
    type automap
}
translate-address disabled
translate-port disabled
vlans-enabled
vs-index 82
}

This is the second VS iRule (irule_FTPS_2):

    when CLIENT_ACCEPTED {
    TCP::collect
    log local0. "client accepted"
    }
    when CLIENT_DATA {
    if { [TCP::payload] contains "PBSZ" }  {
    TCP::payload replace 0 [TCP::payload length] ""
    TCP::respond "200 PBSZ 0 successful\r\n"
    log local0. "client data1"
    } elseif { [TCP::payload] contains "PROT P" } {
    TCP::respond "200 Protection set to Private\r\n"
    TCP::payload replace 0 [TCP::payload length] ""
    log local0. "client data2"
    } elseif { [TCP::payload] contains "FEAT" } {
    TCP::payload replace 0 [TCP::payload length] ""
    TCP::respond "211-Features:  MDTM  REST STREAM  SIZE  AUTH TLS  PBSZ  PROT\r\n211 End\r\n"
    log local0. "client data3"
    }  
    TCP::release
    TCP::collect
    }
    when SERVER_CONNECTED {
    TCP::collect
    log local0. "server connected"
    }
    when SERVER_DATA {
    if { [TCP::payload] contains "220 " } {
    TCP::payload replace 0 [TCP::payload length] ""
    log local0. "server data1"
    } elseif { [TCP::payload] contains "Entering Passive Mode" } {
     You need to modify this section if your servers are not
     configured to hand out the VIP address for Passive transfers.
    log local0. "server data2. sustituyendo IP respuesta"
    regsub {Z,Z,Z,Z} [TCP::payload] "X,X,X,X" tmpstr
    TCP::payload replace 0 [TCP::payload length] $tmpstr
    } 
    TCP::release
    TCP::collect
    }

And this is the log i get in the F5:

    May 18 16:41:50 balanceador2 info tmm1[9754]: Rule /Common/irule_FTPS_1 : client accepted
    May 18 16:41:50 balanceador2 info tmm1[9754]: Rule /Common/irule_FTPS_1 : client data
    May 18 16:41:50 balanceador2 info tmm1[9754]: Rule /Common/irule_FTPS_1 : TCP Release Completed
    May 18 16:41:55 balanceador2 info tmm[9754]: Rule /Common/irule_FTPS_1 : client accepted
    May 18 16:41:55 balanceador2 info tmm[9754]: Rule /Common/irule_FTPS_1 : client data
    May 18 16:41:55 balanceador2 info tmm[9754]: Rule /Common/irule_FTPS_1 : TCP Release Completed

And in the FTP client (FileZilla in this case, but I tried with WinSCP too):

    Status: Connecting to X.X.X.X:21...
    Status: Connection established, waiting for welcome message...
    Response:   220 My ftp server
    Command:    AUTH TLS
    Response:   234 AUTH TLS Successful
    Status: Initializing TLS...
    Error:  GnuTLS error -58: An illegal TLS extension was received.
    Error:  Could not connect to server
    Status: Waiting to retry...
    Status: Delaying connection for 1 second due to previously failed connection attempt...
    Status: Connecting to X.X.X.X:21...
    Status: Connection established, waiting for welcome message...
    Response:   220 My ftp server
    Command:    AUTH TLS
    Response:   234 AUTH TLS Successful
    Status: Initializing TLS...
    Error:  GnuTLS error -58: An illegal TLS extension was received.
    Error:  Could not connect to server

could someone give me the clue about what i am doing wrong?

thanks in advance

4 Replies

  • I believe your problem is that where the guide says to create an "internal virtual server", it means a standard virtual server that is internal to your network, not a virtual server of type 'internal'. I'll get the article updated to make that clearer.

     

    Internal virtual servers (or IVS), which is a virtual server of type 'internal' are used for sideband connections to ICAP servers, APM flows, etc. They can't be selected with the irule 'virtual' command (you'll get a reset cause of '{peer} host unreachable' if you try to do it)

     

  • Second attempt:

    The config below works (it gets past the TLS negotiation, I haven't tested further) for me. The second VS has 'vlans-enabled' (and no vlans defined), which means it won't listen on any vlans. You can't telnet to it, so the only way to access it is via the virtual command.

    The only difference I can spot between this config and yours is the "internal" keyword in your second virtual, which you've now removed. Maybe if you look at it, you'll spot something I've missed.

    ltm virtual VS-PRE-FTPS_1 {
        destination 192.168.0.120:ftp
        ip-protocol tcp
        mask 255.255.255.255
        persist {
            source_addr_FTPS {
                default yes
            }
        }
        profiles {
            clientssl {
                context clientside
            }
            ftp { }
            tcp { }
        }
        rules {
            irule_FTPS_1
        }
        source 0.0.0.0/0
        source-address-translation {
            type automap
        }
    }
    ltm virtual VS-PRE-FTPS_2 {
        destination 0.0.0.0:any
        ip-protocol tcp
        mask any
        persist {
            source_addr_FTPS {
                default yes
            }
        }
        pool pool-preweb-ftp
        profiles {
            tcp { }
        }
        rules {
            irule_FTPS_2
        }
        source 0.0.0.0/0
        source-address-translation {
            type automap
        }
        translate-address disabled
        translate-port disabled
        vlans-enabled
    }
    
    ltm rule irule_FTPS_1 {
        when CLIENT_ACCEPTED {
            log local0. "client accepted"
            SSL::disable
            TCP::respond "220 My ftp server\r\n"
            TCP::collect
        }
        when CLIENT_DATA {
            log local0. "client data"
            TCP::respond "234 AUTH TLS Successful\r\n"
            TCP::payload replace 0 [TCP::payload length] ""
            log local0. "virtual VS-PRE-FTPS_2"
            virtual VS-PRE-FTPS_2
            SSL::enable
            TCP::release
            log local0. "TCP Release Completed"
        }
    
    }
    
    
    And testing:
    
    root@ubuntu-1204-11:~ curl -vk --ftp-ssl ftp://192.168.0.120
    * About to connect() to 192.168.0.120 port 21 (0)
    *   Trying 192.168.0.120... connected
    < 220 My ftp server
    > AUTH SSL
    < 234 AUTH TLS Successful
    * successfully set certificate verify locations:
    *   CAfile: none
      CApath: /etc/ssl/certs
    * SSLv3, TLS handshake, Client hello (1):
    * SSLv3, TLS handshake, Server hello (2):
    * SSLv3, TLS handshake, CERT (11):
    * SSLv3, TLS handshake, Server key exchange (12):
    * SSLv3, TLS handshake, Server finished (14):
    * SSLv3, TLS handshake, Client key exchange (16):
    * SSLv3, TLS change cipher, Client hello (1):
    * SSLv3, TLS handshake, Finished (20):
    * SSLv3, TLS change cipher, Client hello (1):
    * SSLv3, TLS handshake, Finished (20):
    * SSL connection using DHE-RSA-AES256-SHA
    * Server certificate:
    *        subject: C=US; ST=WA; L=Seattle; O=MyCompany; OU=IT; CN=localhost.localdomain; emailAddress=root@localhost.localdomain
    *        start date: 2016-04-02 11:15:35 GMT
    *        expire date: 2026-03-31 11:15:35 GMT
    *        issuer: C=US; ST=WA; L=Seattle; O=MyCompany; OU=IT; CN=localhost.localdomain; emailAddress=root@localhost.localdomain
    *        SSL certificate verify result: self signed certificate (18), continuing anyway.
    > USER anonymous
    
    
    And the ltm log:
    

    /var/log/ltm:

    May 24 02:37:10 ltm-1200-211 info tmm1[8886]: Rule /Common/irule_FTPS_1 : client accepted
    May 24 02:37:10 ltm-1200-211 info tmm1[8886]: Rule /Common/irule_FTPS_1 : client data
    May 24 02:37:10 ltm-1200-211 info tmm1[8886]: Rule /Common/irule_FTPS_1 : virtual VS-PRE-FTPS_2
    May 24 02:37:10 ltm-1200-211 info tmm1[8886]: Rule /Common/irule_FTPS_1 : TCP Release Completed
    May 24 02:37:10 ltm-1200-211 info tmm1[8886]: Rule /Common/irule_FTPS_2 : client accepted
    
  • After changing my config to a Standard virtual server for the second one, and even modifying my wildcard from digicert to the default self-signed certificate like you, given that it could seem like a certificate error, now the config is almost the same than yours:

    ltm virtual VS-PRE-FTPS_1 {
        destination 10.10.0.235:ftp
        ip-protocol tcp
        mask 255.255.255.255
        persist {
            source_addr_FTPS {
                default yes
            }
        }
        profiles {
            clientssl {
                context clientside
            }
            ftp { }
            tcp { }
        }
        rules {
            irule_FTPS_1
        }
        source 0.0.0.0/0
        source-address-translation {
            type automap
        }
        vs-index 44
    }
    ltm virtual VS-PRE-FTPS_2 {
        destination any:any
        ip-protocol tcp
        mask 255.255.255.255
        persist {
            source_addr_FTPS {
                default yes
            }
        }
        pool pool-preweb-ftp2
        profiles {
            tcp { }
        }
        rules {
            irule_FTPS_2
        }
        source 0.0.0.0/0
        source-address-translation {
            type automap
        }
        translate-address disabled
        translate-port disabled
        vlans-enabled
        vs-index 43
    }
    

    But I still have the same error. If run the same curl command that you ran i get the following:

    curl -vk --ftp-ssl ftp://10.10.0.235
    * About to connect() to 10.10.0.235 port 21
    *   Trying 10.10.0.235... connected
    * Connected to 10.10.0.235 (10.10.0.235) port 21
    < 220 My ftp server
    > AUTH SSL
    < 234 AUTH TLS Successful
    * successfully set certificate verify locations:
    *   CAfile: /etc/pki/tls/certs/ca-bundle.crt
      CApath: none
    * SSLv2, Client hello (1):
    SSLv3, TLS handshake, Server hello (2):
    SSLv3, TLS handshake, CERT (11):
    SSLv3, TLS handshake, Server finished (14):
    SSLv3, TLS handshake, Client key exchange (16):
    SSLv3, TLS change cipher, Client hello (1):
    SSLv3, TLS handshake, Finished (20):
    SSLv3, TLS change cipher, Client hello (1):
    SSLv3, TLS handshake, Finished (20):
    SSL connection using AES256-SHA
    * Server certificate:
    *        subject: /C=US/ST=WA/L=Seattle/O=MyCompany/OU=IT/CN=localhost.localdomain/emailAddress=root@localhost.localdomain
    *        start date: 2010-10-15 17:07:28 GMT
    *        expire date: 2020-10-12 17:07:28 GMT
    *        common name: localhost.localdomain (does not match '10.10.0.235')
    *        issuer: /C=US/ST=WA/L=Seattle/O=MyCompany/OU=IT/CN=localhost.localdomain/emailAddress=root@localhost.localdomain
    * SSL certificate verify result: self signed certificate (18), continuing anyway.
    * SSL_write() returned SYSCALL, errno = 104
    
    * Closing connection 0
    curl: (55) SSL_write() returned SYSCALL, errno = 104
    

    And the log indicates that the second iRule is still not being run:

     tail -f /var/log/ltm
    May 26 11:05:04 Balanceador1 info tmm1[9724]: Rule /Common/irule_FTPS_1 : client accepted
    May 26 11:05:04 Balanceador1 info tmm1[9724]: Rule /Common/irule_FTPS_1 : client data
    May 26 11:05:04 Balanceador1 info tmm1[9724]: Rule /Common/irule_FTPS_1 : virtual VS-PRE-FTPS_2
    May 26 11:05:04 Balanceador1 info tmm1[9724]: Rule /Common/irule_FTPS_1 : TCP Release Completed
    

    I am confused about if the SSL handshake error is because of the fail calling second VS from the first one, or conversely is the SSL handshake error what is causing the second iRule never be reached

    • IanB's avatar
      IanB
      Icon for Employee rankEmployee
      The line "SSL_write() returned SYSCALL, errno = 104" indicates that curl was sent a TCP reset (errno 104), so you should be seeing a corresponding reset in the ltm log, as long as reset cause logging is enabled.