Вы здесь

Интересная маршрутизация в Linux.


Интересная маршрутизация в Linux.

Привет в этой статье я покажу вам как можно сделать не обычную маршрутизацию средствами linux. Мы будем направлять трафик на разные шлюзы, в зависимости от того от куда этот трафик прилетел, и куда он направляется.

Это может пригодиться, например, для организации double vpn, или, как было в моем случае, для ускорения загрузки некоторых сайтов (такая схема реализовывалась для человека, находящегося в Китае, где как известно, интернет очень неплохо цензурируется, стабильный канал был получен до vps в Гонконге, а оттуда, в свою очередь, очень не спешно открывались некоторые сайты, и был найден vps со стабильным каналом до Гонконга, от куда медленные сайты открывались значительно быстрее.  При использовании нижеописанной схемы удалось ускорить открытие «медленных» страниц, понимаю что запутанно написал, ну да ладно =) )

Поможет нам в решении этой задачи policy based routing, dnsmasq и ipset. Делать все будем на Ubuntu Server 16.04

Для демонстрации я покажу как вышеописанное можно сделать при использовании pptp сервера (но его использование совсем не обязательно), соответственно после настройки получим что то вроде double vpn для определенных сайтов.

Схема будет выглядеть так:

Схема сети

 

Немного поясню нарисованное.

Есть клиент — находящийся в сети 192.168.5.0/24, он подключен по pptp к нашей Ubuntu Server (192.168.6.1). При отправке запроса, ubuntu смотрит на адрес назначения, если адрес есть в базе, он летит на шлюз — router 1, с адресом 192.168.6.254. В случае, если адрес в базе отсутствует, запрос летит на шлюз по умолчанию для Ubuntu. В случае если запрос прилетает не из сети 192.168.5.0/24 — работает обычная маршрутизация — все запросы отправляются через шлюз по умолчанию.

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

Зайдем в режим суперпользователя:

sudo su

Обновим систему и установим необходимые пакеты:

apt update
apt upgrade
apt install ipset dnsmasq

Далее создадим cписок для ipset:

ipset create to2ndSRV hash:ip

Здесь можно сделать timeout для записей, чтобы в случае добавления большого количества сайтов, не было много неиспользуемых адресов, для этого к команде нужно добавить timeout 300, где 300 — время жизни в секундах.

В случае, если нужно будет вручную добавить адрес в список, можно воспользоваться командой:

ipset add to2ndSRV 8.8.8.8

Для удаления:

ipset del to2ndSRV 8.8.8.8

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

ipset list to2ndSRV

Добавление вручную, это конечно хорошо, но как же быть с ресурсами, у которых большое число адресов? Тут нам на помощь придет dnsmasq. Добавим в него список сайтов/записей, которые должны добавляться в список ipset:

nano /etc/dnsmasq.conf

Добавляем строчки:

listen-address=127.0.0.1
listen-address=192.168.6.1
server=/ident.me/vk.com/127.0.0.1
ipset=/ident.me/vk.com/to2ndSRV

Первые 2 строки, нужны для того что бы dnsmasq не светился на ружу, и как следствие, что бы не приходило абуз от хостера, тут на ваше усмотрение, можно их не добавлять. Кстати, для того что бы адреса стабильно добавлялись в список, dns запросы должны идти как раз через dnsmasq, самое простое, как этого можно добиться — указать в качестве dns сервера на клиенте — наш сервер (192.168.6.1).  Соответственно 192.168.6.1 — адрес нашего сервера в vpn сети.

Нижние же 2 строчки — непосредственно добавление адресов в список.

Перезапускаем dnsmasq:

/etc/init.d/dnsmasq restart

Проверим добавление ресурсов в список:

host ident.me
ipset list

Вывод должен быть примерно такой (должен будет добавиться адрес в members):

Name: to2ndSRV
Type: hash:ip
Revision: 4
Header: family inet hashsize 1024 maxelem 65536 timeout 3600
Size in memory: 320
References: 0
Members:
176.58.123.25 timeout 3594

Если так, продолжаем, если нет ищите у себя ошибку.

Дальше нам нужно сделать так, чтобы трафик маршрутизировался на тот или иной шлюз, в зависимости от наличия в списке адреса. Так же важный момент — нужно что бы, при недоступности второго роутера, трафик летел напрямую. Для этого нужно отредактировать скрипты поднятия и опускания интерфейса. В случае с pptpd это файлы /etc/ppp/ip-up и /etc/ppp/ip-down соответственно. Отредактируем первый:

nano /etc/ppp/ip-up

В конец файла пишем:

case "$5" in
        192.168.6.254)
        echo 2 > /proc/sys/net/ipv4/conf/$1/rp_filter
                       /sbin/ip route add default via 192.168.6.254 table 120
        /sbin/ip rule add fwmark 0x1 table 120 priority 1000
        ip route fush cache
        iptables -t mangle -A PREROUTING -s 192.168.5.0/24 -m set --match-set to2ndSRV dst -j MARK --set-mark 1
        iptables -t nat -A POSTROUTING -o $1 -j MASQUERADE
                ;;
        *)
esac

Разберем написанное:

echo 2 > /proc/sys/net/ipv4/conf/$1/rp_filter — отключения route policy filter, нежелательная строчка, но без нее у меня не заработало.

iptables -t mangle -A PREROUTING -s 192.168.5.0/24 -m set --match-set to2ndSRV dst -j MARK --set-mark 1 — здесь мы добавляем mangle правило в iptables для маркировки пакетов. В случае если адрес назначения присутствует в ipset, пакет маркируется.

/sbin/ip route add default via 192.168.6.254 table 120 — создаем новую таблицу маршрутизации для направления трафика на наш второй роутер.

/sbin/ip rule add fwmark 0x1 table 120 priority 1000 — добавляем правило в созданную таблицу маршрутизации, что бы маркированные пакеты летели на наш второй роутер.

ip route fush cache — отчищаем кэш

iptables -t nat -A POSTROUTING -o $1 -j MASQUERADE — натим трафик на наш второй роутер.

Что бы, в случае недоступности второго роутера, трафик летел напрямую, через шлюз по умолчанию, вышенаписанные правила нужно удалять при отключении роутера, для этого отредактируем файл /etc/ppp/ip-down (или тот, который у вас отвечаем за опускание нужного вам интерфейса)

nano /etc/ppp/ip-down
case $5 in
        192.168.6.254)
        ip rule delete fwmark 0x1 table 120 priority 1000
                ip route delete default via 192.168.6.254 table 120
                ip route flush cache
        iptables -t mangle -D PREROUTING -s 192.168.5.0/24 -m set --match-set to2ndSRV dst -j MARK --set-mark 1
                iptables -t nat -D POSTROUTING -o $1 -j MASQUERADE
                ;;
        *)
esac

Осталось добавить пользователя для клиента и второго роутера:

nano /etc/ppp/chap-sercets

test1   pptpd   testtest        192.168.5.100
srv     pptpd   testtest        192.168.6.254

/etc/init.d/pptpd restart

Всё, можно проверять сделанное: подключаемся клиентом и роутером, с клиента делаем трассировку до ресурса из списка. Пример трассировки до ya.ru (не в списке):

traceroute to ya.ru (87.250.250.242), 30 hops max, 60 byte packets
 1  192.168.6.1 (192.168.6.1)  1.120 ms  1.064 ms  1.048 ms
 2  * * *
 3  192.168.55.1 (192.168.55.1)  4.209 ms  4.237 ms  4.233 ms
 4  10.45.0.1 (10.45.0.1)  6.014 ms  6.008 ms  6.285 ms

И до ident.me (в списке):

traceroute to ident.me (176.58.123.25), 30 hops max, 60 byte packets
 1  192.168.6.1 (192.168.6.1)  1.136 ms  1.171 ms  1.166 ms
 2  cs01.et-code.ru (192.168.6.254)  8.188 ms  8.183 ms  8.179 ms
 3  * * *
 4  192.168.55.1 (192.168.55.1)  26.074 ms  26.123 ms  26.119 ms
 5  10.45.0.1 (10.45.0.1)  30.085 ms  30.198 ms  30.195 ms

Как видим до ident.me пакет проходит через наш шлюз 192.168.6.254 до ya.ru же, летит на прямую.

0 1

Поделитесь статьей с друзьями в соц. сетях, возможно, она будет им полезна.


Если вам помогла статья, вы можете >>отблагодарить автора<<


Комментарии