W tym przewodniku pokażę jak zablokować dostęp do strony internetowej w wybranych krajach. Jeżeli chcesz serwować swoje treści tylko w wybranych krajach, zablokować ruch z konkretnego państwa bądź dostosowywać treść w zależności od lokalizacji geograficznej odwiedzającego to ten wpis może się okazać pomocny.
Część stron i serwisów internetowych jest zablokowana w wybranych krajach. Kontrolowanie dostępu do strony w zależności od kraju z jakiego następuje połączenie lub różnicowanie treści na podstawie geolokalizacji to szeroko stosowana praktyka. Po wprowadzeniu GDPR wiele zagranicznych serwisów po prostu zablokowało dostęp do swoich treści aby nie musieć dostosowywać się do prawa obowiązującego na terenie Unii Europejskiej. Materiały wybranych kanałów na YouTube są możliwe do obejrzenia tylko w wybranych krajach. Netflix może serwować całkowicie odrębne biblioteki filmów a podobna sytuacja jest z aplikacjami do streamingu muzyki.
Na początku warto sobie uzmysłowić, że geolokalizacja usług internetowych (a w szczególności zlokalizowanie adresów IP) nie jest łatwym zadaniem i zawsze będzie mieć pewne niedoskonałości. Rozstrzygnięcie tego z jakiego kraju nawiązywane jest połączenie z serwerem HTTP polega na analizie adresu IP. Niestety, nie istnieją takie reguły adresowania i przydzielania adresów IP, które pozwalałyby w miarę łatwo i precyzyjnie określić położenie geograficzne lub kraj z jakiego łączy się użytkownik naszej strony. Adres IP można też ukryć za pomocą serwerów pośredniczących (ang. Proxy) bądź usług służących do anonimizacji ruchu np. za pomocą VPN.
Oczywiście, istnieją inne techniki lokalizacji usług w Internecie polegające na deklaracji użytkownika lub detekcji języka używanego w przeglądarce internetowej. To między innymi w ten sposób jesteśmy kierowani na odpowiednie wersje językowe podczas wizyt na wielojęzycznych stronach i sklepach internetowych. Te ustawienia deklaruje sam użytkownik i są łatwe do zmiany w zależności od bieżących potrzeb dlatego jak się można domyślić, nie nadają się one do stosowania w zabezpieczeniach, blokadach i prób nakładania ograniczeń, które nas w tym momencie interesują.
Jak określić lokalizację adresu IP?
W przypadku testowania usług hostingowych używałem narzędzia check-host.net do sprawdzenia czy serwer jest postawiony w Polsce czy zagranicą.

Skąd zatem takie narzędzia wiedzą gdzie należy dany adres IP? Narzędzia i API służące do odpytywania o kraj pochodzenia danego adresu IP korzystają z baz danych. Testując adres IP otrzymujemy czasem kilka wyników. W check-host są to aż 4 wyniki pochodzą one z baz:
- DB-IP,
- IPGeolocation.io,
- IP2Location,
- MaxMind GeoLite2
No dobra ale skąd te bazy danych wiedzą do kogo należy dany adres IP? Najpierwotniejszym źródłem o konkretnych adresach jest WHOIS.
WHOIS
WHOIS to szeroko rozpowszechniony protokół TCP, który wysyła zapytania do baz danych DNS po to aby właśnie rozpoznać właściciela domeny czy właściciela danego adresu IP. Z WHOIS można korzystać z poziomu wiersza poleceń. W systemie Windows trzeba pobrać program:

W powyższym przykładzie adres IP został rozwinięty na domenę mansfeld.pl za pomocą rekordu PTR czyli revDNS. Jeżeli nie ustawiłbym tego rekordu pojawiłaby się domena Google Cloud. Każdy adres IP nawet twój aktualny publiczny adres IP da się przekształcić w nazwę domenową za pomocą narzędzia nslookup. Taki adres to przykładowo
apn-95-42-126-5.dynamic.gprs.plus.pl
Po końcówce plus.pl ewidentnie widać, że adres IP należy do Polski i to stąd bazy danych wiedzą gdzie przynależy dany adres IP.
Skoro jest WHOIS to dlaczego wykorzystujemy dodatkowe bazy danych?
Ktoś może zapytać, skoro mamy standard w postaci WHOIS to po co nam jakieś dodatkowe bazy? Po pierwsze: odpowiedź nie jest zwracana natychmiastowo i odpytywanie wspomnianych baz danych (takich jak MaxMind GeoLite2) należy traktować jak korzystanie z pamięci podręcznej. Po drugie: jeżeli ISP korzystałby z domeny .net to określenie kraju nie byłoby tak oczywiste. W dużym uproszczeniu, w bazach danych są zawarte jeszcze dodatkowe informacje, które pozwalają na dokładniejsze i pewniejsze przypisanie krajów do konkretnych adresów IP. Bazy danych nie zawierają wszystkich adresów IP. Posiadają zakresy i inne dodatkowe reguły, które pozwalają zachować ich racjonalny rozmiar.
Jedną z takich baz jest GeoLite2. GeoLite2 jest nieco mniej dokładna niż GeoIP ale za to jest ona całkowicie darmowa. W tym przewodniku wykorzystam bazę GeoLite2 Country. Są one aktualizowane co tydzień we Wtorek. GeoLite2 jest dostępny jako plik oraz web serwis. Ponieważ darmowe konta mogą wykonać tylko 1000 zapytań dziennie wykorzystamy bazy danych w formie pliku do ściągnięcia.

Link: https://dev.maxmind.com/geoip/geolite2-free-geolocation-data?lang=en
Blokada ruchu z danego kraju na poziomie serwera
W tej części pokażę jak zablokować ruch z danego kraju na serwerach Apache.
Krok 1: Pobieranie bazy danych
Na samym początku skopiujmy sobie pobraną bazę danych do folderu /usr/local/share/GeoIP/
Krok 2: Instalacja bibliotek i modułu
Aby moduł Apache działał, musi być zainstalowana biblioteka C libmaxmind. MaxMind udostępnia PPA dla najnowszej wersji Ubuntu. Aby dodać PPA do źródeł APT, uruchom:
sudo add-apt-repository ppa:maxmind/ppa
Następnie intalujemy:
sudo apt update
sudo apt install libmaxminddb0 libmaxminddb-dev mmdb-bin
Następnie instalujemy deweloperską paczkę Apache:
sudo apt-get install apache2-dev
Instalujemy mod_maxminddb:
sudo wget https://github.com/maxmind/mod_maxminddb/releases/download/1.2.0/mod_maxminddb-1.2.0.tar.gz sudo tar -xvzf mod_maxminddb-1.2.0.tar.gz sudo ./configure sudo make install
Następnie resetujemy Apache:
sudo systemctl restart apache2
Krok 3: Połączenie bazy danych z Apache
W pliku konfiguracyjnym Apache, czyli w /etc/apache2/apache2.conf lub w pliku .htaccess umieszczamy link do bazy: danych:
MaxMindDBEnable On
MaxMindDBFile COUNTRY_DB /usr/local/share/GeoIP/GeoLite2-Country.mmdb
MaxMindDBEnv MM_COUNTRY_CODE COUNTRY_DB/country/iso_code
Krok 4: Blokada krajów
W tym samym miejscu tworzymy listę krajów, które chcemy zablokować. Do celów testowych wybieramy Polskę i inne kraje np. Rosję (którą już tutaj sobie zostawimy na stałe) i przykładowo Niemcy:
SetEnvIf MM_COUNTRY_CODE ^(RU|DE|PL) BlockCountry Deny from env=BlockCountry
Sprawdzamy czy działa:

libapache2-mod-geoip
Alternatywnym rozwiązaniem jest skorzystanie z modułu libapache2-mod-geoip bazującego na bibliotece i bazie danych GeoIP.
Instalujemy:
sudo apt install libapache2-mod-geoip
Włączamy:
sudo a2enmod geoip
W pliku /etc/apache2/mods-available/geoip.conf zmieniamy Off na On i odkomentowujemy linię ze ścieżką do pliku GeoIP.dat:
<IfModule mod_geoip.c> GeoIPEnable On GeoIPDBFile /usr/share/GeoIP/GeoIP.dat </IfModule>
W pliku konfiguracyjnym apache.conf lub w .htaccess możemy wybrać kraje do zablokowania:
SetEnvIf GEOIP_COUNTRY_CODE RU BlockCountry SetEnvIf GEOIP_COUNTRY_CODE DE BlockCountry Deny from env=BlockCountry
Po restarcie serwera blokada działa zwracając nagłówek 403 – dokładnie tak jak w przypadku korzystania z modułu mod_maxminddb.
Blokada ruchu z konkretnego kraju na poziomie aplikacji
Nie każdy z nas ma dostęp do pełnej konfiguracji serwera. W tej części pokażę jak zablokować ruch z danego kraju w na poziomie aplikacji na przykładzie najpopularniejszego systemu CMS WordPress. Pobieramy tę samą paczkę z bazą danych GeoLite2 jak w przypadku kroku powyżej.
Krok 1: Pobieranie bazy danych
Pobieramy bazę danych z serwisu MaxMind i kopiujemy ją do lokalizacji: /wp-content/uploads/GeoLite2-Country.mmdb
Krok 2: Instalacja wtyczki
Istnieje wiele wtyczek do blokowania krajów. Jedną z nich jest iQ Block Country Autor: Pascal.
Krok 3: Konfiguracja i wybór krajów
Konfigurujemy wtyczkę według potrzeb.

Sprawdźmy czy działa:

Ta metoda ma jednak zasadniczą wadę. Blokada wymaga zadziałania logiki aplikacji i ograniczenie nie będzie działać kiedy strona używa wtyczki cache takich jak WP Super cache lub W3 Total Cache. W skrajnych przypadkach strona może przez to działać trochę wolniej.
Alternatywne metody blokowania ruchu z konkretnego kraju
Istnieją także inne metody na blokowanie ruchu z konkretnych krajów.
Hosting z wbudowaną funkcją blokowania krajów
Jedną z nich mogą być rozwiązania, które udostępniają usługodawcy hostingu internetowego. Niektóre usługi hostingowe mają porostu wbudowany filtr, który umożliwia odrzucać połączenia pochodzące z konkretnych krajów. Jedną z takich firm hostingowych jest 20i.

Nie znam jakości usług oferowanych przez tę firmę ale unikalna funkcja blokowania ruchu internetowe z konkretnych krajów to coś co przykuwa moją uwagę i świadczy o innowacyjnym podejściu do świadczenia usług.
Generatory ACL
Kolejnym rozwiązaniem mogą być generatory ACL (ang. Access Control List), które wygenerują zakresy adresów IP i całe podsieci, które powinny przynależeć do konkretnego kraju. Jednym z takich serwisów jest https://www.countryipblocks.net/acl.php

Na specjalnej stronie możemy wybrać listę krajów i natychmiastowo wygenerować zakresy IP. Tak przygotowaną listę można teraz wkleić do pliku .htaccess lub do pliku konfiguracyjnego Apache. Rozwiązanie wydaje się być najłatwiejsze do zastosowania na własnym serwerze ale nie mam jednak dokładnych informacji co do tego, na ile generowane w ten sposób listy zakresów IP są dokładne.
Rozwiązania CDN i usługi Reverse Proxy
Na końcu ale nie mniej istotne są rozwiązania CDN. Cloudflare pozwala na blokowanie dostępu na podstawie lokalizacji od pakietu Enterprise.
Popularne rozwiązania CDN takie jak AWS Cloudfront pozwalają na blokowanie połączeń z konkretnych krajów. Przykładowo, aby włączyć ograniczenie geolokalizacyjne w dystrybucji Cloudfront należy przejść do konsoli AWS i wybrać dystrybucję Cloudfront, którą chcemy zablokować w wybranym kraju. Wybieramy zakładkę Geographic Restrictions i klikamy Edit. Wybieramy Block List i wpisujemy państwa, w którym nasza dystrybucja Cloudfront ma odmówić dostępu do swoich zasobów.

Na koniec zapisujemy zmiany.
Podsumowanie
Istnieje wiele technik na zablokowanie dostępu do strony z konkretnych krajów. Jako właściciele stron i sklepów internetowych mamy prawo do blokowania ruchu w konkretnych krajach. Zwróć uwagę na zalety pod kątem oszczędności zasobów i bezpieczeństwa. Przeglądając logi ataków, adresy e-mail podejrzanych kont lub treść spamerskich komentarzy można zauważyć, że większość takich ataków pochodzi z konkretnych krajów. Blokada ruchu przychodzącego z tych lokalizacji może być jedną z najlepszych decyzji, która zapewni bezpieczeństwo i znacznie obniży koszt skalowalnych stron i aplikacji internetowych.
Źródła
- https://github.com/maxmind/libmaxminddb
- https://aws.amazon.com/premiumsupport/knowledge-center/cloudfront-geo-restriction/
- https://www.sitepoint.com/how-to-block-entire-countries-from-accessing-website/
- https://www.20i.com/support/web-hosting/block-visitors-by-country
Odpowiedz lub skomentuj