Forum Discussion

Chris_Olson_172's avatar
Chris_Olson_172
Icon for Nimbostratus rankNimbostratus
Dec 11, 2018

irule to Block specific URLs, allow the rest

I need to block traffic from two explicit URLs, but allow all other traffic even if it starts with the same characters as what is blocked. This is my best guess at syntax. Please correct any errors you see.

 

when HTTP_REQUEST { if { ( [string tolower "[HTTP::host][HTTP::path]"] equals "example.domain.com/xyz/ab/" ) or if { ( [string tolower "[HTTP::host][HTTP::path]"] equals "example.domain.com/xyz/ab" ) reject } } }

 

Any other iteration that starts the same but has additional characters like "example.domain.com/xyz/ab/abc123/..." should be allowed. Is the equals parameter sufficient?

 

7 Replies

  • If you remove some brackets and one of the "if"s it works. You can always test it by logging the output to /var/log/ltm, see below.

    when HTTP_REQUEST {
        if {[string tolower "[HTTP::host][HTTP::path]"] equals "example.domain.com/xyz/ab/"
        or [string tolower "[HTTP::host][HTTP::path]"] equals "example.domain.com/xyz/ab"} {
            log local0. "Rejected Connection [HTTP::host][HTTP::path], converted [string tolower [HTTP::host][HTTP::path]]"
            reject
        }
    }
    
    • Chris_Olson_172's avatar
      Chris_Olson_172
      Icon for Nimbostratus rankNimbostratus

      Thank you so much. I will test. Sadly, we are in a managed environment and I have little access to my own F5's to test and I must rely on your expertise. Thanks again. I will report back on results.

       

    • Chris_Olson_172's avatar
      Chris_Olson_172
      Icon for Nimbostratus rankNimbostratus

      The rule took, but it's not working. I used both URLs specified but it is not being rejected. I can still hit the site. The logs do not show anything is happening. The only thing I can think of is that it is applied to the HTTPS VIP. However, when I try to change the rule to HTTPS I get an error.

       

      [undefined procedure: HTTPS::host][HTTPS::host] /Common/url_reject_https:2: error: [undefined procedure: HTTPS::path][HTTPS::path]

       

      Any ideas?

       

    • gscholz_370150's avatar
      gscholz_370150
      Icon for Nimbostratus rankNimbostratus

      Even if HTTPS is used the contents of the Rule don't change. It is still an HTTP request and not an HTTPS request. If you want to find out whether the iRule gets hit at all, you could add another logging line, like below. In that case you should see one entry for every HTTP request, and a second one for every rejected request.

      when HTTP_REQUEST {
          log local0. "Requested connection [HTTP::host][HTTP::path], converted [string tolower [HTTP::host][HTTP::path]]"
          if {[string tolower "[HTTP::host][HTTP::path]"] equals "example.domain.com/xyz/ab/"
          or [string tolower "[HTTP::host][HTTP::path]"] equals "example.domain.com/xyz/ab"} {
              log local0. "Rejected Connection [HTTP::host][HTTP::path], converted [string tolower [HTTP::host][HTTP::path]]"
              reject
          }
      }
      

      If you are unsure which virtual server gets hit you should be able to see that in a packet capture using tcpdump. Do you have shell access? (In theory packet capture is possible via the GUI as well, but I found it rather painful.)

  • Hi,

     

    the code provided by gscholz may work.

     

    You can also try this code which check both host and path in 2 conditions instead of concatenate, then use string match with no case instead of equals for performance optimization according to this article, and finally respond with a 403 error page instead of reject.

     

    when HTTP_REQUEST {
        log local0. "Requested connection [HTTP::host][HTTP::path], converted [string tolower [HTTP::host][HTTP::path]]"
        if {[string match -nocase "example.domain.com" [HTTP::host]] && [string match -nocase "/xyz/ab" [string trimright [HTTP::path]]]} {
            log local0. "Rejected Connection [HTTP::host][HTTP::path], converted [string tolower [HTTP::host][HTTP::path]]"
            HTTP::respond 403 content{request Forbidden}
        }
    }