There are situations where you don’t want your website to be globally accessible.
Maybe:
Your application is country-specific
You’re running a limited regional rollout
You want to block traffic silently (no 403 errors)
You don’t want to use AWS WAF or application-level logic
In such cases, blocking traffic at the DNS level is one of the cleanest and most underrated approaches.
In this post, I’ll explain how to allow website access only from specific countries using AWS Route 53, what really happens behind the scenes, and the important limitations you must understand before using this in production.
🧠 The Core Idea
Instead of blocking requests after they reach your server, we block them before DNS resolution.
If DNS does not return an IP address:
The browser never reaches your server
No HTTP request is made
No 403 or error page is shown
The site simply appears unreachable
AWS Route 53 provides Geolocation Routing, which allows DNS responses based on the client’s country.
🔄 How Route 53 Geolocation Routing Works
A common misunderstanding is thinking this depends on where your server is hosted.
It doesn’t.
Route 53 makes decisions based on:
The client’s IP location (the user making the request)
It does not care about:
Where EC2 is running
Where ALB is deployed
Which AWS region hosts the application
So:
EC2 can be in Mumbai
ALB can be in Singapore
Access is still decided by the requester’s country
🎯 Example Use Case
Allow access only from:
India
Canada
Singapore
United Kingdom
Nepal
United Arab Emirates
Cocos (Keeling) Islands
Everyone else:
Website should look “not reachable”
No WAF.
No 403.
No application logic.
🛠️ Step 1: Create a Public Hosted Zone
In AWS Route 53:
Create a Public Hosted Zone
Domain example: example.com
Route 53 will generate 4 Name Servers
Update those Name Servers in your domain registrar (Namecheap, GoDaddy, etc.)
Once this is done, Route 53 becomes authoritative for your domain.
🛠️ Step 2: Create Geolocation Records
For each allowed country, create one DNS record.
Example for India:
Record type: A
Routing policy: Geolocation
Location: India
Alias: Yes
Target: Application Load Balancer
Repeat this for every allowed country.
⚠️ The Most Important Rule (Don’t Skip This)
❌ Do NOT create a “Default” record
If you create a default record:
All countries will resolve DNS
Geo-blocking will not work
No default record = silent blocking.
🌍 Why Multiple Records With the Same Name Are Valid
Route 53 treats these records as unique combinations of:
(domain name, record type, routing policy, location)
So this is perfectly valid:
example.com → India
example.com → Canada
example.com → UK
There’s no practical limit for this approach.
🧪 How to Test Properly
From an allowed country:
dig example.com
Result:
DNS resolves
Website loads
From a blocked country:
dig example.com
Result:
NXDOMAIN
Browser message:
“This site can’t be reached”
That confirms DNS-level blocking.
💰 Cost Considerations
Geolocation routing:
Costs the same as Simple routing
No extra cost per country
Charged only per DNS query
In fact, you often save money:
No ALB traffic from blocked regions
No EC2 processing
No WAF charges
⚠️ An Important Limitation: Hosts File Bypass
This approach blocks access at the DNS level, which means it can be bypassed if someone already knows the server’s IP address.
This is not an AWS issue — it’s how DNS works.
Example (Windows)
If someone edits:
C:\Windows\System32\drivers\etc\hosts
And adds:
13.xxx.xxx.xxx example.com
DNS is skipped entirely, and the browser connects directly to the IP.
The same applies on Linux and macOS using /etc/hosts.
🛡️ Does This Make Route 53 Geo Blocking Useless?
Not at all.
This bypass works only if:
The user knows the exact IP
The origin allows direct IP access
No network or application checks exist
Most real users:
Don’t know the IP
Won’t edit hosts files
Use normal DNS resolution
So for traffic control and silent blocking, this method is still very effective.
🔐 How to Harden This Setup (Best Practices)
To prevent bypasses:
Use an ALB instead of direct EC2 IPs
ALBs require proper Host headers
Block direct IP access at Nginx or app level
Reject requests without the correct domain
Hide origin behind CloudFront
Users never see backend IPs
Combine DNS control with network rules
Defense in depth
🧠 When This Approach Is the Right Choice
Use Route 53 Geolocation routing when:
You want silent blocking
You don’t want HTTP errors
You want low operational overhead
You want to block traffic before it hits your infrastructure
✅ Final Thoughts
DNS-level access control is simple, fast, and cost-effective — but it’s not a security boundary by itself.
The real strength comes when:
DNS is your first gate
Network and application controls are your second gate
That layered approach is how production systems are designed.
Top comments (0)