How to Block Russian IPs with .htaccess Guide
Learn to use .htaccess for blocking Russian IP addresses on educational sites. Implement GeoIP blocking, IP deny lists, custom 403 messages like 'This material/link is not available in the Russian Federation', and server-side link hiding for compliance.
How can I use .htaccess to hide controversial links and materials from Russian IP addresses on an educational website?
I have an educational website with materials for learning English and other languages. I read about the legal prosecution of a website that published materials about the British Council and its language exams. How can I hide links to such websites and pages mentioning them from users in Russia? How can I configure .htaccess to display the message “This material/link is not available in the Russian Federation” when attempting to access from Russian IP addresses?
Use .htaccess with GeoIP (or a generated RU IP deny list) to implement блокировка по ip and htaccess блокировка for the specific pages or directories that mention the British Council; then set ErrorDocument 403 to return “This material/link is not available in the Russian Federation”. If you need links removed from HTML rather than just blocking access, render pages without those links for RU visitors (ограничение доступа сайт) on the server side (preferred) or apply on-the-fly substitution (less reliable). Choose GeoIP + a short .htaccess rule for correctness and a server/CDN firewall for scale and performance.
Contents
- How to block Russian IPs with .htaccess (блокировка ip htaccess)
- Block by IP ranges (.htaccess deny list) (блокировка по ip)
- Hide links inside pages: server-side rendering vs .htaccess filters
- Custom 403 message and testing (htaccess блокировка)
- Performance, maintenance and how users bypass blocks (обход геоблокировки)
- Step-by-step recommended implementation
- Sources
- Conclusion
How to block Russian IPs with .htaccess (блокировка ip htaccess)
Goal: deny requests coming from Russian IP ranges and return a friendly, legally compliant message. The most robust approach uses a GeoIP module on the server (mod_maxminddb / mod_geoip2 / mod_geoip depending on what your Apache build supports). That avoids huge .htaccess lists and gives stable country detection.
What you need before editing .htaccess:
- A GeoIP database (for example, MaxMind GeoLite2-Country.mmdb — download/update from MaxMind).
- An Apache GeoIP module installed and enabled on the host (mod_maxminddb or mod_geoip2).
- Permission to use .htaccess for access control (some hosts disallow critical directives in .htaccess; server/virtualhost config is preferred).
Basic examples (adapt to your Apache module and version). Replace /path/to/GeoLite2-Country.mmdb with the actual path.
Apache 2.4 + mod_maxminddb (modern, recommended):
<IfModule mod_maxminddb.c>
MaxMindDBEnable On
MaxMindDBFile COUNTRY_DB /path/to/GeoLite2-Country.mmdb
# store country ISO code in environment variable
MaxMindDBEnv COUNTRY_CODE COUNTRY_DB/country/iso_code
</IfModule>
# block RU
SetEnvIf COUNTRY_CODE ^RU$ BlockCountry
<RequireAll>
Require all granted
Require not env BlockCountry
</RequireAll>
ErrorDocument 403 /russia-blocked.html
Older mod_geoip / legacy Apache (example):
GeoIPEnable On
GeoIPDBFile /path/to/GeoIP.dat
SetEnvIf GEOIP_COUNTRY_CODE RU BlockCountry
<RequireAll>
Require all granted
Require not env BlockCountry
</RequireAll>
ErrorDocument 403 "This material/link is not available in the Russian Federation"
Notes and links:
- Super User has a practical configuration example for GeoIP + .htaccess that shows the same pattern (GeoIP enable, SetEnvIf, Deny env) — see the Super User example.
- Module names and directive names differ by install. Check your distro/docs for mod_maxminddb vs mod_geoip2 before copying rules.
Block by IP ranges (.htaccess deny list) (блокировка по ip)
If you can’t install a GeoIP module, you can generate a list of Russian IP blocks and deny them in .htaccess. This is simpler to understand but can get very large and slow if placed in .htaccess.
How to get IP ranges:
- Use an IP country database generator (many sites let you export RU CIDR lists). Hostinger explains the workflow and tools to generate lists for .htaccess: Hostinger tutorial.
- Stack Overflow shows practical examples for adding IP ranges to .htaccess and maintaining them: Stack Overflow example.
Example — Apache 2.4 (preferred syntax):
<RequireAll>
Require all granted
Require not ip 5.1.0.0/16
Require not ip 31.24.0.0/13
Require not ip 81.52.168.0/23
# add more CIDR lines...
</RequireAll>
ErrorDocument 403 /russia-blocked.html
Example — Apache 2.2 style (older hosts):
Order allow,deny
Allow from all
Deny from 5.1.0.0/16
Deny from 31.24.0.0/13
# more Deny from lines...
ErrorDocument 403 "This material/link is not available in the Russian Federation"
Or a compact mod_rewrite snippet (for a handful of patterns):
RewriteEngine On
RewriteCond %{REMOTE_ADDR} ^81.52.168.
RewriteRule ^ - [F,L]
ErrorDocument 403 /russia-blocked.html
Caveats:
- Big lists in .htaccess = slow per-request parsing. If you have hundreds or thousands of entries, use server-level config, iptables/nftables, or a CDN/firewall rule instead. InMotionHosting discusses alternatives and testing approaches (see InMotionHosting guide).
- Keep lists up to date — IP allocations change. Automate downloads and an update job (monthly/quarterly).
Hide links inside pages: server-side rendering vs .htaccess filters
Important distinction: .htaccess controls access to URLs on your server. It doesn’t selectively remove an tag from HTML before delivery (unless you use output-filter tricks). So if your goal is that Russian visitors never see links or mentions, do one of the following:
- Server-side conditional rendering (best)
- Detect country server-side (MaxMind DB + PHP/Python/Node library) and render the page without the sensitive links for RU visitors. That way the link never appears in the HTML that leaves your server.
- Minimal PHP example (using GeoIP2 reader via Composer):
<?php
use GeoIp2\Database\Reader;
$reader = new Reader('/path/to/GeoLite2-Country.mmdb');
$ip = $_SERVER['REMOTE_ADDR'];
$country = $reader->country($ip)->country->isoCode ?? '';
if ($country === 'RU') {
echo '<p>This material/link is not available in the Russian Federation</p>';
} else {
echo '<a href="https://britishcouncil.org">British Council</a>';
}
?>
- This is the cleanest, most reliable approach. The link is never present and web-scrapers that fetch the page from a RU IP won’t see it.
- On-the-fly HTML substitution (only if server-side changes are hard)
- Apache’s mod_substitute or mod_ext_filter can replace link fragments in the response body for RU requests. It’s fragile (regex-based) and has a runtime cost.
- Example (conceptual):
SetEnvIf GEOIP_COUNTRY_CODE RU BlockCountry
<If "%{ENV:BlockCountry} == '1'">
AddOutputFilterByType SUBSTITUTE text/html
Substitute "s|<a[^>]*href=\"https?://(www.)?britishcouncil.org[^\"]*\">[^<]*</a>|<span>This material/link is not available in the Russian Federation</span>|ni"
</If>
- Don’t rely on this for many pages or high traffic — it’s brittle, and regex can miss variations.
- Client-side hiding (not recommended)
- JavaScript that hides links based on a geolocation API is easy to bypass and still exposes the link to crawlers and savvy users. Don’t use it as the sole measure.
Which to pick? If you control the application code, do server-side rendering. If you only have .htaccess, use GeoIP blocking or deny lists to prevent access to the target URLs and show the custom message.
Custom 403 message and testing (htaccess блокировка)
You asked for the exact message. Two options:
A — Inline short message (simple):
ErrorDocument 403 "This material/link is not available in the Russian Federation"
This instructs Apache to return that exact string as the body for 403 responses.
B — HTML page (recommended — better UX and branding):
ErrorDocument 403 /russia-blocked.html
Create russia-blocked.html:
<!doctype html>
<html lang="en">
<head><meta charset="utf-8"><title>Not available</title></head>
<body>
<h1>Access restricted</h1>
<p>This material/link is not available in the Russian Federation</p>
</body>
</html>
Testing tips:
- Test from a Russian IP (best): use a Russian VPN or an online proxy. That’s the most reliable check.
- If you can’t VPN, inspect server logs after forcing a request — you’ll see 403 entries.
- If you want to simulate via curl, you can try a known RU IP in the X-Forwarded-For header, but only if your server actually trusts that header (typical only behind a reverse proxy). Example:
curl -i -H “X-Forwarded-For: 5.255.255.5” https://yourdomain/target-page - If you use a CDN/proxy (Cloudflare, Fastly), country detection must use the header that CDN provides (for example, Cloudflare sets CF-IPCountry). You’ll need to check and use that header in your .htaccess logic.
Performance, maintenance and how users bypass blocks (обход геоблокировки)
Practical points you’ll run into:
-
Performance: .htaccess is parsed on every request. Hundreds of deny lines slow Apache. If you’re blocking an entire country, prefer server config (httpd.conf), iptables/nftables, or the CDN/firewall’s geoblocking feature. See the InMotionHosting notes on alternatives and testing: InMotionHosting guide.
-
Maintenance: IP allocations shift. Automate downloading an up-to-date RU CIDR list and regenerating deny rules or updating your GeoIP DB. Hostinger and community examples describe this workflow and trade-offs: Hostinger tutorial.
-
Scale / safety: If your .htaccess becomes thousand+ lines, stop and move to a firewall or CDN rule. Many hosts and CDNs (and WAFs) block by country much more efficiently.
-
Bypass: Any IP-based geoblocking can be defeated by VPNs, proxies, or Tor. Ask: do you need to make content unavailable to casual browsers only, or are you trying to prevent all access? If the latter, consider authentication (require login), remove the content entirely, or take down the pages.
-
Logging & audit: Keep access logs for blocked requests (for legal defense and audits). If you ever need to prove you attempted to restrict access, logs are your friend.
-
Word of caution about legal risk: if the content has already attracted legal attention, consult counsel before publishing or blocking content. Blocking IPs reduces exposure but isn’t a legal shield.
Step-by-step recommended implementation
- Decide scope: block entire site, specific directories (place .htaccess in that directory), or only the pages mentioning the British Council.
- Prefer server-side removal of links for RU visitors (if you can change templates) — use GeoIP lookup in app code.
- If you must use .htaccess only: install a GeoIP module and use a short rule to deny RU (example in Super User).
- Add ErrorDocument 403 /russia-blocked.html (or inline string) with the exact message.
- Test from a RU IP (VPN) and check logs. Adjust rules if behind a proxy/CDN (use header-based detection such as CF-IPCountry).
- Automate GeoIP DB updates or IP-list downloads; move to firewall/CDN if lists grow.
- Monitor bypass attempts (VPNs) and decide whether to require authentication or remove content entirely.
Sources
- How to use .htaccess to block Russian IP addresses? - Super User
- How to Block an IP address range using the .htaccess file - Stack Overflow
- How to Block IP by Country Using .htaccess File - Hostinger
- How to Block a Country Blocking in WordPress via .htaccess & Plugin - GetAstra
- Block Country IPs From Your Site Using htaccess - InMotionHosting
Conclusion
You can implement effective блокировка по ip and htaccess блокировка by using GeoIP in .htaccess (or a deny-list) and returning a custom 403 that says “This material/link is not available in the Russian Federation”. If your aim is that Russian visitors never see the links at all, render pages conditionally on the server (recommended) rather than relying on client-side tricks. For large-scale blocking choose server-level or CDN firewall methods, and remember users can still try обход геоблокировки (VPNs/proxies), so combine technical controls with policy and logging.