irule
676 TopicsIs it possible to select ASM BoT profile from irule?
Hi. . Is it possible to select BoT profile from irule? . Concept is we have different set of IP which need to allow "some" BoT type. That why we can't use whitelist IP in BoT profile because it will allow all BoT type. So We want to use iRule to check if it IP A > use BoT profile which have some exception, but if all other IP > use normally BoT profile. . when HTTP_REQUEST { # Check IP and select BoT profile from that if { [IP::client_addr] eq "A" } { ASM::enable allow_some_bot_profile } else { ASM::enable normally_bot_profile } } ps. I didn't see any document about how to select BoT profile. So I'm not sure if ASM::enable can do that.48Views0likes3CommentsBest approach to serve maintenance page
Hi, We need to put website under maintenance for about 6 hours. Traffic flow: Clients -->Akamai--->F5-->Backend servers. We have maintenance page hosted in AWS cloud Front. which approach is better? DNS Change – Temporarily point our domain (via CNAME) to CloudFront by adjusting the TTL to 2 minutes. F5 Configuration – Issue a 302 redirect from F5 to CloudFront or forward (reverse proxy) traffic from F5 to CloudFront by modifying the Host header. This keeps the browser on our domain and returns a 200 OK. Main concerns : Avoiding browser/edge caching issues (we can clear Akamai cache if needed). Ensuring a quick rollback after maintenance. Which approach would be best? Could you advise on the correct implementation?105Views0likes4CommentsTrigger js challenge/Captcha for ip reputation/ip intelligence categories
Problem solved by this Code Snippet Because some ISP or cloud providers do not monitor their users a lot of times client ip addresses are marked as "spam sources" or "windows exploits" and as the ip addresses are dynamic and after time a legitimate user can use this ip addresses the categories are often stopped in the IP intelligence profile or under the ASM/AWAF policy. This usually happens in Public Clouds that do not monitor what their users do and the IP gets marked as bad then another good user after a day or two has this ip address and this causes the issue. For many of my clients I had to stop the ip reputation/ip intelligence category "spam sources" and in some cases "windows exploits" so having a javascript/captcha checks seems a nice compromise 😎 To still make use of this categories the users coming from those ip addresses can be forced to solve captcha checks or at least to be checked for javascript support! How to use this Code Snippet Have AWAF/ASM and ip intelligence licensed Add AWAF/ASM policy with irule support option (by default not enabled under the policy) or/and Bot profile under the Virtual server Optionally add IP intelligence profile or enable the Ip intelligence under the WAF policy without the categories that cause a lot of false positives, Add the irule and if needed modify the categories for which it triggers Do not forget to first create the data group, used in the code or delete that part of the code and to uncomment the Bot part of the code, if you plan to do js check and not captcha and maybe comment the captcha part ! Code Snippet Meta Information Version: 17.1.3 Coding Language: TCL Code You can find the code and further documentation in my GitHub repository: reputation-javascript-captcha-challlenge/ at main · Nikoolayy1/reputation-javascript-captcha-challlenge when HTTP_REQUEST { # Take the ip address for ip reputation/intelligence check from the XFF header if it comes from the whitelisted source ip addresses in data group "client_ip_class" if { [HTTP::header exists "X-Forwarded-For"] && [class match [IP::client_addr] equals "/Common/client_ip_class"] } { set trueIP [HTTP::header "X-Forwarded-For"] } else { set trueIP [IP::client_addr] } # Check if IP reputation is triggered and it is containing "Spam Sources" if { ([llength [IP::reputation $trueIP]] != 0) && ([IP::reputation $trueIP] contains "Spam Sources") }{ log local0. "The category is [IP::reputation $trueIP] from [IP::client_addr]" # Set the variable 1 or bulean true as to trigger ASM captcha or bot defense javascript set js_ch 1 } else { set js_ch 0 } # Custom response page just for testing if there is no real backend origin server for testing if {!$js_ch} { HTTP::respond 200 content { <html> <head> <title>Apology Page</title> </head> <body> We are sorry, but the site you are looking for is temporarily out of service<br> If you feel you have reached this page in error, please try again. </body> </html> } } } # when BOTDEFENSE_ACTION { # Trigger bot defense action javascript check for Spam Sources # if {$js_ch && (not ([BOTDEFENSE::reason] starts_with "passed browser challenge")) && ([BOTDEFENSE::action] eq "allow") }{ # BOTDEFENSE::action browser_challenge # } # } when ASM_REQUEST_DONE { # Trigger ASM captcha check only for users comming from Spam sources that have not already passed the captcha check (don't have the captcha cookie) if {$js_ch && [ASM::captcha_status] ne "correct"} { set res [ASM::captcha] if {$res ne "ok"} { log local0. "Cannot send captcha_challenge: \"$res\"" } } } Extra References: BOTDEFENSE::action ASM::captcha ASM::captcha_status271Views1like1CommentJson parsing with iRules
JSON is now the format of choice for most APIs. It's time we were able to parse JSON with F5 iRules too, as simple string matching is not always good enough. That's why I wrote a simple JSON parser for iRules. It is a validating single pass parser that processes the JSON string char by char until the JsonPath expression matches, no recursion or any other fancy stuff. As I do not wanted to reinvent the wheel, it is basically a rewrite of the JSON parser found in the mongoose webserver project in plain TCL. The usage is very simple: set token [call json::json_get_tok { $json $path }] $json is the json string to parse $path is a JsonPath expression, following operators are implemented: Operator Description $ The root element to query. This starts all path expressions. .<name> Dot-notated child. [<number>] Array index. Example Simple JSON: { "aud": "audience \"test\"", "iss": "https://issuer.de/issuer/", "iat": 1701422123, "roles": [ "role1", "role2" ], "obj": { "sub": "adcad2b8", }, "ver": "2.0" } JsonPath expression to parse this simple JSON: JsonPath Return value $.aud "audience \"test\"" $.iat 1701422123 $.obj.sub "adcad2b8" $.roles[0] "role1" To decode the extracted JSON string: set decoded [call json::json_decode_str { $token }] This removes the enclosing quotes from a string and decodes JSON escapes. Code You can find the code and further documentation in my GitHub repository: https://github.com/JuergenMang/f5-irules-json884Views3likes2Commentsirule to block a non valid url
Hi, we send web traffic to our F5 APM, this traffic is analyzed by an Elasticsearch server Sometimes our APM receives an invalid http request that causes problems on our Elasticsearch server. The URL contains a lot of special characters Is there any idea for a rule to block such invalid requests? correct xxxx TECH_REQUEST w.x.y.z:42426 CONNECT vcsa.vmware.com:443 1 Internet_SrvUpdates 708b5c79 (ALLOWED_WILDCARD) incorrect xxxx TECH_REQUEST w.x.y.z :52900 ��_ ��[� ��+��>�©L��^'�9����&�,�+�$�#� 1 Internet_SrvUpdates 708b5c79 (BLOCKED_NO_WILDCARD_OR_TUPLE) many thanks73Views0likes2Comments- 93Views0likes4Comments
How can I log remaining timeout of session persistence if persistence record is found
As always being challenged F5 is not working as expected and I'm attemp to prove IT'S NOT f5. Customer has asked to setup source address persistence with 60 minutes timeout value. But, saying their session being booted before timeout and F5 is load balancing to different pool member as session sticky is not working. I don't want to run tcpdump for long time. I don't see any documenation on how to log timeout if a persistence record is found. I put together an irule but not showing the timeout. when CLIENT_ACCEPTED { if { [persist lookup source_addr [IP::client_addr]] ne "" } { # Get the persistence timeout value (in seconds) set timeout [lindex [persist lookup source_addr [IP::client_addr]] 1] log local0. "LB INFO - Client: [IP::remote_addr], Pool: [LB::server], Persist: [persist lookup source_addr [IP::client_addr]] with timeout: $timeout" } else { log local0. "LB INFO - Client: [IP::remote_addr], Pool: [LB::server], Persist: xxx [persist lookup source_addr [IP::client_addr]]" } } Seems this line of code is not doing what it claims would do (blame ChatGPT if does not seem right) ;-) set timeout [lindex [persist lookup source_addr [IP::client_addr]] 1] Any direction will be appreciated.Solved101Views0likes2Comments