Linux tap интерфейс как создать

Обновлено: 03.07.2024

Работа с сетью в qemu достаточна проста, но зачастую вызывает множество вопросов у начинающих. Несмотря на то, что в сети существует ряд полезных руководств, в процессе решения прикладных задач возникают мелкие, но неприятные проблемы. В данной статье, я постараюсь постепенно собирать ряд рецептов и рекомендаций по настройке сети в qemu. Со стороны читателей приветствуются замечания и дополнения.

Все примеры в статье проверены на Fedora 14, qemu 0.13.0, kvm включен.

Основы.

С самого начала надо пояснить, как создать сетевой адаптер в гостевой системе. Для этого служит опция -net с параметром nic (Network Interface Card)

При указании данной опции в гостевой системе появится сетевой интерефейс заданной модели, с указанным mac адресом. При отсутствии параметра model будет эмулироваться адаптер realtek. Узнать какие адаптеры поддерживаются qemu для вашей архитектуры можно при помощи следующей команды

После указания адаптера самое время подумать, как он будет взаимодействовать с внешним миром. Qemu предоставляет несколько различных способов сетевого поключения для гостевой системы, но прежде чем перейти к описанию некоторых из них, необходимо познакомиться с понятием vlan. Сразу хочу отметить,что к Virtual Local Area Network этот термин не имеет отношения. В терминологии qemu vlan - это виртуальный коммутатор который создается процессом qemu, на один процесс их может быть несколько штук, и различаются они по номеру. Подключить сетевой адаптер к нужному vlan можно указав номер в качестве параметра, например

Все что поступает на vlan передаётся другим подключенным туда интерфейсам, а весь секрет взаимодействия с хост системой и внешней сетью заключается в том, что помимо адаптера гостевой системы к vlan можно подлючить много чего ещё.


Так как же всё таки настроить работающую сеть?

Самый простой способ подключения сети в гостевой системе - использование встроенной в qemu системы сетевого обмена с хостом (user mod). Она не требует дополнительной конфигурации - если на хост-системе настроена сеть, то qemu сам позаботиться о том, чтобы запросы автоматически перенаправлялись на нужный сетевой интерфейс.

В данном случае к vlan 0 подключается с одной стороны сетевой адаптер гостевой системы, с другой стороны к этому же vlan подключается встроеннsq в qemu маршрутизатор. Гостевая система при этом получает IP адрес по DHCP (по умолчанию в диапазоне 10.0.2.0/8).

Необходимо подчернуть, что user режим работы сети включается по умолчнию, даже если не прописывать параметры конфигурации в командной строке qemu. Кроме того user режим имеет несколько полезных настроек - как всегда их можно подсмотреть в man`e.

Несмотря на свою простоту данный способ настройки сети для гостевой системы обладает рядом недостатков:

  • Медленная скорость сетевого соединения
  • Нет связи с другими виртульными машиными запущенными на данном хосте
  • Гостевая система недоступна с хост системы и с дригих машин в сети хоста.

К счастью существуют способы, позволяющие устранить эти проблемы.

Сетевое соединение между виртуальными машинами

Нижеописанный способ соединения позволяет установить связь между двумя виртуальными машинами qemu, через сетевой сокет на хост-системе. Для этого будет использоваться параметр -net socket

Сначала запустим первую машину, которая будет слушать порт 2030 по адресу 127.0.0.1

Вторая запущенная виртуальная машина поключается к этому сокету (подразумевается, что машины запущены на одной хост-системе)


Во второй системе создается два интерфейса, один из которых подключается к первой виртуальной машине через сокет, а второй работает в user режиме (NAT встроенный в qemu и описанный выше) - благодаря этому вторая машина получает и доступ во внешнюю сеть и кроме того может обмениваться информацией с первой виртуальной машиной


Необходимо отметить, что при использовании socket механизма, сетевые настройки конечно же не раздаются автоматически. На скриншотах сетевые интерфейсы машин соединенных при помощи сокета на хост системе имеют адреса 192.168.200.1 и 192.168.200.2 (назначены руками) для Linux и Windows соответсвенно. На Linux системе также заметен и второй интерфейс eth2, который предоставляет доступ к внешней сети при помощи NAT.

Схему данной сети можно представить в следующем виде


Кроме того для связи нескольких машин друг с другом может использоваться схема UDP мультикаст сокетов, при этом сами виртуальные машины могут быть запущены на разных хостах. На этой схеме я подробно останавливаться не буду, так как сам её не использовал, а переписывать краткий мануал было бы бессмысленно.

Использование tun/tap интерфейсов для связи машин


Теперь для соединения между хостом и гостевой системой достаточно назначить адреса для tap интерефейса и сетевого адаптера на гостевой системе.

Например, на хост-системе создан мост virtnet0, тогда для добавления в этот мост tap интерфейса привязанного к виртуальной машине /etc/qemu-ifup может выглядеть так

Первый параметр передаваемый скрипту - это имя tap адаптера, он переводится в promisc mode и добавляется в сетевой мост.

Таким образом, если запустить несколько виртаульных машин, то для каждой из них будет назначен tap интерфейс и добавлен в мост virtnet0. При этом машины могут общаться друг с другом и с хост системой (в этом случае мосту в хост системе назнаяается IP адрес).

Кроме того, можно изначально добавить в сетевой мост один из сетевых интерфейсов хост системы - тогда виртуальные машины получаею доступ во внешнюю сеть наравне с хост системой.


В сети можно найти множество различных руководств по настройке подобной конфигурации, поэтому здесь хочется отметить только несколько моментов. Если вы хотите использовать PXE загрузку (например для автоматической установки систем), то крайне рекомендую установить forward delay для моста равным 0

Кроме того, если вы используете NetworkManager для настройки сети, то могли заметить, что он пока что не работает сетевыми мостами (Я не нашел адекватного и быстрого способа). Для решения этой проблемы можно создавать мост непосредственно в скрипте /etc/qemu-ifup

Знаете ли вы, что можете присвоить более чем один IP-адрес физическому сетевому интерфейсу? Эта техника очень полезна, например при работе с Apache и виртуальными хостами, так как позволяет получить доступ к одному и тому же серверу Apache с двух разных IP-адресов.

2. Временный виртуальный сетевой интерфейс

Процесс создания виртуального сетевого интерфейса в Linux не занимает много времени. Он включает один запуск команды ifconfig.

Приведенная выше команда создает виртуальный сетевой интерфейс, базирующийся на оригинальном физическом сетевом интерфейсе eth0. Самое важное условие для создания виртуального сетевого интерфейса - должен существовать физический сетевой интерфейс, в нашем случае eth0. Ниже приведен полный пример:

Теперь мы можем настроить новый виртуальный интерфейс на базе eth0. После выполнения команды ifconfig новый виртуальный интерфейс готов к немедленному использованию.

2.1. Отключение виртуального сетевого интерфейса

Для отключения нашего, созданного ранее, временного сетевого интерфейса мы можем также использовать команду ifconfig с флагом down.

3. Присвоение виртуальному интерфейсу постоянного адреса

Описанные выше настройки не сохраняются после перезагрузки. Если вы хотите, чтобы виртуальный сетевой интерфейс работал постоянно, необходимо модифицировать конфигурационные файлы в соответствии с требованиями вашего дистрибутива Linux. Ниже описан этот процесс для самых распространенных дистрибутивов:

3.1. Debian / Ubuntu

3.1.1. Статический адрес

В Debian или Ubuntu вам необходимо отредактировать файл /etc/network/interfaces, добавив в него следующие строки:

3.1.2. Dhcp

Возможно также использовать витруальный сетевой интерфейс с DHCP. В этом случае вам необходимо добавить в /etc/network/interfaces следующую строку:

Для того, чтобы изменения вступили в силу, необходимо перезапустить сеть:

3.2. Redhat / Fedora / CentOS

3.2.1. Статический адрес

В Redhat, Fedora или CentOS Linux директория, отвечающая за присвоение постоянных IP-адресов - это /etc/sysconfig/network-scripts. В этой директории необходимо создать файл, соответствующий вашему новому виртуальному интерфейсу. В нашем случае этот файл будет называться ifcfg-eth0:0. Создайте этот новый файл и вставьте в него приведенные ниже строки. После перезагрузки адрес будет присвоен виртуальному интерфейсу на постоянной основе.

3.2.2. Dhcp

Когда закончите, перезапустите ваши интерфейсы:

4. Заключение

Раньше один физический сервер обслуживал один веб-сайт. Сегодня такой способ хостинга уже не является жизнеспособным, поэтому способность операционной системы создавать виртуальные сетевые интерфейсы действительно необходима.

Так на обеих концах, с учетом адресации. Кто бы по другому приготовил?


Эээ, а ты курицу с яйцом то не путаешь? OpenVPN сам создает и настраивает интерфейс, зачем ты его руками-то делаешь? Какая-то очень хитрая магия :)

Почитай любые доки по OpenVPN и всё станет ясно.


Эээ, а ты курицу с яйцом то не путаешь? OpenVPN сам создает и настраивает интерфейс, зачем ты его руками-то делаешь? Какая-то очень хитрая магия :)

При таком подходе на tap0 интерфейсе нет адреса, что упрощает маршрутизацию при задаче соединить две сети. В ходе экспериментов, схожего поведения, используя только конфигурирование openvpn добиться не удалось. Создаваемый интерфейс tap без адреса все равно приходилось принудительно поднимать. Допускаю, что документы не дочитал, прошу указать.

petav ★★★★★ ( 09.12.13 22:22:07 )
Последнее исправление: petav 09.12.13 22:22:37 (всего исправлений: 1)

Так можно tun. Зачем тебе tap укакался? Чем тебе tun не подошло?


Так можно tun. Зачем тебе tap укакался? Чем тебе tun не подошло?

Укажите на преимущество использование tun в моем случае, я сам его не просматриваю.

Если тебе не нужен L2 межсетевой (а скорее всего он реально не нужен), но и нет смысла усложнять всё.

Это моё ИМХО на опыте полутора лет.


Преимущества ты должен выявить сам

А что не так? Если тебе не нужен L2, то зачем его городить? Если тебе достаточно L3, то есть смысл использовать то, что будет более быстрее и где будет меньше трафика бегать.


А что не так? Если тебе не нужен L2, то зачем его городить? Если тебе достаточно L3, то есть смысл использовать то, что будет более быстрее и где будет меньше трафика бегать.

но и нет смысла усложнять всё

что именно усложняет использование tap и что упрощает использование tun и где это заметно. Трафик прошу не рассматривать.

Он дело говорит, не дерзи, tap нужен только если тебе надо поиметь общий канальный уровень в двух сетях, а это нужно раз в сто лет для какого-то убогого костыля. Опять же, tap тоже поднимается с полпинка, а если вылазят какие-то косяки с ним, то дело вовсе не в openvpn


Опять же, tap тоже поднимается с полпинка

Я к этому и веду.

tun это L3 интерфейс, передает только IP пакеты. TAP - это L2 интерфейс, гоняет ethernet. Преимущества у каждого свои.

Если нужно объеденить езернет сегменты, то tap и в бридж их с физическим интерфейсом.

Чем отсутствие адреса на интерфейсе может помочь маршрутизации это вообще за гранью моего понимания :)

blind_oracle ★★★★★ ( 09.12.13 22:55:52 )
Последнее исправление: blind_oracle 09.12.13 22:56:38 (всего исправлений: 1)

openvpn на третьем уровне тебе прекрасно всё соединит. Начни в гугле набирать: openvpn tu. - оно тебе само допишет tun vs tap или наоборот. Я думаю ты там всё прочтёшь и сделаешь за десять минут. Опять-же короткие how-to как поднять openvpn есть прямо на сайте openvpn. Если надо что-то поинтереснее - то ман для стека udp читается очень легко и не сложно - в отличии от заморочек с tcp и tap. - Даже в мане написано, что если не знаешь зачем тебе всё усложнять юзай: udp как транспортный канал, и tun как интерфейсы.


uspen ★★★★★ ( 10.12.13 02:18:30 )
Последнее исправление: uspen 10.12.13 02:18:40 (всего исправлений: 1)



blind_oracle , спасибо большое за конструктивное и внятное изложение своей позиции в этом вопросе и потраченное время. Я должен признаться, что оформляя тему я немного опустил детали, для легкости восприятия, а так же хотел предупредить попытки некоторого кол-ва сообщества ЛОРа к ненужным комментариям. Я полагаю Вы это заметили, цитирую:

Обычно, при создании VPN, используется подключение типа точка-точка к некоторому серверу, либо установка ethernet-туннеля с некоторым сервером, при котором туннелю назначается определённая подсеть. Сервер VPN при этом выполняет функции маршрутизации и фильтрования трафика для доступа к локальной сети через VPN.

Данная статья рассматривает другой подход к созданию виртуальной сети, при котором удалённые системы включаются в уже существующую локальную подсеть, а сервер VPN выполняет роль Ethernet-шлюза. При использовании такого подхода мы всё ещё имеем возможность фильтровать трафик на основании способа подключения (например, использовать для локальной сети и для удалённых пользователей разные фильтры), но исключается необходимость настройки маршрутизации, а удалённые машины включаются прямо в локальную сеть, видят ресурсы, даже способны использовать широковещательные посылки вообще без дополнительной настройки. Через такой VPN у них отображаются все компьютеры локальной сети Windows, все доступные XDMCP-серверы при XDMCP broadcast и т. д.

Структура сети и настройка сервера

Предположим, что имеется офис с локальной сетью, используется IP-подсеть 192.168.168.0/24. В эту локальную сеть мы включим домашних пользователей, то есть они будут иметь адрес из этой же самой подсети. Необходимо убедиться, что у них «дома» не встречается данная подсеть, и что никакие системы в локальной сети не имеют адресов из диапазона, который мы выделим для удалённых пользователей.

Поддержка моста в ядре

Для работы такой техники нам нужны некоторые ядерные драйвера. Это универсальный драйвер виртуальных сетевых интерфейсов tun, и драйвер ethernet-моста bridge. Можно включить их в ядро, или собрать модулями:


Если они будут собраны модулями, необходимо либо включить автоматическую загрузку модулей в ядре, либо загружать их самому перед установкой VPN-соединения.

Программное обеспечение

Для сервера потребуется OpenVPN и утилиты для обслуживания моста. В Gentoo они собираются следующим образом:

При использовании >=sys-apps/baselayout-1.12.6 этого достаточно, для более старых версий потребуются специальные утилиты для обслуживания tun/tap-устройств:

Настройка сети

Положим, eth2 — интерфейс, к которому подключена локальная сеть, с назначенным адресом 192.168.168.254. Его настройка выглядела примерно так:

Поскольку он будет участвовать в мосте, ему не нужно назначать адреса. Также, в мосте участвует вновь создаваемый виртуальный интерфейс tap0, которому тоже не назначается никакого адреса. Адрес, который использовался eth2, назначается теперь мосту br0:

Также нужно создать настроечные скрипты для указанных интерфейсов:

Достаточно автоматически загружать только интерфейс br0. depend_br0() автоматически поднимет все остальные необходимые ему для работы:

Создание ключей OpenVPN

Мы будем авторизовывать клиентов посредством RSA-ключей OpenSSL. Для упрощения процесса, для нас приготовили несколько init-скриптов:

Там есть файл vars, в который мы занесём общие значения:

Внизу этого файла мы заполняем наши переменные:

Загружаем переменные из этого файла и строим CA (Certificate Authority):

Ключ сервера

Для генерации ключа сервера с именем office, используем следующую команду:

На вопрос «Common Name» нужно ответить именем сервера (в нашем случае, office). На два вопроса в конце «Sign the certificate? [y/n]» и «1 out of 1 certificate requests certified, commit? [y/n]» отвечаем «y».

При необходимости, можно будет создать дополнительные ключи серверов. Например, это могут быть резервные серверы доступа для повышения надёжности системы. Они создаются той же командой, перед ней нужно выполнить source ./vars.

Параметры Диффи-Хеллмана

Здесь ничего дополнительно делать не придётся, но придётся подождать.

Этот файл нужен только на сервере.

Ключи клиентов

Каждому клиенту необходимо выдать свой ключ. Для клиента с именем client ключ создаётся командой

На вопрос о «Common Name» отвечаем именем клиента (в данном случае, client). На два вопроса в конце отвечаем согласием.

Сгенерированные ключи и сертификаты передаём клиентам через защищённый канал. При необходимости, можно создавать ещё ключи той же командой. Перед её запуском, необходимо загрузить окружение — выполнить source ./vars.

Настройка и запуск сервиса OpenVPN

Для запуска следует использовать следующую конфигурацию сервера (файл /etc/openvpn/openvpn.conf):

Ключ office.key должен иметь режим 600 (доступ только владельцу). Файлы office.crt и dh1024.pem имеют режим 644.

Настройка фильтрования

Поскольку мы используем мост, есть несколько особенностей организации фильтрования пакетов. Например, не все проходящие пакеты могут вообще оказаться IPv4. Для настройки работы моста в ядре существует несколько параметров:

  • bridge-nf-call-arptables
    Логическая переменная bridge-nf-call-arptables управляет передачей трафика ARP в цепочку FORWARD пакетного фильтра arptables. Установленное по умолчанию значение 1 разрешает передачу пакетов фильтрам, 0 – запрещает.
  • bridge-nf-call-iptables
    Логическая переменная bridge-nf-call-iptables управляет передачей проходящего через мост трафика IPv4 в цепочки iptables. Используемое по умолчанию значение 1 разрешает передачу пакетов для фильтрации, 0 – запрещает.
  • bridge-nf-call-ip6tables
    Действие аналогично предыдущему, только оно настраивает передачу трафика IPv6 для фильтрования в цепочки ip6tables.
  • bridge-nf-filter-vlan-tagged
    Логическая переменная bridge-nf-filter-vlan-tagged определяет возможность передачи трафика IP/ARP с тегами VLAN программам фильтрации пакетов (arptables/iptables). Значение 1 (установлено по умолчанию) разрешает передачу пакетов с тегами VLAN программам фильтрации, 0 – запрещает.

Для фильтрования пакетов, проходящих через мост, используется соответствие physdev, которое различает, с какого и на какой порт моста следует пакет. Включаем его в ядре:

Кроме этого, конфигурация ядра должна разрешать передачу пакетов на фильтрацию iptables, т.е. bridge-nf-call-iptables=1 и bridge-nf-call-ip6tables=1 (если вы используете IPv6).
После можете использовать, например, такие правила для фильтрования:


Поподробнее про настройку фильтрации между портами поста можно почитать в статье Building bridges with Linux

Если вы не хотите делать никаких различий между пользователями LAN и пользователями bridged VPN, вы можете просто выключить эти параметры в ядре (они включены по умолчанию):

Клиенты

На клиенте необходимо создать конфигурационный файл OpenVPN следующего содержания:

Если сервер подключен через несколько провайдеров, можно повысить устойчивость сети к отказам. Для этого клиенту нужно прописать несколько опций remote, по одной на сервер, в порядке «сначала предпочтительные».

Имена файлов, указанные в параметрах ca, cert и key — это файлы, переданные через защищённый канал. Права доступа к файлу key должны быть установлены в 600.

Linux

Необходим universal tun/tap driver в ядре, либо модулем, но загруженный.

Gentoo

Соответственно, помещаем туда вышеприведённый конфиг, создаём симлинк и кладём скрипты в поддиректорию в /etc/openvpn/. В конфиге прописываем полный путь к ключу и сертификатам. Следите, чтобы имена файлов в конфиге не пересекались, во избежание неприятных эффектов!

Windows

Конфигурационный файл помещается в директорию «C:\Program Files\OpenVPN\config\» с именем вроде «office.ovpn», туда же помещаются остальные файлы — ключи и сертификаты. Если мы их помещаем в поддиректорию (например, хотим использовать несколько виртуальных сетей и все они предоставили файлы с одинаковым именем ca.crt), указываем полные пути к файлам.

Для запуска сетей можно либо запустить сервис OpenVPN (тогда будут запущены все конфигурации *.ovpn, найденные в config\), либо по отдельности — щёлкаем по файлу .ovpn правой кнопкой и выбираем «Запустить OpenVPN с этой конфигурацией».

Возможные проблемы

Проверить доступность сервера, если он запущен на TCP, можно обычным telnetом.

Windows

Нет свободного виртуального адаптера TAP

По логу OpenVPN видно, что клиент успешно присоединился к серверу, авторизовался, но не смог привязать виртуальную сеть к виртуальному адаптеру. Скорее всего, какие-то другие процессы уже задествовали все имеющиеся в системе адаптеры TAP-Win32. Это мог быть и сам OpenVPN, повисший и не отдавший адаптер.

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

Авторизуясь в LiveJournal с помощью стороннего сервиса вы принимаете условия Пользовательского соглашения LiveJournal

Через /etc/network/interfaces, а не совсем вручную.
1) tun/tap:
iface tap10 inet manual
pre-up ip tuntap add tap10 mode tap user root
up ip link set dev tap10 up
post-down ip link del dev tap10

2) trunk, разделящий пакеты от разных VLANов по псевдоинтерфейсам, как оказалось, конфигурируется исключительно просто:
iface eth1.1 inet static
address 192.168.1.10
netmask 255.255.255.0
gateway 192.168.1.1

3) Несколько IPшников, возможно, из разных подсетей, на одном интерфейсе. Типичный случай, когда в одном физическом сегменте используется несколько подсетей, или когда одна машина должна отзываться на несколько адресов:
iface eth0 inet static
address 192.168.0.1
netmask 255.255.255.0
gateway 192.168.0.1

iface eth0:0 inet static
address 192.168.100.150
netmask 255.255.255.0

iface eth0:1 inet static
address 192.168.200.10
netmask 255.255.255.0

На одном из этих eth0* можно вместо статического адреса использовать DHCP:
iface eth0 inet dhcp

4) А вот если хочется на одном физическом интерфейсе получить несколько разных адресов по DHCP, то придётся поизвращаться. Поскольку DHCP-сервер привязывает выдаваемые IP к MAC-адресам, а MAC-то у физического интерфейса только один, то больше одного IP ему не дадут. Так что придётся добавить к физическому интерфейсу (скажем, eth0) фейковый интерфейс с другим MAC-адресом:
iface eth0 inet dhcp

iface ethFake inet dhcp
pre-up ip link add link eth0 name ethFake address 00:01:02:03:04:05 type macvlan
up ip link set dev ethFake up
post-down ip link del dev ethFake
MAC указывать не обязательно. Если его нет, то ip link add сгенерирует случайный адрес.

А теперь хитрый вопрос для продвинутых сисадминов: поскольку обычно DHCP-сервер выдаёт клиенту адрес гейта, а DHCP-клиент приделывает его в качестве дефолтового маршрута (причём с указанием клиентского IP в качестве src), то при начальном конфигурировании этих двух интерфейсов и при последующих обновлениях дефолтовый маршрут будет перебрасываться с eth0 на ethFake и обратно, и тем ломать маршрутизацию и ронять установленные на тот момент соединения с другого клиентского IP. Как этого избежать?
(Если чё, я знаю ответ :)

Читайте также: