Один мой друг (ОМД) как-то спросил у меня: «Апельсин, а как бы вот заблокировать целую страну, чтобы не могли твой сайт посещать? Китайцы лезут, индусы достают, да и после переезда в Европу хочется забыть про скрепы и прочую духовность». Я объяснил в общих чертах, что сделать это можно так: geoip + настройка nginx, либо без — прямо через .htaccess отрубать и все. ОМД пошел настраивать, но ничего у него не вышло: в nginx нет нужного модуля и его нужно пересобрать, а в htaccess он не умеет (я, кстати, тоже не очень). Ну, тут я понял, что проще самому настроить и написать мануал в бложек, авось пригодится. Вобщем, перво-наперво нам понадобится установленный на сервере GeoIP. Как его устанавливать я писать не буду, ибо процедура примитивная: yum и pecl всем в помощь. Будем отталкиваться, что на сервере geoip имеется. Чтобы nginx обрабатывал оттуда данные, требуется иметь nginx, собранный вместе с модулем http_geoip_module. Обычно, за такую процедуру админы возьмут с вас рублей 500, да и доступ к серверу придется дать. Не ссым, сейчас мы научимся добавлять модули самостоятельно.

Как добавить модуль в конфигурацию nginx

Коннектимся к серверу по ssh и в консоли набираем

nginx -V

и смотрим на список того ,что нам ответили.

nginx -V
nginx version: nginx/1.8.0
built by gcc 4.8.5 20150623 (Red Hat 4.8.5-4) (GCC)
built with OpenSSL 1.0.1e-fips 11 Feb 2013
TLS SNI support enabled
configure arguments: —prefix=/etc/nginx —sbin-path=/usr/sbin/nginx —conf-path=/etc/nginx/nginx.conf —error-log-path=/var/log/nginx/error.log —http-log-path=/var/log/nginx/access.log —pid-path=/var/run/nginx.pid —lock-path=/var/run/nginx.lock —http-client-body-temp-path=/var/cache/nginx/client_temp —http-proxy-temp-path=/var/cache/nginx/proxy_temp —http-fastcgi-temp-path=/var/cache/nginx/fastcgi_temp —http-uwsgi-temp-path=/var/cache/nginx/uwsgi_temp —http-scgi-temp-path=/var/cache/nginx/scgi_temp —user=nginx —group=nginx —with-http_ssl_module —with-http_realip_module —with-http_addition_module —with-http_sub_module —with-http_dav_module —with-http_flv_module —with-http_mp4_module —with-http_gunzip_module —with-http_gzip_static_module —with-http_random_index_module —with-http_secure_link_module —with-http_stub_status_module —with-http_auth_request_module —with-mail —with-mail_ssl_module —with-file-aio —with-ipv6 —with-http_spdy_module —with-cc-opt=’-O2 -g -pipe -Wall -Wp,-D_FORTIFY_SOURCE=2 -fexceptions -fstack-protector-strong —param=ssp-buffer-size=4 -grecord-gcc-switches -m64 -mtune=generic’ —with-http_geoip_module

Если в списке присутствует with-http_geoip_module (а выше он присутствует), то это хорошо и пересобирать ничего не нужно. Если же нет, то тогда — начинаем этот модуль добавлять.

1. Сначала сохраним все, что мы получили после nginx -V куда-нибудь в Notepad++ или в Sublime, в дальнейшем нам это пригодится.
2. Посмотрим, какая версия nginx у нас сейчас стоит: в выводе команды видно, что это 1.8.0
3. Качаем такую же версию с сайта разработчика, распаковываем, переходим в папку:

# wget http://nginx.org/download/nginx-1.8.0.tar.gz
# tar –xvf nginx-1.8.0.tar.gz
# cd nginx-1.8.0

4. В процессе нам понадобятся кое-какие пакеты и сейчас мы их установим. Если пакеты уже стоят, то ставить не надо. Не страшно ввести команду — если пакет есть, то увидите что-то типа «already installed» или типа того. Итак.

# yum install gcc gcc-c++ kernel-devel
# yum groupinstall ‘Development Tools’

5. Теперь самое главное — начинаем добавлять нужный нам модуль, в нашем случае http_geoip_module.
Копируем то, что мы сохранили в блокноте, начиная от —prefix и заканчивая последним модулем (—with-бла-бла-бла), пишем в консоли

./congigure

Жмем пробел и вставляем скопированное из блокнота. Таким образом, должно получиться как-то так:

./congigure —prefix=/etc/nginx —sbin-path=/usr/sbin/nginx —conf-path=/etc/nginx/nginx.conf —error-log-path=/var/log/nginx/error.log —http-log-path=/var/log/nginx/access.log —pid-path=/var/run/nginx.pid —lock-path=/var/run/nginx.lock —http-client-body-temp-path=/var/cache/nginx/client_temp —http-proxy-temp-path=/var/cache/nginx/proxy_temp —http-fastcgi-temp-path=/var/cache/nginx/fastcgi_temp —http-uwsgi-temp-path=/var/cache/nginx/uwsgi_temp —http-scgi-temp-path=/var/cache/nginx/scgi_temp —user=nginx —group=nginx —with-http_ssl_module —with-http_realip_module —with-http_addition_module —with-http_sub_module —with-http_dav_module —with-http_flv_module —with-http_mp4_module —with-http_gunzip_module —with-http_gzip_static_module —with-http_random_index_module —with-http_secure_link_module —with-http_stub_status_module —with-http_auth_request_module —with-mail —with-mail_ssl_module —with-file-aio —with-ipv6 —with-http_spdy_module —with-cc-opt=’-O2 -g -pipe -Wall -Wp,-D_FORTIFY_SOURCE=2 -fexceptions -fstack-protector-strong —param=ssp-buffer-size=4 -grecord-gcc-switches -m64 -mtune=generic’

И добавляем в конце, сделав пробел, —with-http_geoip_module, чтобы общая картина выглядела так:

./congigure —prefix=/etc/nginx —sbin-path=/usr/sbin/nginx —conf-path=/etc/nginx/nginx.conf —error-log-path=/var/log/nginx/error.log —http-log-path=/var/log/nginx/access.log —pid-path=/var/run/nginx.pid —lock-path=/var/run/nginx.lock —http-client-body-temp-path=/var/cache/nginx/client_temp —http-proxy-temp-path=/var/cache/nginx/proxy_temp —http-fastcgi-temp-path=/var/cache/nginx/fastcgi_temp —http-uwsgi-temp-path=/var/cache/nginx/uwsgi_temp —http-scgi-temp-path=/var/cache/nginx/scgi_temp —user=nginx —group=nginx —with-http_ssl_module —with-http_realip_module —with-http_addition_module —with-http_sub_module —with-http_dav_module —with-http_flv_module —with-http_mp4_module —with-http_gunzip_module —with-http_gzip_static_module —with-http_random_index_module —with-http_secure_link_module —with-http_stub_status_module —with-http_auth_request_module —with-mail —with-mail_ssl_module —with-file-aio —with-ipv6 —with-http_spdy_module —with-cc-opt=’-O2 -g -pipe -Wall -Wp,-D_FORTIFY_SOURCE=2 -fexceptions -fstack-protector-strong —param=ssp-buffer-size=4 -grecord-gcc-switches -m64 -mtune=generic’ —with-http_geoip_module

Жамкаем Энтер и наблюдаем за процессом. Если все пройдет без ошибок, то в конце мы увидим список путей, которыми nginx пользуется:

nginx configuration prefix: «/etc/nginx»
nginx configuration file: «/etc/nginx/nginx.conf»
nginx pid file: «/var/run/nginx.pid»
nginx error log file: «/var/log/nginx/error.log»
итд.

Если по ходу пьесы будут возникать ошибки, то тогда необходимо доставить то, чего не хватает. Ниже я приведу список того, что, возможно, придется доставлять. Сравнивайте требования в ошибке с библиотеками, которые в списке ниже и доставляйте. Итак, список того, что возможно попросят поставить и команда установки.

# yum install openssl-devel
# yum install GeoIP-devel
# yum install libxslt-devel
# yum install pcre-devel

Если ошибки возникали и вы что-то ставили из списка выше, то после каждой установки сбоку nginx надо запускать заново:

./congigure —prefix=/etc/nginx —sbin-path=/usr/sbin/nginx —conf-path=/etc/nginx/nginx.conf —error-log-path=/var/log/nginx/error.log —http-log-path=/var/log/nginx/access.log —pid-path=/var/run/nginx.pid —lock-path=/var/run/nginx.lock —http-client-body-temp-path=/var/cache/nginx/client_temp —http-proxy-temp-path=/var/cache/nginx/proxy_temp —http-fastcgi-temp-path=/var/cache/nginx/fastcgi_temp —http-uwsgi-temp-path=/var/cache/nginx/uwsgi_temp —http-scgi-temp-path=/var/cache/nginx/scgi_temp —user=nginx —group=nginx —with-http_ssl_module —with-http_realip_module —with-http_addition_module —with-http_sub_module —with-http_dav_module —with-http_flv_module —with-http_mp4_module —with-http_gunzip_module —with-http_gzip_static_module —with-http_random_index_module —with-http_secure_link_module —with-http_stub_status_module —with-http_auth_request_module —with-mail —with-mail_ssl_module —with-file-aio —with-ipv6 —with-http_spdy_module —with-cc-opt=’-O2 -g -pipe -Wall -Wp,-D_FORTIFY_SOURCE=2 -fexceptions -fstack-protector-strong —param=ssp-buffer-size=4 -grecord-gcc-switches -m64 -mtune=generic’ —with-http_geoip_module

6. Теперь, соственно, компилируем бинарник nginx. Сначала выполняем

# make

а после

# make install

и ждем завершения процесса.

7. Проверяем, что у нас все установилось и тут есть два варианта: либо новый бинарник собрался сразу там, где надо — /usr/sbin/nginx, а старый — забекапился там же в nginx.old. Либо, он собрался в папке /etc/nginx/sbin/nginx и тогда нам надо его переместить в нужное место. Итак, если бинарник собрался в /etc/nginx/sbin/nginx, то тогда:
останавливаем nginx,

# service nginx stop (CentOS до 6.х)
# systemctl stop nginx.service (CentOS от 7.х)

делаем бэкап старого бинарника,

# mv /usr/sbin/nginx /usr/sbin/nginx.old

свежесобранный бинарник отправляем туда, где он и должен работать:

# mv /etc/nginx/sbin/nginx /usr/sbin/nginx

Ну и запускаемся:

# service nginx start (CentOS до 6.х)
# systemctl start nginx.service (CentOS от 7.х)

Если бинарник сразу собрался там, где надо (/usr/sbin/nginx) и создал бэкап .old, то телодвижений с переименованием и переносом не нужно, да и нечего будет переносить)
Проверяем, есть ли модуль:

nginx -V

и если все хорошо, то видим, что мы пересобрали nginx с нужным нам модулем:

nginx -V
nginx version: nginx/1.8.0
built by gcc 4.8.5 20150623 (Red Hat 4.8.5-4) (GCC)
built with OpenSSL 1.0.1e-fips 11 Feb 2013
TLS SNI support enabled
configure arguments: —prefix=/etc/nginx —sbin-path=/usr/sbin/nginx —conf-path=/etc/nginx/nginx.conf —error-log-path=/var/log/nginx/error.log —http-log-path=/var/log/nginx/access.log —pid-path=/var/run/nginx.pid —lock-path=/var/run/nginx.lock —http-client-body-temp-path=/var/cache/nginx/client_temp —http-proxy-temp-path=/var/cache/nginx/proxy_temp —http-fastcgi-temp-path=/var/cache/nginx/fastcgi_temp —http-uwsgi-temp-path=/var/cache/nginx/uwsgi_temp —http-scgi-temp-path=/var/cache/nginx/scgi_temp —user=nginx —group=nginx —with-http_ssl_module —with-http_realip_module —with-http_addition_module —with-http_sub_module —with-http_dav_module —with-http_flv_module —with-http_mp4_module —with-http_gunzip_module —with-http_gzip_static_module —with-http_random_index_module —with-http_secure_link_module —with-http_stub_status_module —with-http_auth_request_module —with-mail —with-mail_ssl_module —with-file-aio —with-ipv6 —with-http_spdy_module —with-cc-opt=’-O2 -g -pipe -Wall -Wp,-D_FORTIFY_SOURCE=2 -fexceptions -fstack-protector-strong —param=ssp-buffer-size=4 -grecord-gcc-switches -m64 -mtune=generic’ —with-http_geoip_module

На этом все с добавлением модуля в nginx) На самом деле это совсем не сложно и займет у вас минут 5-7, просто я старался максимально с подробностями. Итак, мы добавили модуль в конфиг. А теперь самое время закрыть нахер доступ к сайту из неугодных нам стран!)

Запрещаем просмотр сайта из определенных стран

У нас установлен geoip и модуль для nginx, приступаем к настройке.
1. Заходим в конфиг nginx (/etc/nginx/nginx.conf) и добавляем в http {} секцию следующее

geoip_country /usr/share/GeoIP/GeoIP.dat;
map $geoip_country_code $bad_country {
default 1;
include goodcountries;
}

Путь к /usr/share/GeoIP/GeoIP.dat у вас может отличаться, так что проверьте, где лежит GeoIP.dat

Этим конфигом мы сказали nginx, что ему нужно смотреть откуда пришел юзер по geoip и сверять страну с файлом goodcountries, который мы сейчас и заполним.
Создаем в /etc/nginx/ сам файл goodcountries и наполняем его вот таким содержимым.
А теперь подключаем это к конфигу самого сайта в nginx, в секцию localhost:

if ($bad_country){
return 403;
}

и получится вот такой location

location @fallback {
proxy_pass http://127.0.0.1:8080;
proxy_redirect http://127.0.0.1:8080 /;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
access_log off ;
if ($bad_country){
return 403;
}

}

Вот и все. Перезапускаем nginx и на этом мучения закончились)
Теперь, если мы хотим заблокировать какую-либо страну и запретить оттуда доступ к нашему сайту, то в файле goodcountries мы просто меняем «0» на «1» напротив нужной страны. Также, в файл можно добавить значения:

A1 1;
A2 1;
O1 1;

Где А1 — блокирует доступ через анонимные прокси, А2 — доступ через спутниковых провайдеров и О1 — блокирует «прочие» страны.

На этом на сегодня все) Надеюсь, было полезно. А я беру пока отпуск от постов и ухожу в запой на пару деньков, а то я подустал). А к пятнице намечено похмел пати, на котором я напишу первый пост из серии «Отчет по Евротрипу».

PS. Забыл добавить, что базы данных GeoIP нужно обновлять хотя бы раз в месяц. Делать руками это весьма геморно, поэтому бонусом вам bash скриптик, который будет делать это на автомате)
Создадим где-нибудь в непалевной папке сервера скрипт и назовем его updgeo.sh и наполним его вот таким содержимым:

#!/bin/bash
cd /usr/share/GeoIP/
mv GeoIP.dat GeoIP.dat.old && mv GeoLiteCity.dat GeoLiteCity.dat.old
/usr/bin/wget http://geolite.maxmind.com/download/geoip/database/GeoLiteCountry/GeoIP.dat.gz
/usr/bin/wget http://geolite.maxmind.com/download/geoip/database/GeoLiteCity.dat.gz
gunzip GeoIP.dat.gz && gunzip GeoLiteCity.dat.gz

Обязательно ставим нужные права:

# chmod 750 /ne/palevnaya/papka/updgeo.sh

И ставим на крон раз в неделю-месяц. Вот, теперь точно все)


8 Comments

  1. спасибо )

  2. Апельсин а неподскажешь такую вещь, провайдер закрыл доступ к сайту. Как обойти запрет и снова открыть сайт. Не все ру провайдеры блокируют а некоторые. И такая ерунда, кто-то из рашки заходит а кто-то хрен. Пробовал заходить через анонимайзер, но там не все работает на сайте с таким заходом. Может подскажешь какой то норм анонимайзер.Через проси ненадо, нужен ип мой РФ.

    • ClockWorkOrange

      Я чего то подзабыл: в РФ уже ввели ответственность за публикацию материалов об обходе блокировок? Или еще нет?)

      Отвечу я тебе так. То, что заблокированный сайт доступен через некоторых провайдеров, — явление временное. Просто не все провайдеры успели обновить «расстрельные» списки, обновить ДНС и вот это все. Через месяц зайти на сайт не получится совсем.

      Когда ты заходишь через анонимайзер, то ясное дело работать будет не все. Не будет работать JS и тд. Поэтому тебе нужен VPN или SSH-туннель, через который ты будешь смотреть заблокированные сайты. Сервисов по предоставлению VPN огромное множество, есть и русскоязычные и нет. Цена от 50 рублей в месяц. Гуглишь «VPN» и выбираешь на вкус и кошелек.

      С SSH-туннелем тебе придется настраиваться самому, но это не так сложно. В любом случаем, при использовании таких серверов у тебя не будет IP из РФ, будут IP других стран.

      И, конечно же, я против таких действий, как обход блокировок!!11 Если правительство заблокировало какой-то сайт, то оно все сделало правильно: может, на этих сайтах учат нехорошему и вообще там нет духовности!
      Государство заботится о нас и это надо ценить!!11

  3. VPN за 50 руб?! Нет сейчас таких, ибо сервис востребован как никогда прежде. За нормальный готовьте платить от 10$ до 20$ или берите VPS за 5 баксов и ставьте сами.

    • ClockWorkOrange

      Даже бесплатные имеются пока еще) А также фригейт в виде браузерного плагина и тд.

  4. Да так в казино хорошим хотел посидеть поиграть :-). Кстати там можно и на фантики играть. Но самое главное там можно выиграть, в отличии от того что у нас якобы убрано (но на самом деле все осталось в офлайне, но только играют через компьютер,в зале где и раньше были, только сейчас там букмекерская, а в соседнем зале пожалуйста. И естественно все там скручено, обычный скрипт настраиваемый, в отличии от норм софта в европейских казино) Тоесть наши неразрешают играть в западных казино, а в наших лохотронах пожалуйста! :-)

Комментарии закрыты, так как статья древняя.

Close