cancel
Showing results for 
Search instead for 
Did you mean: 

Pulse Secure vADC

Sort by:
Web spiders are clever critters - they are automated programs designed to crawl over web pages, retrieving information from the whole of a site. (For example, Spiders power search engines and shopping comparison sites). But what do you do if your website is being overrun by the bugs? How can you prevent your service from being slowed down by a badly written, over-eager web spider?   Web spiders, (sometimes called robots, or bots), are meant to adhere to the Robot exclusion standard. By putting a file called robots.txt at the top of your site, you can restrict the pages that a web spider should load. However, not all spiders bother to check this file. Even worse, the standard gives no control over how often a spider may fetch pages. A poorly written spider could hammer your site with requests, trying to discover the price of everything that you are selling every minute of the day. The problem is, how do you stop these spiders while allowing your normal visitors to use the site without restrictions?   As you might expect, Stingray has the answer! The key feature to use is the 'Request Rate Shaping' classes. These will prevent any one user from fetching too many pages from your site.   Let's see how to put them to use:   Create a Rate Shaping Class   You can create a new class from the Catalogs page. You need to pick at least one rate limit: the maximum allowed requests per minute, or per second. For our example, we'll create a class called 'limit' that allows up to 100 requests a minute.   Put the rate shaping class into use - first attempt   Now, create a TrafficScript rule to use this class. Don't forget to add this new rule to the Virtual Server that runs your web site.   rate.use( "limit" );   This rule is run for each HTTP request to your site. It applies the rate shaping class to each of them.   However, this isn't good enough. We have just limited the entire range of visitors to the site to 100 requests a minute, in total. If we leave the settings as is, this would have a terrible effect on the site. We need to apply the rate shaping limits to each individual user.   Rate shaping - second attempt   Edit the TrafficScript rule and use this code instead:   rate.use( "limit", connection.getRemoteIP() );   We have provided a second parameter to the rate.use() function. The rule is taking the client IP address and using this to identify a user. It then applies the rate shaping class separately to each unique IP address. So, a user coming from IP address 1.2.3.4 can make up to 100 requests a minute, and a user from 5.6.7.8 could also make 100 requests at the same time.   Now, if a web spider browses your site, it will be rate limited.   Improvements   We can make this rate shaping work even better. One slight problem with the above code is that sometimes you may have multiple users arriving at your site from one IP address. For example, a company may have a single web proxy. Everyone in that company will appear to come from the same IP address. We don't want to collectively slow them down.   To work around this, we can use cookies to identify individual users. Let's assume your site already sets a cookie called 'USERID'. The value is unique for each visitor. We can use this in the rate shaping:   # Try reading the cookie $userid = http.getCookie( "USERID" ); if( $userid == "" ) { $userid = connection.getRemoteIP(); } rate.use( "limit", $userid );   This TrafficScript rule tries to use the cookie to identify a user. If it isn't present, it falls back to using the client IP address.   Even more improvements   There are many other possibilities for further improvements. We could detect web spiders by their User-Agent names, or perhaps we could only rate shape users who aren't accepting cookies. But we have already achieved our goal - now we have a means to limit the page requests by automated programs, while allowing ordinary users to fully use the site.   This article was originally written by Ben Mansell in December 2006.
View full article
Update: 2013 06018 - I had to do 50 conversions today, so I have attached a shell script to to automate this process. == Assumptions: You have a pkcs12 bundle with a private key and certificate in it - in this example we will use a file called www.website.com.p12.  I use SimpleAuthority as it is cross platform and the free edition lets you create up to 5 keypairs, which is plenty for the lab... You don't have a password on the private key (passwords on machine loaded keys are a waste of time IMHO) You have a Linux / MacOS X / Unix system with openssl installed (Mac OS X does by default, so do most Linux installs...) 3 commands you need: First we take the p12 and export just the private key (-nocerts) and export it in RSA format with no encryption (-nodes) openssl pkcs12 -in www.website.com.p12 -nocerts -out www.website.com.key.pem -nodes Second we take the p12 and export just the certificate (-nokeys) and export it in RSA format with no encryption (-nodes) openssl pkcs12 -in www.website.com.p12 -nokeys -out www.website.com.cert.pem -nodes Third, we convert the private key into the format Stingray wants it in (-text) openssl rsa -in www.website.com.key.pem -out www.website.com.key.txt.pem -text You are left with a list of files, only two of them are needed to import into the Stingray: www.website.com.key.txt.pem is the private key you need www.website.com.cert.pem is the certificate you need These can then be imported into the STM under Catalogues > SSL > Server Certs Hope this helps.. 1 ~ $ ./p12_convert.sh -h ./p12_convert.sh written by Aidan Clarke <aidan.clarke at riverbed.com> Copyright Riverbed Technologies 2013 usage: ./p12_convert.sh -i inputfile -o outputfile This script converts a p12 bundle to PEM formated key and certificate ready for import into Stingray Traffif Manager OPTIONS:    -h      Show this message    -i      Input file name    -o      Output file name stub
View full article
Loggly is a cloud-based log management service.  The idea with Loggly is that you direct all your applications, hardware, software, etc. to send their logs to Loggly.  Once all the logs are in the Loggly cloud you can : Root cause and solve problems by performing powerful and flexible searches across all your devices and applications Set up alerts on log events Measure application performance Create custom graphs and analytics to better understand user behavior and experience   Having your Virtual Traffic Manager (vTM) logs alongside your application logs will provide valuable information to help further analyze and debug your applications.  You can export both the vTM event log as well as the request logs for each individual Virtual Server to Loggly.   vTM Event Log The vTM event log contains both error logs and informational messages.  To export the vTM Event Log to Loggly we will first create an Input into Loggly.  In the Loggly web interface navigate to Incoming Data -> Inputs and click on "+ Add Input".  The key field is the Service Type which must be set to Syslog UDP. After creating the input you'll be given a destination to send the logs to.  The next step is to tell the vTM to send logs to this destination. In the vTM web interface navigate to System > Alerting and select Syslog under the drop down menu for All Events. Click Update to save the changes. The final step is to click on Syslog and update the sysloghost to the Loggly destination. Virtual Server Request Logs Connections to a virtual server can be recorded in request logs. These logs can help track the usage of the virtual server, and can record many different pieces of information about each connection.  To export virtual server request logs to Loggly first navigate to Services > Virtual Servers > (your virtual server) > Request Logging. First set log!enabled to Yes, its not on by default. Scroll down and set syslog!enabled to Yes and set the syslog!endpoint to the same destination as with the vTM Event Logs.  Click Update to save the changes. Alternatively you can create a new input in Loggly for request logs if you don't want them to get mixed up with the Event Logs.   Making sure it works An easy way to make sure it works is to modify the configuration by creating and deleting a virtual for example.  This will generate an event in the vTM Event Log.  In Loggly you should see the light turn green for this input. The Virtual Traffic Manager is designed to be flexible, being the only software application delivery controller that can be seamlessly deployed in private, public, and hybrid clouds.  And now by exporting your vTM logs you can take full advantage of the powerful analysis tools available within Loggly.
View full article
This article describes how to inspect and load-balance WebSockets traffic using Stingray Traffic Manager, and when necessary, how to manage WebSockets and HTTP traffic that is received on the same IP address and port.   Overview   WebSockets is an emerging protocol that is used by many web developers to provide responsive and interactive applications.  It's commonly used for talk and email applications, real-time games, and stock market and other monitoring applications.   By design, WebSockets is intended to resemble HTTP.  It is transported over tcp/80, and the initial handshake resembles an HTTP transaction, but the underlying protocol is a simple bidirectional TCP connection.   For more information on the protocol, refer to the Wikipedia summary and RFC 6455.     Basic WebSockets load balancing   Basic WebSockets Load Balancing   Basic WebSockets load balancing is straightforward.  You must use the 'Generic Streaming' protocol type to ensure that Stingray will correctly handle the asynchronous nature of websockets traffic.   Inspecting and modifying the WebSocket handshake   A WebSocket handshake message resembles an HTTP request, but you cannot use the built-in http.* TrafficScript functions to manage it because these are only available in HTTP-type virtual servers.   The libWebSockets.rts library (see below) implements analogous functions that you can use instead:   libWebSockets.rts   Paste the libWebSockets.txt library to your Rules catalog and reference it from your TrafficScript rule as follows:   import libWebSockets.rts as ws;   You can then use the ws.* functions to inspect and modify WebSockets handshakes.  Common operations include fixing up host headers and URLs in the request, and selecting the target servers (the 'pool') based on the attributes of the request.   import libWebSockets.rts as ws; if( ws.getHeader( "Host" ) == "echo.example.com" ) { ws.setHeader( "Host", "www.example.com" ); ws.setPath( "/echo" ); pool.use( "WebSockets servers" ); }   Ensure that the rules associated with WebSockets virtual server are configured to run at the Request stage, and to run 'Once', not 'Every'.  The rule should just be triggered to read and process the initial client handshake, and does not need to run against subsequent messages in the websocket connection:   Code to handle the WebSocket handshake should be configured as a Request Rule, with 'Run Once'   SSL-encrypted WebSockets   Stingray can SSL-decrypt TCP connections, and this operates fully with the SSL-encrypted wss:// protocol: Configure your virtual server to listen on port 443 (or another port if necessary) Enable SSL decryption on the virtual server, using a suitable certificate Note that when testing this capability, we found that Chrome refused to connect to WebSocket services with untrusted or invalid certificates, and did not issue a warning or prompt to trust the certificate.  Other web browsers may operate similarly.  In Chrome's case, it was necessary to access the virtual server directly ( https:// ), save the certificate and then import it into the certificate store.   Stingray can also SSL-encrypt downstream TCP connections (enable SSL encryption in the pool containing the real websocket servers) and this operates fully with SSL-enabled origin WebSockets servers.   Handling HTTP and WebSockets traffic   HTTP traffic should be handled by an HTTP-type virtual server rather than a Generic Streaming one.  HTTP virtual servers can employ HTTP optimizations (keepalive handling, HTTP upgrades, Compression, Caching, HTTP Session Persistence) and can access the http.* TrafficScript functions in their rules.   If possible, you should run two public-facing virtual servers, listening on two separate IP addresses.  For example, HTTP traffic should be directed to www.site.com (which resolves to the public IP for the HTTP virtual server) and WebSockets traffic should be directed to ws.site.com (resolving to the other public IP): Configure two virtual servers, each listening on the appropriate IP address   Sometimes, this is not possible – the WebSockets code is hardwired to the main www domain, or it's not possible to obtain a second public IP address. In that case, all traffic can be directed to the WebSockets virtual server and then HTTP traffic can be demultiplexed and forwarded internally to an HTTP virtual server:   Listen on a single IP address, and split off the HTTP traffic to a second HTTP virtual server   The following TrafficScript code, attached to the 'WS Virtual Server', will detect if the request is an HTTP request (rather than a WebSockets one) and hand the request off internally to an HTTP virtual server by way of a special 'Loopback Pool':   import libWebSockets.rts as ws; if( !ws.isWS() ) pool.use( "Loopback Pool" );   Notes: Testing WebSockets   The implementation described in this article was developed using the following browser-based client, load-balancing traffic to public 'echo' servers (ws://echo.websocket.org/, wss://echo.websocket.org, ws://ajf.me:8080/).   testclient.html   At the time of testing: echo.websocket.org did not respond to ping tests, so the default ping health monitor needed to be removed Chrome24 refused to connect to SSL-enabled wss resources unless they had a trusted certificate, and did not warn otherwise If you find this solution useful, please let us know in the comments below.
View full article
The libLDAP.rts library and supporting library files (written by Mark Boddington) allow you to interrogate and modify LDAP traffic from a TrafficScript rule, and to respond directly to an LDAP request when desired.   You can use the library to meet a range of use cases, as described in the document Managing LDAP traffic with libLDAP.rts.   Note: This library allows you to inspect and modify LDAP traffic as it is balanced by Stingray.  If you want to issue LDAP requests from Stingray, check out the auth.query() TrafficScript function for this purpose, or the equivalent Authenticating users with Active Directory and Stingray Java Extensions Java Extension.   Overview   A long, long time ago on a Traffic Manager far, far away, I (Mark Boddington) wrote some libraries for processing LDAP traffic in TrafficScript:   libBER.rts – This is a TrafficScript library which implements all of the required Basic Encoding Rules (BER) functionality for LDAP. It does not completely implement BER though, LDAP doesn't use all of the available types, and this library hasn't implemented those not required by LDAP. libLDAP.rts – This is a TrafficScript library of functions which can be used to inspect and manipulate LDAP requests and responses. It requires libBER.rts to encode the LDAP packets. libLDAPauth.rts – This is a small library which uses libLdap to provide simple LDAP authentication to other services.   That library (version 1.0) mostly focused on inspecting LDAP requests. It was not particularly well suited to processing LDAP responses. Now, thanks to a Stingray PoC being run in partnership with the guys over at Clever Consulting, I've had cause to revist this library and improve upon the original. I'm pleased to announce libLDAP.rts version 1.1 has arrived.     What's new in libLdap Version 1.1?   Lazy Decoding. The library now only decodes the envelope  when getPacket() or getNextPacket() is called. This gets you the MessageID and the Operation. If you want to process further, the other functions handle decoding additional data as needed. New support for processing streams of LDAP Responses. Unlike Requests LDAP Responses are typically made up of multiple LDAP messages. The library can now be used to process multiple packets in a response. New SearchResult processing functions: getSearchResultDetails(), getSearchResultAttributes() and updateSearchResultDetails()   Lazy Decoding   Now that the decoding is lazier it means you can almost entirely bypass decoding for packets which you have no interest in. So if you only want to check BindRequests and/or BindResponses then those are the only packets you need to fully decode. The rest are sent through un-inspected (well except for the envelope).   Support for LDAP Response streams   We now have several functions to allow you to process responses which are made up of multiple LDAP messages, such  as those for Search Requests. You can use a loop with the "getNextPacket($packet["lastByte"])" function to process each LDAP message as it is returned from the LDAP server. The LDAP packet hash  now has a "lastByte" entry to help you keep track of the messages in the stream. There is also a new skipPacket() function to allow you to skip the encoder for packets which ou aren't modifying.   Search Result Processing   With the ability to process response streams I have added a  number of functions specifically for processing SearchResults. The getSearchDetails() function will return a SearchResult hash which contains the ObjectName decoded. If you are then interested in the object you can  call getSearchResultAttributes() to decode the Attributes which have been returned. If you make any changes to the Search Result you can then call updateSearchResultDetails() to update the packet, and then encodePacket() to re-encode it. Of course if at any point you determine that no changes are needed then you can call skipPacket() instead.   Example - Search Result Processing   import libDLAP.rts as ldap; $packet = ldap.getNextPacket(0); while ( $packet ) { # Get the Operation $op = ldap.getOp($packet); # Are we a Search Request Entry? if ( $op == "SearchRequestEntry" ) { $searchResult = ldap.getSearchResultDetails($packet); # Is the LDAPDN within example.com? if ( string.endsWith($searchResult["objectName"], "dc=example,dc=com") ) { # We have a search result in the tree we're interested in. Get the Attributes ldap.getSearchResultAttributes($searchResult); # Process all User Objects if ( array.contains($searchResult["attributes"]["objectClass"], "inetOrgPerson") ) { # Log the DN and all of the attributes log.info("DN: " . $searchResult["objectName"] ); foreach ( $att in hash.keys($searchResult["attributes"]) ) { log.info($att . " = " . lang.dump($searchResult["attributes"][$att]) ); } # Add the users favourite colour $searchResult["attributes"]["Favourite_Colour"] = [ "Riverbed Orange" ]; # If the password attribute is included.... remove it hash.delete($searchResult["attributes"], "userPassword"); # Update the search result ldap.updateSearchResultDetails($packet, $searchResult); # Commit the changes $stream .= ldap.encodePacket( $packet ); $packet = ldap.getNextPacket($packet["lastByte"]); continue; } } } # Not an interesting packet. Skip and move on. $stream .= ldap.skipPacket( $packet ); $packet = ldap.getNextPacket($packet["lastByte"]); } response.set($stream); response.flush();   This example reads each packet in turn by calling getNextPacket() and passing the lastByte attribute from the previously processed packet as the argument. We're looking for SearchResultEntry operations, If we find one we pass the packet to getSearchResultDetails() to decode the object which the search was for in order to determine the DN. If it's in example.com then we decide to process further and decode the attributes with getSearchResultAttributes(). If the object has an objectClass of inetOrgPerson we then print the attributes to the event log, remove the userPassword if it exists and set a favourite colour for the user. Finally we encode the packet and move on to the next one. Packets which we aren't interested in modifying are skipped.   Of course, rather than do all this checking in the response, we could have checked the SearchRequest in a request rule and then used connection.data.set() to flag the message ID for further processing.   We should also have a request rule which ensures that the objectClass is in the list of attributes requested by the end-user. But I'll leave that as an exercise for the reader ;-)   If you want more examples of how this library can be used, then please check out the additional use cases here: Managing LDAP traffic with libLDAP.rts
View full article
This Document provides step by step instructions on how to set up Brocade Virtual Traffic Manager for Microsoft Lync 2010.
View full article
This Document provides step by step instructions on how to set up Brocade Virtual Traffic Manager for Oracle WebLogic Applications. Sample applications that can be deployed using this document include Oracle's PeopleSoft and Blackboard's Academic Suite.   This document has been updated from the original deployment guides written for Riverbed Stingray and SteelApp software.
View full article
Following up on this earlier article try using the below TrafficScript code snippet to automatically insert the Google Analytics code on all your webpages.  To use it: Copy the rule onto your Stingray Traffic Manager  by first navigating Catalogs -> Rules Scroll down to Create new rule, give the rule a name, and select Use TrafficScript Language.  Click Create Rule to create the rule. Copy and paste the rule below. Change $account to your Google Analytics account number. If you are using multiple domains as described here set $multiple_domains to TRUE and set $tld to your Top Level Domain as specified in your Google Analytics account. Set the rule as a Response Rule in your Virtual Server by navigating to Services -> Virtual Servers -> <your virtual server> -> Rules -> Response Rules and Add rule. After that you should be good to go.  No need to individually modify your web pages, TrafficScript will take care of it all. # # Replace UA-XXXXXXXX-X with your Google Analytics Account Number # $account = 'UA-XXXXXXXX-X'; # # If you are tracking multiple domains, ie yourdomain.com, # yourdomain.net, etc. then set $mutliple_domains to TRUE and # replace yourdomain.com with your Top Level Domain as specified # in your Google Analytics account # $multiple_domains = FALSE; $tld = 'yourdomain.com'; # # Only modify text/html pages # if( !string.startsWith( http.getResponseHeader( "Content-Type" ), "text/html" )) break; # # This variable contains the code to be inserted in the web page. Do not modify. # $html = "\n<script type=\"text/javascript\"> \n \   var _gaq = _gaq || []; \n \   _gaq.push(['_setAccount', " . $account . "]); \n"; if( $multiple_domains == TRUE ) {   $html .= " _gaq.push(['_setDomainName', " . $tld . "]); \n \   _gaq.push(['_setAllowLinker', true]); \n"; } $html .= " _gaq.push(['_trackPageview']); \n \   (function() { \n \   var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true; \n \   ga.src=('https:' == document.location.protocol ? ' https://ssl ' : ' http://www ') + '.google-analytics.com/ga.js'; \n \   var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s); \n \   })(); \n \ </script>\n"; # # Insert the code right before the </head> tag in the page # $body = http.getResponseBody(); $body = string.replace( $body, "</head>", $html . "</head>"); http.setResponseBody( $body );
View full article
A great usage of TrafficScipt is for managing and inserting widgets on to your site.  The attached TrafficScript code snippet inserts a Twitter Profile Widget to your site, as described here (sign in required).   To use it.   In the Stingray web interface navigate to Catalogs -> Rules and s croll down to Create new rule .  Give it a name such as Twitter Feed and select Use TrafficScript Language.  Click Create Rule to create the rule. Copy and paste the code and save the rule. Modify the $user and $tag as described in the TrafficScript code snippet.  $user is your Twitter username and $tag specifies where in the web page the feed should go. Navigate to the Rules page of your Virtual Server ( Services -> Virtual Servers -> <your virtual server> -> Rules) and add Twitter Feed as a Response Rule   Reload your webpage and you should see the Twitter feed.   # # This TrafficScript code snippet will insert a Twitter Profile widget # for user $user as described here: # https://twitter.com/about/resources/widgets/widget_profile # The widget will be added directly after $tag. The resultant page will # look like: # ... # <tag> # <Twitter feed> # ... # # Replace 'riverbed' with your Twitter username $user = "riverbed"; # # You can keep the tag as <!--TWITTER FEED--> and insert that tag into # your web page or change $tag to some existing text in your web page, ie # $tag = "Our Twitter Feed:" $tag = "<!--TWITTER FEED-->"; # Only modify text/html pages if( !string.startsWith( http.getResponseHeader( "Content-Type" ), "text/html" )) break; # # The actual code that will be inserted. Various values such as color, # height, width, etc. can be changed here. # $html = "\n\ <script charset=\"utf-8\" src=\"http://widgets.twimg.com/j/2/widget.js\"></script> \n \ <script> \n \ new TWTR.Widget({ \n \ version: 2, \n \ type: 'profile', \n \ rpp: 4, \n \ interval: 30000, \n \ width: 250, \n \ height: 300, \n \ theme: { \n \ shell: { \n \ background: '#333333', \n \ color: '#ffffff' \n \ }, \n \ tweets: { \n \ background: '#000000', \n \ color: '#ffffff', \n \ links: '#eb8507' \n \ } \n \ }, \n \ features: { \n \ scrollbar: false, \n \ loop: false, \n \ live: false, \n \ behavior: 'all' \n \ } \n \ }).render().setUser('".$user."').start(); \n \ </script><br>\n"; # This section inserts $html into the HTTP response after $tag $body = http.getResponseBody(); $body = string.replace( $body, $tag, $tag. $html); http.setResponseBody( $body );   Give it a try and let us know how you get on!   More Twitter solutions:   Traffic Managers can Tweet Too TrafficScript can Tweet Too
View full article
If you're running Apache HTTPD, you might have seen the recent advisory (and update) which can cause "significant CPU and memory usage" by abusing the HTTP/1.1 Range header.   If you're using Stingray Application Firewall simply update your baseline rules and you will be immediately protected. Otherwise, you can use TrafficScript to block this attack:   # Updated: Remove (if present) an old name that Apache accepts, MSIE 3 vintage http.removeHeader( "Request-Range" ); $r = http.getHeader( "Range" ); if( $r && string.count( $r, "," ) >= 5 ) { # Too many ranges, refuse the request http.sendResponse( "403 Forbidden", "text/plain", "Forbidden\n", "" ); }   This simply returns a 403 Forbidden response for any request asking for more than 5 ranges (at least 5 commas in the Range header). This is in line with the advisory's suggested mitigation: we don't block multiple ranges completely because they have legitimate uses, such as PDF readers that request parts of the document as you scroll through it, and the attack requires many more ranges to be effective.
View full article