Forum Discussion

Nick_68106's avatar
Nick_68106
Icon for Nimbostratus rankNimbostratus
Dec 09, 2011

iRule to route traffic to different pool when pool members down in default pool

Greetings,

We are running a transparent proxy in our environment and have decided that when the both proxy servers in our proxy server pool become unavailable we would like to route the traffic out the internet unfiltered (VLAN C). All clients have public IPv4 addresses.

 

 

 

I have a wildcard VIP setup (with a lasthop pool overriding the autolast hop featuere) to accept traffic on VLAN A pass the traffic back to VLAN B (where the proxy servers are) and then go out the lasthop pool on VLAN C.

 

 

 

I have an iRule on the wildcard VIP which redirects HTTP requests to the proxy server when needed by replacing the HTTP host and HTTP uri.

 

 

 

When the proxy servers are not down this setup works flawlessly. However when both proxy servers are down and I choose to use the lasthop pool instead of the proxy pool traffic does not flow correctly. If I remove both the iRule with the HTTP redirects in it and the HTTP profile and apply a iRule with just when LB::failed statement in it to reselect the lasthop pool as it's target I can asymetrically route the traffic to the internet just fine. This makes me believe that there is something in the HTTP profile (possibly iRule) which is causing a change to the HTTP packet before it goes to the lasthop pool that the router in the lasthop does not like.

 

 

 

Any help or suggestions would be great.

 

 

 

Configuration:

 

virtual capture_virt {

 

lasthop pool captured_lasthop

 

pool capture_pool

 

destination any:any

 

mask 0.0.0.0

 

ip protocol tcp

 

rules captured-HTTP_rule

 

profiles {

 

captured_prof {}

 

captured_tcp_prof {}

 

}

 

vlans captured-A enable

 

}

 

 

 

pool captured_lasthop {

 

monitor all gateway_icmp

 

members 10.1.5.41:any {}

 

}

 

 

 

____iRule below__________

 

 

 

rule captured-HTTP_rule {

 

when CLIENT_ACCEPTED {

 

if { [active_members capture_pool] < 1 } {

 

use pool captured_lasthop

 

}

 

}

 

when LB_FAILED {

 

if { [active_members capture_pool] < 1 } {

 

use pool captured_lasthop

 

}

 

}

 

when HTTP_REQUEST {

 

if { [HTTP::host] eq "www.facebook.com" } {

 

use pool captured_lasthop

 

} elseif { [HTTP::host] eq "www.google.com" } {

 

use pool captured_lasthop

 

} elseif { [HTTP::host] eq "www.yahoo.com" } {

 

use pool captured_lasthop

 

} else {

 

log local0. "Client IP address is: [IP::remote_addr]"

 

HTTP::header replace Host "www.example.com"

 

log local0. "Replacing Host"

 

HTTP::uri "/example/login.html"

 

log local0. "Replacing URI"

 

}

 

}

 

}

 

 

 

 

_____iRule above______

 

 

 

pool capture_pool {

 

monitor all cp-web_HTTP_DEV01_mon

 

members {

 

10.1.5.20:http {}

 

10.1.5.21:http {}

 

}

 

}

 

 

 

 

 

profile http captured_prof {

 

defaults from http

 

}

 

 

 

profile tcp captured_tcp_prof {

 

defaults from tcp

 

}

 

 

9 Replies

  • However when both proxy servers are down and I choose to use the lasthop pool instead of the proxy pool traffic does not flow correctly.can you try to put "forward" command above pool captured_lasthop?
  • Greetings nitass,

     

    I inserted 'forward' above the pool selection like so in the iRule:

     

     

    rule captured-HTTP_rule {

     

    when CLIENT_ACCEPTED {

     

    if { [active_members capture_pool] < 1 } {

     

    use pool captured_lasthop

     

    }

     

    }

     

    when LB_FAILED {

     

    if { [active_members capture_pool] < 1 } {

     

    use pool captured_lasthop

     

    }

     

    }

     

     

    The outcome is still the same.
  • is it similar to this? but it still doesn't work, does it?

    when CLIENT_ACCEPTED { 
       if { [active_members capture_pool] < 1 } { 
          forward
          pool captured_lasthop 
       } 
    } 
    when LB_FAILED { 
       if { [active_members capture_pool] < 1 } { 
          forward
          pool captured_lasthop 
       } 
    }
    
  • Yes sorry, copy paste fail there. It is identical to what you have posted and still does not work.
  • never mind. forward command is not needed in your configuration.

     

     

    by the way, can you try to also check active members in HTTP_REQUEST?

     

     

    e.g.

     

     

    when HTTP_REQUEST {

     

    switch [string tolower [HTTP::host]] {

     

    "www.facebook.com" -

     

    "www.google.com" -

     

    "www.yahoo.com" {

     

    pool captured_lasthop

     

    }

     

    default {

     

    if {[active_members [LB::server pool]] > 0} {

     

    log local0. "Client IP address is: [IP::remote_addr]"

     

    HTTP::header replace Host "www.example.com"

     

    log local0. "Replacing Host"

     

    HTTP::uri "/example/login.html"

     

    log local0. "Replacing URI"

     

    }

     

    }

     

    }

     

    }
  • I tried that as well and ended up with the same results. I think it has something to do with the TCP profile that is required by the HTTP profile because when I do a packet capture on the lasthop pool VLAN (VLAN C) you can see the load balancer responding with a TCP SYN/ACK as the destination IP address which I imagine is what most likely is causing the problem.

     

     

    I believe this because when I remove the HTTP profile and leave the TCP profile and remove the iRule which requires the HTTP profile the load balancer acts the same way sending a TCP SYN/ACK acting as the destination IP address. If I then remove the TCP profile the load balancer does not send a TCP SYN/ACK acting as the destination IP address and the traffic flows as expected (i.e. I can route the traffic out to the internet no problem).

     

     

    I believe then that this is causing the client and the real server (i.e. www.facebook.com or whatever) to never finish a TCP 3 way hand shake since the client is getting a response from both the real end server and the fake end server (the load balancer in this case). Does anyone know how to disable/workaround this in the TCP profile? I would imagine if I disabled this in the TCP profile then when the proxy servers are both up and working the virtual server would not work correctly.

     

     

  • i understand what you are describing is how tcp profile works i.e. full proxy architecture.

     

     

    sol8082: Overview of TCP connection set-up for BIG-IP LTM virtual server types

     

    http://support.f5.com/kb/en-us/solutions/public/8000/000/sol8082.html

     

     

    i do not think so far there is a way to change tcp to fastl4 profile in irule. not sure if we create two virtual servers; one uses tcp profile and the other one uses fastl4 profile, and then when active members is less than 1, send traffic to the fastl4 virtual server is workable.

     

     

    anyway, i think tcp profile should also work. it could have something we missed. may you run this tcpdump command and have a look one more time? or can you upload the tcpdump file here or open a support ticket to get support guy to take a look?

     

     

    tcpdump -nni 0.0:nnn -s0 -w /var/tmp/output.pcap host x.x.x.x

     

    x.x.x.x is client ip address
  • nitass, thank you for all the help here. I do have a ticket open with F5 in regards to this issue and one of the recommendations my support engineer gave me was to post my problem to this forum.

     

     

    I have been able to work around the issue I was having by doing the following:

     

     

    setup iptables on the web servers to nat the destination to the web server on port 80

     

     

    setup apache with mod_rewrite to rewrite anything that is not destined for my web server to the web servers fqdn/uri

     

     

    removed the http_profile, tcp_profile from the wildcard virtual server.

     

     

    changed the irule so it does not whitelist based on hostname in the http request during an HTTP_REQUEST but to whitelist based on destination IP address during CLIENT_ACCEPTED. removed the fqdn/uri rewriting from the irule.

     

     

    This works in our environment but would be much more flexible if it could be handled in the load balancer and use hostnames instead of IP's. However this is satisfactory for us at the current time.

     

     

    Thanks again for all the help!!!

     

     

    Best Regards,

     

    --Nick
  • i do not have transparent proxy in lab, so i have to enable translate address and service on virtual server. also, snat is required in my lab.

    from my test, you will see when proxy_pool was down, bigip sent traffic to web server directly. the destination address (98.137.149.56) and port number (80) were not translated since forward command disabled them.

    C:\>nslookup www.yahoo.com

    Server: xxx.xxx.xxx

    Address: 192.168.204.178

    Non-authoritative answer:

    Name: any-fp3-real.wa1.b.yahoo.com

    Addresses: 72.30.2.43

    98.137.149.56

    Aliases: www.yahoo.com

    fp3.wg1.b.yahoo.com

    sg-fp3-lfb.wg1.b.yahoo.com

    any-fp3-lfb.wa1.b.yahoo.com

    [root@ve1023:Active] config  b virtual bar list
    virtual bar {
       translate address enable
       translate service enable
       snat automap
       pool proxy_pool
       destination any:any
       mask 0.0.0.0
       ip protocol 6
       rules myrule
       profiles {
          http {}
          tcp {}
       }
    }
    [root@ve1023:Active] config  b pool proxy_pool list
    pool proxy_pool {
       members 192.168.12.105:3128 {}
    }
    [root@ve1023:Active] config  b pool gateway_pool list
    pool gateway_pool {
       members 172.28.19.254:any {}
    }
    [root@ve1023:Active] config  b rule myrule list
    rule myrule {
       when HTTP_REQUEST {
            if {[string tolower [HTTP::host]] equals "www.google.com" or \
                    [active_members [LB::server pool]] < 1} {
                    forward
                    pool gateway_pool
            }
    }
    }
    
     curl -I http://www.yahoo.com/
    
    [root@ve1023:Active] config  tcpdump -nni 0.0 port 80 or port 3128
    tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
    listening on 0.0, link-type EN10MB (Ethernet), capture size 108 bytes
    02:58:14.159318 IP 200.200.200.101.37253 > 72.30.2.43.80: S 2842128339:2842128339(0) win 5840 
    02:58:14.159349 IP 72.30.2.43.80 > 200.200.200.101.37253: S 1156550803:1156550803(0) ack 2842128340 win 4380 
    02:58:14.160283 IP 200.200.200.101.37253 > 72.30.2.43.80: . ack 1 win 46 
    02:58:14.160301 IP 200.200.200.101.37253 > 72.30.2.43.80: P 1:157(156) ack 1 win 46 
    02:58:14.160443 IP 172.28.19.80.37253 > 192.168.12.105.3128: S 668650010:668650010(0) win 4380 
    02:58:14.260381 IP 72.30.2.43.80 > 200.200.200.101.37253: . ack 157 win 4536 
    02:58:14.325384 IP 192.168.12.105.3128 > 172.28.19.80.37253: S 1758187351:1758187351(0) ack 668650011 win 5792 
    02:58:14.325401 IP 172.28.19.80.37253 > 192.168.12.105.3128: . ack 1 win 4380 
    02:58:14.325412 IP 172.28.19.80.37253 > 192.168.12.105.3128: P 1:157(156) ack 1 win 4380 
    02:58:14.491573 IP 192.168.12.105.3128 > 172.28.19.80.37253: . ack 157 win 5792 
    02:58:14.491592 IP 192.168.12.105.3128 > 172.28.19.80.37253: P 1:365(364) ack 157 win 5792 
    02:58:14.491617 IP 72.30.2.43.80 > 200.200.200.101.37253: P 1:365(364) ack 157 win 4536 
    02:58:14.491621 IP 192.168.12.105.3128 > 172.28.19.80.37253: F 365:365(0) ack 157 win 5792 
    02:58:14.491628 IP 172.28.19.80.37253 > 192.168.12.105.3128: . ack 366 win 4744 
    02:58:14.491631 IP 72.30.2.43.80 > 200.200.200.101.37253: F 365:365(0) ack 157 win 4536 
    02:58:14.492247 IP 200.200.200.101.37253 > 72.30.2.43.80: . ack 365 win 54 
    02:58:14.492255 IP 200.200.200.101.37253 > 72.30.2.43.80: F 157:157(0) ack 366 win 54 
    02:58:14.492262 IP 72.30.2.43.80 > 200.200.200.101.37253: . ack 158 win 4536 
    02:58:14.492266 IP 172.28.19.80.37253 > 192.168.12.105.3128: F 157:157(0) ack 366 win 4744 
    02:58:14.657271 IP 192.168.12.105.3128 > 172.28.19.80.37253: . ack 158 win 5792 
    
    [root@ve1023:Active] config  b pool proxy_pool monitor all fake
    [root@ve1023:Active] config  b pool proxy_pool|grep -i pool\ member
    +-> POOL MEMBER proxy_pool/192.168.12.105:3128   inactive,down
    
     curl -I http://www.yahoo.com/
    
    [root@ve1023:Active] config  tcpdump -nni 0.0 port 80
    tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
    listening on 0.0, link-type EN10MB (Ethernet), capture size 108 bytes
    02:59:18.619344 IP 200.200.200.101.39373 > 98.137.149.56.80: S 1710494010:1710494010(0) win 5840 
    02:59:18.619379 IP 98.137.149.56.80 > 200.200.200.101.39373: S 1489332666:1489332666(0) ack 1710494011 win 4380 
    02:59:18.620321 IP 200.200.200.101.39373 > 98.137.149.56.80: . ack 1 win 46 
    02:59:18.620349 IP 200.200.200.101.39373 > 98.137.149.56.80: P 1:157(156) ack 1 win 46 
    02:59:18.620418 IP 172.28.19.80.39373 > 98.137.149.56.80: S 3312724555:3312724555(0) win 4380 
    02:59:18.720813 IP 98.137.149.56.80 > 200.200.200.101.39373: . ack 157 win 4536 
    02:59:18.800356 IP 98.137.149.56.80 > 172.28.19.80.39373: S 3513074640:3513074640(0) ack 3312724556 win 5792 
    02:59:18.800377 IP 172.28.19.80.39373 > 98.137.149.56.80: . ack 1 win 4380 
    02:59:18.800391 IP 172.28.19.80.39373 > 98.137.149.56.80: P 1:157(156) ack 1 win 4380 
    02:59:18.981489 IP 98.137.149.56.80 > 172.28.19.80.39373: . ack 157 win 27 
    02:59:19.011277 IP 98.137.149.56.80 > 172.28.19.80.39373: P 1:835(834) ack 157 win 27 
    02:59:19.011315 IP 98.137.149.56.80 > 200.200.200.101.39373: P 1:835(834) ack 157 win 4536 
    02:59:19.012420 IP 200.200.200.101.39373 > 98.137.149.56.80: . ack 835 win 59 
    02:59:19.012441 IP 200.200.200.101.39373 > 98.137.149.56.80: F 157:157(0) ack 835 win 59 
    02:59:19.012451 IP 98.137.149.56.80 > 200.200.200.101.39373: . ack 158 win 4536 
    02:59:19.012456 IP 172.28.19.80.39373 > 98.137.149.56.80: F 157:157(0) ack 835 win 5214 
    02:59:19.195404 IP 98.137.149.56.80 > 172.28.19.80.39373: F 835:835(0) ack 158 win 27 
    02:59:19.195434 IP 172.28.19.80.39373 > 98.137.149.56.80: . ack 836 win 5214 
    02:59:19.195441 IP 98.137.149.56.80 > 200.200.200.101.39373: F 835:835(0) ack 158 win 4536 
    02:59:19.196481 IP 200.200.200.101.39373 > 98.137.149.56.80: . ack 836 win 59