I had a request from a Hosting Client this week to look at options around blocking malicious users from causing trouble on a local Auction site. As the site was only for Australian and New Zealand users we needed to come up with a solution to block the whole world except AU and NZ visitors. Obviously I know there are mechanisms in existence that have annoyed me in the past while trying to source overseas content and getting the message telling you that you can’t access this site in your region.
I’ve never personally had to act on a request like this, and thought about options relating to some sort of code based filtering or filtering at the gateway level. I’ve known that in real terms I haven’t even scratched the surface of what our Citrix NetScaler VPX’s can do, and with that I searched for some guidelines on getting up GeoIP Responder rules at the Load Balancer’s Virtual Server level. Not being able to find anything definitive end to end, here are the steps I took to achieve the end result.
Citirx NetScaler Article – How to Block Access to a Site by Country using a Location Database
First step is to enable the Responder Feature is it’s not already enabled. Citrix suggest you disable any feature not in use to save on system resources.
> enable feature RESPONDER
In order for the NetScaler to work our what location a visitor is coming from it needs to reference a GeoIP database. MaxMind offer a free database from here: These are updated on the first Tuesday of everymonth, so a little upkeep is required moving forward. There are IPv4/6 versions as well as an extended database City version which lets you get very granular in terms of allowing city access. For this exercise we will use the GeoIPCountryWhois CSV database.
Jump into the shell of the NetScaler and create a new directory. Note that if you have a HA setup, you need to do this on each NetScaler node.
Copyright (c) 1992-2008 The FreeBSD Project.
Copyright (c) 1979, 1980, 1983, 1986, 1988, 1989, 1991, 1992, 1993, 1994
The Regents of the University of California. All rights reserved.
root@NSLB01# cd /var/
root@NSLB01# mkdir geoip
Use SCP to upload the CSV database to that location just created on the NetScaler and then run the following command to import the location parameters. Once done you can query the location database to ensure you have imported the CSV line items.
> add locationfile /var/geoip/GeoIPCountryWhois.csv -format GeoIP-Country
> show locationparameter
Database mode: File
Flushing: Idle; Loading: Idle
Qualifier 1 label: Continent
Qualifier 2 label: Country
Qualifier 3 label: Region
Qualifier 4 label: City
Qualifier 5 label: ISP
Qualifier 6 label: Organization
Location file (format: geoip-country):
Lines: 170195 Warnings: 0 Errors: 0
Current static entries: 170195 Current custom entries: 0
Now that you have the GeoIP location locked and loaded, you can created the Responder Policy. I had a little trouble trying to work out how to structure the rule to work correctly limiting visitors to only .AU and .NZ. I’ll be honest here and admit that trial and error was the winner here, but eventually I came up with the following that works.
> add responder policy GeoAusNZOnly "CLIENT.IP.SRC.MATCHES_LOCATION("*.AU.*.*.*.*").NOT && CLIENT.IP.SRC.MATCHES_LOCATION("*.NZ.*.*.*.*").NOT" RESET
Reading through the policy it’s easy enough to see what’s going on…this page references the Location Database General Information and formats, however it’s confusing at best..my advice is for Country Based GeoIP use the above as a template and simply change the country codes to suit.
Back to the GUI of the NetScaler and under Load Balancing settings of the Virtual Server(s) in question, open the Virtual Server for editing and go to the Policies Tab -> Click on the Responder sub tab and right click to Insert Policy and the end result will be similar to what’s shown below.
I was able to use Twitter contacts with servers in global locations to test out the rule which was behaving exactly as expected. If you go back to the Policy menu item under Responder and check the Responder Policies you will be able to see if the rule is active and how many hits the rule has triggered.
The default action of the policy is to DROP or RESET the connection. You do have the option of creating a custom REDIRECT rule that will allow you to make the end user a little nicer in terms of presenting the user with a HTML page letting them know the page is restricted ..with the DROP and REST the browser simply shows a page not found or connection reset. I’ll update this post once i’ve created the REDIRECT rule.
Update: Turns out that if you apply the above rule it’s not that great for Google Analytics and the bots that hit your site. If you want to get the GoogleBot User Agent through the rule, create a rule similar to below
> add responder policy GeoAusNZGoogleOnly "CLIENT.IP.SRC.MATCHES_LOCATION("*.AU.*.*.*.*").NOT && CLIENT.IP.SRC.MATCHES_LOCATION("*.NZ.*.*.*.*").NOT && HTTP.REQ.HEADER("User-Agent").SET_TEXT_MODE(IGNORECASE).REGEX_MATCH(re/Googlebot/).NOT" RESET
Looking at that additional condition you are looking in the HTTP Request Header, ignoring case and matching Googlebot.