Таким образом возникает целый зоопарк скриптов и утилит: демон networking под Debian, который управляет конфигурацией сети через ifupdown, использующий файлы конфигурации хранящиеся в /etc/networking/interfaces.d и файл /etc/networking/interfaces, под CentOS network, который использует скрипты ifup и ifdown и, конечно же, свои файлы конфигурации находящиеся в /etc/sysconfig/network-scripts, netctl под ArchLinux. Всем известно, что Linux — конструктор, но почему бы такой простой и общей для самых различных систем вещи как настройка сети не иметь одинаковый вид?
Мы предлагаем начать использовать быстрый и простой демон systemd-networkd, особенно в свете того, что многие дистрибутивы уже перешли на systemd, поэтому переключение на systemd-networkd не составит труда. На текущий момент systemd-networkd может заменить собой множество утилит и поддерживает настройку сети как по DHCP (клиент и сервер) так и со статическими IP-адресами, мосты, туннели, VLANs, беспроводные сети (используя при этом wpa_supplicant).
В статье мы рассмотрим, как активировать systemd-networkd и начать его использовать, и в чем его основные преимущества перед остальными демонами.
Запуск systemd-networkd
Несмотря на страсти, кипевшие вокруг внедрения systemd, многие популярные дистрибутивы Linux стали использовать этот менеджер служб и поставлять его по умолчанию. Поэтому, вероятно, ваша система уже содержит всё необходимое для включения systemd-networkd. Необходим systemd версии 210 и выше.
Проверить версию можно с помощью команды:
$ systemctl --version
Чтобы использовать, запустите следующие две службы и включите их работу при загрузке системы (отключив при этом другие демоны, управляющие конфигурацией сети):
$ systemctl enable systemd-networkd
$ systemctl start systemd-networkd
$ systemctl enable systemd-resolved
$ systemctl start systemd-resolved
Конфигурирование
В качестве примера переключения рассмотрим перенос конфигурации сети по умолчанию в CentOS (/etc/rc.d/init.d/network initscript) на systemd-networkd.
Полностью аналогичо переезд можно осуществить для Fedora и, с небольшими изменениями, для других дистрибутивов. Конфигурационные файлы systemd-networkd находятся в директории /etc/systemd/network. Доступны следующие типы:
- .link – описывают физические параметры каждого интерфейс: имя, MAC, MTU и другие
- .network – описывают параметры сети: IP, маршруты, DNS и другие
- .netdev – описывают виртуальные интерфейсы, мосты
Конфигурация для примера: два интерфейса со статическим IP в LAN и WAN.
$ ip addr
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
inet6 ::1/128 scope host
valid_lft forever preferred_lft forever
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP group default qlen 1000
link/ether 04:01:40:23:1f:01 brd ff:ff:ff:ff:ff:ff
inet 188.166.46.238/18 brd 188.166.63.255 scope global eth0
valid_lft forever preferred_lft forever
inet6 2a03:b0c0:2:d0::69:7001/64 scope global
valid_lft forever preferred_lft forever
inet6 fe80::601:40ff:fe23:1f01/64 scope link
valid_lft forever preferred_lft forever
3: eth1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP group default qlen 1000
link/ether 04:01:40:23:1f:02 brd ff:ff:ff:ff:ff:ff
inet 10.133.248.54/16 brd 10.133.255.255 scope global eth1
valid_lft forever preferred_lft forever
inet6 fe80::601:40ff:fe23:1f02/64 scope link
valid_lft forever preferred_lft forever
Конфигурационные файлы для CentOS (или Fedora) можно найти в директории /etc/sysconfig/network-scripts
$ cat /etc/sysconfig/network-scripts/ifcfg-eth0
DEVICE='eth0'
TYPE=Ethernet
BOOTPROTO=none
ONBOOT='yes'
HWADDR=04:01:40:23:1f:01
IPADDR=188.166.46.238
NETMASK=255.255.192.0
GATEWAY=188.166.0.1
NM_CONTROLLED='yes'
IPV6INIT=yes
IPV6ADDR=2A03:B0C0:0002:00D0:0000:0000:0069:7001/64
IPV6_DEFAULTGW=2A03:B0C0:0002:00D0:0000:0000:0000:0001
IPV6_AUTOCONF=no
DNS1=2001:4860:4860::8844
DNS2=2001:4860:4860::8888
DNS3=8.8.8.8
Необходимо создать 4 файла в директории /etc/systemd/network/
$ cat /etc/systemd/network/90-external.link
[Match]
MACAddress=04:01:40:23:1f:01
[Link]
Name=eth-outer
$ cat /etc/systemd/network/90-internal.link
[Match]
MACAddress=04:01:40:23:1f:02
[Link]
Name=eth-inner
$ cat eth-external.network
[Match]
Name= eth-outer
[Network]
DHCP=no
Adress=188.166.46.238/18
Adress=2A03:B0C0:0002:00D0:0000:0000:0000:0069:7001/64
Gateway=188.166.0.1
Gateway= 2A03:B0C0:0002:00D0:0000:0000:0000:0000:0001
DNS=2001:4860:4860:8844
DNS=2001:4860:4860:8888
DNS=8.8.8.8
$ cat eth-internal.network
[Match]
Name=eth-inner
[Network]
Address=10.133.248.54/16
Вот и всё: конфигурация сети завершена. Теперь можно перезапустить сервис:
systemctl restart systemd-networkd
$ networkctl
IDX LINK TYPE OPERATIONAL SETUP
1 lo loopback n/a n/a
2 eth-outer ether routable configured
3 eth-inner ether routable configured
Другие типы сетей:
DHCP
В данном примере сконфигурируем DHCP IPv4 и IPv6; IPv6 если не нужен, можно исключить.
$ cat /etc/systemd/network/wired-dhcp.network
[Match]
Name=eth*
[Network]
DHCP=ipv4
DHCP=ipv6
Подключение типа «Мост»
Сначала создает конфигурацию виртуального интерфейса:
$ cat /etc/systemd/network/bridge.netdev
[NetDev]
Name=br0
Kind=bridge
$ cat /etc/systemd/network/bridge.network
[Match]
Name=br0
[Network]
DHCP=ipv4
И настраиваем интерфейс для подключения:
$ cat /etc/systemd/network/wired.network
[Match]
Name=eth*
[Network]
Bridge=br0
Недостатки (не актуальны, по большому счету, для серверов)
1. Не будет работать без systemd.
2. Нет ни CLI ни GUI фронтендов. И NetworkManager, и netctl не страдают таким недостатком. Например, для подключения к WiFi вам понадобится командная строка. Не совсем актуально для сервера.
3. Для первого подключения к WiFi необходимы root права. Однако это не совсем недостаток, так как в будущем к этой беспроводной сети подключение будет происходить автоматически.
4. Если быть не осторожным, то пароль от WiFi может храниться в открытом виде в истории команд. но этого можно легко избежать несколькими способами: временно отключить запись команд в историю (для bash: set +o history, set -o history), использовать shell не запоминающий историю (например dash) или просто вручную удалить пароль из истории.
Бенчмарк
Тестируется скорость получения адресов по DHCP, Network manager and dnsmasq отключены.
Софт:
— CentOS 7
— kernel-3.10.0-327.28.3.el7
— systemd 219
— ISC DHCP client daemon and dhclient-script 4.2.5
systemd-networkd
$ systemctl start systemd-networkd
$ journalctl -u systemd-networkd.service
Sep 01 13:04:41 localhost systemd[1]: Starting Network Service...
Sep 01 13:04:41 localhost systemd-networkd[4085]: Enumeration completed
Sep 01 13:04:41 localhost systemd[1]: Started Network Service.
Sep 01 13:04:41 localhost systemd-networkd[4085]: eth0: DHCPv4 address 192.168.1.114/24 via 192.168.1.1
Sep 01 13:04:41 localhost systemd-networkd[4085]: eth0: Configured
Меньше чем за секунду.
ISC DHCP
$ time dhclient -v eth0
Interface up - dhclient
Internet Systems Consortium DHCP Client 4.2.5
Copyright 2004-2013 Internet Systems Consortium.
All rights reserved.
For info, please visit https://www.isc.org/software/dhcp/
Listening on LPF/enp2s0/94:de:80:1a:da:af
Sending on LPF/enp2s0/94:de:80:1a:da:af
Sending on Socket/fallback
DHCPREQUEST on eth0 to 255.255.255.255 port 67 (xid=0x5b763f4d)
DHCPACK from 192.168.1.1 (xid=0x5b763f4d)
bound to 192.168.1.115 -- renewal in 20662 seconds.
real 0m2.243s
user 0m0.042s
sys 0m0.216s
Среднее время после нескольких попыток составило 2.5 секунд.
Заключение
В виду активного использования systemd различными топовыми дистрибутивами Linux можно заключить, что, всё же, сообщество стремится к унификации основных системных функций. К ним относится, в том числе, конфигурирование сети, а systemd, в свою очередь, предлагает удобное, быстрое и функциональное решение. И пусть пока это решение сталкивается с проблемой отсутствия GUI для десктопных систем, но для Linux серверов оно, возможно, станет стандартом «де-факто» и заменит кучу легаси демонов и отдельных утилит. Это сделает Linux гораздо более удобным для контейнеризации и использования на виртуальных машинах.
Комментарии (39)
o_serega
01.09.2016 17:53Так в чем преимущества systemd-networkd?
orgkhnargh
02.09.2016 10:19В первом же абзаце написано, что systemd-networkd требует всего 2 МБ памяти (против 20 у NetworkManager).
o_serega
02.09.2016 10:35В жизни его не использовал на серверах, если уж на то пошло, а вообще, тут, пора, уже придумать тег сарказм. А вообще, как было сказано в конце статьи, я вижу только один плюс — это попытка унификации системы инициализации для linux систем, но то что вы итоге вышло, перечеркивает все благие начинания.
Constin
02.09.2016 12:13+1это надуманное преимущество. Они сравнивают десткопный NetworkManager с systemd, в то время как NetworkManager не используется на серверах. Нет никакого преимущества. Давайте все запихнем в наш «прекрасный» systemd комбаин, потому что просто так. Вот и все. Дай им волю, они и реестр сделают в linux.
bugrazoid
02.09.2016 19:41Да такими темпами, systemd скоро научится писать болванки и перегонит Nero по функционалу )))
justhabrauser
03.09.2016 11:32Есть один нюанс — в RH-based дистрибутивах systemd — by default. Т.е. он из системы не вырезается никак. Прибито гвоздями.
И NM — by default. Однако не прибито.
Автор рисует путь вырезать бОльшее зло (NM) в пользу меньшего зла (systemd).
Если Вы хотите совсем без зла — RTFM «Linux From Scratch».
(как Вы будете поддерживать в одно лицо пару-тройку LFS-серверов — это второй вопрос).Constin
03.09.2016 13:57Автор ничего не рисует, автор рекламирует свой хостинг. И он не предлагает вырезать NM, он ссылается на то, что он есть в десктопных версиях, а потом вообще без логики перескакивает на systemd network на серверах. Выглядит это так: смотрите, у верблюдов есть горб, поэтому предлагаю отрезать у лошади хвост и посадить вместо него куст черной смородины.
al_sh
01.09.2016 18:12мне так и не удалось подружить на малине systemd-networkd с WiFi с WPA2. Интересно было бы почитать, как умные люди systemd c wpa_supplicant подружили.
ildus
01.09.2016 19:06А в чем проблема была? У меня как раз так и настроено. Например если интерфейс называется wlp3s0b1, то надо просто разрешить и запустить сервис wpa_supplicant@wlp3s0b1.service, и создать файл /etc/wpa_supplicant/wpa_supplicant-wlp3s0b1.conf, в котором и прописываются данные для соединения. Сами соединения удобнее настраивать через wpa_cli.
al_sh
02.09.2016 10:56Ну это понятно. Проблема в том, что wpa_supplicant пишет в лог, что, якобы, интерфейс уже поднят и поднимать его повторно он не хочет(точную формулировку не вспомню). После этого все работает нормально. Поэтому я и написал «подружить»))
ru_vds
01.09.2016 23:20На вопрос о дружбе, думаю, уместнее всего ответить скриптом.
Тестировал на Debian 8.
DHCP wireless configuration script#!/bin/bash TARGET_DEVICE=wlan0 WIFI_ESSID='<ESSID>' WIFI_PASSF='<wpapassphrase>' systemctl disable networking systemctl disable wpa_supplicant.service systemctl disable NetworkManager cat > /etc/systemd/network/21-dhcp-wireless.network << EOF [Match] Name=TARGET_DEVICE [Network] DHCP=yes EOF # Если вдруг отсутствует cat > /etc/systemd/system/wpa_supplicant@.service << EOF [Unit] Description=Interface-specific version of WPA supplicant daemon Requires=sys-subsystem-net-devices-%i.device After=sys-subsystem-net-devices-%i.device Before=network.target Wants=network.target [Service] Type=simple ExecStart=/sbin/wpa_supplicant -c/etc/wpa_supplicant/wpa_supplicant-%I.conf -i%I [Install] Alias=multi-user.target.wants/wpa_supplicant@%i.service EOF cat > /etc/wpa_supplicant/wpa_supplicant-TARGET_DEVICE.conf << EOF update_config=1 eapol_version=1 ap_scan=1 fast_reauth=1 EOF # passphrase будет записан в файле, в том числе, открытым текстом! wpa_passphrase WIFI_ESSID WIFI_PASSF >> /etc/wpa_supplicant/wpa_supplicant-TARGET_DEVICE.conf chmod go-rwx /etc/wpa_supplicant/wpa_supplicant-TARGET_DEVICE.conf rm /etc/resolv.conf ln -s /run/systemd/resolve/resolv.conf /etc/resolv.conf systemctl enable wpa_supplicant@TARGET_DEVICE.service systemctl enable systemd-networkd.service systemctl enable systemd-resolved.service systemctl start wpa_supplicant@TARGET_DEVICE.service systemctl start systemd-networkd.service systemctl start systemd-resolved.service
justhabrauser
01.09.2016 19:02Автору — +100500. Век живи — век учись — так придурком и помрешь :-)
Это я о себе.
От себя добавлю (Fedora/CentOS7 (версия CentOS — важно)):
* NetworkManager в CentOS7 реально бесит. Лечится (пока) установкой пакета initscripts, зачисткой пакетов rpmreaper'ом, после чего включаются олдскульные «chkconfig network on» и «service network restart». NM можно удалять. И без всяких systemd (без которого — никак, поэтому Ваш вариант лучше).
* не развернута тема конфликта /etc/rc.d/network и systemd-networkd. Надо будет потыкать палочкой.
G-M-A-X
01.09.2016 22:30У меня на не особо нагруженном CentOS 7 NetworkManager занимает 3.6 МБ
А если сеть не заведется, то что делать, не имея доступа к серверу? Делать бекапы?grumbler66rus
06.09.2016 11:03Если «железный» — подключиться через IPMI или BMC
Если виртуальный — ещё проще.
maxpax
02.09.2016 10:20А что насчет примеров настроек 802.1q, qiniq, LAG, route?
rino906
04.09.2016 11:51LACP+802.1qСетевые интерфейсы называются eno{1,2,3,4}
==> eno.network <== [Match] Name=eno* [Link] MTUBytes=9000 [Network] Bond=bond1 ==> bond1.netdev <== [NetDev] Name=bond1 Kind=bond [Bond] Mode=802.3ad LACPTransmitRate=slow TransmitHashPolicy=layer3+4 MinLinks=1 MIIMonitorSec=1s UpDelaySec=2s DownDelaySec=8s ==> bond1.network <== [Match] Name=bond1 [Link] MTUBytes=9000 [Network] VLAN=l2domru VLAN=megafon ==> l2domru.netdev <== [NetDev] Name=l2domru Kind=vlan [VLAN] Id=900 ==> l2domru.network <== [Match] Name=l2domru [Link] MTUBytes=9000 [Network] IPForward=yes [Address] Address=192.168.170.4/29 [Route] Destination=172.16.253.0/30 Gateway=192.168.170.2 [Route] Destination=172.16.254.0/30 Gateway=192.168.170.3 ==> megafon.netdev <== [NetDev] Name=megafon Kind=vlan [VLAN] Id=910 ==> megafon.network <== [Match] Name=megafon [Link] MTUBytes=1500 [Network] DNS=4.2.2.4 DNS=77.88.8.8 DNS=8.8.4.4 IPForward=yes [Address] Address=x.x.x.x/27
rino906
04.09.2016 12:17Существовала проблема с bond интерфейсами — bond0 никак не заводился в режиме 802.3ad(не знаю исправили это сейчас или нет), так что лучше начинать с bond1
nefelim4ag
06.09.2016 15:22+1Он заводится, нужно делать:
modprobe bonding max_bonds=0
Т.к. он не умеет реконфигурять уже созданный bond.
andrzzc
02.09.2016 10:20Хотелось бы информацию о том как отлаживать это хозяйство, наверно это сложнее чем классические bash-скрипты.
1. Куда заносится информация о DNS-серверах, автоматически перезаписывается /etc/resolv.conf?
2. DHCP-клиент тянет за собой isc-dhcp-client или используется свой велосипед?
3. Как добавить несколько IP-адресов на один интерфейс, типа как раньше eth0:0 и т.п.?
4. Как добавлять разные VLANы на физический интерфейс?
5. Можно ли в случае проблем просто выключить systemd-networkd и поднять интерфейс руками? (ip addr add и т.д...)ru_vds
02.09.2016 11:021. Куда заносится информация о DNS-серверах, автоматически перезаписывается /etc/resolv.conf?
Если вы получаете DNS от DHCP или указываете DNS в файлах .network, то конфигурированием занимается демон systemd-resolved; он пишет конфиг в /run/systemd/resolve/resolv.conf, так что необходимо создать симлинк
ln -s /run/systemd/resolve/resolv.conf /etc/resolv.conf
И resolvconf нужно будет удалить.
Спасибо за замечание, это важный момент.
2. DHCP-клиент тянет за собой isc-dhcp-client или используется свой велосипед?
Реализация DHCP своя. Здесь разработчик пишет о производительности реализации.
3. Как добавить несколько IP-адресов на один интерфейс, типа как раньше eth0:0 и т.п.?
Нужно просто добавить несколько строк вида Address= в секцию [Network]
[Network]
Address=192.168.1.2/24
Address=10.23.8.7/16
Gateway=...
Или можно сделать несколько секций [Address] и в каждой из них указать адрес.
Несколько адресов в одной секции [Address] указывать нельзя.
[Network]
Gateway=...
[Address]
Address=10.2.3.4/16
[Address]
Address=10.6.7.8/16
4. Как добавлять разные VLANы на физический интерфейс?
Нужно создать файлы .netdev для ваших vlan'ов:
first-vlan.netdev
[NetDev]
Name=vlan1
Kind=vlan
[VLAN]
Id=1
second-vlan.netdev
[NetDev]
Name=vlan2
Kind=vlan
[VLAN]
Id=2
А в конфиг .network в секцию [Network] вписать строки
VLAN=vlan1
VLAN=vlan2
P.S. Даже, вроде, можно список VLAN'ов указать через пробел
VLAN=vlan1 vlan2
5. Можно ли в случае проблем просто выключить systemd-networkd и поднять интерфейс руками? (ip addr add и т.д...)
Конечно можно.
P.S. «это хозяйство» пишет вполне вразумительные логи, обычно их хватает.o_serega
02.09.2016 14:50Мда, и это удобно? Вот удобно:
config_enp66s0=«null»
bridge_br2=«enp66s0»
brctl_br2=(
«setfd 0»
«sethello 0»
«stp off»
)
config_br2=«10.10.10.10/24 20.20.20.20/24 и тд „
routes_br2=“default via 10.10.10.1»
vlans_br2=«90 91 92 93»
vlan90_name=«vlan90»
vlan91_name=«vlan91»
vlan92_name=«vlan92»
vlan93_name=«vlan93»
config_vlan90=«null»
config_vlan91=«null»
config_vlan92=«null»
config_vlan93=«null»
Различную логику можно реализовать через
postup() {}
postdown() {}
если не хватает штатного инструментария, тот же сорс роутинг на несколько направлений.
И это все в одном месте, читабельно и все видно, что от чего зависит, а не мешанина файлов.
Повторюсь, у него одно «преимущество» — попытка унифицировать систему инициализации в среде linux систем, плюс реализация некоторых плюшек, типа паралельного старта процессов и зависимостей, хотя это не килер фича системд, до него было тоже реализовано.
acmnu
02.09.2016 11:38-1Эм. А зачем вообще подобный софт на сервере? Статической конфигурации для сервера более чем достаточно. Зачем держать некий демон в памяти если настройка сети с 99% вероятностью больше не будет менять после перезагрузки?
evg_krsk
02.09.2016 18:51+1Наверное затем, что в наши дни и на сервере конфигурация бывает не такой уж статической. Например, срочно понадобился дополнительный сетевой интерфейс — подоткнули Ethernet-USB-свисток, networkd его настроит (если у него есть подходящие правила, конечно).
Constin
02.09.2016 12:05-3fuck systemd! это не linux way. одна утилита должна делать делать что-то одно и хорошо.
evg_krsk
02.09.2016 18:27+1Спасибо, полезно.
Когда у тебя в хозяйстве исторический зоопарк дистрибутивов, networkd выглядит лучом света в тёмном царстве :-)
P.S.: у вас пара опечаток в листинге, "Adress=" (одна "d").
evg_krsk
02.09.2016 18:53Ещё к сожаленью не упомянуто о такой интересной фиче как приём и передача LLDP. Очень помогает разобраться, что куда в реальности подключено.
VGusev2007
06.09.2016 10:32Уважаемый ru_vds, спасибо за статью, и дополнение про resolv.conf. Вы могли бы ответить на следующий вопрос? Появился механизм именования сет. интерфейсов, основанный на физическом месторасположении устройства в слоте, напр: p1p1, em1, em0 и т.д. И вроде как, в этом, участие принимают компоненты systemd. Вроде это как благо, и теперь, при смене железки, не нужно ничего делать руками. Однако, Ваша статья, противоречит этому, снова прибивая всё гвоздями к MAC адресу карточки. Вы можете как-то прокомментировать это? Я как системный администратор уже не понимаю что происходит… Вот поставил я CentOS7, у меня там: em1, em2. Вроде, как-бы теперь должно всё быть динамически. Однако, nmtui, в общем то, так же молотком прибивает mac+имя. В общем, я не понимаю, к чему все эти измнения от eth к em1/p1p1, если всё равно, всё гвоздями колотится?
Спасибо!grumbler66rus
06.09.2016 11:11И вроде как, в этом, участие принимают компоненты systemd.
В этом принимает участие udev и только он.
Смотрите его рулесы, там есть скрипт /lib/udev/rules.d/80-net-name-slot.rules, назначающий имена интерфейсов по их расположению. Регулируется это созданием/удалением в /etc/udev/rules.d одноимённого со скриптом симлинка на /dev/null
ru_vds
06.09.2016 11:42Спасибо Вам за замечание. Сопоставлять конфигурацию сетевому интерфейсу можно массой способов. Привязка к hwaddr для иллюстрации .link конфигов. Можно не создавать .link файлов, а в .network в секции [Match] использовать, например, имена сетвых интерфейсов Name=enp2s0 или Name=wl* (для нескольких сетевых интерфейсов типа wlp1s0). Также в этой секции можно использовать ключ Path=pci-0000:02:00.0-*, или, например привязаться к драйверу (Driver=brcmsmac). Подробнее можете посмотреть здесь.
VGusev2007
06.09.2016 11:51Огромное спасибо! Будет здорово, если на основе всей ветки коментариев дополнить основную статью.
lopatoid
Чтобы введённая команда не сохранилась в history, достаточно перед ней поставить пробел.
o_serega
Это зависит от настроек окружения
Sild
уточню: для баша зависит от переменной HISTCONTROL в ~/.bashrc (или вашем альтернативным конфигурационном файле баша)
Воможные значения: ignorespace, ignoredups, ignoreboth