Imagine you release a new API that provides weather data for locations worldwide. Except, for some reason, your weather satellites have two blindspots on the globe. They’re not able to display accurate weather information for the island nations of American Samoa and Iceland.
While you work to fix the issue, you don’t want to frustrate users in either country by giving them inaccurate information. Instead, you want a clean user experience with a custom error message. You can do this by geoblocking with your API gateway.
Geoblocking is a strategy that restricts access to your API based on the request's geographic location or the regional Point of Presence (PoP) that received the request. Locations are pulled from geolocation registries, which store geolocation information and map it to IP addresses in the region. API gateways such as ngrok can use this information to filter, route, and block requests.
At its core, geoblocking is about control. With APIs often exposed globally, the ability to block traffic from specific regions can enhance security, reduce risk, and ensure compliance. In our example, we want to restrict requests seeking weather data in regions our API doesn’t support. However, you may have other reasons to geoblock requests.
For instance, if you're operating in a region with strict data privacy laws, you might want to restrict access from countries with uncertain compliance. Similarly, blocking traffic from regions with high malicious activity—like botnets or repeated DDoS attacks—can help reduce your attack surface.
Geoblocking can also improve performance. Limiting traffic to regions where you know your users are located can avoid unnecessary load on your servers and reduce latency for legitimate users.
ngrok enables geoblocking through Common Expression Language (CEL) expressions in the Traffic Policy engine.
Those expressions also support a variety of variables and macros.
Variables in the conn.geo
namespace allow for ngrok to block requests based on the location of the request. The conn.geo.country_code
variable allows you to build expressions using two-letter country codes.
In the case of the weather API mentioned earlier, conn.geo.country_code
allows you to identify all requests from America Samoa (AS) and Iceland (IS) using their country codes.
To block those requests and return a custom-response
, the Traffic Policy rule would look something like this:
on_http_request:
- expressions:
- "conn.geo.country_code in ['AS', 'IS']"
actions:
- type: custom-response
config:
status_code: 403
body: "Forbidden request due to unsupported country of origin"
The rule blocks all requests originating from the listed countries and returns a custom-response
with status_code: 403
.
Should your geoblocking needs require more granularity, the conn.geo
namespace also has variables for city, longitude, latitude, server region, and even radius–the kilometers around the latitude and longitude where the conn.client_ip
is likely to originate.
You can even combine expressions. If you only want to geoblock certain endpoints, that expression would look like this:
- expressions:
- "conn.geo.country_code in ['AS', 'IS']"
- “req.URL.contains(‘/api/forecast’)”
Geoblocking isn’t just for HTTP connections.
You can also filter requests on the TCP layer.
Using Traffic Policy, the variables from the conn.geo
namespace are still available to build expressions.
The only difference is the expression would be under a on_tcp_connect
phase rather than the on_http_connect
phase.
While there are other strategies for geoblocking, such as DNS-based geoblocking and blocking at the application layer, blocking with the location of the client IP is the most common way to geoblock.
Geoblocking can be a powerful tool, but there are a few factors to keep in mind:
To get started working with the geolocations of requests on your API, sign up for an ngrok account and check out the documentation for ngrok’s Traffic Policy module to see how to formulate expressions and actions. Then, dive into the Connection Geo Variables section of the HTTP Variables document to discover the different ways to retrieve geoinformation for requests.