пятница, 1 июля 2016 г.

Как переименовать сетевой интерфейс в CentOS 7

Во FreeBSD, когда настраиваешь сетевые параметры, есть очень удобный механизм переименовывания названий сетевых интерфейсов. Можно, к примеру, интерфейс em0 назвать lan0, а xl0 - wan0. Во-первых, это придаёт настройкам всевозможных конфигурационных файлов осмысленности: сразу понятно, какой интерфейс за что отвечает, а во-вторых, в различных конфигурационных файлах можно использовать эти псевдонимы и, в случае замены сетевой карты, нужно всего-лишь поменять одну строчку в rc.conf. Причём, делается такое переименование элементарно - одной строкой в конфиге rc.conf:

ifconfig_em0_name="lan0"
ifconfig_xl0_name="wan0"

И всё! Дальше везде используем только имена lan0 и wan0.


Когда я начал настраивать очередной Linux сервер, был сильно удивлён, что этот, вроде бы, тривиальный механизм в линуксе устроен, мягко говоря, несколько сложнее. Казалось бы, чего проще - добавь в конфигурационный файл сетевого интерфейса параметр NAME и интерфейс сам переименуется. Но нет. Там нужно задействовать какие-то сложные и не до конца понятные механизмы udev. 99% советов сводится к необходимости добавить в конфигурационный файл /etc/udev/rules.d/70-persistent-ipoib.rules строк типа:

SUBSYSTEM=="net", ACTION=="add", DRIVERS=="?*", ATTR{address}=="90:2b:34:87:d1:7d", ATTR{dev_id}=="0x0", ATTR{type}=="1", NAME="lan0"

Тут с ходу понятно только, что сетевому интерфейсу с соответствующим mac-адресом присваивается имя lan0. Объяснения, зачем нужны остальные параметры, и что они означают, найти весьма непросто.
Но и это ещё не всё. После описанных действий нужно переименовать в каталоге /etc/sysconfig/network-scripts/ файл с именем ifcfg-старое_имя в файл ifcfg-новое_имя и изменить в самом файле все названия интерфейсов со старого на новый. (Написанное выше справедливо для CentOS, в Ubuntu немного по-другому).

В последних дистрибутивах (RHEL7, CentOS 7, Ubuntu 16.04) всё ещё больше запуталось. Там отказались от традиционного для линуксов именования сетевых интерфейсов, типа eth0, eth1 и т.д., и внедрили именование более сложное, основанное на аппаратном расположении интерфейса. Как это теперь работает, можно почитать, к примеру, здесь:
http://val-khmyrov.blogspot.ru/2015/11/blog-post_22.html
Всё понятно? Мне не совсем.
Я же, когда начал копать в сторону решения проблемы наткнулся на следующий мануал:
https://www.freedesktop.org/software/systemd/man/systemd.link.html
Т.е., по идее, с помощью этого механизма можно легко переименовать любой сетевой инерфейс, используя штатное средство systemd.link. Для этого всего-лишь нужно для каждого интерфейса в каталоге /etc/systemd/network/ создать файл, например с именем 10-lan0.link примерно следующего содержания:

[Match]
MACAddress=00:a0:de:63:7a:e6
[Link]
Name=lan0

после чего интерфейс с соответствующим mac-адресом, по идее, должен переименоваться. Но не тут то было! Сделал, как написано - не работает. Начал гуглить и обнаружил, что про это почти нигде ничего не сказано, кроме вышеприведённого мануала.
Хотел уже плюнуть на всё и воспользоваться методом редактирования 70-persistent-ipoib.rules (благо, он в CentOS 7 тоже работает), но случайно попал на основополагающий сайт документации RHEL. Там, вот на этой странице:
https://access.redhat.com/documentation/en-US/Red_Hat_Enterprise_Linux/7/html/Networking_Guide/sec-Disabling_Consistent_Network_Device_Naming.html
увидел совет, как отключить существующую схему именования. А именно нужно сделать симлинк:

ln -s /dev/null /etc/udev/rules.d/80-net-name-slot.rules

Таким образом отключается именование интерфейсов по слотам и включается именование по линкам.
И вот только после этого начинает работать механизм systemd.link. Победа!

В итоге имеем следующее.
Чтобы переименовать, к примеру, сетевой интерфейс ens160 в lan0 в CentOS 7, нужно сначала создать символическую ссылку:

ln -s /dev/null /etc/udev/rules.d/80-net-name-slot.rules

В каталоге /etc/systemd/network/ создаём файл 10-lan0.link следующего содержания:

[Match]
MACAddress=00:a0:de:63:7a:e6
[Link]
Name=lan0

указав реальный mac-адрес интерфейса, который пытаемся переименовать.

После чего, в каталоге /etc/sysconfig/network-scripts/ переименовываем файл ifcfg-ens160 в файл ifcfg-lan0 и в самом файле изменяем параметры NAME и DEVICE на новые. Перегружаемся, наслаждаемся новым именем.

И всё это вместо одной строчки:
ifconfig_ens16_name="lan0"
во FreeBSD.
Архитекторы Linux тут явно перемудрили.