Перенос IP с одного сервера на другой в одной сети

Как перенести айпи с одной сетевой карты на другую? В этой статье я разбираюсь с проблемами, которые могут возникнуть по пути и с ARP.

Мне тут недавно понадобилось перекинуть в серверной адрес с одной карточки на другую, но это оказалось не так просто.

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

Допустим, у вас есть два сервера. Они подключены к одному маршрутизатору, находятся в одной внутренней сети. У каждого есть внутренний адрес вида 10.0.0.x и белый внешний адрес.

Сервер web1
-------------------------
eth0 10.0.0.1
eth1 195.206.58.122/29
Сервер web4
-------------------------
eno1 10.0.0.4

Вам нужно перебросить айпишник 195.206.58.122/29 с сетевой карты первого сервера на сетевую карту второго сервера, с eth1 на eno1. Как это сделать?

Очевидное решение

Отключаем интерфейсeth1 на первом сервере:

# дебиан
$ sudo ifdown eth0

А на web4 наоборот, присваиваем айпишник:

# ubuntu
$ ip addr add 195.206.58.122/29 dev eno1

Готово. Должно работать.

Небольшой пинг-тест из внешней сети показывает, что пакеты не доходят до нового сервера:

$ ping 195.206.58.122
PING 195.206.58.122 (195.206.58.122) 56(84) bytes of data.
^C
--- 195.206.58.122 ping statistics ---
3 packets transmitted, 0 received, 100% packet loss, time 2029ms

Попробуем разобраться, в чем тут проблема.

Отладка

Может быть пакет поступает на сервер, но его отбрасывает фаерволл? Давайте проверим, приходит ли он вообще. Для этого запустим tcpdump - пусть он ловит все пакеты на сервере веб4, которые адресованы на айпи 195.206.58.122:

$ sudo tcpdump host 195.206.58.122
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on vethe37e8d0, link-type EN10MB (Ethernet), capture size 262144 bytes
^C
0 packets captured
0 packets received by filter
0 packets dropped by kernel

Прошла минута... Ничего.

Значит, пакеты не приходят на сервер web4. Может быть они все еще волшебным образом попадают на web1? Попробуем запустить tcpdump там:

$ ssh web1
$ sudo tcpdump host 195.206.58.122
...
110 packets captured
710 packets received by filter
569 packets dropped by kernel

Да! Они все еще уходят на старую сетевую карту. Почему так? Кто отвечает за то, в какой именно провод пойдут пакеты?

Покопавшись немного в интернете, я понял, что дело тут в ARP.

ARP

Все компьютеры соединяются друг с другом в сеть через свитч. Именно свитч решает, в какой провод перенаправить сигнал. Он запоминает, какому IP соответствует какой MAC и на каком проводе он находится.

Обычно, когда в линуксе поднимается сетевой интерфейс, сетевая карта отправляет пакет ARP-Announcement, то есть, оповещает всех, что в сети появилось устройство с таким-то айпи и таким-то мак-адресом. Чтобы другие участники сети могли обновить свои кеши.

Но при добавлении дополнительного IP через команду ip addr add, почему-то такой пакет не отправлялся. И свитч не знает, что теперь этот айпи находится на другой сетевой карте.

Решение

В итоге мне помогла команда, запущенная на web4:

$ arping -S 195.206.58.122 -i eno1 195.206.58.125

Тут 195.206.58.122 - новый адрес, который мы добавили сетевой карте, а 195.206.58.125 - это айпишник маршрутизатора он же default gateway.

Список использованной литературы:

How to broadcast ARP update to all neighbors in Linux?
Some clients in the subnet has cached the IP with old MAC address, I want them to update the new value by doing a ARP broadcast, is it possible in Linux?

https://ru.wikipedia.org/wiki/ARP