
В Интернете много инструкций на эту тему, но среди них много не актуальных или недостаточно подробных. По этому я напишу свой вариант. Возможно кому-то он будет полезен.
Стоит знать перед началом
- Чем коммутатор отличается от маршрутизатора
- Первые 3 уровня модели OSI
- Хотя бы примерно понимать как работает коммутатор
Без этих знаний возможно у Вас не получится понять и правильно использовать информацию из этой статьи.
Сетевые мосты нужны чтобы виртуальная машина могла взаимодействовать с локальными сетями а не просто иметь доступ в Интернет. Если на Вашей виртуальной машине нужен только Интернет, используйте в QEMU режим сети "user".
Почти все указанные команды сработают только от имени пользователя root. Если вы вошли под другим именем - не забудьте использовать sudo.
О сетевых мостах в целом
Они встречаются во многих операционных системах и везде принцип похожий. Пустой сетевой мост, в который не добавили ни одного сетевого интерфейса - это виртуальный коммутатор с бесконечным количеством портов, и один виртуальный сетевой интерфейс, который соединён с один из портов виртуального коммутатора. Виртуальный интерфейс как правило называется так же как сетевой мост. Если добавить в мост ещё один или несколько интерфейсов, они станут портами виртуального коммутатора. Они больше не будут самостоятельными интерфейсами, на них не получится назначить IP-адреса, или как-то ещё использовать их отдельно, их MAC-адреса ни где не будут учитываться.
Если вставить в компьютер 3 сетевые карты, у компьютера будет 3 сетевых интерфейса, на которые можно назначить IP-адреса, 3 разных MAC-адреса. Если создать мост и в него добавить все 3, физические сетевые карты станут портами виртуального коммутатора. Этот компьютер можно будет использовать как обычный коммутатор. У компьютера будет один сетевой интерфейс, у которого есть MAC-адрес, и на который можно назначить IP-адрес, он будет так же подключён к виртуальному коммутатору. У виртуального коммутатора будет 4 активных порта (3 физические сетевые карты + 1 виртуальный интерфейс, которые называется так же как мост).
О сетевых мостах в Debian 12
Они ведут себя и так же как описано выше. Пакет bridge-utils отвечает за их поддержку, он есть в apt. Их можно моментально создавать и удалять, добавлять в них и убирать сетевые интерфейсы, без перезапуска чего либо, просто командами. Разумеется только root имеет достаточно прав чтобы делать это. Но после перезагрузки сетевые мосты пропадут.
Служба networking так же может создавать сетевые мосты и управлять ими. Если создать их путём редактирования её конфигурации, они останутся после перезагрузки. Но чтобы изменения вступили в силу, нужно перезапускать службу.
О сети в QEMU
Есть несколько режимов сети. В данном случае будем использовать режим "bridge", который подразумевает создание внутри виртуальной машины сетевого адаптера с заданными параметрами, создание на физическом компьютере виртуального сетевого адаптера tap, и прямое соединение этих сетевых интерфейсов виртуальным патчкордом. Так же tap адаптер будет автоматически добавлен в указанный сетевой мост.
Создание моста (временно)
Просто создать мост с названием bridge0, и настройками по умолчанию:ip link add bridge0 type bridge
И включить его:ip link set dev bridge0 up
Разумеется выключить тоже можно, заменив в команде "up" на "down". MAC-адрес виртуального интерфейса будет случайный. Состояние виртуального интерфейса будет DOWN даже если его включили командой выше. Состояние сменится на UP когда в мост будет добавлен хотя бы один активный сетевой интерфейс. Активный - значит физическая сетевая карта, к которой что-то подключено, или tap адаптер, соединённый с работающей виртуальной машиной.
Статус и прочую информацию об интерфейсах можно смотреть разными способами. Я предпочитаю команду ip a
.
Состояние интерфейса

Так же можно (но не обязательно) добавить в мост уже существующий интерфейс вот так:ip link set enp2s0 master bridge0
Например физическую сетевую карту. Так часто делают чтобы виртуальные машины стали узлами физической локальной сети и могли полноценно взаимодействовать с ней как и физические узлы.
Убрать интерфейс из моста можно так:ip link set enp2s0 nomaster
Добавление и отображение

Это можно смело делать даже с единственной сетевой картой. Физический компьютер сможет использовать виртуальный интерфейс точно так же как и сетевую карту, и всё так же взаимодействовать с физической локальной сетью. Разве что MAC-адрес будет другой. Далее я расскажу как присвоить виртуальному интерфейсу MAC-адрес физического интерфейса.
И кстати WI-FI адаптер точно так же можно добавить в мост.
Однако сеть в данный момент пропадёт. IP-адрес на физической сетевой карте больше не имеет значения, а на виртуальном интерфейсе его нет.
Нужно запустить DHCP-клиент чтобы получить его:dhclient -v bridge0
Если в этой сети не используется DHCP - добавить вручную IP-адрес:ip a add 172.16.5.2/24 dev bridge0
И маршрут по умолчанию:ip route add 0.0.0.0/0 via 172.16.5.1 dev bridge0
DHCP-клиент

Если всё сделано правильно, сеть на физическом компьютере заработает. И если сейчас запустить правильно настроенную виртуальную машину, она получит IP-адрес от DHCP-сервера в физической сети. Если конечно он там есть.
Как настроить виртуальную машину - расскажу далее в этой статье.
Виртуальная машина

Как я уже говорил, такой мост удалится при перезагрузке физического компьютера. Так же его можно удалить командой:ip link delete bridge0
После удаления моста, интерфейсы, которые были добавлены в мост, станут отдельными.
Создание моста (постоянно)
Чтобы мост не удалялся после перезагрузки, его нужно создавать другим способом - через службу networking.
Можно описать мост в этом файле /etc/network/interfaces
как и другие сетевые интерфейсы или создать отдельный файл в этой папке /etc/network/interfaces.d/
. У меня мостов и интерфейсов не много, я предпочитаю держать всё в одном файле. Пустые строки и комментарии через # здесь допускаются. Советую использовать их чтобы было понятнее.
Вот базовая конфигурация моста:
auto virtbr0
iface virtbr0 inet static
address 10.15.15.1
netmask 255.255.255.0
bridge_fd 0
bridge_maxwait 0
bridge_ports none
bridge_hello 2
bridge_maxage 20
bridge_stp off
Разберём подробнее.auto virtbr0
iface virtbr0 inet static
Мост будет называться "virtbr0". "auto" - значит его нужно создавать и включать автоматически при запуске службы, в том числе при загрузке системы. "static" - значит на этом интерфейсе не будет DHCP-клиента, но нужно будет назначить ему статический IP-адрес. Если хотите всё таки создать мост, но при этом оставить виртуальный сетевой интерфейс без IP-адреса, замените "static" на "manual" и не добавляйте параметры "address" и "netmask". Вы всё ровно можете позже добавить IP-адрес на этот интерфейс командной. Разумеется он удалится после перезагрузки.
Если добавлять в мост физическую сетевую карту, то возможно "static" стоит заменить на "dhcp".address 10.15.15.1
netmask 255.255.255.0
IP-адрес и маска подсети, которые будут назначены на виртуальный интерфейс. После IP-адреса можно указать префикс маски, например /24 и убрать параметр netmask - тут уж как больше нравится. Если выше "static" поменять на "dhcp", эти параметры не нужны. Если "static" - то обязательны, без них мост не будет создан.bridge_ports none
Указывает что мост будет создан, но интерфейсы не будут добавлены в него. QEMU всё ровно сможет добавить в него интерфейсы при запуске виртуальных машин. Так же Вы можете добавить в него интерфейсы тем же способом, что я описал выше в разделе "Создание моста (временно)".
Вместо "none" можно указать один интерфейс или перечислить несколько через пробел.
Прочие параметры
bridge_fd 0
Время в секундах, на которое будет отложено включение моста после его создания. Возможно это пригодится в каких-то сложных, автоматических конфигурациях. Я использую 0 и у меня всё работает.bridge_maxwait 0
Время в секундах, через которое мост будет считаться рабочим после его создания. Отношусь к этому а налогично с предыдущим.bridge_hello 2
Интервал в секундах между hello-кадрами, дающими понять что L2-соединение всё ещё существует. Все коммутаторы по умолчанию используют 2 секунды, и я не видел чтобы кто-то где-то ставил другое значение и при этом мог это аргументировать.bridge_maxage 20
Оригинальное описание такое: "set max message age to time seconds, default is 20, can have a fractional part."
Мне так и не удалось понять что за сообщения, максимальный возраст которых здесь задаётся. Так и оставил на 20 секунд.bridge_stp off
Spanning Tree Protocol - технология, которая защищает от петель коммутации. Сама по себе полезная функция, но не имеет смысла в простой инфраструктуре вроде компьютера с парочкой тестовых виртуальных машин, управляемых одним человеком.
Описание всех параметров можно прочитать в приложении man для пакета bridge-utils-interfaces.man bridge-utils-interfaces
bridge_hw 08:40:2a:9c:aa:29
Так можно указать MAC-адрес для виртуального сетевого интерфейса, который будет называться так же как мост. Вместо MAC-адреса можно указать название физического интерфейса, с которого будет скопирован MAC-адрес. Это не обязательный параметр. Без него MAC-адрес виртуального интерфейса будет случайный.
Если будете добавлять физическую сетевую карту в мост, с неё стоит убрать DHCP-клиент, заменив "dhcp" на "manual" в её параметрах (см. скриншот в спойлере).
Физическая сетевая карта

Чтобы изменения вступили в силу, нужно перезапустить службу networking так:systemctl restart networking.service
Так же стоит учесть, что если убрать из конфигурационного файла мост, который на данный момент уже создан в системе, после перезапуска службы мост не удалится. Его нужно будет удалить вручную или перезагрузить физический компьютер. Актуальное состояние дел всегда можно посмотреть командой ip a
.
Настройка виртуальной машины
Я имею ввиду запуск QEMU напрямую, просто командой. Без libvirt и подобных управлялок. В длинную команду запуска QEMU нужно добавить сетевые настройки:-net nic,model=e1000e,macaddr=52:54:00:a9:2b:c7 -net bridge,br=bridge0
Первый параметр -net указывает на начало перечисления настроек сетевого интерфейса, который увидит операционная система на виртуальной машине, это будет нечто похожее на физическую гигабитную сетевую карту от Intel с явно указанным MAC-адресом. Это лишь пример, Вы можете использовать другие модель, режим, и MAC-адрес. Если к одному мосту будут подключены несколько виртуальных машин, их сетевым интерфейсам необходимо сделать разные MAC-адреса. Можно не указывать MAC-адрес, он будет случайный.
А второй параметр -net это tap адаптер, который будет добавлен на физический компьютер, и будет соединён с предыдущим интерфейсом как прямое соединение виртуальным патчкордом. У него тоже можно указать MAC-адрес, но поскольку интерфейс будет сразу добавлен в мост, его MAC-адрес не будет иметь значения. Пусть останется случайным.bridge
Это название выбранного режима. А именно: создать виртуальный tap адаптер и сразу добавить его в сетевой мост.br=bridge0
В параметре br задаётся название моста, в который нужно добавить виртуальный интерфейс при создании. Если указанного моста не существует, виртуальная машина не запустится.
Разумеется для запуска виртуальной машины и операционной системы на ней, в команду потребуется добавить и другие параметры. Но это статья лишь о сетевых мостах, по этому я не буду о них писать.