The Power of Source Address

Way back in TMOS v11.3, the “Source Address” field was added to the configurable items on a Virtual Server.  As you probably know, the Source Address specifies an IP address or network from which the Virtual Server accepts traffic. The Virtual Server accepts connections only from one of these IP addresses. You don’t have to use this setting (you can just leave it blank to accept traffic from any address).  For this setting to function effectively, you should specify a value other than 0.0.0.0/0 or ::/0 (that is, any/0, any6/0).  In order to maximize the utility of this setting, you should be as specific as possible while covering all customer addresses but eliminating all others.  The IP addresses are listed in Classless Inter-Domain Routing (CIDR) format: address/prefix, where the prefix length is in bits.  For example, IPv4 addresses will look like this: 10.0.0.1/32 or 10.0.0.0/24, and IPv6 addresses will look like this: ffe1::0020/64 or 2001:ed8:77b5:2:10:10:100:42/64.  You specify the Source Address when you create the Virtual Server (screenshot below).

This setting seems to have been put in place to assist Carrier-Grade Network Address Translation (CGNAT), but it can be used in some very interesting and powerful ways outside of CGNAT.

I had the pleasure of attending a Tech Summit for F5, and one of the speakers (Don Flinspach) gave an amazing talk where he encouraged everyone to “Think Inside the Box” of the F5 BIG-IP.  The essence of his talk centered around the fact that, while sometimes features are added to the BIG-IP for specific reasons, it’s productive to think about the actual functionality of those features and use them in other creative and powerful ways.  And, frankly, this is true for any feature in the BIG-IP…while it might have been created for one thing, it can (and should) be used in all sorts of creative ways.  In this article, we will look at Source Address.

Virtual Server Precedence

As I mentioned before, Source Address looks at the incoming address of the client that sent the request, and, if the address matches, then the client is allowed access to that Virtual Server.  Of course, there are many scenarios where a client will send a request destined to arrive at a Virtual Server, but more than one Virtual Servers have that same destination address (and possibly even the same port).  TMOS has a series of precedence levels that are used to determine which Virtual Server will serve the connection.   The table below lists the order of precedence for Virtual Server connections.

Also, here’s a video that explains the precedence in a little more detail:  https://www.youtube.com/watch?v=i0Ggz2w19Xc

And, here's a link to support article K14800 on Virtual Server precedence:  Order of precedence for virtual server matching (11.3.0 and later)

Creative Ways to Use Source Address

One way to use source address is to create a more specific Virtual Server which can be used to simplify a configuration (possibly eliminate iRules or LTM Policies that select/reject traffic).  As Don points out, creating a more specific Virtual Server might require a little more initial planning, but the Virtual Server elements are easier to move around than iRules and policies. 

Another creative way to use Source Address is for troubleshooting assistance.  You can simply create an identical virtual server to the one under investigation, but limit the Source Address to a test client’s address or test clients’ range of addresses.  Changes can even be made to that newly-created Virtual Server while the production virtual server remains in place.  This can also be used in orchestration.

Finally, you can use the Source Address field for the alternative configuration of a “global SNAT” as a Virtual Server.  A fellow F5’er once said: “There’s no good reason not to do this (the configuration burden is about identical, plus it’s easier to troubleshoot).”  In the simplest form, create a 0.0.0.0 Virtual Server Destination Address with a Source Address of the SNAT origin and a SNAT pool of the new address.  Here’s a sample configuration:

ltm virtual NAT_192.0.2.1_TO_10.0.2.1 {

destination 0.0.0.0:0

ip-forward

source 192.0.2.1/32

source-address-translation {

pool 10.0.2.1

type snat

}

translate-address disabled

translate-port disabled

}

ltm snatpool 10.0.2.1 {

members {

10.0.2.1

}

}

If you ask Don, this is actually The Right Way To Do It. Here are his reasons (and these have all happened to customers around the world):

1. If a SNAT is in place, the Origin IP address is always translated, even when that IP address is connecting to a virtual server. For example, take a simple configuration where the origin IP 192.0.2.1 is to be translated to 10.0.2.1. This is usually fine until 192.0.2.1 tries to connect to a virtual server (e.g., 192.0.3.1:80).

    • The pool member may accept the translation address in the SNAT (10.0.2.1), but only if the pool member allows/accepts communication on that network.
    • If the first reason doesn’t apply (e.g., the pool members are on another VLAN using, for example, the network of self IP 11.0.2.1/24), the traffic will break just for that one client. While it’s pretty easy to figure out why, most customers feel they’re painted into a corner. It’s often unclear how to get that address “changed back” or “changed to” what they need it to be.
    • If you implement SNAT as a virtual server, it follows all the virtual server precedence rules, so for connections from 192.0.2.1 → 192.0.3.1:80, BIG-IP uses 11.0.2.1 to connect to the pool member, otherwise the translation occurs through the SNAT virtual server, becoming 10.0.2.1.

2.  If a NAT/SNAT is in place, only the Origin IP address is translated, and the BIG-IP might then otherwise attempt to route untranslated traffic. For example, let’s take the same simple configuration from above: origin IP 192.0.2.1 is to be translated to 10.0.2.1. If 192.0.2.2 attempts to connect to/through BIG-IP, different things may occur:

    • 192.0.2.2 is not allowed to connect because of some firewall rule or configuration, often external to BIG-IP. This might be the best case.
    • 192.0.2.2 connects to BIG-IP and is routed to a destination.
      • The destination has a return route. This allows 192.0.2.2 to use the service when it probably shouldn’t.
      • The destination has no return route. The traffic is discarded, but that server is susceptible to SYN floods or other connections it should likely never see.
      • The destination is a router that returns the untranslated traffic—either directly or indirectly—to the BIG-IP. A routing loop occurs.
    • If you implement SNAT as a virtual server, only traffic that matches the source will be accepted. All other traffic will be rejected.

While this is not an exhaustive list of all the ways to use Source Address, I hope this at least sparks a bit of excitement for some creative ways to use the power and flexibility of the BIG-IP.  Feel free to comment below on some other ways to “Think Inside the Box” and get creative with all the features of the BIG-IP!

Updated Jun 06, 2023
Version 2.0

Was this article helpful?

3 Comments

  • In addition to ".. a video that explains the precedence in a little more detail:", a hyperlink to K14800?

     

  • Hi John,

     

    As usual very interesting article, never considered using VS with Source Address set instead of SNAT (anyway I am trying to avoid SNAT or NAT at all).

     

    Just curious - is that possible to enter more than one subnet in Source Address - I am pretty sure it's not possible but just to be sure. If not why it was implemented like that - being able to add non contiguous IP ranges would be nice.

     

    I guess only way to do that is:

     

    • iRule
    • Local Traffic Policy
    • AFM rule or policy

    Piotr