Forum Discussion

keith_varga_107's avatar
keith_varga_107
Icon for Nimbostratus rankNimbostratus
Apr 11, 2013

self aware irules from IIS settings

DevCentral Team,

 

Currently, we run 32bit 10.2.3 version of F5.

 

Have 100+ websites in IIS on windows 2008R2, each assigned their own custom host headers and separate internal IP that NAT to their own external IP. For example:

 

IIS Site 1:

 

internal IP: 10.33.145.21

 

external IP: 192.147.20.60

 

host headers:

 

something1.domainA.com

 

something2.domainA.com

 

IIS Site 2:

 

internal IP: 10.33.145.22

 

external IP: 192.147.20.61

 

host headers:

 

something1.domainB.com

 

something2.domainB.com

 

etc... (up to 100+ sites...)

 

 

The customer can add more host headers to IIS programmatically through their website.

 

For example, IIS site 2 can add something3.domainB.com to the IIS host headers.

 

We don't want to have to burn an external IP address for each 1 to 1 NAT for each site, and want to instead have one external IP that redirects the user via an irule to the correct internal IP based on the host header.

 

And, of course, we don't want to alter the irule by hand.

 

Question:

 

Is there a best practice method for automatically detecting a new addition in IIS host headers for any of the given sites, and then automatically updating the irule for that new host header to point to the corresponding internal IP?

 

 

thanks much,

 

Keith Varga

 

10 Replies

  • I like to think that there are a hundred ways to do anything on a BIG-IP, but in this case I can only think of one that isn't unnecessarily complex. So for simplicity sake:

    Create a data group (file-based or internal doesn't really matter) and assign each host header value to a server node and port.

    Ex. (host_header_datagroup)

    something1.domaina.com := 10.33.145.21:80

    something2.domaina.com := 10.33.145.21:80

    something1.domainb.com := 10.33.145.22:80

    something2.domainb.com := 10.33.145.22:80

    Create a virtual server using just one of the external IPs and apply this iRule (and other required profiles):

    
    when HTTP_REQUEST {
         if { [class match [string tolower [HTTP::host]] equals host_header_datagroup] } {
              node [class match -value [string tolower [HTTP::host]] equals host_header_datagroup]
         } else {
              HTTP::respond 200 content "no such service"
         }
    }
    

    So what happens is that the client's request (host name) is looked up in a data group list, and if it exists the traffic is forwarded to the corresponding node and port. By the way, the ProxyPass iRule will do the same thing but also control SNATs and Host headers.

    Now for the fun part - updating the data group. My best suggest here is to have the customer add an iControl call into their website provisioning script that calls out to the BIG-IP and writes to the data group. That is by far the cleanest and simplest approach I can think of.

  • Just to add to this, here's an example TMSH command line to add a new entry to an internal data group:

     

     

    tmsh modify ltm data-group internal host_header_datagroup records add { something6.domaina.com { data 10.70.0.6:80 } }
  • Thanks very much Kevin! I'll take this back to our team, and see what we can do!

     

     

    thanks again,

     

    Keith
  • We had one more question on this one. We have a pair of F5 Load Balancers that are running active / secondary. If we programatically are updating the datagroup on the primary unit, is there any way to update sync the changes to the secondary unit?

     

    Or, is best practice to connect to each one, and write to both of them with separate commands?

     

     

    thanks again!

     

    -Keith
  • Internal datagroups are contained within the bigip.conf config file, so they are automatically synced when the boxes are synced. External classes are external files that are defined in the bigip.conf config file. A file called "cs.dat" defines which folders in the filesystem get synchronized between peers, and the folder where you traditional put external datagroup files, /var/class, is on that list.

     

     

    By the way, the tmsh command I gave you was for internal datagroups. Manipulating external datagroups is a little different.
  • thanks again Kevin! You're a great help! What the bosses are worried about is that a bunch of datagroups are added w/ the (icontrol or tmsh, etc) automation to the primary unit. And, if the primary goes down (knock on wood), the changes were never synced to the standby, leaving us without the needed changes. Is there a best practice method for programmatically keeping them in sync? The bosses said they're not opposed to auto syncing every hour if that is a good solution to this one. We just don't want to sync them by hand if there's new datagroup values being added every hour for instance.

     

  • It's perfectly reasonable to programmatically update the data groups on both devices, as long as you understand that one of the data groups will be rewritten when you perform an actual sync of the two boxes.
  • thanks again Kevin! Now another questions has popped up. Is there a good way to lock down the user that will access the F5, so that they only have access to edit that single data group?
  • That's where partitions come in. If you create your objects in administrative partitions, then assign users to those administrative partitions, they can only edit the objects created within those partitions. At a minimum a use needs the "Application Editor" role to be able to edit internal data group values from the shell.