Showing posts with label lab. Show all posts
Showing posts with label lab. Show all posts

Friday, February 20, 2015

Alteon AppShape++ persistency and multiple scripts per service

Lab goal

Create new VIP on 10.136.6.17.

Using an AppShape++ script to choose the preconfigured group/pool "10".

Once the laodbalancer chooses a server, all requests from the client's source IP should go to the same server. This is called persistence or stickiness.

Setup

I'll use my Loadbalancer Lab Setup.

The loadbalancer is Radware's Alteon VA version 29.5.1.0

The initial Alteon VA configuration can be found here.

Notice the group and hosts are preconfigured:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
/c/slb/real 1
        ena
        ipver v4
        rip 10.136.85.1
/c/slb/real 2
        ena
        ipver v4
        rip 10.136.85.2
/c/slb/real 3
        ena
        ipver v4
        rip 10.136.85.3
/c/slb/group 10
        ipver v4
        add 1
        add 2
        add 3

 

Alteon configuration

First the AppShape++ script:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
/cfg/slb/appshape/script take_10/en/import


attach group 10

when HTTP_REQUEST {
    group select 10
}

-----END

Line 1 - This allows to just copy paste the whole text to Alteon's CLI. It defines a script if its not exists, enable it and imports it.
Line 7 - Selects group 10.

Next, lets configure VIP/virt with its services:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
/c/slb/virt 6_17
       ena
       ipver v4
       vip 10.136.6.17
/c/slb/virt 6_17/service 80 http
       group 1
       rport 80
       pbind clientip norport
       dbind forceproxy
/c/slb/virt /service 80 http/appshape
       add 10 take_10

Line 8 - Add the stickiness/persistence part, based on the clients IP address.
Line 11- Add AppShape++ script.

 

Test


This didn't go well. We still see that all servers were used and not just one.

The reason for that is that once we select a group/pool using AppShape++, Alteon will ignore pbind settings.

 

Another try

AppShape++ has the following command : persist

This command can be used to create a persistence/stickiness .

One way we can use this command is by fixing our script. Another way would be to create another script and add it to the service. Using a separate script will allow us to reuse that script on more than on service / VIP.


1
2
3
4
5
6
7
/cfg/slb/appshape/script persist/en/import

when HTTP_REQUEST {
    persist source_addr 255.255.255.255
}

-----END

Line 4 - Create persistence/stickiness by using the source IP address with /32 mask.

Now lets add it to the service:

1
2
/c/slb/virt 6_17/service 80 http/appshape
       add 16 persist

Line 2 - We have added the new AppShape++ script to the service. We use priority 16  which means this will run after priority 10 which was take_10 script.

 

Another Test 

It works! SRV3 was selected for all HTTP requests.

We can also have a look at the persistance table:


1
2
3
4
5
>> LB1 - Persistency Information# /i/slb/persist/dump 

 Printing Data Table Entries for SP 1
key-10.136.3.1,vs:10.136.6.17,80,g:10,value-g:10 rs:3 80, age 178
Total number of session IDs: 1

Line 1 - Is the command to show all persistence object, in yellow.
Line 4 - Me in red, is using SRV3 in green, and the idle timeout is 178 seconds in blue.

 

Summary

So we learned that not everything we configure on the VIP/virl service applies when we use AppShape++.

We also learned how and why to use more than one script per service.

Enjoy...

Monday, January 26, 2015

VIRL - A slow greatness

I had a migration project from 6500 to ASRs. I have decided to check out VIRL.

My migration setup requires 14 routers and a test server. Reading the system requirements for such a setup made me decide not to install on my laptop.

I went ahead and installed it on a not so small ESX server: A new UCS machine (24 cores, 380G memory, running 4 VMs, including VIRL), ESX 5.1.

I have allocated VIRL 4vCPU, 16GB memory.

The installation was not that short, but not that hard either. After the installation was over, I installed VM Maestro and started building my lab. Working with VM Maestro, which is VIRL's GUI, was really easy. The only annoying thing was my inability to set the interface numbers for the connections between routers.

Here is how my final setup looks like:


The setup is running 12 vIOS, 2 CSR1K, and one Ubuntu server, from where I ran my automated tests.

I pressed on "Start simulation" and then when trouble started. It took about 40 minutes for all the routers to load. Then the CLI felt like 2400 baud. It was crawling!

Notice that each time you start the simulation, for example after adding or removing a link, all the routers are rebuild from scratch. They are not just powered on. They are cloned from a template and go through lengthy installation process. Especially the ASRs which take forever to install themselves.

So I tried to run just 4 routers. That was working well and everything was snappy.

Then I tried to upgrade the VM to 6 vCPUs. Now it took just 3 minutes to load all the routers. The CLI felt much better at 9600 baud.

Then I tried to upgrade the VM to 8 vCPUs. Now everything works almost as fast as GNS3 with IOU!

After setting up the lab foundation, it was time actually to start configuring the lab. I have configured OSPF and BGP. Everything worked, but the response time was slower. Although the response time was slower, the lab was very usable.

To run the test, I am using some VRF magic and bash scripting on the Linux machine. I think it worth a blog entry on its own. Then after 30 minute of stepping away from the lab, I noticed that most OSPF and BGP sessions were lost. I had to press "enter" several times on each router's prompt to wake everything up:

Just when I wake the routers:

16:54:20 +++++-+---+-+---+--++++--++--+-+++++++++
16:54:33 +++++++++++++++++++++++--+++++++++++++++
16:54:36 +++++++++++++++++++++++--+++++++++++++++
16:54:40 ++++++++++++++++++++++++++++++++++++++++
16:54:42 ++++++++++++++++++++++++++++++++++++++++
16:54:43 ++++++++++++++++++++++++++++++++++++++++
16:54:45 ++++++++++++++++++++++++++++++++++++++++

After 30 minutes:
 
17:21:53 ++++++++++++++++++++++++++++++++++++++++
17:21:55 ++++++++++++++++++++++++++++++++++++++++
17:21:56 ++++++++++++++++++++++++++++++++++++++++
17:21:58 ++++++++++++++++++++++++++++++++++++++++
17:22:00 ++++++++++++++++++++++++++++++++++++++++
17:22:01 ++++++++++++++--+------++++--+--+-++++++
time     111112222222333333444445555666677788899B
%H:%M:%S 589BC34679BC4679BC679BC89BC79BC9BC9BCBCC
17:22:17 +++++-----+-----+------++++--+--+-++++++
17:22:40 +++++-----+-----+------++++--+--+-++++++
17:23:02 +++++-----+-----+------++++--+--+-++++++
17:23:24 +++++-----+-----+------++++--+--+-++++++


Friday, December 5, 2014

Alteon's REST API

AlteonOS has a reach REST API for monitor, operation, and configuration.

REST can be used/called with verity of programming languages, or even just using wget. However, since this blog was already using TCL for AppShape++ scripting, we may as well keep using TCL for REST too. However, RESTing with TCL is a bit pain in the ..., so this time I'll use python instead.

All most forgot to explain what REST is. Its a way to run remote procedures calls using HTTP. Example calls:
  1. Read interface counters
  2. Update real's weight
  3. Bring down a real inside a group
I strongly recommend using  a browser plugin for testing out REST calls. I use HttpRequest for firefox.

Here are two screenshots. The first is how I get the current status of real 1, and the second is how I disable real 1.



 

 

 Lab goal


Using the base setup, create python script to toggle the status of real 1 from not enabled to enabled and from disable to enable.

 

Setup


I'll use my Loadbalancer Lab Setup.

The loadbalancer is Radware's Alteon VA version 29.5.1.0

The initial Alteon VA configuration can be found here.

Notice the group and hosts are preconfigured:


 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
/c/slb/real 1
        ena
        ipver v4
        rip 10.136.85.1
/c/slb/real 2
        ena
        ipver v4
        rip 10.136.85.2
/c/slb/real 3
        ena
        ipver v4
        rip 10.136.85.3
/c/slb/group 10
        ipver v4
        add 1
        add 2
        add 3

 

Python script


I have used python 2.7 and the following modules: json and requests

Alteon's REST API is using json as its data format. Python's build in json module converts python dict to json format and vice-versa.

requests is a very easy python module to use for REST API.

Here is the source code for the python script. See the comments inside for explanations:


 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
import requests
import json
import sys


# set Alteon and real parameters
ALTEON = "10.136.1.100"
REAL = "1"
USER = "admin"
PASSWORD = "admin"

# get the current status of real server
# ============================================================

# set authentication object
myAuth=requests.auth.HTTPBasicAuth(USER, PASSWORD)

# set request string with the ALTEON name/ip address and the 'real' we want to toggle
reqSTR =  "https://"+ALTEON+"/config/SlbOperEnhRealServerTable/" + REAL

# turn off SSL warning. Don't do this in production!
# see here how to deal with it http://docs.python-requests.org/en/latest/user/advanced/#ssl-cert-verification

requests.packages.urllib3.disable_warnings()

# send the request, use the auth object, don't verify certification and return a python dct out of json string
# The return is a one item dict with  'SlbNewCfgEnhRealServerTable' as key. 
# That item contains one item list, hence the [0]
# That list item is another dict with two entries: 'Status' and 'Index' we need the Status
r = requests.get(reqSTR, auth=myAuth, verify=False).json()['SlbOperEnhRealServerTable'][0]
state = r['Status']


# print current state and set the new requierd state
if state == 1:
    print "Real is enabled. Changing status to disabled"
    newStatus = "2" # disabled
elif state == 2:
    print "Real is disabled. Changing status to enabled"
    newStatus = "1" # enabled
elif state == 3:
    print "Real is disabled but waiting for cookies to timeout. Changing status to enabled"
    newStatus = "1" # enabled
elif state == 4:
    print "Real is disabled but waiting for sessions to timeout. Changing status to enabled"
    newStatus = "1" # enabled
elif state == 5:
    print "Real is disabled but waiting for sessions to timeout and for cookeis to timeout. Changing status to enabled"
    newStatus = "1" # enabled
else:
    # we should never get here
    print "error retrieving real status. return object:"
    print r
    sys.exit(0)

# set the new real status
# ============================================================

# create JSON data to be passed
myData = json.dumps({'Status' : newStatus})

# send the oper command to change the status. Notice that his time the method is PUT
r = requests.put(reqSTR, auth=myAuth, verify=False, data=myData).json()['status']

# print the return status of the command
print r

Test



Notice how the status is changing from one run to the other.

 

Summary


Alteon's REST API is easy to use and straight forward. It is way better then using expect scripts for automation.

 


Friday, November 14, 2014

GNS3 - ASAv and XRv and IOU and XEv

I am able to run ASAv and XRv and IOU and XEv on my la;ptop, forming OSPF neighbor relationship between them.

I then pinged each loopback from the ASA and also pinged each loopback from IOU. This test shows:
  • One way broadcast and one way unicast are working - ARP
  • Unicast is working - ICMP
  • Multicast is working - OSPF

All thanks for GNS3 v1.1. Isn't it great?

Here is the topology:


And here is some show commands from the ASA:


GNS3 integration with Virtual box is very useful. Whatever you can run inside Virtualbox, you can connect to each other with endless possibilities.

My system76 laptop is running Ubuntu 14.04, 16GB, i7 and SSDs.

I was using the following resources:





Thursday, November 6, 2014

Alteon - each server is different

Lab goal

Create VIP 10.136.6.16 with the following servers/reals:
  • "r8080" - 10.136.85.1 port 8080
  • "r8081" - 10.136.85.2 port 8081
  • "r8082" - 10.136.85.3 port 8082
The group name should be "gMulti".

Setup

I'll use my Loadbalancer Lab Setup.

The loadbalancer is Radware's Alteon VA version 29.5.1.0

The initial Alteon VA configuration can be found here.

Alteon configuration

First lets add the reals.



 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
/c/slb/real r8080
       ena
       ipver v4
       rip 10.136.85.1
       addport 8080
/c/slb/real r8081
       ena
       ipver v4
       rip 10.136.85.2
       addport 8081
/c/slb/real r8082
       ena
       ipver v4
       rip 10.136.85.3
       addport 8082
/c/slb/group gMulti
       ipver v4
       add r8080
       add r8081
       add r8082
/c/slb/virt 6_16
       ena
       ipver v4
       vip 10.136.6.16                   
/c/slb/virt 6_16/service 80 http
       group gMulti
       rport 0       

  • Lines 1-15 : Configure the real servers
    • Notice the addport command, which sets the port being used by the server.
  • Lines 16-20: Create a new group and adds the previously defined servers
  • Lines 21-27: Create the VIP
    • Notice line 27, which states that the Alteon should use the rport configured on a real server's configuration.

Test


Notice the SRV_PORT and SRV_ADDR, which shows that the 808X port is being used.

But a better way to see that is to see the sessions in the session table:



1
2
3
4
5
6
7
8
9
>> LB1 - Session Table Information# /i/slb/sess/cip 10.136.3.1 

 Printing Sessions for SP 1
1,01: 10.136.3.1 50040, 10.136.6.16 http -> 2094 10.136.85.3 8082 tcp age 10 v:1  E
1,01: 10.136.3.1 50041, 10.136.6.16 http -> 2095 10.136.85.2 8081 tcp age 10 v:1  E
1,01: 10.136.3.1 50042, 10.136.6.16 http -> 2096 10.136.85.1 8080 tcp age 10 v:1  E
1,01: 10.136.3.1 50043, 10.136.6.16 http -> 2097 10.136.85.3 8082 tcp age 10 v:1  E
1,01: 10.136.3.1 50044, 10.136.6.16 http -> 2098 10.136.85.2 8081 tcp age 10 v:1  E
1,01: 10.136.3.1 50046, 10.136.6.16 http -> 2100 10.136.85.3 8082 tcp age 10 v:1  E

Summary

As usual, the configurations are simple and straight forward.

Tuesday, October 28, 2014

GNS3 1.1


I was never a big fan of GUI tools, so I used dynagen and dynamips for my network designs. But since 15.2 was the last version released for 7200, dynamips is no longer useful (especially for IKEv2 and OSPFv3 stuff)

I was hoping that Cisco would release VIRL, and they promised to do so for the past year and a half, but it looks like it will never come. Shelling out 10K$ for CML (the payed version of VIRL) is a bit too much for most of us. But there is a good alternative:

Not long time ago GNS3 version 1.0 was released and soon after version 1.1. was released too. And after long time of being a backer for their funding campaign I have decided to try GNS3 with IOU.

After installing GNS3 on both linux and windows (vmware required), I found that GNS3 is really easy to use, and that IOU is AMAZING. IOU is sooooo fast, and everything just works(tm). I wish I had it years ago!

Goodbye dynamips and dynagen, and thank you so much.

Hello IOU and GNS3. I know it will be a start of a wonderful friendship :)


Friday, September 26, 2014

Change HTTP reply content with AppShape++

Lab goal

When a clients asks for beta/a2.html, return "Hello" instead.

Use VIP 10.136.85.14

Setup

I'll use my Loadbalancer Lab Setup.


The loadbalancer is Radware's Alteon VA version 29.5.1.0

The initial Alteon VA configuration can be found here.

Notice the group and hosts are preconfigured:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
/c/slb/real 1
        ena
        ipver v4
        rip 10.136.85.1
/c/slb/real 2
        ena
        ipver v4
        rip 10.136.85.2
/c/slb/real 3
        ena
        ipver v4
        rip 10.136.85.3
/c/slb/group 10
        ipver v4
        add 1
        add 2
        add 3

Alteon configuration

First, lets configure the VIP/virt.

Remember routing! The returning traffic needs to go through the Alteon, otherwise TCP will break. So we also need to configure Proxy IP/SNAT so return traffic will go through the Alteon.


1
2
3
4
5
6
7
8
 /c/slb/virt 85_14
        ena
        vip 10.136.85.14
 /c/slb/virt 85_14/service 80 http
        group 10
 /c/slb/virt 85_14/service 80 http/pip
        mode address
        addr v4 10.136.85.200

Next we need to write the Appshape++ script:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
when HTTP_REQUEST {
    # retrieve URL from the request
    set url [HTTP::uri]
    set reply {
        <html>
        <body>
        <h1>Hello!</h1>
        <body>
        </html>
    }

    # check if URL is with /beta/a2.html
    if {[string match "/beta/a2.html" $url] == 1} {
        # change the URL and select SRV1
        HTTP::respond 200 content $reply
    }
}

-----END


  • Line 1-17 - When a request comes in do:
    • Line 3 - Extract the URL
    • Line 4-10 - Set a response content.
    • Lines 13-16 - If the URL is "beta/a2.html" then:
      • Line 15 - Respond with code 200 and the content we set earlier.
  • Line 19 - The end of the script.
Now lets import the script and apply it to the VIP/virt:


 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
 /c/slb/appshape/script respond
        ena
        import text 
 when HTTP_REQUEST {
     # retrieve URL from the request
     set url [HTTP::uri]
     set reply {
         <html>
         <body>
         <h1>Hello!</h1>
         <body>
         </html>
     }
     # check if URL is /beta/a2.html
     if {[string match "/beta/a2.html" $url] == 1} {
         # change the URL and select SRV1
         HTTP::respond 200 content $reply
     }
 }
 -----END
 
 /c/slb/virt 85_14/service 80 http/appshape
        add 10 respond

Test


Notice the "Hello!". Success!

Summary

After writing few AppShape++ , a pattern emerges: It really easy :)

Thursday, September 18, 2014

Using AppShape++ to change a request's URL

Lab goal

  • When a clients asks for /cgi-bin/* change that to /alpha/a1.html, and serve it from SRV1 
  • Fix the 404 page not found.

Use VIP 10.136.6.13.

Setup

I'll use my Loadbalancer Lab Setup.


The loadbalancer is Radware's Alteon VA version 29.5.1.0

The initial Alteon VA configuration can be found here.

Notice the group and hosts are preconfigured:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
/c/slb/real 1
        ena
        ipver v4
        rip 10.136.85.1
/c/slb/real 2
        ena
        ipver v4
        rip 10.136.85.2
/c/slb/real 3
        ena
        ipver v4
        rip 10.136.85.3
/c/slb/group 10
        ipver v4
        add 1
        add 2
        add 3

Alteon configuration

Lets first create the VIP/virt and test it out.


1
2
3
4
5
 /c/slb/virt 6_13
        ena
        vip 10.136.6.13
 /c/slb/virt 6_13/service 80 http
        group 10

To fix the 404 at the bottom of the webpage, we need to change the request URL from /not_here to /here.html.

So lets write the AppShape++ script:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
attach group 10

when HTTP_REQUEST {
    # retrieve URL from the request
    set url [HTTP::uri]

    # check if URL begins with /cgi-bin/
    if {[string match "/cgi-bin/*" $url] == 1} {
        # change the URL and select SRV1
        HTTP::uri "/alpha/a1.html"
        group select 10 server 1
    # check if the request is for /not_here
    } elseif {[string match "/not_here" $url] == 1} {
        # change the URL to here.html
        HTTP::uri "/here.html"
    }
}

-----END


  • Line 1 - declare that we are about to use group 10.
  • Lines 3 - 17 - When HTTP_REQUEST comes from the client to the VIP do this:
    • Line 5 - Retrieve the URL
    • Lines 8-13 - Check if the URL begins with /cgi-bin/ if so:
      • Lines 10-11 - Send the request to the web server as "/alpha/a1.html" and select SRV1.
    • Lines 13-16 - Check if the URL is not_here if so:
      • Line 15 - Send the request to the web server as "here.html"
Now lets apply this script to the Alteon:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
 /c/slb/appshape/script set_url
        ena
        import text 
 attach group 10
 when HTTP_REQUEST {
     # retrieve URL from the request
     set url [HTTP::uri]
     # check if URL begins with /cgi-bin/
     if {[string match "/cgi-bin/*" $url] == 1} {
         # change the URL and select SRV1
         HTTP::uri "/alpha/a1.html"
         group select 10 server 1
     # check if the request is for /not_here
     } elseif {[string match "/not_here" $url] == 1} {
         # change the URL to here.html
         HTTP::uri "/here.html"
     }
 }
 -----END

 /c/slb/virt 6_13/service 80 http/appshape
        add 10 set_url


  • Lines 1-19 - importing the script
  • Lines 21-22 - applying the script to the VIP

Test


Before:



After:


Success!

Notice how the CGI script, which shows connection data (it just prints ENV vars), changed to show a static page from SRV1 and also notice that the 404 is fixed.

Summary

Setting the URL is really easy, once you know how.... :)

Friday, September 12, 2014

HTTP to HTTPs redirect with a twist

Lab goal

Create a new VIP/virt - 10.136.85.13.

The main page should be using HTTP but all the other elements should be using SSL.


Setup

I'll use my Loadbalancer Lab Setup.



The loadbalancer is Radware's Alteon VA version 29.5.1.0

The initial Alteon VA configuration can be found here.

Alteon configuration

We will reuse group 10 which includes all web servers.

So all is left is to create a VIP/virt with services HTTP and HTTPS

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
 /c/slb/virt 86_13
        ena
        ipver v4
        vip 10.136.85.13
 /c/slb/virt 86_13/service 80 http
        group 10
        rport 80
 /c/slb/virt 86_13/service 80 http/pip
        mode address
        addr v4 10.136.85.200 
 /c/slb/virt 86_13/service 443 https
        group 10
        rport 443
 /c/slb/virt 86_13/service 443 https/pip
        mode address
        addr v4 10.136.85.200 

Lines 8-10 - Source NAT. Without it traffic from the server will go directly to client without going first through the Alteon.

Now for the AppShape script:


 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
when HTTP_REQUEST {
    # exctract the fields from the HTTP headers
    set url [HTTP::uri]
    set host [HTTP::host]


    if {[string equal $url "/"] ==0} {
        HTTP::redirect "https://$host$url" 301
    }
}

-----END


  • Line 7 checks if the path is not  /" and then:
    • Line 8 Redirect all requests to the page elements, such as pictures, iFrames and CGI-BIN to HTTPS
    • Notice that the redirect was built with the extracted host name and the URL
Next lets import and apply the AppShape++ script:


 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
 /c/slb/appshape/script redirect_to_https
        ena
        import text 
 when HTTP_REQUEST {
     # exctract the fields from the HTTP headers
     set url [HTTP::uri]
     set host [HTTP::host]
     if {[string equal $url "/"] ==0} {
         HTTP::redirect "https://$host$url" 301
     }
 }
 -----END

 /c/slb/virt 86_13/service 80 http/appshape
        add 10 redirect_to_https

Test


It looks like a regular HTTP page, but notice the TCP port being used inside the iFrame. Its 443, which is HTTPS.

Success!

Summary

This exact setup can be done with crule,but I think that using AppShape++ is much easier to understand, as you see the condition and the action in one place.

Wednesday, September 10, 2014

Alteon AppShape++ Redirects

Lab goals

In the lab we will practice:

  • Redirection - r.dans-net.com should be redirected to 3.dans-net.com
  • Decision by URL matching:
    • If URL length is 1 or 2, not including the leading "/", then redirect to 3.dans-net.com
    • If URL is "/images/number.jpg" or "/icons/number.jpg" then select SRV1
    • URL begins with  "/alpha" or with "/beta" then select SRV2
    • URL contains "cgi-bin" or "gamma" then select SRV3
Both r.dans-net.com and 3.dans-net.com should resolve to 10.136.6.11.

Setup

I'll use my Loadbalancer Lab Setup.


The loadbalancer is Radware's Alteon VA version 29.5.1.0

Here is the /etc/hosts or c:\windows\system32\drivers\etc\hosts resolve snippet:


1
2
10.136.6.11     3.dans-net.com
10.136.6.11     r.dans-net.com

Alteon configuration

Fist lets create 3 groups, one for each SRV:



1
2
3
4
5
6
7
8
9
/c/slb/group g1
        ipver v4
        add 1
/c/slb/group g2
        ipver v4
        add 2
/c/slb/group g3
        ipver v4
        add 3

Next, lets configure create the VIP/virt:


1
2
3
4
 /c/slb/virt 6_11
        ena
        vip 10.136.6.11
 /c/slb/virt 6_11/service 80 http

Next the AppShape++ script. This time I'll show two parts. The draft and the final.

Draft Script

The draft script is a regular TCL script, where I test the script with regular TCL enviourment, such as ActiveTCL for windows.


 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
#attach group g1
#attach group g2
#attach group g3
#
#when HTTP_REQUEST {
#}
#
#-----END

# usage
# redirect_url_match [URL] [HOST]

# set default values
set host "3.dans-net.com"
set url "/a"

# set values if exists
if {$argc == 1} {
    set url [lindex $argv 0]
} elseif {$argc > 1} {
    set host [lindex $argv 1]
}


# the code to use later on the alteon
if {[string equal $host "r.dans-net.com"]} {
    puts "redirect to 3.dans-net.com"
} else {
    # check length of url. since the cout also includes the leading / we need to add 1 to the comparison
    if {[string length $url] == 2 || [string length $url] == 3} {
        puts "redirect to 3.dans-net.com"
    # exact match    
    } elseif { [string match "/images/number.jpg" $url] || [string match "/icons/number.jpg" $url ] } {
        puts "SRV1"
    #match begin with    
    } elseif { [string match "/alpha*" $url] || [string match "/beta*" $url] } {
        puts "SRV2"
    # match contains X
    } elseif { [string match "*gama*" $url] || [string match "*cgi-bin*" $url] } {
        puts "SRV3"
    }

}


  • Lines 1-8 - This is my template for AppShape++ scripts. Its is currently commented out.
  • Lines 14-22 - Simulate HTTP headers and URL
    • We are basing our group/pool selection on Host name and URL, so we need to simulate those parameters.
    • Lines 14-15 - Set the default Host and URL
    • Lines 18-22 - Extract the URL and Host name from command line arguments.
    • The script can be run:
      • Without arguments: tclsh.exe my_script.tcl . Then the URL is "/a" and the host is "3.dans-net.com"
      • With just one argument: tclsh.exe my_script /gamma/a3.html. Then the URL is "/gamma/a3.html" and the host is "3.dans-net.com".
      • With two arguments: tclsh.exe my_script /gamma/a3.html r.dans-net.com. Then the URL is "/gamma/a3.html" and the host is "r.dans-net.com"
  • Lines 26-28 - Check if host name is "r.dans-net.com". If so, print "redirect to 3.dans-net.com". This is instead of actually using the Alteon command HTTP::redirect 
  • Lines 28-43 - Check the URL
    • Line 30 is checking the length of the URL.
    • Line 33 is checking exact match.for the URL
    • Line 36 is checking if the URL begins with....
    • Line 39 is checking if the URL contains ....
After running the script and checking that its actually working as indicated in the Lab Goals, we need to convert it to Alteon AppShape script:


 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
attach group g1
attach group g2
attach group g3
attach group 10

when HTTP_REQUEST {
    # exctract the fields from the HTTP headers
    set host [HTTP::host]
    set url [HTTP::uri]


    if {[string equal $host "r.dans-net.com"]} {
        HTTP::redirect "http://3.dans-net.com" 301
    } else {
        # check length of url. since the cout also includes the leading / we need to add 1 to the comparison
        if {[string length $url] == 2 || [string length $url] == 3} {
            HTTP::redirect "http://3.dans-net.com" 
        # exact match    
        } elseif { [string match "/images/number.jpg" $url] || [string match "/icons/number.jpg" $url ] } {
            group select g1
        #match begin with    
        } elseif { [string match "/alpha*" $url] || [string match "/beta*" $url] } {
            group select g2
        # match contains X
        } elseif { [string match "*gamma*" $url] || [string match "*cgi-bin*" $url] } {
            group select g3
        } else {
            group select 10
        }

    }
}

-----END

This is basically the same script as before, with just Alten AppShape++ commands like HTTP::redirect:  and group select

Notice that at line 28, we have a default action, which is to use group 10, which includes all web servers. This will allow serving the main page, javascript and css.

Also notice the difference between the redirect at line 13 and the redirect at line 17. The first will return 301 - permanent move, and the second will send the default 302 which is temporary move.

Now lets import the script and apply it to the virt configuration



 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
 /c/slb/appshape/script redirect_match_url
        ena
        import text 
 attach group g1
 attach group g2
 attach group g3
 attach group 10
 when HTTP_REQUEST {
     # exctract the fields from the HTTP headers
     set host [HTTP::host]
     set url [HTTP::uri]
     if {[string equal $host "r.dans-net.com"]} {
         HTTP::redirect "http://3.dans-net.com" 301
     } else {
         # check length of url. since the cout also includes the leading / we need to add 1 to the comparison
         if {[string length $url] == 2 || [string length $url] == 3} {
             HTTP::redirect "http://3.dans-net.com" 
         # exact match    
         } elseif { [string match "/images/number.jpg" $url] || [string match "/icons/number.jpg" $url ] } {
             group select g1
         #match begin with    
         } elseif { [string match "/alpha*" $url] || [string match "/beta*" $url] } {
             group select g2
         # match contains X
         } elseif { [string match "*gamma*" $url] || [string match "*cgi-bin*" $url] } {
             group select g3
         } else {
             group select 10
         }
     }
 }
 -----END
 

 /c/slb/virt 6_11/service 80 http
        dbind forceproxy
 /c/slb/virt 6_11/service 80 http/appshape
        add 10 redirect_match_url

Test

First I tried some redirection tests. The best way to see them is using chrome or firefox developer tools and have a look at the network tab. However, this is not the best way to show it here as the data is hierarchical and I can't show in one snapshot how redirection worked.

So I used wireshark to show the redirection.



  • Packet 4 is the request for r.dans-net.com
  • Packet 6 is the reply with the redirect
  • Packet 7 is the new request to the redirected host
Next lets see how the page looks like:


We can see that reach element (in red) is using the correct SRV.

Summary

I really like TCL. It is very simple. So is AppShape++.