Learn F5 Technologies, Get Answers & Share Community Solutions Join DevCentral

Filter by:
  • Solution
  • Technology
Clear all filters
Answers

iRule required to change Citrix ICA IP address.

Hi,

I am currently load balancing a Citrix Web Interface using a BIG-IP LTM.

When I connect to the external facing VIP I can login to the web interface and browse the citrix apps as expected. The issue I am experiencing is that when I try and launch the chosen app the ICA launcher tries to connect to the XenApp servers using a private IP address and hence fails to launch.

Is there any iRules available to re-write the ICA IP address?

Thanks,

Nathan

0
Rate this Question

Answers to this Question

placeholder+image
USER ACCEPTED ANSWER & F5 ACCEPTED ANSWER

There's an entire product capability based on this. The Access Policy Manager (APM) module provides a gateway replacement and ICA patching functionality that super-simplifies a XenApp environment.

0
Comments on this Answer
Comment made 27-Feb-2014 by Nathan Andrews 83
Thanks Kevin, I only have an LTM so can this be done any other way?
0
placeholder+image
USER ACCEPTED ANSWER & F5 ACCEPTED ANSWER

Yeah. I have an iRule for that... Hold on...

Not sure whether I got the original from codeshare and then added a few bits... APM is way easier though...

You'll also need a separate VS for the ICA traffic, because you need HTTP enabled on this one, but the ICA traffic can't go through an HTTP enabled VS (Or write another iRule to detect the ICA traffic and disable HTTP processing of course)

Oh... I had to change a few bits in there on the fly (My original one actually re-wrote the SSLProxy differently)... Any syntax errors are the responsibility of the keyboard.

timing on

when CLIENT_ACCEPTED {
  #set al_debugFlag 2

  set icapHSL        [HSL::open -proto UDP -pool hsl-log-01]
  set icapLogPrefix "<190>[virtual]:ica-patch-1.2HSL:[IP::client_addr]:[TCP::client_port]:"
}

when HTTP_REQUEST {
  HSL::send $icapHSL "$icapLogPrefix: [HTTP::uri]"

  set vipHost "[HTTP::host]"
}

# catch the ICA file
when HTTP_RESPONSE {
  if { [HTTP::header Content-Type] contains "application/x-ica" } {
    HSL::send $icapHSL "$icapLogPrefix: application/x-ica Collecting [HTTP::header Content-Length]" 
    HTTP::collect [HTTP::header Content-Length]
  }
}

# and patch it
when HTTP_RESPONSE_DATA {
  # set proxy thru this VIP
  set payload [HTTP::payload]
  set vipHost "my.vs.address"

  # Wherever the SSLProxyHost exists... Re-write with the vip
  set payload [ regsub -nocase -all {^SSLProxyHost=[\w\d\.\:]+\n} $payload "SSLProxyHost=$vipHost\r\n" ]

  HTTP::respond 200 content $payload Content-Type [HTTP::header Content-Type]

  HSL::send $icapHSL "$icapLogPrefix: Patched ICA host ==> $vipHost:444"
}
0
Comments on this Answer
Comment made 27-Feb-2014 by Nathan Andrews 83
Hi Hamish, So which VIP would I need to apply this iRule to? The newly created VIP for ICA traffic or my existing VIP that is listening on 443? I currently have a VIP listening on 443 and its pool member is the Citrix Web Interface. How do I associate the ICA VIP with my current Citrix Web Interface VIP? Thanks, Nathan
0
placeholder+image
USER ACCEPTED ANSWER & F5 ACCEPTED ANSWER

It goes on the VIP that fronts the web interface.

FWIW if you go for APM, you can configure this WITHOUT the web interface servers. The APM web top includes javascript that the browser uses to build the interface o the fly from the XMLBroker information.

H

0
Comments on this Answer
Comment made 27-Feb-2014 by Nathan Andrews 83
Thanks Hamish, Would I need to change some of the parameters in RED to reflect my VIP's, Pools etc? So far I changed the following entries in your iRule: set vipHost "my.vs.address" - Changed this to reflect my ICA HTTP VIP. Pool members in this VIP are listening on ports 1494 & 2598. set icapHSL [HSL::open -proto UDP -pool hsl-log-01] - Changed pool to my Citrix Web Interface pool. Members in this pool are listening on HTTP port 80 so not sure if i need to change anything here. Please let me know if you would like to look at my VIP configurations. Thanks, Nathan
0
placeholder+image
USER ACCEPTED ANSWER & F5 ACCEPTED ANSWER

Just change the line

set vipHost "my.vs.address"

to put the FQDN of the ICA VS in there and you should be fine (You could comment out the line in HTTP_REQUEST that sets it as well... That's not actually needed (Sorry, I left a few old bits in there. I only used it for real for a few weeks).

e.g.

when HTTP_REQUEST {
  HSL::send $icapHSL "$icapLogPrefix: [HTTP::uri]"

  #set vipHost "[HTTP::host]"
}

That HTTP_REQUEST is really just debugging, it does nothing useful any more...

0
Comments on this Answer
Comment made 28-Feb-2014 by Nathan Andrews 83
Thanks Hamish, I tried this but it still doesn't proxy the ICA requests. Once connected and authenticated to the web interface I notice that the destination IP address in the launch.ica file is still pointing to the private IP address of the ICA server and this would be why I cannot launch the apps. Any ideas? Thanks, Nathan
0
placeholder+image
USER ACCEPTED ANSWER & F5 ACCEPTED ANSWER

Ahh... Sorry. I read through your emails again... I had an additional piece of kit doing the ICA proxy that we were just front ending...

Hmm... You may want to pend some $$ on APM... What you'll need to do is

  1. Adjust the iRule to insert the necessary information to use an SSL proxy for the ICA traffic. Also save the destination IP that was originally specified.
  2. Write an iRule that will recognise the ICA proxy request coming in and lookup the previously saved destination IP and use that as the pool member you dispatch to..

Which is essentially what APM does for you...

H

0
Comments on this Answer
Comment made 28-Feb-2014 by Nathan Andrews 83
Many thanks Hamish, APM is the way to go but for now I have opted to use the CSG as the ICA proxy. So essentially my Web Interface VS has the CSG as a pool member. I also had to enable SSL passthrough. All is working now. Many thanks for your help. Nathan
0
placeholder+image
USER ACCEPTED ANSWER & F5 ACCEPTED ANSWER

Hi Nathan, can you please post your complete up to date Irule that you used to integrate LTM with the Citrix solution? Thank you Marvin

0
placeholder+image
USER ACCEPTED ANSWER & F5 ACCEPTED ANSWER

I spent quite some time looking into this one and have seen multiple suggestions but here is what worked for me (using [HTTP::payload] enables you to split the stream expression to run only when a specific IP is matched other wise you can't rewrite the session reliability port this is identical in every ICA file);

Apply the following iRule to your StoreFront VIP;

when HTTP_REQUEST {
    # Disable stream profile to improve performance.
    STREAM::disable
        # Remove Accept-Encoding to prevent compression or STREAM will not work.
        HTTP::header remove "Accept-Encoding"
    set payload 0
   }
when HTTP_RESPONSE {
    # Run stream profile only when application header contains x-ica
    if { [HTTP::header value Content-Type] contains "application/x-ica" }{
    set payload [HTTP::payload]
    # Check ICA file individually so you can port map ICA and Session Reliability port.
    if { $payload contains "[INTERNAL-IP_1]:1494" }{
        STREAM::expression {@[INTERNAL-IP_1]:1494@[EXTERNAL-IP_1]:1495@@:2598@:2599@}
        STREAM::enable
        }
    elseif { $payload contains "[INTERNAL-IP_2]:1494" }{
        STREAM::expression {@[INTERNAL-IP_2]:1494@[EXTERNAL-IP_1]:1496@@:2598@:2600@}
        STREAM::enable
    } else { 
        if { $payload contains "[INTERNAL-IP_3]:1494" }{
        STREAM::expression {@[INTERNAL-IP_3]:1494@[EXTERNAL-IP_1]:1497@@:2598@:2601@}
        STREAM::enable
            }
        }
    }
}

This rule maps each internal resource server to a public IP and unique port above the standard 1494 and 2598. You can then map these ports back to the correct resource server with the following rule applied to a VIP listening on ANY port (remember to enable port translation on the VIP) with a pool defined for each resource server;

when CLIENT_ACCEPTED {
    switch -glob [TCP::local_port] {
    1495 { pool citrix-vda-1_1494_pool }
    2599 { pool citrix-vda-1_2598_pool }
    1496 { pool citrix-vda-2_1494_pool }
    2600 { pool citrix-vda-2_2598_pool }
    1497 { pool citrix-vda-3_1494_pool }
    2601 { pool citrix-vda-3_2598_pool }
    default { discard }
    }
}

This doesn't replace APM in anyway as you can't tunnel over SSL etc, but it works nicely and is scalable..

0