Restrict Access to particular URLs
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
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:
0
Comments
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.
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
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
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
}
}
}
example "contains": http://a10.com/test.html or http://a10.com or /test.hml
Genard
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