Forum Discussion

Andi_102219's avatar
Andi_102219
Icon for Nimbostratus rankNimbostratus
Apr 14, 2011

Kerberos for web proxy clients

Hi folks,

 

I want to authenticate my web proxy clients with Kerberos as they are using primarily NTLM and that's producing too much overhead in my network and on the DCs.

 

All the clients are using the same equal proxy pac and the proxy DNS name which is returned is balanced over two sites by GTM. GTM returns the virtual IP of each sites LTM.

 

The DNS domain which is hosted on the GTM is different to my active directory domain.

 

So the clients are talking to proxy.gtm-domain.net:

 

This name can't be registered as SPN in active directory to each proxy in the backend as it has to be unique.

 

Each proxy in the backend (ISA 2006) is joined to the our AD and has a default SPN registered like HTTP/proxy12.ad-domain.net

 

 

My concern is now, how do I get Kerberos to work as the virtual GTM name can't be used/registered as SPN?

 

 

Today the clients which can talk Kerberos are searching the AD for the SPN HTTP/proxy.gtm-domain.net but that can't work as there is no SPN registered.

 

The ISA 2006 service on the machines can't be started with an AD account where I could register the SPN on.

 

 

My idea is now that the LTM on each site has an iRule which can tell the client to request the SPN for the returned backend server.

 

F.e.:

 

- client makes a request to http://www.google.com and sends it to proxy.gtm-domain.net

 

- GTM balances to the closest site

 

- LTM of the site balance the request to a backend server proxy12.ad-domain.net

 

- backend proxy returns HTTP status 407 authentication required (Negogiate, Keberos, NTLM)

 

- client makes Kerberos authentcation with the SPN HTTP/proxy12.ad-domain.net instead of the not existing SPN HTTP/proxy.gtm-domain.net

 

 

Is that possible? Can that be done with an iRule? Other ideas?

 

 

Many thanks,

 

Andreas

 

  • Unless "gtm-domain.net" is a domain identifier for another AD domain that's trusted by your main "ad-domain.net" zone, then no. The client will only request a Kerberos ticket for zones that he can resolve a KDC for -- if you don't have a Kerberos TGT server in that domain or the domain your ISA servers are unaware of a trust to the other domain, this won't work. I also don't think that Windows browsers will "follow" the CNAME DNS lookups returned by a query for "proxy.gtm-domain.net". They'll tend to want to request the SPN that's been configured for them in the proxy settings or learned via PAC. Any reason you can't add an NS record somewhere in ad-domain.net pointed to the GTM for, say "proxy.ad-domain.net"?

     

     

    That may be a moot point, anyway, as I've got a sneaking suspicion here that maybe what you need is a to simply create a PAC file that selects the proxy based on network location and the proxy that it points to will be the name registered to the regional proxy in ad-domain.net. In fact, you could potentially use an iRule to build a custom PAC file to feed out to each individual user based on Geolocationing iRule calls and bypass the whole GTM thing altogether.
  • I don't know exactly how you're splitting things with GTM (topology or geolocationing), but here's an example of sending out a "customized" PAC file based on an Address datagroup match:

    when RULE_INIT {
    
     Set the contents of the PAC file to be delivered. Setting
     specific logic here is fine, although the "localized" proxy
     should be returned using the $selected_proxy variable... this
     variable will be filled in at the time the file is delivered
     with the value learned from the DataGroup.
    
    set static::pacfile {
    function FindProxyForURL(url, host) {
    
    if (isPlainHostName(host))
    return "DIRECT";
    
    return "$selected_proxy";
    }
    }
    }
    
    when CLIENT_ACCEPTED {
    
     Create a DataGroup class called "proxy_regions" and populate it with
     the IP networks and their proxy value assignments:
    
     "10.0.0.0/8" := "proxy12.ad-domain.net:8080"
    
    if { [class match [IP::client_addr] eq proxy_regions] } {
    set selected_proxy "[class match -value [IP::client_addr] eq proxy_regions]"
    } else {
    set selected_proxy "DIRECT"
    }
    }
    
    when HTTP_REQUEST {
    
     Return any request for "proxy.pac" with the determined content and the
     correct Content-Type.
    
    switch [string tolower [HTTP::uri]] {
    "/proxy.pac" {
    HTTP::respond 200 content [subst $static::pacfile] "Content-Type" "application/x-ns-proxy-autoconfig" "Pragma" "no-cache"
    }
    }
    }  

    The data group created would look a little like this:

    Name: proxy_regions
    Type: Address
    "10.0.0.0/255.0.0.0" := "proxy12.ad-domain.net:8080"
    ..etc..
    "10.10.0.0/255.255.255.0" := "proxy13.ad-domain.net:8080"

    So if the user's IP is 10.0.1.13, he'd go via proxy12, but if it was 10.10.0.244, he'd go to proxy13. This works fine for RFC-1918 networks; if you're looking to do the same based on geolocationing and public IP addresses, that'd be possible too -- just use whereis.
  • I'm splitting in GTM with QoS (RTT) not region based. It's just with the network stats of the LDNS.

     

    Thanks for your idea.

     

     

    I think the impossible circumstance I have is to not loose a current functionality. Sure I can return

     

    a direct proxy name to make Kerberos possible but I'll lose LTM functionality.

     

     

    The only option I see is to influence it on my LTMs. I have the servers which are generating the proxy

     

    pac file for the clients also behind the LTMs. Same network as my proxies. I'm thinking about a way

     

    to tell the client to make Kerberos with the assigned proxy DNS name from LTM. But I stuck how I

     

    can do that without losing LTM capabilities.
  • Are you using ROUTE::rtt or TCP::rtt in a GTM iRule to do that? Because you could still do that with connections arriving at the LTM for a PAC file, and it might even be more precise because you'd be assessing RTT of the actual client rather than the LDNS. Is there any way you can post some of your configs in an anonymized way? I think we might be able to do this without losing -- but possibly improving -- functionality.
  • No I don't use an iRule on the GTM. Here the wideIP and pool from the config of my GTM:

    wideip {
       name         "proxyfarm.gtm-domain.net"
       partition "Common"
       pool         "proxyfarm-global"
    }
    
    pool {
       name           "proxyfarm-global"
       ttl            30
       preferred      rtt
       alternate      packet_rate
       fallback       qos
       partition "Common"
    
       member         ltm-site1:84
       member         ltm-site2:84
    }
    
    Same is configured for the proxy pac servers. I have a Wide IP proxyconf.gtm-domain.net which is balancing with the same method to my LTMs.

    Here some parts from my LTM config:

    virtual proxy-uba {
       pool proxy-uba
       destination V-IP:84
       ip protocol tcp
       profiles fastL4
       persist source_addr
    }
    pool proxy-uba {
       lb method least conn
       action on svcdown reselect
       monitor all isa_85
       members
          member1:85
          member2:85
          member3:85
          member4:85
          member5:85
          member6:85
          member7:85
    }
    
    virtual proxyconf.gtm-domain.net {
       pool proxyconf
       destination V-IP:http
       ip protocol tcp
    }
    pool proxyconf {
       lb method least conn
       action on svcdown reselect
       monitor all proxyconf_84
       members
          member1:84
          member2:84
    }
     

    Please let me know if you have an idea or need further details.

    Maybe there is a chance/way to create an iRule on the LTMs to make Kerberos authentication possible as the clients

    are passing the LTMs for fetching the PAC file and getting to the Internet over the proxies.
  • I think you may still be able to do this by distributing a PAC file from your proxyconf.gtm-domain.net VS directly (using something like the iRule I posted above), but determining which proxy name to hand out based on some sort of logic within the iRule. Think about this: with GTM, you're basing your returned IP on your knowledge of things about the user's _resolver_, not where the user actually is. If you change the proxy host that a user gets when you're generating the PAC file for the user, then you've got the actual USER connecting over a TCP connection coming in -- you can localize both the user's address _and_ whatever you can get from their TCP session to select the best proxy for them.

     

     

    It'd suggest combining logic like the iRule above on your proxyconf.gtm-domain.net VS with "TCP::rtt". Then you can hand out proxy hostnames that match your Kerberos SPNs for the proxies that are already working, while at the same time maintaining a "closest-to-the-user" approach. As a side benefit, you don't need any pool members attached to the proxyconf VS, as it'll all come out of an iRule. Yes, this moves you away from using GTM's "QoS" functions, but there's a lot more you can do from a load-balancing perspective if you can deal with a user directly as opposed to dealing with their LDNS.
  • Ok, but if I understand you correctly you'd setup this iRule on the GTM, right? Or do you mean by VS the virtual IP for my proxyconf on the LTMs?

     

     

    I stuck a little bit with the idea to return a fixed proxy name to the client as I'm afraid to loose the balancing of my proxies in the backend.

     

    If some proxy becomes unavailable or I have to force it down (for maintenance or whatever) how do I establish to route the clients to a different system?
  • Andi: The iRule would go on the VS for the proxyconf at the LTMs; essentially, instead of feeding out a PAC file from the servers, you'd have the LTM generate one for you for each user based on that user's location.

    If you want to enable a failover capability, then it's possible to do that with individual proxies via the PAC file. When returning the proxy servers, you can return several PROXY statements in the return statement of a PAC file's JS method, and the browser's behavior is to attempt a connection to each proxy in sequence. If a proxy becomes unavailable, the browser client will simply move to the next one in the list. For IE, for example, it will try the first proxy and move on to the next after not getting a response in just over a second. Here's an example:

    return "PROXY proxy1.domain.com:8080; PROXY proxy2.domain.com:8080; PROXY proxy3.domain.com:8080"
    This would require modifying the iRule a bit to hand out a list of regional proxies rather than a single name, but it's doable. You could then force down a proxy anytime you like and your browser clients on that proxy would migrate to the next in the list. You would ensure proper load distribution by dividing the user population up by network -- then set their primary proxy to be the closest regional one, failing over to the next closest, and the next.

    It's an approach that would require a little forethought and planning, but in the end analysis, I'd be willing to bet it'd be more precise than GTM for this purpose.