НОВОСТИ Настройка GeoIP ACL в HAProxy в два шага

Bonnie
Оффлайн
Регистрация
12.04.17
Сообщения
19.095
Реакции
107
Репутация
0
7qdgdzgalavv30lucx95rbufjnw.jpeg



Иногда возникает задача управления трафиком в зависимости от географического положения клиента. Возможные области применения — блокировка некоторых локаций либо перенаправление трафика на итоговый сервер в зависимости от локации клиента. Традиционно подобные вещи реализуются при помощи библиотек GeoIP компании . В статье расскажу, как это сделать.

Настройка доступа к библиотекам MaxMind


Раньше не нужно было настраивать доступ, так как MaxMind предоставляли часть своих библиотек для прямого скачивания по ссылке. Однако сейчас . Поэтому сначала нужно , заполнив форму:

2292acb39fa7370ec5b9e8803c86d905.png


После этого шага вам на почту придет письмо с дальнейшими инструкциями:

f631693cdb8d7e99c5a5103a357b51d1.png


Перейдите по ссылке для создания пароля:

93cbc58ec351a8b22ab3c01f8de664a6.png


После завершения регистрации вы попадете в личный кабинет:

88da34da8a0e4f3750af4cdcdb758abf.png


Чтобы скачивать файлы MaxMind напрямую, необходимо выписать лицензию на сайте. Для этого нужно перейти по ссылке My License Key:

e54d008028cc86e7bc088c915dd0c2be.png


Далее:

28441ad53f1c9b8b35e4984a42deb7f1.png


Далее:

793cfca2e41df86e57044c5539faa08c.png


На экране отобразится номер лицензии, который нужно сохранить — потом увидеть его будет нельзя, только выписывать новую лицензию:

d014dd2771d55b50d5e2788925934912.png


Теперь, с номером лицензии, можно скачивать файлы баз данных GeoIP. Как это сделать .

Дальше переходим по ссылке: , и нажимаем линк Get permalinks напротив базы данных GeoLite2 Country: CSV Format:

460654902c0e8eaf4f46cd4888caccd2.png


В следующем окне указаны ссылки на скачивание:

8a9cdaa4a329cd62ffc9938f4e698d63.png


Обратите внимание, что нужно заменить YOUR_LICENSE_KEY на вашу лицензию, которую вы выписали ранее.

На этом настройка получения базы GeoIP закончена, переходим непосредственно к настройке.

Настройка HAProxy


HAProxy не умеет работать напрямую с базами MaxMind, однако умеет строить ACL на основе списков сетей. Вот как это описывается в конфиге HAProxy:


frontend frontend-https
bind *:80

# GeoIP ACL
acl acl_SNG src -f /etc/haproxy/geoip/SNG.txt

Содержимое файла /etc/haproxy/geoip/SNG.txt:


...
188.215.252.0/22
188.237.0.0/16
188.240.70.0/24
188.244.16.0/20
191.96.60.0/23
192.121.87.0/24
193.8.167.0/24
193.16.111.0/24
193.17.78.0/24
...

То есть файл SNG.txt содержит в себе список сетей, которые попадут в ACL.

Перед нами стоит задача автоматизировать создание файла со списком сетей из баз данных MaxMind.

Сформулируем задачу, которую мы хотим решить: необходимо, чтобы трафик из России, Беларуси и Украины шел на один бэкенд, а трафик из других локаций уходил на другой бэкенд. Для решения этой задачи напишем shell-скрипт. Скрипт будет состоять из нескольких этапов.

Сначала получим свежую копию базы данных MaxMind в формате csv:


# Download geoip2 lite csv database
wget
" {MAXMIND_LICENSE}&suffix=zip" -qO geoip2lite.zip
&& unzip -j geoip2lite.zip

Здесь ${MAXMIND_LICENSE} — это номер лицензии, который мы выписали ранее на сайте MaxMind.

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


root@ash:/tmp/geo2lite# ls -1
COPYRIGHT.txt
GeoLite2-Country-Blocks-IPv4.csv
GeoLite2-Country-Blocks-IPv6.csv
GeoLite2-Country-Locations-de.csv
GeoLite2-Country-Locations-en.csv
GeoLite2-Country-Locations-es.csv
GeoLite2-Country-Locations-fr.csv
GeoLite2-Country-Locations-ja.csv
GeoLite2-Country-Locations-pt-BR.csv
GeoLite2-Country-Locations-ru.csv
GeoLite2-Country-Locations-zh-CN.csv
LICENSE.txt
README.txt

Нас интересуют два файла — GeoLite2-Country-Blocks-IPv4.csv, содержащий информацию о принадлежности сетей ipv4 странам, и GeoLite2-Country-Locations-en.csv, содержащий соответствия названий стран цифровым кодам.

Соответственно, если нам нужно получить все сети, принадлежащие России, мы для начала получаем код России:


root@ash:/tmp/geo2lite# cat GeoLite2-Country-Locations-en.csv | grep
Russia
2017370,en,EU,Europe,RU,Russia,0

Здесь 2017370 — это искомый код.

Теперь по нему можно определить сети.


root@ash:/tmp/geo2lite# cat GeoLite2-Country-Blocks-IPv4.csv | grep 2017370
...
217.147.16.0/20,2017370,2017370,,0,0
217.148.48.0/20,2017370,2017370,,0,0
217.148.192.0/19,2017370,2017370,,0,0
217.149.16.0/20,2017370,2017370,,0,0
217.149.176.0/20,2017370,2017370,,0,0
217.150.0.0/18,2017370,2017370,,0,0
217.150.72.0/21,2017370,2017370,,0,0
217.150.192.0/20,2017370,2017370,,0,0

Обратите внимание, что число 2017370 встречается в каждой строке два раза. Обратимся к описанию формата файла:


root@ash:/tmp/geo2lite# cat GeoLite2-Country-Blocks-IPv4.csv | head -n 1
network,geoname_id,registered_country_geoname_id,represented_country_geo
name_id,is_anonymous_proxy,is_satellite_provider

Здесь registered_country_geoname_id — код страны, за которой зарегистрирована сеть, а represented_country_geoname_id — код страны, из которой происходит роутинг сети.

Возможна ситуация, когда сеть зарегистрирована, например за Россией, а роутинг происходит из Голландии. Как поступать в такой ситуации, решайте сами, я выбирал только сети, зарегистрированные и маршрутизируемые из запрашиваемой страны.

Соответственно, выбирая нужные сети из файла GeoLite2-Country-Blocks-IPv4.csv, можно сформировать файл для HAProxy ACL.

Сама работа с ACL в HAProxy:


frontend frontend
# GeoIP ACL
acl acl_SNG src -f /etc/haproxy/geoip/SNG.txt

use_backend backend1 if acl_SNG
default_backend backend2

Соответственно, если IP-адрес источника будет из сети, описанной в файле SNG.txt, то запрос уйдет на backend1, в противном случае — на backend2.

Для автоматизации операций был написан скрипт:


root@ash:~# cat haproxy_geoip_list.sh
#!/bin/bash
#-----------------------------------------------------------------------------------------------------------------------
# Variables
TMPDIR="/tmp/geo2lite"
MAXMIND_LICENSE="xxxxxxxxxxxxx"
LOCATIONS="Russia Ukraine Belarus"
HAPROXY_PATH="/etc/haproxy/geoip"
HAPROXY_FILE="SNG.txt"
#-----------------------------------------------------------------------------------------------------------------------
mkdir -p ${TMPDIR}
pushd ${TMPDIR}
# Download geoip2 lite csv database
wget
" {MAXMIND_LICENSE}&suffix=zip" -qO geoip2lite.zip
&& unzip -j geoip2lite.zip
if [ $? -gt 0 ]; then
logger -t "haproxy_geoip" "Download not success."
exit 1
fi

exit
for COUNTRY in ${LOCATIONS}; do
echo "# ${COUNTRY}"
COUNTRY_CODE=`cat GeoLite2-Country-Locations-en.csv | grep -i
"${COUNTRY}" | awk -F "," '{print $1}'`
grep ",${COUNTRY_CODE}," GeoLite2-Country-Blocks-IPv4.csv | awk -F ","
'{print $1}'
done > ${HAPROXY_FILE}

# Check file
if [ ! -s ${HAPROXY_FILE} ]; then
logger -t "haproxy_geoip" "File is not exist"
exit 1
fi

if [ -s ${HAPROXY_PATH}/${HAPROXY_FILE} ]; then
MD5_FILE=`md5sum ${HAPROXY_PATH}/${HAPROXY_FILE} | awk '{print $1}'`
fi

MD5_TMPFILE=`md5sum ${HAPROXY_FILE} | awk '{print $1}'`

if [ "${MD5_TMPFILE}" != "${MD5_FILE}" ]; then
logger -t "haproxy_geoip" "File ${HAPROXY_FILE} is changed"
cp ${HAPROXY_PATH}/${HAPROXY_FILE}
${HAPROXY_PATH}/${HAPROXY_FILE}.backup
mv ${HAPROXY_FILE} ${HAPROXY_PATH}/${HAPROXY_FILE}
# Test new haprpoxy cfg
/usr/sbin/haproxy -c -f /etc/haproxy/haproxy.cfg
if [ $? -gt 0 ]; then
logger -t "haproxy_geoip" "New file is corrupted, replace by older one from backup."
mv ${HAPROXY_PATH}/${HAPROXY_FILE}.backup
${HAPROXY_PATH}/${HAPROXY_FILE}
fi
fi

popd
rm -rf "${TMPDIR}"

Перед запуском не забудьте заполнить секцию Variables под ваши нужды.

Удачи!



Что еще почитать:

  1. .
  2. .
  3. .
 
Сверху Снизу