Over a million developers have joined DZone.

Migrating F5 iRules and Citrix Policies to NGINX Plus

Need to move from an F5 system to NGINX Plus? Check out this post on how to go about performing this migration.

· Performance Zone

Discover 50 of the latest mobile performance statistics with the Ultimate Guide to Digital Experience Monitoring, brought to you in partnership with Catchpoint.

Administrators of traditional hardware application delivery controllers (ADCs) are often faced with use cases that the rule sets provided by ADC vendors don’t cover, and certainly not at the necessary fine‑grained level of control over how requests and responses are processed. As a result, most organizations have written their own custom rules, and as they move to software‑based load balancers, whether on-premises or in the cloud, they need an easy way to migrate that ADC logic along with their applications. NGINX and NGINX Plus offer a powerful configuration language that covers many of these use cases.

This blog post explains how to convert several common types of policies or scripts from popular hardware ADCs to NGINX configuration blocks. We here at NGINX, Inc. have found that many times the apparent difficulty of converting policies is just due to differences in terminology or implementation and we’d like to bridge that gap.

Note: Some scripts and policies are indeed too complex to implement easily with the NGINX configuration language, but there are dynamic modules for NGINX and NGINX Plus that enable scripting in Lua, Perl, and JavaScript (with the nginScript module in NGINX Plus R10 and later). For more information and use instructions, see Dynamic Modules with NGINX Plus.

The information in this post applies to both NGINX and NGINX Plus, but for brevity, we’ll refer to NGINX Plus only in the post.

Migrating Logic for Request Routing

Request routing, also known as content‑based routing or content switching, is a way to host many different applications at the same fully qualified domain name (FQDN) but give the end user the impression of a single unified application. The ADC or NGINX Plus sends each request to the appropriate upstream application based on a header or the URI.

NGINX Plus implements request routing with the location directive, using either a URI prefix or regular expressions to match against requests. For more detail, see Configuring Locations in the NGINX Plus Admin Guide.

Example 1 – Request Routing Based on URI

In this example, request routing is based on the URI. Specifically, if the URI starts with /music, the request is routed to the music_backend upstream group. All other URIs are sent to the configured default upstream group.

F5 iRule

when HTTP_REQUEST {

    switch -glob [string tolower [HTTP::uri]] {

        "/music*"  {pool music_backend}

        default {pool default_backend}

    }

}

NetScaler Policy

#> add cs vserver csapp HTTP 192.168.10.120 80 -cltTimeout 180

#> add cs policy cs_music -rule "HTTP.REQ.URL.STARTSWITH(\"/music\")"

#> bind cs vserver csapp -policyName cs_music -targetLBVserver music_backend -priority 100

#> bind cs vserver csapp -lbvserver default_backend

NGINX Plus Configuration

location /music {

    proxy_pass http://music_backend;

}

location / {

    proxy_pass http://default_backend;

}

Example 2 – Request Routing Based on the User‑Agent Header

The following examples perform request routing based on the User‑Agent header in the client request, directing requests from iOS and Android devices to separate backend application servers and traffic from all other devices to a configured application server. In the NGINX Plus map block, the $http_user_agent variable is compared to the specified regular expressions, and the $upstream_choice variable is set to the upstream group associated with the matching expression. Then the $upstream_choice variable determines which upstream group is chosen by the proxy_pass directive.

F5 iRule

when HTTP_REQUEST {

    switch -glob [HTTP::header User-Agent] {

        "*iPhone*"  -

        "*iPad*"  -

        "*iPod*"  {pool iosapp}

        "*Android*"  {pool androidapp}

        default {pool musicapp}

    }

}

NetScaler Policy

#> add cs vserver csapp HTTP 192.168.10.120 80 -cltTimeout 180

#> add cs policy ios_agent -rule "HTTP.REQ.HEADER(\"User-Agent\").CONTAINS(\"iPhone\")

 || HTTP.REQ.HEADER(\"User-Agent\").CONTAINS(\"iPad\") || HTTP.REQ.HEADER(\"User-Agent\").CONTAINS(\"iPad\")"

#> add cs policy android_agent -rule "HTTP.REQ.HEADER(\"User-Agent\").CONTAINS(\"Android\")"

#> bind cs vserver csapp -policyName ios_agent -targetLBVserver ios_backend -priority 100

#> bind cs vserver csapp -policyName android_agent -targetLBVserver android_backend -priority 110

#> bind cs vserver csapp -lbvserver vs_default

NGINX Plus Configuration

map $http_user_agent $upstream_choice {

  ~(iPhone|iPad|iPod) ios_backend;

  ~Android android_backend;

  default default_backend;

}
server {
 listen 80;
 location / {
 proxy_pass http://$upstream_choice;
 }
 }

Migrating Logic for Request Redirect

It is often necessary to redirect client requests, for example redirecting a client who sends a plain HTTP request to a connection secured with HTTPS. Other example use cases are shortened URLs or changes in the application URL structure.

To redirect requests with NGINX Plus, use the return directive. It takes two parameters: the response code (for example, 301 or 302) and the redirect URL. For further discussion and more examples, see Returning Specific Status Codes and Creating NGINX Rewrite Rules.

Example – Request Redirect to HTTPS

The following examples redirect the client from HTTP to HTTPS to ensure the session is encrypted.

F5 iRule

when HTTP_REQUEST {

   HTTP::redirect "https://[getfield [HTTP::host] ":" 1][HTTP::uri]"

}

NetScaler Policy

#> add responder action ssl_redirect_act redirect "\"https://\" + HTTP.REQ.HEADER(\"Host\").HTTP_HEADER_SAFE + HTTP.REQ.URL.PATH_AND_QUERY.HTTP_URL_SAFE" -responseStatusCode 301

#> add responder policy sslredirect TRUE ssl_redirect_act

#> bind lb vserver default_backend -policyName sslredirect -priority 100 -gotoPriorityExpression END -type REQUEST

NGINX Plus Configuration

location / {

    return 301 https://$host$request_uri;

}

Migrating Logic for Request Rewrite

Common reasons to rewrite requests are to provide additional information in headers or to change the URI, effectively hiding the directory structure of an application or creating URLs that are easier to read and remember.

To manipulate requests with NGINX Plus, use the rewrite directive. It takes two required parameters: a regular expression that matches the string to be rewritten and the replacement string. For further discussion and more examples, see Rewriting URIs in Requests and Creating NGINX Rewrite Rules.

Example – Request Rewrite to Change URI Structure

The following examples rewrite the URI structure of requests for /music/artist/song to /mp3/artistsong.mp3.

F5 iRule

when HTTP_REQUEST {

  if {[string tolower [HTTP::uri]] matches_regex {^/music/([a-z]+)/([a-z]+)/?$} } {

    set myuri [string tolower [HTTP::uri]]

    HTTP::uri [regsub {^/music/([a-z]+)/([a-z]+)/?$} $myuri "/mp3/\\1-\\2.mp3"]

  }

}

NetScaler Policy

#> add rewrite action act_rewrite_music replace "HTTP.REQ.URL.REGEX_SELECT(re!^\\/music\\/[a-z]+\\/[a-z]+(\\/)?$!)" "\"/mp3/\" + HTTP.REQ.URL.AFTER_REGEX(re!^\\/music\\/!).BEFORE_REGEX(re!\\/[a-z]+(\\/)?$!) + \"-\" + HTTP.REQ.URL.AFTER_REGEX(re!^\\/music\\/[a-z]+\\/!).BEFORE_REGEX(re!(\\/)?$!) + \".mp3\""

#> add rewrite policy pol_rewrite_music "HTTP.REQ.URL.REGEX_MATCH(re!^\\/music\\/[a-z]+\\/[a-z]+(\\/)?$!)" act_rewrite_music

#> bind lb vserver music_backend -policyName pol_rewrite_music -priority 100 -gotoPriorityExpression END -type REQUEST

NGINX Plus Configuration

location ~*^/music/[a-z]+/[a-z]+/?$ {

    rewrite ^/music/([a-z]+)/([a-z]+)/?$ /mp3/$1-$2.mp3 break;

    proxy_pass http://music_backend;

}

Migrating Logic for Response Rewrite

Rewriting the response body is often done along with request routing, to change links in the response body to reflect the new URI structure created by the request routing. It can also be used to make other changes to the response body before it’s sent to the client.

To rewrite HTTP responses with NGINX Plus, use the sub_filter directive. It takes two parameters: the string for NGINX Plus to search for and replace, and the replacement string. For further discussion, see Rewriting HTTP Responses.

Example – Response Rewrite to Change Link Paths

The following examples search through the response body for links containing the /mp3/ directory element and replace it with /music/.

F5 iRule

when HTTP_RESPONSE {

   if {[HTTP::header value Content-Type] contains "text"}{

     STREAM::expression {@/mp3/@/music/@}

     STREAM::enable

   }

}

NetScaler Policy

#> add rewrite action act_rewrite_body replace_all "HTTP.RES.BODY(100000)" "\"/music/\"" -search "text(\"/mp3/\")"

#> add rewrite policy pol_rewrite_body TRUE act_rewrite_body

#> bind lb vserver default_backend -policyName pol_rewrite_body -priority 100 -gotoPriorityExpression END -type RESPONSE

NGINX Plus Configuration

location / {

    sub_filter '/mp3/' '/music/';

    proxy_pass http://default_backend;

}

Conclusion

As you can see, the NGINX and NGINX Plus configuration language covers many scripting use cases associated with ADCs. With this powerful toolset, migrating to software‑based load balancing is simple and straightforward to accomplish.

Use cases that are more complicated, or require custom behavior can be accomplished with embedded scripting languages such as Lua, Perl, and JavaScript (with the nginScript module in NGINX Plus R10 and later). For more information and use instructions, see Dynamic Modules with NGINX Plus.

Is your APM strategy broken? This ebook explores the latest in Gartner research to help you learn how to close the end-user experience gap in APM, brought to you in partnership with Catchpoint.

Topics:
configuration ,nginx plus ,rules ,nginx ,f5 ,policies ,migration

Published at DZone with permission of Shaun Empie, DZone MVB. See the original article here.

Opinions expressed by DZone contributors are their own.

The best of DZone straight to your inbox.

SEE AN EXAMPLE
Please provide a valid email address.

Thanks for subscribing!

Awesome! Check your inbox to verify your email so you can start receiving the latest in tech news and resources.
Subscribe

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}