local traffic policy
34 TopicsSNI Routing with BIG-IP
In the previous article, The Three HTTP Routing Patterns, Lori MacVittie covers 3 methods of routing. Today we will look at Server Name Indication (SNI) routing as an additional method of routing HTTPS or any protocol that uses TLS and SNI. Using SNI we can route traffic to a destination without having to terminate the SSL connection. This enables several benefits including: Reduced number of Public IPs Simplified configuration More intelligent routing of TLS traffic Terminating SSL Connections When you havea SSL certificate and key you can perform the cryptographic actions required to encrypt traffic using TLS. This is what I refer to as “terminating the SSL connection” throughout this article. When you want to route traffic this is a chickenand an egg problem, becausefor TLS traffic you want to be able to route the traffic by being able to inspect the contents, but this normally requires being able to “terminate the SSL connection”. The goal of this article is to layer in traffic routing for TLS traffic without having to require having/knowing the original SSL certificate and key. Server Name Indication (SNI) SNI is a TLS extension that makes it possible to "share" certificates on a single IP address. This is possible due to a client using a TLS extension that requests a specific name before the server responds with a SSL certificate. Prior to SNI, the other options would be a wildcard certificate or Subject Alternative Name (SAN) that allows you to specify multiple names with a single certificate. SNI with Virtual Servers It has been possible to use SNI on F5 BIG-IP since TMOS 11.3.0. The following KB13452 outlines how it can be configured. In this scenario (from the KB article) the BIG-IP is terminating the SSL connection. Not all clients support SNI and you will always need to specify a “fallback” profile that will be used if a SNI name is not used or matched. The next example will look at how to use SNI without terminating the SSL connection. SNI Routing Occasionally you may have the need to have a hybrid configuration of terminating SSL connections on the BIG-IP and sending connections without terminating SSL. One method is to create two separate virtual servers, one for SSL connections that the BIG-IP will handle (using clientssl profile) and one that it will not handle SSL (just TCP). This works OK for a small number of backends, but does not scale well if you have many backends (run out of Public IP addresses). Using SNI Routing we can handle everything on a single virtual server / Public IP address. There are 3 methods for performing SNI Routing with BIG-IP iRule with binary scan a. Article by Colin Walker code attribute to Joel Moses b. Code Share by Stanislas Piron iRule with SSL::extensions Local Traffic Policy Option #1 is for folks that prefer complete control of the TLS protocol. It only requires the use of a TCP profile. Options #2 and #3 only require the use of a SSL persistence profile and TCP profile. SNI Routing with Local Traffic Policy We will skip option #1 and #2 in this article and look at using a Local Traffic Policy for SNI Routing. For a review of Local Traffic Policies check out the following DevCentral articles: LTM Policy Jan 2015 Simplifying Local Traffic Policies in BIG-IP 12.1 June 2016 In previous articles about Local Traffic Policiesthe focus was on routing HTTP traffic, but today we will use it to route SSL connections using SNI. In the following example, using a Local Traffic Policy named “sni_routing”, we are setting a condition on the SSL Extension “servername” and sending the traffic to a pool without terminating the SSL connection. The pool member could be another server or another BIG-IP device. The next example will forward the traffic to another virtual server that is configured with a clientssl profile. This uses VIP targeting to send traffic to another virtual server on the same device. In both examples it is important to note that the “condition”/“action” has been changed from occurring on “request” (that maps to a HTTP L7 request) to “ssl client hello”. By performing the action prior to any L7 functions occurring, we can forward the traffic without terminating the SSL connection. The previous example policy, “sni_routing”, can be attached to a Virtual Server that only has a TCP profile and SSL persistence profile. No HTTP or clientssl profile is required! This method can also be used to solve the issue of how to consolidate multiple SSL virtual servers behind a single virtual server that have different APM and/or ASM policies. This is similar to the architecture that is used by the Container Connector for Cloud Foundry; in creating a two-tier load balancing solution on a single device. Routed Correctly? TLS 1.3 has interesting proposals on how to obscure the servername (TLS in TLS?), but for now this is a useful and practical method of handling multiple SSL certs on a single IP. In the future this may still be possible as well with TLS 1.3. For example the use of a HTTP Fronting service could be a tier 1 virtual server (this is just my personal speculation, I have not tried, at the time of publishing this was still a draft proposal). In other news it has been demonstrated that a combination of using SNI and a different host header can be used for “domain fronting”. A method to enforce consistent policy (prevent domain fronting) would be to layer in additional conditions that match requested SNI servername (TLS extension) with requested HOST header (L7 HTTP header). This would help enforce that a tenant is using a certificate that is associated with their application and not “borrowing” the name and certificate that is being used by an adjacent service. We don’t think of a TLS extension as an attribute that can be used to route application traffic, but it is useful and possible on BIG-IP.24KViews0likes16CommentsThree Ways to Specify Multiple Ports on a Virtual Server
Last month, community member Racquel Mays asked for some assistance with creating a local traffic policy to apply to a virtual server to listen only on specific ports. I knew of only two obvious ways to solve that problem until fellow F5er Simon Blakely dumped a whole bowl of awesome sauce on us. In this article, I’ll cover not one way, not two ways, but also a completely new to me third way: traffic matching criteria. Before jumping into the specifics, I want to clarify something in Racquel’s question. If a virtual server is listening on port 0, then it is listening on all ports, even if you then, after the fact, filter them down to a select interesting list. For details on packets/flows in the BIG-IP system, check out my Lightboard Lesson on that. Option 1 - Use an iRule This is almost always my first thought. Mostly because I love iRules and I’m comfortable with them. But iRules aren’t always the best option, so it’s a good idea to evaluate from an operational perspective as well as performance. If both are negligible, this solution is very simple to implement, easily understood, and because of the simplicity, fairly performant when compared with the next option. ltm rule allports_irule { when CLIENT_ACCEPTED { switch [TCP::local_port] { 80 - 8080 { pool nerdlife_pool } default { reject } } } } In this iRule, when the TCP connection is established, the local port (BIG-IP side of the client connection) is evaluated and if it handled by a switch case, the pool is selected. The same pool is not required for each service but is used in this example. Any port that is not specified in the switch statement will result in a rejected TCP connection to the client. Option 2 - Use a Local Traffic Policy For a growing set of services, iRules can be retired and polices can be used in their place. They are built-in to TMOS and (unless you call Tcl from them) do not require the Tcl interpreter and thus will likely be more performant. However, if you have to split functionality between iRules and policies on a single application service, my preference is to keep the logic in one place so operational complexity is reduced. ltm policy allports_policy { controls { forwarding } requires { tcp } rules { tcp-80 { actions { 0 { forward client-accepted select pool nerdlife_pool } } conditions { 0 { tcp client-accepted port local values { 80 } } } } tcp-8080 { actions { 0 { forward client-accepted select pool nerdlife_pool } } conditions { 0 { tcp client-accepted port local values { 8080 } } } ordinal 1 } tcp-all-else { actions { 0 { shutdown client-accepted connection } } conditions { 0 { tcp client-accepted port local not values { 80 8080 } } } ordinal 2 } } status published strategy first-match } The policy is a tad verbose, no? This is due to the hierarchical nature of policies, having the policy root details like publications status and matching strategy, and then the rules for conditions and actions. Here in the text it’s easy to spot the condition of the local TCP port, but in the GUI, you have to select that in a hidden options menu. That got me for a hot minute while trying to make the policy work. In any event, options one and two are functionally equivalent when applied to a virtual server listening on port 0 with a TCP profile applied, so either approach is a good option depending on your business and technical standards for how BIG-IP objects are used. Option 3 - Traffic Matching Criteria I wanted to write the article when Simon shared this solution so I could be cool by saying “I was today years old when I learned you could do this” but alas, priorities! In this solution, there are two differences in this approach from the other two: multiple addresses as well as multiple ports are supported, so you can scale without requiring configuring additional virtuals there is no way in the criteria to map service port -> pool, so if you need that beyond a default pool in the virtual config, you're going to need an iRule or policy anyway You can find and create address and port lists in the GUI under Main->Shared Objects. I started my work in tmsh for this article and the lists are in the tmsh /net namespace, so I had to hunt for these as I was looking for them in the GUI’s Network section. You’ll need those to create your own traffic-matching-criteria object, but you can’t do that directly in the GUI. It is done on your behalf when you specify the lists in the creation of a virtual server. This will create this traffic-matching-criteria object in tmsh: ltm traffic-matching-criteria vip3_tmc_VS_TMC_OBJ { destination-address-inline 0.0.0.0 destination-address-list dal1 destination-port-list dpl1 protocol tcp source-address-inline 0.0.0.0 } It appends _VS_TMC_OBJ to the virtual server name as the object name it creates. The GUI also specifies the destination-address-inline and source-address-inline arguments, but I didn't need those in my object for it to work. That said, if the GUI selects them, there's probably a good reason so maybe default there as well and adjust as necessary in testing. Do It Yourself You already have the iRule and policy you need to test in your own lab above, now all you need are the other the virtual servers for options one and two and then the lists, traffic-matching-criteria, and virtual for option three. You can create all those with the tmsh commands below. My client-side lab network is 192.168.102.0/24 and I have a working pool (nerdlife_pool) on the server-side. You’ll need to swap those values out for your environment. # With iRule - Address 192.168.102.61 # tmsh create ltm virtual vip1_irule destination 192.168.102.61:0 ip-protocol tcp profiles add { http { } tcp { } } rules { allports_irule } source-address-translation { type automap } # With Policy - Address 192.168.102.62 # tmsh create ltm virtual vip2_policy destination 192.168.102.62:0 ip-protocol tcp profiles add { http { } tcp { } } policies add { allports_policy { } } source-address-translation { type automap } # With Matching Criteria - Address 192.168.102.63 # # If you do this in the GUI, it creates the traffic-matching-criteria for you, but no control of naming or modification that way tmsh create /net address-list dal1 addresses add { 192.168.102.63 } tmsh create /net port-list dpl1 ports add { 80 8080 } tmsh create /ltm traffic-matching-criteria tmc1 protocol tcp destination-address-list dal1 destination-port-list dpl1 tmsh create /ltm virtual vip3_tmc ip-protocol tcp traffic-matching-criteria tmc1 source-address-translation { type automap } pool nerdlife_pool profiles add { tcp http } You should now have three virtual servers with like functionality. Test Results Now that everything is configured, let’s test it out! We’ll test the two ports we want to answer, 80 and 8080, and then a third port we don’t, 8081. We should get an “achievement: unlocked” on the first two and a connection reset on the third. # Test results - iRule rahm@FLD-ML-00029232 ~ % curl http://192.168.102.61/a achievement: unlocked rahm@FLD-ML-00029232 ~ % curl http://192.168.102.61:8080/a achievement: unlocked rahm@FLD-ML-00029232 ~ % curl http://192.168.102.61:8081/a curl: (56) Recv failure: Connection reset by peer # Test results - Policy rahm@FLD-ML-00029232 ~ % curl http://192.168.102.62/a achievement: unlocked rahm@FLD-ML-00029232 ~ % curl http://192.168.102.62:8080/a achievement: unlocked rahm@FLD-ML-00029232 ~ % curl http://192.168.102.62:8081/a curl: (56) Recv failure: Connection reset by peer Test results - TMC rahm@FLD-ML-00029232 ~ % curl http://192.168.102.63/a achievement: unlocked rahm@FLD-ML-00029232 ~ % curl http://192.168.102.63:8080/a achievement: unlocked rahm@FLD-ML-00029232 ~ % curl http://192.168.102.63:8081/a curl: (7) Failed to connect to 192.168.102.63 port 8081: Connection refused The traffic-matching-criteria virtual didn't reset like the other two explicitly configured to do so, but it did refuse the connection all the same. I couldn't walk away from that without understanding why so I fired up Wireshark and took a tcpdump capture to investigate. What’s happening here is that with the iRule and policy solutions, we are acting at the CLIENT_ACCEPTED event, which means the TCP session has already been established and the HTTP request is in flight. So you see two TCP resets for each of the curl requests to 192.168.102.61:8081 and 192.168.102.62:8081, the first to the rejected TCP port, and the second to the HTTP request, which because it was already in flight, arrived even before the first TCP reset was sent. With the traffic-matching-criteria solution, it’s all wrapped up before a connection is even established so only the one reset message. That results in greaterefficiency with local resources. Conclusion I say this a lot but I’m always excited to learn new things, particularly new ways of doing something I’ve done differently for years. If you’ve ever watched a master craftsman work, they have their favorite tools, but they have specialty tools as well for situations that call for it. I liken discoveries like this to that scenario. I’m not sure how many use cases I’d find for the traffic-matching-criteria that wouldn’t also rely on a policy and/or iRule, but I’m happy to now know that it exists just in case. How many of you knew about this and didn’t tell me? Drop me a comment below!9.5KViews0likes5CommentsF5 Local traffic policy / wrong requirement!
Hi, I worked on a customer deployment where we wanted to create a virtual server to dispatch HTTPS requests to internal virtual servers based on Host header. In version 13.0, there is a condition ssl-extension server-name .I thought Great, I can create the main VS without HTTP profile and filter based SNI extension So I tried to create a ltm policy with rules like: condition : Server name equals "mysite1.company.com" action : forward virtual server VS-mysite1.company.com And tried to assign it to the VS with only ClientSSL profile. I can't because of policy requirements... When I looked in policy configuration in tmsh, the policy requires http ssl-persistence which is weird when I look the rule configuration. In versions 11.X, this configuration was manual but starting with version 12, this is created automatically when selecting rule conditions and actions. I didn't checked if the requirements selected is also wrong in v12. I so tried to create a policy and looked the generated configuration in TMSH policy without rule ltm policy Drafts/bug_policy_requires { last-modified 2017-08-28:18:36:02 status draft strategy first-match } Policy with one rule assigning pool without condition ltm policy Drafts/bug_policy_requires { controls { forwarding } last-modified 2017-08-28:18:37:17 requires { http } rules { rule_no_condition { actions { 0 { forward select pool Pool_icap } } } } status draft strategy first-match } what configuration in this rule requires http ??? Policy with one rule assigning pool and with SNI condition ltm policy Drafts/bug_policy_requires { controls { forwarding } last-modified 2017-08-28:18:38:20 requires { http ssl-persistence } rules { rule_condition_sni { actions { 0 { forward select pool pool_ad_http } } conditions { 0 { ssl-extension ssl-client-hello server-name values { test.company.com } } } ordinal 1 } rule_no_condition { actions { 0 { forward select pool Pool_icap } } } } status draft strategy first-match } Why ssl-persistence and not client-ssl condition which may be the best requirement?434Views0likes3CommentsTraffic policy not evaluating TCL commands
I've setup a traffic policy to check if a header exists and if it doesn't then to add it. That bit of the logic works however it doesn't add what I need it to - it basically doesn't evaluate the tcl command I put in. I've tried it using with and without quotes and basically the output I get into the XFF header is the string so either "tcl:[IP::client_addr]" or just tcl:[IP::client_addr] actions { 0 { http-header replace name X-Forwarded-for value \"tcl:[IP::client_addr]\" } or actions { 0 { http-header replace name X-Forwarded-for value tcl:[IP::client_addr] } There are good reasons why I am not using the standard Insert XFF in the HTTP profile and whilst it could easily be done by an iRule I really need this to work, as it should do, in a traffic policy. I am running 11.5.1 HF7557Views0likes2CommentsComplex Irule transform to local traffic policy which is with the substring.
I'm trying to convert this below Complex irule to a local traffic policy.I'm facing problem at converting that substring. Can anyone help me. elseif { $http_uri starts_with "/servicecenter/servicerequest"} { set http_uri_suffix [substr $http_uri 14] HTTP::uri "$http_uri_suffix" SSL::disable serverside HTTP::redirect "https://www.xyz.com[HTTP::uri]"198Views0likes1CommentLocal Traffic Policy for complex URI transform; order of eval relative to iRules
New to 11.4, and getting my hands around Local Traffic Policies. I have a scenario in which I evaluate starts-with against the URI, and depending on value, select a pool. But for certain URIs, I also change the URI in a non-trivial manner. For example: when HTTP_REQUEST { if {[HTTP::uri] starts_with "/MP"} { pool pool1 } elseif {[HTTP::uri] starts_with "/MA/2.00"} { HTTP::uri [string map {"/MA/2.00" "/MA"} [HTTP::uri]] pool pool2 } } First – how do I do that URI transformation with a Policy? Target: http-uri has parameters of path, query-string and value. Can I just select “value” and add “[string map {"/MA/2.00" "/MA"} [HTTP::uri]]”? I mean, does an action get evaluated that way, such that you can use TCL string functions and data class references? As an alternative, I considered using the Policy to select a pool (easy to do), and leaving the URI transform as a smaller, simpler iRule – but which gets run first, the Policy or the iRules? If the iRule went first, it would prevent to Policy "URI starts-with" condition from being met, because the URI would have been changed to not match, and no pool would get selected. Sorry if this kind of thing is clarified somewhere – I couldn’t find it if so.273Views0likes3CommentsProblema policy forward url to pool
hello people, I'm having trouble using URL to forward specific policy pool. follows the configuration: ----------Policy---------- Name: rewrite_extranet_ssl Configuration: forward_pool_portaleconomiario http-host all equals test.extranet.box http-uri all equals /Portalonline forward select pool /Common/Pool_Portalonline ----------Virtual Server ltm virtual vs_extranet_ssl { destination 192.168.100.130:https ip-protocol tcp mask 255.255.255.255 persist { source_addr { default yes } } policies { rewrite_extranet_ssl } pool Pool_Extranet profiles { box_extranet_ssl { context clientside } http_with_redirect_rewrite { } rewrite_extranet_ssl { } stream { } tcp { } } rules {} source 0.0.0.0/0 source-address-translation { type automap } vs-index 1576 } Turns out he is not headed for the pool specified in the policy but for the VS default pool Any idea?218Views0likes0Commentslocal traffic policy http-header insert action
Hi! BIG-IP 11.4 introduces new feature called Local Traffic Policies. Could you please help with the question if it is possible to use iRules commands inside local traffic policies? I want use logic like represented below. Insert specific header with IP address value. policy_rule_1 { actions { 0 { http-header insert name My-Header-Client-IP value [IP::client_addr] } } conditions { none } }367Views0likes12CommentsHelp with Local Traffic Policy with streaming app. and basic understanding.
This is a homelab to have a better understanding of F5 BIG-IP and appercaite any help. For testing purpose I have setup a PLEX server for streaming service and will be setting up a Horizon View UAGs. I only have one public IP address and thanks to others I have setup a external VIP using a local traffic policy. I am running into couple issues with the policy. I have been doing a lot of reading but still missing something.I created a local traffic policy that matches "HTTP Host to abc.domain.com" that points to a virtual server for PLEX. If the VS is set to use the policy PLEX works via the web interface and the macOS apps works however using PLEX iOS/iPadOS app fails. It does not connect back. I have changed "forward traffic to pool and node" and still same problem. If I change the resourse setting to use "default pool" to the PLEX pool and remove the policy. The app works. I have done a tcpdump on F5 as well proxy capture of an iOS device and cipher suite are correct. I have looked at the ltm log but not seeing any errors. I have made multiple changes with SSL Profile on client/server but no luck. Any suggestions what would cause the app not to work using policy but works when default pool is set? What other troubleshooting should I look at?Solved1.6KViews0likes5CommentsHTTPS passthrough for a single domain name
Hi Everyone, I have 1x HTTPS virtual server hosting multiple applications/ domain names (e.g. X.com, Y.com, Z.com, etc.) it is configured with SSL Bridging mode (both VS and pool members are 443). My question is if I want a specific domain nameY.comto be handled as SSL passthrough wherecertificate is terminated on the backend servers. Meaning if domain name isY.comthe traffic will not be inspected, and HTTP, clientssl, and serverssl profiles must disable in this case. Not sure if this could be implemented, but any idea would be highly appreciated. Thank you.1.4KViews0likes9Comments