Объединение двух локальных сетей с одинаковым номерами сетей на Linux-шлюзе
При создании локальной сети не каждый администратор подходит с ответственностью к выбору диапазона адресов. А может и не каждый догадывается о наличии частных диапазонов кроме 192.168.0.0/24. И со временем такая бомба замедленного действия может дать о себе знать. Локальные сети объединяются, возникает потребность в коммуникации между хостами разных сетей. И тут выясняется, что номера сетей совпадают. И менять их по каким либо причинам проблематично или невозможно.
В таком случае, серверу, маршрутизирующему пакеты между сетями, остается сделать вид, что номера сетей различны и выдавать желаемое за действительное. В богатом арсенале Linux есть средства для таких манипуляций: iptables с NETMAP и утилита ip.
Цель
Из сети LAN1 мы хотим послать пакет в сеть LAN2. Но мы не можем послать его в сеть, номер которой одинаков с нашим. В самом частом случае 192.168.0.0/24. Если такой пакет появится в LAN1, он не будет знать, что есть LAN2, он будет искать такую машину в LAN1. Таковы правила маршрутизации по умолчанию.
Значит, надо посылать пакеты с другими адресами, которые уйдут в роутер.
Как это должно вглядеть для наблюдателя из LAN1
Например, пользователь сети LAN1 будет видеть сеть LAN2 как 10.8.1.0/24. Тут уже никакого пересечения адресов. LAN1 доволен.
Как это выглядит с обеих сторон
Из LAN1 приходит пакет с адресом отправителя 192.168.0.100 и адресом назначения 10.8.1.200. Из роутера с интерфейса LAN2 выходит тот же пакет с адресом отправителя 10.8.1.100 и с адресом назначения 192.168.0.200. Пакет проходит до адреса назначения и тот шлет в ответ на адрес отправителя со своим адресом. Пакет уходит в роутер. В нем происходит обратное преобразование и пользователь LAN1 получает ответ с того адреса, на который отправил пакет.
Теория. Путь пакета в ядре роутера: netfilter
Здесь я попытаюсь рассказать о путешествии транзитного трафика через наш Linux-роутер. Для полного понимания процесса путешествия пакета лучше видеть схему его прохождения из Википедии по цепочкам netfilter.
Наш пакет с [источником|назначением] [192.168.0.100|10.8.1.200] попадает на сетевой интерфейс роутера и первой его цепочкой будет PREROUTING.
PREROUTING
Проходя по цепочке он попадает в таблицу PREROUTING mangle. В которой посредством iptables мы определяем интерфейс, с которого он пришел, и адрес источника. Если это наш пациент, мы его помечаем действием MARK.
После чего пакет [192.168.0.100|10.8.1.200|(marked)] попадает в таблицу nat. Эта таблица предназначена для трансляции адресов. Поскольку не существует реального адреса 10.8.1.200, то на последующем этапе маршрутизации пакет будет отброшен или уйдет в неизвестном направлении. Поэтому заменяем ему адрес назначения на тот, на который он действительно должен пойти именно тут: [192.168.0.100|192.168.0.200|(marked)]. Делается это действием NETMAP, которое заменяет номер сети по маске.
ROUTING
Наш пакет пакет попадает на этап принятия решения, куда он должен идти дальше. Он промаркирован, поэтому можем отправить его в специальную таблицу маршрутизации, которую мы создали для такого случая. Там принимается решение, что пакет не предназначен для локального компьютера и должен идти в LAN2.
Пакет успешно проходит цепочку FORWARDING. Попадает опять на этап маршрутизации. Если в FORWARDING с ним ничего не случилось, а по идее не должно было. Он идет тем же путем. После чего попадает в POSTROUTING.
POSTROUTING
Без изменений доходя до таблицы nat. Мы должны изменить адрес источника. Ведь ответ на пакет [192.168.0.100|192.168.0.200] будет отправлен в локальную сеть, а не в роутер. Чтоб он попал обратно в роутер, меняем адрес источника на несуществующий [10.8.1.100|192.168.0.200]. Опять же NETMAP. После этого пакет выходит в LAN2.
С ответным пакетом проделываем обратную процедуру, чтоб он дошел до изначального источника.
Реализация
iptables -t mangle -A PREROUTING -i tun0 -d 10.8.1.0/24 -j MARK --set-mark 8
Метим входящие пакеты на нашу несуществующую сеть для дальнейшего их опознавания в netfilter. Можно обойтись и без меток, использовать в качестве критериев адрес источника, входной интерфейс и адрес назначения, но в случае сложной маршрутизации с отдельными таблицами маршрутизации решить куда отправить пакет будет проще всего по метке.
iptables -t nat -A PREROUTING -m mark --mark 8 -j NETMAP --to 192.168.0.0/24
iptables -t nat -A POSTROUTING -m mark --mark 8 -j NETMAP --to 10.8.2.0/24
В POSTROUTING NETMAP подменяет адрес источника.
После этого все обращения на подсеть 10.8.1.0/24 будут выглядеть внутри LAN2, как обращения из подсети 10.8.2.0/24.
ROUTING
Чтобы маршрутизировать пакеты по метке необходимо создать свою таблицу маршрутизации.Редактируем /etc/iproute2/rt_tables, добавляя уникальное число и название новой таблицы.
256 netmap
Далее надо добавить правило, по которому в эту таблицу будут направляться пакеты на маршрутизацию.
ip ru add fwmark 8 lookup netmap
Теперь помеченные пакеты будут уходить на маршрутизацию в таблицу netmap.
И последним шагом нужно определить маршруты в таблице netmap.
ip route add default dev eth1 table netmap
Или можно указать в особом случае отдельный шлюз, если в эту сеть трафик от роутера идет через него. Что-то в духе:
ip route add default via 192.168.1.254 dev eth1 table netmap
Пока рано радоваться, к нам придет ответ из LAN2 [192.168.0.100|10.8.2.200].
Надо сделать все тоже самое, но только преобразовать обратно. Увы, netfilter сам этого не делает. Все действия уже описаны, приведу только последовательность команд для преобразования адресов в одну и в обратную сторону. (В первой таблице маршрутизации необходимости в данном случае нет, но при иных обстоятельствах может понадобиться.)
ip rule add fwmark 8 lookup netmap ip route add 192.168.0.0/24 dev eth1 table netmap iptables -t mangle -A PREROUTING -i tun0 -d 10.8.1.0/24 -j MARK --set-mark 8 iptables -t nat -A PREROUTING -m mark --mark 8 -j NETMAP --to 192.168.0.0/24 iptables -t nat -A POSTROUTING -m mark --mark 8 -j NETMAP --to 10.8.2.0/24 # в обратную сторону ip rule add fwmark 9 lookup netmap2 ip route add 192.168.0.0/24 dev tun0 table netmap2 iptables -t mangle -A PREROUTING -i eth1 -d 10.8.2.0/24 -j MARK --set-mark 9 iptables -t nat -A PREROUTING -m mark --mark 9 -j NETMAP --to 192.168.0.0/24 iptables -t nat -A POSTROUTING -m mark --mark 9 -j NETMAP --to 10.8.1.0/24
Результаты
12:46:46.358969 IP 192.168.0.100.41930 > 10.8.1.200.5900: Flags [P.], seq 647:657, ack 261127, win 1213, options [nop,nop,TS val 460624 ecr 171318], length 10
12:46:46.358978 IP 10.8.2.100.41930 > 192.168.0.200.5900: Flags [P.], seq 647:657, ack 261127, win 1213, options [nop,nop,TS val 460624 ecr 171318], length 10
12:46:46.505847 IP 192.168.0.200.5900 > 10.8.2.100.41930: Flags [.], ack 657, win 64879, options [nop,nop,TS val 171320 ecr 460624], length 0
12:46:46.505861 IP 10.8.1.200.5900 > 192.168.0.100.41930: Flags [.], ack 657, win 64879, options [nop,nop,TS val 171320 ecr 460624], length 0
12:47:46.363905 IP 192.168.0.100 > 10.8.1.200: ICMP echo request, id 2111, seq 1, length 64
12:47:46.363922 IP 10.8.2.100 > 192.168.0.200: ICMP echo request, id 2111, seq 1, length 64
12:47:46.364049 IP 192.168.0.200 > 10.8.2.100: ICMP echo reply, id 2111, seq 1, length 64
12:47:46.364054 IP 10.8.1.200 > 192.168.0.100: ICMP echo reply, id 2111, seq 1, length 64
Tcpdump отлично демонстрирует, как происходит преобразование адресов на входе в один интерфейс и на выходе в другой и в обратную сторону.
Так же отлично работают остальные сервисы, типа Samba и ее аналог на Windows.
Note
Если соединение между сетями организовано посредством туннеля OpenVPN, то для правильной маршрутизации со стороны клиента в конфиг сервера необходимо добавить дополнительный маршрут через туннель.
push «route 10.8.1.0 255.255.255.0»
Warning!
При отладке конфигурации не пытайтесь законнектиться к серверу, на котором шлюз. Соединяйтесь с машинами за ним в LAN2.
И вот почему. Правила расчитаны, что пакет будет проходить через шлюз, i. e.
PREROUTING -> Маршрутизация -> FORWARD -> Маршрутизация -> POSTROUTING
Если пакеты будут адресованы 10.8.2.1 (серверу), то они в результате маршрутизации пойдут в цепочку INPUT и преобразование адреса источника в POSTROUTING не будет выполнено.
PREROUTING -> Маршрутизация -> INPUT -> Приложение
Соответственно, адрес источника не будет измненен и ответ будет послан не на 10.8.2.xy, а на 192.168.0.xy — на маршрут по умолчанию для этого диапазона, т. е. в LAN2, а не в LAN1.
Introduction to Network Bonding
Network Bonding is the bonding or combination of two different physical network interfaces to increase the bandwidth or backup connectivity in case an interface fails.
The addition of a network interface in order to backup connectivity is called “network redundancy”, in short network redundancy is when a network interface fails, the second (it may be more than 2 interfaces) replaces its functionality preventing connectivity failure. On the other hand, Network Bonding can be useful to distribute traffic between different network interfaces increasing the bandwidth capability, this is called “Load Balancing” and there are different types to provide both network redundancy and load balancing, or both of them.
There are different types of network bonding, in the first place you can combine you ethernet and wifi cards to achieve network redundancy, or load balancing (it won’t increase the speed provided by your ISP), there are also available devices to achieve network balancing bonding 4g connections from mobiles, but you can also turn your Linux computer into a Network Bonding device.
There are 7 types of Network Bonding:
- mode=0 (Balance Round Robin)
- mode=1 (Active backup) ⇒ Explained in this tutorial.
- mode=2 (Balance XOR)
- mode=3 (Broadcast)
- mode=4 (802.3ad)
- mode=5 (Balance TLB)
- mode=6 (Balance ALB)
This tutorial explains how to configure Network Bonding on Debian and Ubuntu Linux distributions in a way the wired connection is the default while the wireless is the backup when the wired isn’t connected. This is the mode 1 (Active Backup) and the Wireless device will work only when the wired fails. Both network devices will be bonded through bond0 interface.
Configuring Network Bonding wired & wireless on Debian 10 Buster (DHCP)
Before starting you need to install the ifenslave package to attach and detach slave network devices to a bonding device. Run:
Just in case load the bonding modules