Showing results for 
Search instead for 
Did you mean: 

Managing FTP traffic with Stingray

An interesting use case cropped up recently - one of our users wanted to do some smarts with the login credentials of an FTP session.


This article steps through a few sample FTP rules and explains how to manage this sort of traffic.


Before you begin


  • Make sure you have a suitable FTP client.  The command-line ftp tool shipped with most Unix-like systems supports a -d flag that reports the underlying FTP messages, so it's great for this exercise.


  • Pick a target FTP server.  I tested against and, but other ftp servers may differ for subtle reasons.


  • Review the FTP protocol specification - it's sufficient to know that it's a single TCP control channel, requests are of the form 'VERB[ parameter]\r\n" and responses are of the form 'CODE message\n'.  Multi-line responses are accepted; all but the last line of the reponse include an additional hyphen ('CODE-message\n').


Create your FTP virtual server


Use the 'Add a new service' wizard to create your FTP virtual server.  Just for fun, add a server banner (Virtual Server > Connection Management > FTP-Specific Settings):


Screen Shot 2013-05-16 at 15.05.05.png


Verify that you can log in to your FTP server through Stingray, and that the banner is rewritten:

Screen Shot 2013-05-16 at 15.08.22.png

Now we're good to go!


Intercepting login credentials


We want to intercept FTP login attempts, and change all logins to 'anonymous'.  If a user logs in with 'usernameSmiley Tongueassword', we're going to convert that to 'anonymous:username' and discard the password.


Create the following Request Rule, and assign it to the FTP virtual server: "Recieved connection: state is '" . "state" ) . "'" ); 

if( "state" ) == "" ) {
   # This is server-first, so we have no data on the first connect "state", "connected" );

if( "state" ) == "connected" ) {
   # Get the request line
   $req = string.trim( request.endswith( "\n" ) ); " ... got request '" . $req . "'" );
   if( string.regexmatch( $req, "USER (.*)" ) ) { "user", $1 );  

      # Translate this to an anonymous login " ... rewriting request to 'USER anonymous'" );
      request.set( "USER anonymous\r\n" );

   if( string.regexmatch( $req, "PASS (.*)" ) ) { 
      $pass = $1; "pass", $pass );
      $user = "user" );

      # Set the appropriate password " ... rewriting request to 'PASS ".$user."'" ); 
      request.set( "PASS ".$user."\r\n" );


Now, if you log in with your email address (for example) and a password, the rule will switch your login to an anonymous one and will log the result:



Authenticating the user's credentials


You can extend this rule to authenticate the credentials that the user provided.  At the point in the rule where you have the username and password, you can call a Stingray authenticator, a Java Extension, or reference a libTable.rts: Interrogating tables of data in TrafficScript in your TrafficScript rule:


#AD authentication

   $ldap = auth.query( "AD Auth", $user, $pass );

   if( $ldap['Error'] ) {
      log.error( "Error with authenticator 'AD Auth': " . $auth['Error'] );

   else if( !$ldap['OK'] ) {"User not authenticated.  Username and/or password incorrect");


Version history
Revision #:
1 of 1
Last update:
‎05-16-2013 07:39:AM
Updated by:
Labels (1)