Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Restricting website access by country

I am hosting my website using AWS.

The website is on 2 ec2 instances, with a load balancer (ELB) balancing traffic between them.

Currently, I am using my DNS (Route 53) to restrict the access to the website by using Route 53's geolocation routing: http://docs.aws.amazon.com/Route53/latest/DeveloperGuide/routing-policy.html#routing-policy-geo

(The geolocation restriction is just to limit the initial release of my website. It is not for security reasons. Meaning the restriction just needs to work for the general public)

This worries me a little because my load balancer is still exposed to access from everywhere. So I am concerned that my load balancer will get indexed by google or something and then people outside of my region will be able to access the site.

Are there any fixes for this? Am I restricting access by location the wrong way? Is there a way perhaps to specify in the ELB's security group that it only receive inbound traffic from my DNS (of course then I would also have to specify that inbound traffic from edge locations be allowed as well for my static content but this is not a problem)?

Note: There is an option when selecting inbound rules for a security group, under "type" to select "DNS(UDP)" or "DNS(TCP)". I tried adding two rules for both DNS types (and IP Address="anywhere") for my ELB but this did not limit access to the ELB to be solely through my DNS.

Thank you.

like image 609
theyuv Avatar asked Jan 29 '16 09:01

theyuv


People also ask

Can I block a country from accessing my website?

Blocking a country couldn't be easier. Just log in and go to 'Threat Control', then where it says 'Add custom rule', start typing the full country name and then click it from the dropdown list. Click the big red 'Block' button and you're done!

How do I stop certain countries from traffic?

To block traffic coming from a certain country (or countries), we can use a simple Firewall rule. Go to the Apps view and then click the Firewall application. Click on the Rules tab and then the Add button to create a new rule.

How do I block a website from a specific country in Cpanel?

Navigate to Security Center -> cPHulk Brute Force Protection Here, go to the Countries Management tab. 4. Select which countries you want to block, click the gear icon on the right of the list, and select the Blacklist Selected Countries option.

How do I restrict access to my content by country?

Geo Restriction or Geoblocking lets you choose the countries in which you want to restrict access to your content. By configuring either a whitelist or a blacklist of countries you can control delivery of your content through Amazon CloudFront only to countries where you have the license to distribute.

How do I control site access from specific countries?

You can control site access from specific countries by using allow and deny directives in an .htaccess file. To do this, you must obtain the ranges of IP addresses that are assigned to a particular country. There are several web sites that enable you to generate these .htaccess directives automatically based on the country or countries you specify.

How to block or allow countries on a Hostinger website?

Finally, paste the IP addresses of the countries you want to block or allow to .htaccess file. Here’s how to do it using Hostinger’s hPanel: Go to Files -> File Manager. Select your domain and hit Go To File Manager. Navigate to the public_html folder and double-click the .htaccess file. Paste ACL to your .htaccess file and hit Save & Close.

How do I block or allow visitors from specific countries?

In this tutorial, you’ve learned the easy way to block or allow visitors from specific countries. All you need to do is generate the country’s IP address via Country IP Blocks, then insert an access control list (ACL) into your .htaccess file. We hope that this guide was helpful.


2 Answers

The simple solution, here, is found in CloudFront. Two solutions, actually:

CloudFront can use its GeoIP database to do the blocking for you...

When a user requests your content, CloudFront typically serves the requested content regardless of where the user is located. If you need to prevent users in specific countries from accessing your content, you can use the CloudFront geo restriction feature[...]

http://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/georestrictions.html

You can configure CloudFront with which countries are allowed, or which are denied. You can also configure static pages, stored in S3, which are displayed to denied users. (You can also configure static custom error pages for other CloudFront errors that might occur, and store those pages in S3 as well, where CloudFront will fetch them if it ever needs them).

...or...

CloudFront can pass the location information back to your server using the CloudFront-Viewer-Country: header, and your application code, based on the contents accompanying that header, can do the blocking. The incoming request looks something like this (some headers munged or removed for clarity):

GET / HTTP/1.1
Host: example.com
X-Amz-Cf-Id: 3fkkTxKhNxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx==
Via: 1.1 cb76b079000000000000000000000000.cloudfront.net (CloudFront)
CloudFront-Viewer-Country: US
CloudFront-Forwarded-Proto: https
Accept-Encoding: gzip

CloudFront caches the responses against the combination of the requested page and the viewer's country, and any other whitelisted headers, so it will correctly cache your denied responses as well as your allowed responses, independently.

Here's more about how you enable the CloudFront-Viewer-Country: header:

If you want CloudFront to cache different versions of your objects based on the country that the request came from, configure CloudFront to forward the CloudFront-Viewer-Country header to your origin. CloudFront automatically converts the IP address that the request came from into a two-letter country code.

http://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/header-caching.html#header-caching-web-location

Or, of course, you can enable both features, letting CloudFront do the blocking, while still giving your app a heads-up on the country codes for the locations that were allowed through.


But how do you solve the issue with the fact that your load balancer is still open to the world?

CloudFront has recently solved this one, too, with Custom Origin Headers. These are secret custom headers sent to your origin server, by CloudFront, with each request.

You can identify the requests that are forwarded to your custom origin by CloudFront. This is useful if you want to know whether users are bypassing CloudFront[...]

http://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/forward-custom-headers.html

So, let's say you added a custom header to CloudFront:

X-Yes-This-Request-Is-Legit: TE9MIHdoYXQgd2VyZSB5b3UgZXhwZWN0aW5nIHRvIHNlZT8=

What's all that line noise? Nothing, really, just a made up secret value that only your server and CloudFront know about. Configure your web server so that if this header and value are not present in the incoming request, then access is denied -- this is a request that didn't pass through CloudFront.

Don't use the above secret, of course... make up your own. It's entirely arbitrary.


Caveat applicable to any GeoIP-restricting strategy: it isn't perfect. CloudFront claims 99.8% accuracy.

like image 191
Michael - sqlbot Avatar answered Oct 04 '22 06:10

Michael - sqlbot


The most reliable way to implement geographic IP restrictions, is to use a geographic location database or service API, and implement it at the application level.

For example, for a web site in practically any language, it is very simple to add test at the start of each page request, and compare the client IP against the geo ip database or service, and handle the response from there.

At the application level, it is easier to manage the countries you accept/deny, and log those events, as needed, than at the network level.

IP based geo location data is generally reliable, and there are many sources for this data. While you may trust AWS for many things, I do think that there are many reliable 3rd party sources for geo IP dat, that focus on this data.

  • freegeoip.net provides a public HTTP API to search the geolocation of IP addresses. You're allowed up to 10,000 queries per hour.
  • ip2location.com LITE is a free IP geolocation database for personal or commercial use.

If your application uses a database, these geo databases are quite easy to import and reference in your app.

like image 42
Rodrigo Murillo Avatar answered Oct 04 '22 07:10

Rodrigo Murillo