SSL Orchestrator Advanced Use Cases: Custom Blocking Pages
Introduction
Sometimes you just have to say 'no'. When you've had enough to eat and your mother-in-law asks if you want any more of her "famous" tuna casarole. When you find the kids trying to jump off the roof with a makeshift bed sheet parachute. When an enterprise user attempts to access an Internet resource known for malware exposure. No is sometimes the best, and perhaps only correct response. In the IT world, 'no' typically means a TCP reset, or a blocking page. If you want the user to know why something is 'no', and maybe who to call to discuss this response, then a blocking page is usually the right way to go.
F5 BIG-IP SSL Orchestrator already supports the TCP reset/drop options for policy rule decisions, but in this article I'll show you how to easily create a customizable blocking page. The below is intended for SSL Orchestrator versions 9.0 and above, but will technically work for any modern version. The only caveat for versions prior to 9.0 is that you'll need to unlock strictness on the security service object that you create, and leave it unlocked. Let's get started!
SSL Orchestrator Advanced Use Cases: Custom Blocking Pages
The basic idea is to perform the following five steps:
- Deploy a generic TAP service in SSL Orchestrator
- Create a blocking page iRule
- Modify the TAP service to perform blocking page function(s)
- Add the new blocking service to a new service chain and apply to policy conditions
- Modify the iRule as required
Step 1: Deploy a generic TAP service in SSL Orchestrator
We'll use a TAP service here to make it super-easy to add the required functionality. In the SSL Orchestrator UI, either edit an existing topology workflow, or go directly to the Services tab and click the Add button.
- MAC Address: you're not using this as an actual TAP service, so just enter a random value in MAC address format (ex. f5:f5:f5:f5:f5:f5).
- VLAN: again, not creating an actual TAP service, but you do need to select a network here. The best recommendation is to select an unused interface. If VLAN tagging is used anywhere else, you can also select one of the already-used interfaces and enter a unique unused VLAN tag.
Click the Save & Next button. You can either skip the service chain selection and do this in a separate step (below), or create a new service chain on the next screen. Whatever you do, you'll want to add this new "blocking page" service to a new service chain.
Now comes an interesting question. Do you want the other "real" security services to see your blocking page event? If you do, then you can insert those services in the new service chain as well. Make sure to position the blocking page as the last service in the service chain so that the content flows through the other services before getting to the blocking page response.
Step 2: Create a blocking page iRule
I will dig into the following iRule a little later in the article, but for now, in the BIG-IP UI under Local Traffic -> iRules -> iRule List, create a new iRule and paste the following contents:
when CLIENT_ACCEPTED {
sharedvar ctx
if { ( [info exist ctx(ptcl)] ) and ( $ctx(ptcl) starts_with "http" ) } {
HTTP::enable
} else {
HTTP::disable
}
}
when HTTP_REQUEST {
HTTP::respond 503 content "Access Blocked\r\n\r\n" "Connection" "close"
}
Step 3: Modify the TAP service to perform blocking page function(s)
Now we need to modify the TAP service to a) remove its clone pool, b) add an http profile, and c) add the above iRule. You can only get to the clone pool setting of this type of service from the command line (TMSH), so we'll do everything from there.
tmsh modify ltm virtual ssloS_blocker.app/ssloS_blocker-t-4 clone-pools none profiles add { http } rules { blocker-rule }
In the above, I assume the TAP service is called "blocker", which creates a virtual server called "ssloS_blocker.app/ssloS_blocker-t-4". It also creates a "-t-6" for TCP/IPv6, "-u-4" for UDP/IPv4, and "-u-6" for UDP/IPv6. An HTML blocking page is only going to happen for TCP traffic, so you can limit modifications to the -t-4 and -t-6 virtual servers. The above removes the clone pool, adds an http profile, and adds an iRule. I also assume here that the iRule is called "blocker-rule". Modify the virtual server and iRule names as needed.
It's worth noting again that in SSL Orchestrator 9.0 and above, there is no strictness applied to security services, so you can freely edit this object in the BIG-IP. Prior to 9.0, you need to disable the lock icon for the new TAP service before attempting to make any changes to the service. The lock will need to remain unlocked.
Step 4: Add the new blocking service to a new service chain and apply to policy conditions
You may have already created a service chain in step 1 above. Otherwise, in the SSL Orchestrator UI under the Service Chains tab, click Add and create a new service chain. The objective here is to create a NEW service chain that contains the blocking page service. If you want any of the other security services to see the blocking action, add those to the service chain as well. Just make sure the blocking page service is the last service in the service chain.
Now that you have a service chain created, you can create any necessary security policies that attach this service chain. Either edit an existing topology workflow or go directly to the Security Policies tab in the SSL Orchestrator UI. You are injecting an HTML page to the client here, and for that to be possible, you must have access to the cleartext (decrypted) traffic flow. Whatever policy rule you attach this new service chain to must also intercept TLS. When your security policy is to to your needs, (re)deploy.
Step 5: Modify the iRule as required
At this point, you should have a security policy, attached to a topology, that has at least one traffic rule that intercepts TLS and sends to your blocking page service (via service chain). The above iRule will simply respond with "Access Blocked" and close the TCP connection. You can certainly get fancier than this in the iRule as needed. For example, you could import base64-encoded images into iFiles, and then embed those directly in your HTML block page response:
when CLIENT_ACCEPTED {
sharedvar ctx
if { ( [info exist ctx(ptcl)] ) and ( $ctx(ptcl) starts_with "http" ) } {
HTTP::enable
} else {
HTTP::disable
}
}
when HTTP_REQUEST {
set img_logo [ifile get blocking_page.png.b64]
HTTP::respond 503 content "<html><body><img src=\"data:image/jpeg;base64,${img_logo}\"></body></html>" "Connection" "close"
}
You can base64-encode an image like this:
base64 blocking_page.png > blocking_page.png.b64
Then import that encoded image as an iFile. The sky is really the limit in what type of content you can send back to the user.
The code inside the CLIENT_ACCEPTED event is important to enable the underlying TAP service object to enable or disable the http filter depending on the inbound traffic type. For example, a (TCP) DNS request flowing through this service chain would need to disable http. The iRule handles this by examining the detected protocol.
Summary
And there you have it. with an iRule and just a few configuration changes we have been able to implement a capability on top of SSL Orchestrator to create custom blocking pages. This flexibility is just one of the many interesting benefits of an SSL Orchestrator solution.
Thanks!
Again great article Kevin_Stewart . Another cool direction is F5 SSLO integration with Vectra Detect as it is a normal TAP but maybe for the Vectra Detect to be able to send to F5 SSLO using API a command to block infected source or destination IP address/Domain in its policy when Vectra Detect sees bad traffic. Parnership between F5 and Vectra will go long way as played with their NDR product to see how will fit with F5 and it will work great with F5 SSLO/LTM.
My comment got posted 2 times 🙂