Options

Restrict Access to particular URLs

rwilliamsrwilliams Member
I am looking at the best way to only allow access to particular URLs on a VIP. One way I thought of was to use a aFlex script to allow/deny access. I have not found any specific scripts to do this, but I have found some for other providers. I am looking for the best most efficient way for latency/system resources to accomplish this. The two methods I have are as follows:

Method 1:
when HTTP_REQUEST {

# Check if URI is not exactly /analytics
if {not ([HTTP::uri] eq "/analytics")}{

reject
}
}

Method2:

if { [ class match [string tolower [HTTP::uri]] contains allowed_uris ] } {
#Stop processing the Rule for this event here
return }
else {
drop }
}

and the data group is defined as:

class allowed_uris {
"/site1/"
"/site2/"
"/site3/"
}

Regards

Ryan
Tagged:

Comments

  • Options
    rwilliamsrwilliams Member
    edited January 2016
    Hi All,

    So I have a working instance of method 1 which is reliant on only having the one allowed uri.

    when HTTP_REQUEST {

    if {not ([HTTP::uri] starts_with "/example/")} {

    #drop
    HTTP::redirect "http://www.google.com"
    }
    }

    as you can see I commented out the drop and replaced it with a redirect so that I could confirm that it works.
  • Options
    dshindshin Member
    edited January 2016
    I would prefer that you use aFleX Method 2 as you can dynamically add the allowed URIs from a class-list. I think using a class-match and class-list will be much simpler. Going with Method 1 will create a significant amount of “if” statements and could be process intensive.

    In addition, I do not have the full detail of your deployment but you can also disable directory browsing within your webservers for potential users to have a chance to access unwanted URIs.

    My two cents.

    Genard
  • Options
    rwilliamsrwilliams Member
    edited January 2016
    Thanks for your reply. Is there anyway to include both the Host and URI in Method 2? i.e the class list will look like:

    class allowed_urls {
    “//www.example1.com/path/”
    “//www.example2.com/path/”
    “//www.example3.com/path/”
    }

    The main reason for the deployment is that we migrated from some old Cisco CSS which just did content switching based on the full URL (host+uri) one of the byproducts of this was it stopped vulnerability scans conducted by our managed service provide from getting through to the back end servers. It also meant that unless you had the correct Host and uri a connection did not get to the back end, which added to the security.

    Now I could do content switching using a http template on the A10 to achieve similar. but the one thing I noticed was that when you viewed the dashboard's Service map. The service map no longer should the details of the Servers assigned to a VIP as there was no longer any Service-group assigned to the VIP. The service group was chosen in the http template. So from a monitoring point of view. I no longer have an easy dashboard showing if I have a server down connected with a specific VIP.

    By using an aFlex script either method1 or 2 to whitelist only specified URLS I can maintain a view of the server statuses assigned to a VIP on the Dashboard.

    Ryan
  • Options
    edited January 2016
    Is this what you are looking for?


    when RULE_INIT {
    set ::uri_list "URL-CLASS-LIST" ;# Class List used for URI used for uri path and configured in partition
    set ::host_list "DOMAIN-LIST" ;# Class List used for hosts and configured in partition
    }

    when CLIENT_ACCEPTED {
    set vip [IP::client_addr]:[TCP::client_port]
    set curtime [TIME::clock seconds]
    set formattedtime [clock format $curtime -format {%H:%S} ]
    }

    when HTTP_REQUEST {
    if {[HTTP::header exists "Host"] } {
    set URI [string tolower [HTTP::uri]]
    set HOST [string tolower [HTTP::host]]

    if { [CLASS::match $HOST contains $::host_list ] || [CLASS::match $HOST$URI contains $::uri_list ] } {
    #
    log local0.CRIT "Violation: $vip Accessing $HOST$URI, Action: Session Closed"
    HTTP::close
    } else {
    pool SG_Gateway
    }
    }
    }
  • Options
    dshindshin Member
    edited January 2016
    So Class-list entries can support a mixed of host or uri string values.

    example "contains": http://a10.com/test.html or http://a10.com or /test.hml

    Genard
  • Options
    rwilliamsrwilliams Member
    edited January 2016
    Hi,

    Thanks tjones and Genard for your help on this so far. I have come up with a class-list based script that is using elements of all those suggested so far. Preliminary results in our Dev network looks like it is doing as I would like, in that only allowed hosts and paths are permitted. So I would like to have your take on the following:

    # The class-list for allowed hosts and paths is called
    # "cl-allowed-urls" of type "string" and has to contain
    # the following data:
    # str <host> <uri>
    #
    #
    # For Example:
    # class-list cl-allowed-urls string
    # str www.example.com /path/
    # str www.anotherexample.com /
    # str www.3rdexample.com /anotherpath/

    when RULE_INIT {
    set ::CLASSLIST "cl-allowed-urls"
    }

    when HTTP_REQUEST {
    set HOST [string tolower [HTTP::host]]
    set URI [CLASS::match $HOST contains $::CLASSLIST value]

    # Checks to see if Host is in the allowed list
    if {not[CLASS::match $HOST contains $::CLASSLIST]} {
    drop
    }
    # If the Host does exist, checks to see if the path is valid
    if {not ([HTTP::uri] starts_with "$URI")} {
    drop
    }
    }


    I have noticed in some examples that there is a "set ::DEBUG 0" at the beginning. What does this do and is it vital to include. I am not really concerned about logging what is dropped as this will just produce too many logs. I am already W3 logs for the successful connections.

    Ryan
Sign In or Register to comment.