Jump to content
Welcome to our new Citrix community!

Geo-location policies to block a large list of countries

Recommended Posts

Hi all,

I'm looking for the best way to block connections from a large list of countries (90) by using the geo-location database and responder policies. The only option I can think of at this moment is as described in article https://support.citrix.com/article/CTX130701, however in my case it would mean I'll need about 90 policies or a single policy made of 90 expressions, which I think is not a very clean way to do it.

Is there any other way than can be simplier to manage? Using datasets maybe?

Link to comment
Share on other sites

Yes datasets would handle this. Or a callout.  But for 90 entities a dataset (or series of data sets) should be fine.

If not used to working with them, here is a brief example for geo blocking:



And some other dataset expression examples:

More varied scenarios, but the discussion was a about both types of policy examples with and without patternsets/datasets and typecasting for ips (and some path examples): https://discussions.citrix.com/topic/409145-netscaler-policy-assistance/



If you need a specific example, I can adjust the first posts examples to meet your needs. But this should help.

Link to comment
Share on other sites

I just noted this in another thread and will dig it up for you.

If you are using a responder policy to filter this traffic, then assign a Log Action to the policy with the custom message.  By default, this will log to syslog which is preferred.

Update your local syslog parameters OR any external syslog audit policies to include User Configurable Log Messages (which allows these log actions to be displayed).

Message can be "<policy name or vserver name>:  Connection from source ip: " + client.ip.src + " dropped by geolocation filter policy for " + client.ip.src.location

Or something similar:  https://docs.citrix.com/en-us/citrix-adc/current-release/load-balancing/load-balancing-advanced-settings/retrieve-location-details-using-ip-address-from-geolocation-database.html



Since your are likely blocking or redirecting on violation, be sure the responder policy is still doing the drop/redirect action in addition to the log action and your binding behavior is set to Goto: End. (I note this, because the thread I'm going to refer to used NOOP and NEXT to do a log only response and allow additional traffic handling to occur). But if you need more info, I can clarify.  (Log action example here, but the other details are very different from your example as noted:  https://discussions.citrix.com/topic/413011-capture-source-ips-on-vip-for-any-connections-which-are-using-weak-ciphers/)

More generic log action example:  https://support.citrix.com/article/CTX200908





Link to comment
Share on other sites

After importing the inbuilt location db and then doing some testing with command shell  nsmap –d –t, I notice that continents are not identified by code but by full name instead, like this:

Asia, Africa, Europe, North America, South America, Australia and Oceania.




If I wanted to set the patsets for this, since there are space in between those continent names should I add another pair of ""? In other words, which of the following patterns would be correct for the gui:  "North America.*.*.*.*.*" or ""North America".*.*.*.*.*"  ?


Link to comment
Share on other sites

See if this helps. I finally, had time to throw an example together.

I want a little overboard and built some examples (as I kind of misread the question...but you still might like the example anyway). 

If you do it in GUI, no quotes needed. If in CLI, quote as one string...  "North America.US....."   (but see next point).

BUT you won't need the extra stars in most cases. The "*" are needed in the database to match "all".  In the patternset, that's not going to work in the same way as you have to extract the elements you want from the location string to compare against the patternset.




First: Location Expression Examples:

Basic GEO listing (though it may vary based on database used and format):



I'm going to guess you may be creating your geo blacklist by Continent or Country (or maybe additional criteria).  Let's start with either first field or second field and go from there.



Basic Location expression examples and then we can figure out what your patternset should be:


Test Client with  an IP who's location returns:  Asia.In.Karnataka.Bangalore  (as used in the admin guide above):

<expr>                                        returns value

# here's the location output for an IP found in the geo database ranges....

client.ip.src.location              Asia.In.Karnataka.Bangalore


# here's how to retrieve a specific element; zero-based array; usually get is 1-based.  Exampes for first three elements.

client.ip.src.location.get(0)     Asia

client.ip.src.location.get(1)      In

client.ip.src.location.get(2)     Karnataka


# here's how to retrieve the first two (together) or first three together:

client.ip.src.location(2)     Asia.In

client.ip.src.location(3)     Asia.In.Karnataka


So, now when constructing your patternset, you just need to decide what strings you want to look for.  





And we can build one or more patternsets as needed.

I'm just going to create simple patternsets with just two or three sample entries (based on my custom entry for local testing). Since I was in an "internal network"; i just made up a US mapping for the private IP I was testing with.  So my locations are based on the builtin database + one custom entry.


Next:  Example PatternSets






add policy patset ps_blockbygeo_continentlist
bind policy patset ps_blockbygeo_continentlist NA
bind policy patset ps_blockbygeo_continentlist Asia


add policy patset ps_blockbygeo_countrylist
bind policy patset ps_blockbygeo_countrylist In 
bind policy patset ps_blockbygeo_countrylist US


add policy patset ps_blockbygeo_continent_andcountrylist
bind policy patset ps_blockbygeo_continent_andcountrylist Continent2.CC
bind policy patset ps_blockbygeo_continent_andcountrylist Continent1.BB 
bind policy patset ps_blockbygeo_continent_andcountrylist Continent1.AA 


Once you figure out what criteria you want to look at (one level or multiple levels; exact matches or partial matches) there are a lot of different ways to compose the patternsets and the expressions.


Then, Example Responder Filter Examples:

# just using a drop action.... redirect/resets are fine too

#  Example 1: by continent only:

add responder policy rs_pol_blockgeoip1 "client.IP.SRC.LOCATION.GET(0).SET_TEXT_MODE(ignorecase).EQUALS_ANY(\"ps_blockbygeo_continentlist\")" DROP
# Example 2:  by country only:

add responder policy rs_pol_blockgeoip2 "client.IP.SRC.LOCATION.GET(1).SET_TEXT_MODE(ignorecase).EQUALS_ANY(\"ps_blockbygeo_countrylist\")" DROP
# Example 3:  by both with separate patternsets so you can do the continent list or more granular countries when needed:

add responder policy rs_pol_blockgeoip3 "client.IP.SRC.LOCATION.GET(0).SET_TEXT_MODE(ignorecase).EQUALS_ANY(\"ps_blockbygeo_continentlist\")  || client.IP.SRC.LOCATION.GET(1).SET_TEXT_MODE(ignorecase).EQUALS_ANY(\"ps_blockbygeo_countrylist\")" DROP

# Or if you want to build continent.country lists, then your expression could be this one:

add responder policy rs_pol_blockgeoip4 "client.IP.SRC.LOCATION(2).SET_TEXT_MODE(ignorecase).EQUALS_ANY(\"ps_blockbygeo_continent_andcountrylist\")" BLOCK


You can also build a patternset as a "whitelist" if you need to exempt overlapping criteria.

But the less granular you make it the shorter the pattern set would be.

In the above examples, I manipulated the expression to extract the exact parts of the location I wanted:

continent only, country only, OR continent.country so I could use the equals_any("<patset>") operator instead of a the contains_any("<patset>") and I would have fewer partial matches or have less needed for trying to match the entire location string.


AND there are other ways to do this. Basically, once you know what your blocking criteria is we can build the expression and the patternset or patternsets to suit the evaluation.



  • Like 1
Link to comment
Share on other sites

I really appreciate that you take the time to explain it so nicely.

Sadly, I just found that the version I'm running (12.0) doesn't have the "location" function yet, and the only one I can use is "matches_location" which apparently only accepts strings in the "*.*.*.*.*.*" fashion.

I'm already in the process of upgrading to 12.1 but it's going to take a while since we found some compatibility issues with our old MDM platfrom that are under investigation.


In the meanwhile, can you tell me if the "matches_location" function can be used along with patsets?

The patset would contain the list of countries like this:


bind policy patset WAF_GeoDB_BloqueoXPaises "\"*.CZ.*.*.*.*\"" -index 5 -charset ASCII
bind policy patset WAF_GeoDB_BloqueoXPaises "\"*.RO.*.*.*.*\"" -index 9 -charset ASCII
bind policy patset WAF_GeoDB_BloqueoXPaises "\"*.CG.*.*.*.*\"" -index 6 -charset ASCII
bind policy patset WAF_GeoDB_BloqueoXPaises "\"*.AL.*.*.*.*\"" -index 1 -charset ASCII

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
  • Create New...