На новогодних каникулах появилось, наконец, свободное время, чтобы заняться домашним сервером. Вместо Ubuntu 12.04 LTS был установлен VMWare ESXi 6.5, а сама система была разделена на несколько виртуалок, каждая под свою задачу.
С контейнерами пока решил не связываться – я пока не могу придумать реальную задачу, чтобы ради неё засесть за изучение Docker или LXC. Так что у нас будет классика – Debian 8 с последними апдейтами, свежая VMWare и Mikrotik (“железный”) в качестве роутера для всего этого счастья.
0. Disclaimer
Для начала о том, чего тут НЕ будет.
– Здесь не будет описываться установка VMWare или Debian
– Здесь не будет описываться настройка Mikrotik “с нуля”
– Здесь не будет описываться установка пакетов через apt (будь то ansible, zabbix или apache)
Я предполагаю, что компетенция моих читателей достаточна для того, чтобы не только прочитать всё то, что написано ниже, но и применять на практике с умом и пониманием, что вообще делается и для чего.
1. Связь. Настройка аплинков, failover, nat
С чего начинается лаба? Правильно, с сети. У меня в наличии роутер Mikrotik, два интернет-провайдера и некоторое количество клиентов, часть из которых – собственно сервер с виртуалками, часть – обычная домашняя сеть.
Разделять локалку на подсети не будем (пока), без ipv6 тоже обойдемся (хотя в будущем, разумеется, попробуем). Зато сделаем балансировку трафика (виртуалки должны ходить через резервный канал связи по умолчанию) и failover. А т.к. у меня на виртуалках есть ресурсы, опубликованные в интернет, то хотелось бы иметь к ним доступ изнутри сети, не заморачиваясь с перенастройкой DNS.
Нечто похожее я описывал 4,5 года назад в своей статье про policy-based routing на Mikrotik. С тех пор утекло много воды (и версий ROS), так что пользоваться ip rule уже не модно – гораздо проще маркировать пакеты с помощью mangle-цепочки фаервола.
1.1 Два провайдера: балансировка нагрузки
Имеем: два провайдера.
Один из них отдаёт нам честный белый ip-адрес по DHCP. Его мы будем использовать для доступа к виртуалкам снаружи и выпуска самих виртуалок в инет. Для остальных клиентов в локалке он является резервным.
Второй провайдер интернет даёт через l2tp-подключение, и выделенный ip не предоставляет. Его мы будем использовать для всей остальной локалки, как основной, и резервный для виртуалок. В принципе, можно даже настроить DynDNS, чтобы не терять связи с виртуалками в случае падения первого канала. Но не будем пытаться объять необъятное и впихнуть невпихуемое.
Основная задача – настроить автоматическое переключение между каналами в случае падения одного из линков.
Начальная конфигурация:
Активируем dhcp-клиенты на интерфейсах, куда включены провайдеры (у меня это первый и пятый порты)
ip dhcp-client
1 2 3 4 5
| /ip dhcp-client option add code=55 name=parameter_request_list value=0x01F90321062A /ip dhcp-client add add-default-route=no comment=BeeLine dhcp-options=parameter_request_list disabled=no interface=ether1-gateway add comment=Skynet default-route-distance=10 dhcp-options=hostname,clientid disabled=no interface=ether5-slave-local |
Поднимаем l2tp-сессию с оператором:
interface l2tp-client
1 2
| /interface l2tp-client add add-default-route=yes allow=chap connect-to=tp.internet.beeline.ru disabled=no keepalive-timeout=disabled max-mru=1420 max-mtu=1420 name=l2tp-beeline password=Aa123456789 profile=ppp-profile-beeline user=0123456789 |
Настраиваем роутинг. Т.к. нам нужно иметь два активных маршрута, то используем routing-mark. Да, маршруты придётся дублировать с теми, что прилетели по dhcp, а что делать?
В некоторых мануалах по настройке мультипровайдерной конфигурации советуют использовать директиву check-gateway в вариантe arp или ping. Это разумно, но нужно быть внимательным – шлюз провайдера на icmp-запросы отвечать, в общем случае, не обязан.
ip route
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
| /ip route #Дефолтные маршруты. Для каждой марки их две, т.к. нам нужно проверять оба шлюза и выпускать трафик тоже через обоих. add distance=1 gateway=128.75.224.1 routing-mark=route_to_bee add distance=100 gateway=94.20.244.1 routing-mark=route_to_bee add distance=1 gateway=94.20.244.1 routing-mark=route_to_sky add distance=100 gateway=128.75.224.1 routing-mark=route_to_sky #Маршруты на внутрисеть провайдера, который является основным для локалки (у меня это билайн) add distance=1 dst-address=10.0.0.0/8 gateway=10.75.64.1 routing-mark=route_to_bee add distance=1 dst-address=78.107.196.0/22 gateway=10.75.64.1 routing-mark=route_to_bee add distance=1 dst-address=85.21.0.0/24 gateway=10.75.64.1 routing-mark=route_to_bee add distance=1 dst-address=85.21.59.0/24 gateway=10.75.64.1 routing-mark=route_to_bee add distance=1 dst-address=85.21.192.0/24 gateway=10.75.64.1 routing-mark=route_to_bee add distance=1 dst-address=89.179.76.0/24 gateway=10.75.64.1 routing-mark=route_to_bee add distance=1 dst-address=213.234.192.0/24 gateway=10.75.64.1 routing-mark=route_to_bee #Маршруты на внутрисеть второго провайдера (для торрентов будет полезно, чтобы почём зря не грузить l2tp-подключение) add distance=1 dst-address=93.100.0.0/16 gateway=94.20.244.1 routing-mark=route_to_sky add distance=1 dst-address=94.19.0.0/16 gateway=94.20.244.1 routing-mark=route_to_sky add distance=1 dst-address=188.242.0.0/15 gateway=94.20.244.1 routing-mark=route_to_sky #Специальные маршруты до DNS-серверов и l2tp-терминаторов Билайн, чтобы соединение, ненароком, не установилось через другого провайдера add distance=1 dst-address=83.102.254.223/32 gateway=10.75.64.1 add distance=100 dst-address=83.102.254.223/32 type=blackhole add distance=1 dst-address=83.102.255.55/32 gateway=10.75.64.1 add distance=100 dst-address=83.102.255.55/32 type=blackhole add distance=1 dst-address=85.21.192.3/32 gateway=10.75.64.1 add distance=1 dst-address=213.234.192.8/32 gateway=10.75.64.1 |
Настраиваем правила таблицы mangle фаервола. С помощью этих правил мы будем помечать соединения пришедшие через тот или другой аплинк, а также маркировать исходящие из локалки пакеты, чтобы они попадали в нужный аплинк
ip firewall mangle
1 2 3 4 5 6 7 8 9 10 11 12
| /ip firewall mangle add action=mark-connection chain=input in-interface=l2tp-beeline new-connection-mark=conn_bee passthrough=no add action=mark-connection chain=input in-interface=ether5-slave-local new-connection-mark=conn_sky passthrough=no add action=mark-routing chain=output connection-mark=conn_bee new-routing-mark=route_to_bee passthrough=no add action=mark-routing chain=output connection-mark=conn_sky new-routing-mark=route_to_sky passthrough=no #Здесь мы балансируем каналы между потребителями. По умолчанию в SkyNet отправляются виртуалки (address-list "VMs"), а в билайн все остальные (address-list "LAN"). Для сетей обоих провайдеров пакеты маркируются вне зависимости от источника. add action=mark-routing chain=prerouting comment="Routes to SkyNet LAN" dst-address-list=Skynet new-routing-mark=route_to_sky passthrough=no src-address-list=LAN add action=mark-routing chain=prerouting comment="Routes to BeeLine LAN" dst-address-list=BeeLine new-routing-mark=route_to_bee passthrough=no src-address-list=LAN add action=mark-routing chain=prerouting comment="VMs go to Internet over SkyNet by default" new-routing-mark=route_to_sky passthrough=no src-address-list=VMs add action=mark-routing chain=prerouting comment="LAN go to Internet over BeeLine by default" new-routing-mark=route_to_bee passthrough=no src-address-list=LAN |
Правила NAT. Ну тут совсем всё просто: делаем src-nat на всех исходящих интерфейсах (у меня это два eth-интерфейса и l2tp).
ip firewall nat
1 2 3 4
| /ip firewall nat add action=masquerade chain=srcnat comment="NAT to SkyNet" out-interface=ether5 add action=masquerade chain=srcnat comment="NAT to Beeline" out-interface=l2tp-beeline add action=masquerade chain=srcnat comment="NAT to BeeLine LAN" out-interface=ether1 |
Осталось только собрать всё это вместе и проверить, что всё работает. Отключить сначала один шнурок, потом второй. Переключение должно произойти автоматически.
В таблице маршрутизации после всех настроек мы увидим примерно следующее (сейчас работают оба провайдера):
ip route print
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
| Flags: X - disabled, A - active, D - dynamic, C - connect, S - static, r - rip, b - bgp, o - ospf, m - mme, B - blackhole, U - unreachable, P - prohibit # DST-ADDRESS PREF-SRC GATEWAY DISTANCE 0 A S 0.0.0.0/0 128.75.224.1 1 1 S 0.0.0.0/0 94.20.244.1 100 2 A S 10.0.0.0/8 10.75.64.1 1 3 A S 78.107.196.0/22 10.75.64.1 1 4 A S 85.21.0.0/24 10.75.64.1 1 5 A S 85.21.59.0/24 10.75.64.1 1 6 A S 85.21.192.0/24 10.75.64.1 1 7 A S 89.179.76.0/24 10.75.64.1 1 8 A S 213.234.192.0/24 10.75.64.1 1 9 A S 0.0.0.0/0 94.20.244.1 1 10 S 0.0.0.0/0 128.75.224.1 100 11 A S 93.100.0.0/16 94.20.244.1 1 12 A S 94.19.0.0/16 94.20.244.1 1 13 A S 188.242.0.0/15 94.20.244.1 1 14 ADS 0.0.0.0/0 128.75.224.1 0 15 DS 0.0.0.0/0 94.20.244.1 10 16 ADC 10.0.10.1/32 10.0.10.2 l2tp-nixman 0 17 ADC 10.75.64.0/21 10.75.64.93 ether1-gateway 0 18 A S 83.102.254.223/32 10.75.64.1 1 19 SB 83.102.254.223/32 100 20 ADS 83.102.255.55/32 10.75.64.1 0 21 S 83.102.255.55/32 10.75.64.1 1 22 SB 83.102.255.55/32 100 24 A S 85.21.192.3/32 10.75.64.1 1 25 ADC 94.20.244.0/24 94.20.244.244 ether5-slave-local 0 26 ADC 128.75.224.1/32 128.75.249.101 l2tp-beeline 0 30 S 192.168.1.0/24 192.168.10.0 1 31 ADC 192.168.88.0/24 192.168.88.1 bridge-local 0 34 A S 213.234.192.8/32 10.75.64.1 1 |
1.2 Hairpin NAT в условиях балансировки трафика
Балансировку мы настроили, теперь идем дальше. Некоторые ресурсы, расположенные на виртуалках, опубликованы в инет. Изнутри локалки тоже хотелось бы иметь к ним доступ, и при этом не мудрить с подменой DNS-записей. При обычном DST-NAT у нас ничего не получится – т.к. сервер увидит, что src-ip находится в одной с ним подсети, и просто пошлёт ему ответный пакет, минуя роутер. Таким образом, TCP-соединение не сможет установиться. Чтобы обойти эту проблему, был придуман механизм hairpin NAT, когда при обращении из локалки на внешний ip роутера делается не только DST-NAT, но и SRC-NAT в адрес роутера, смотрящий в локалку.
Настраивается всё это достаточно просто. Для начала, добавляем нужные записи в настройки NAT:
ip firewall nat
1 2 3 4 5
| /ip firewall nat add action=masquerade chain=srcnat comment="HTTP Hairpin" dst-address=192.168.88.189 dst-port=80 out-interface=bridge-local protocol=tcp src-address=192.168.88.0/24 add action=masquerade chain=srcnat comment="HTTPS Hairpin" dst-address=192.168.88.189 dst-port=443 out-interface=bridge-local protocol=tcp src-address=192.168.88.0/24 add action=dst-nat chain=dstnat comment="HTTPS proxy" dst-address=94.20.244.244 dst-port=443 protocol=tcp to-addresses=192.168.88.189 to-ports=443 add action=dst-nat chain=dstnat comment="HTTP proxy" dst-address=94.20.244.244 dst-port=80 protocol=tcp to-addresses=192.168.88.189 to-ports=80 |
Здесь 192.168.88.189 – это адрес моего прокси-сервера, который уже более “детально” разбирает запросы и раскидывает их по нужным виртуалкам.
В таблице mangle мы добавляем правила hairpin в “исключения” (я просто навесил routing-mark, который нигде более не используется), чтобы они не попадали в правила балансировки исходящего трафика. Эти правила необходимо поместить ДО правил, отвечающих за маркировку пакетов
ip firewall mangle
1 2 3 4 5 6 7 8
| /ip firewall mangle ... add action=mark-packet chain=prerouting comment="Hairpin NAT" dst-address-list=Self new-packet-mark=hairpin passthrough=no src-address-list=LAN add action=mark-packet chain=prerouting comment="Hairpin NAT" dst-address-list=LAN new-packet-mark=hairpin passthrough=no src-address-list=Self add action=mark-routing chain=prerouting comment="Routes to SkyNet LAN" dst-address-list=Skynet new-routing-mark=route_to_sky passthrough=no src-address-list=LAN add action=mark-routing chain=prerouting comment="Routes to BeeLine LAN" dst-address-list=BeeLine new-routing-mark=route_to_bee passthrough=no src-address-list=LAN add action=mark-routing chain=prerouting comment="VMs go to Internet over SkyNet by default" new-routing-mark=route_to_sky passthrough=no src-address-list=VMs add action=mark-routing chain=prerouting comment="LAN go to Internet over BeeLine by default" new-routing-mark=route_to_bee passthrough=no src-address-list=LAN |
Если у вас есть на роутере еще VPN для качания торрентов доступа, например, к рабочим ресурсам и сетям, то нужно поступить по аналогии и добавить правило, вешающее соответствующий routing-mark:
1 2 3
| /ip firewall mangle ... add action=mark-packet chain=prerouting comment="VPN to Nixman" dst-address-list=VPN new-packet-mark=nixman passthrough=no src-address-list=LAN |
В dst-address VPN помещаем ресурсы, к которым мы ходим через VPN.
На этом всё. Сеть мы настроили, теперь можно идти дальше – к настройке reverse proxy, ssl и прочего хозяйства.
Бонус
Бонусом к этой части я оставлю два скрипта, которые существенно ускоряют процесс переключения. Первый определяет шлюз по умолчанию, выданный по l2tp (а он время от времени меняется), и подставляет его в наш маршрут.
system script
1 2 3 4 5 6 7
| /system script add comment="Detect changes of BeeLine gateway IP" name=beegwipchecker owner=admin policy=ftp,reboot,read,write,policy,test,password,sniff,sensitive source="#default gw in marked route\ \n:local currbeegwip [/ip route get [find dst-address="0.0.0.0/0" and routing-mark="route_to_bee"] gateway]\ \n#Detect actual beeline default gw\ \n:local newbeegwip [/ip route get [find gateway=l2tp-beeline] dst-address]\ \n:set newbeegwip [:pick \$newbeegwip 0 [:find \$newbeegwip "/"]]\ \n:if (\$currbeegwip!=\$newbeegwip) do={/ip route set [find dst-address="0.0.0.0/0" and routing-mark="route_to_bee"] gateway=\$newbeegwip}" |
Теперь добавляем наш скрипт в шедулер.
Заодно пишем второй – он раз в 30 секунд резолвит имя l2tp-терминатора Билайн через его же DNS-сервер (т.к. при переключении на резервный канал становятся активными его DNS-сервера, и достучаться до точки входа становится невозможно).
system scheduler
1 2 3 4
| /system scheduler add interval=5s name=bee_gwip_checker on-event=beegwipchecker policy=read,write,policy,test,sniff start-date=jan/07/2017 start-time=18:58:42 add comment="Resolve l2tp gateway for beeline" interval=30s name=bee_tp_resolver on-event=":resolve tp.internet.beeline.ru server=213.234.192.8" policy=\ ftp,reboot,read,write,policy,test,password,sniff,sensitive start-date=jan/08/2017 start-time=02:41:55 |
Вот теперь точно всё. Ждите следующую серию ;)
Like this:
Like Loading...
Related
Возможно ли пояснить четвёртый раздел кода с маркировкой по листам. В коде присутствуют три листа: Skynet, который судя из комента должен быть VMs, LAN ну тут всё понятно, и собственно VMs. Можно подробнее пояснить содержание этих листов?
Ну да ещё и address-list=BeeLine. Что перечисляется в листе с именем провайдера?