---
description: 'Сложные вопросы работы в сети в FreeBSD: основы шлюзов и маршрутов, CARP, настройка нескольких VLAN в FreeBSD и так далее'
next: books/handbook/partv
params:
  path: /books/handbook/advanced-networking/
part: 'IV. Сетевое взаимодействие'
prev: books/handbook/firewalls
showBookMenu: 'true'
tags: ["Advanced Networking", "Handbook", "gateway", "routes", "wireless", "tethering", "bluetooth", "bridging", "CARP", "VLAN", "WiFi"]
title: 'Глава 34. Сложные вопросы работы в сети'
weight: 39
---

[[advanced-networking]]
= Сложные вопросы работы в сети
:doctype: book
:toc: macro
:toclevels: 1
:icons: font
:sectnums:
:sectnumlevels: 6
:sectnumoffset: 34
:partnums:
:source-highlighter: rouge
:experimental:
:images-path: books/handbook/advanced-networking/

ifdef::env-beastie[]
ifdef::backend-html5[]
:imagesdir: ../../../../images/{images-path}
endif::[]
ifndef::book[]
include::shared/authors.adoc[]
include::shared/mirrors.adoc[]
include::shared/releases.adoc[]
include::shared/attributes/attributes-{{% lang %}}.adoc[]
include::shared/{{% lang %}}/teams.adoc[]
include::shared/{{% lang %}}/mailing-lists.adoc[]
include::shared/{{% lang %}}/urls.adoc[]
toc::[]
endif::[]
ifdef::backend-pdf,backend-epub3[]
include::../../../../../shared/asciidoctor.adoc[]
endif::[]
endif::[]

ifndef::env-beastie[]
toc::[]
include::../../../../../shared/asciidoctor.adoc[]
endif::[]

[[advanced-networking-synopsis]]
== Обзор

Эта глава охватывает ряд сложных тем, связанных с сетями.

Прочтите эту главу, чтобы узнать:

* Основы шлюзов и маршрутов.
* Как настроить USB-тетеринг.
* Как настроить устройства IEEE(R) 802.11 и Bluetooth(R).
* Как сделать так, чтобы система FreeBSD работала как мост.
* Как настроить загрузку системы из сети с помощью PXE.
* Как включить и использовать возможности протокола Common Address Redundancy Protocol (CARP) в FreeBSD.
* Как настроить несколько VLAN в FreeBSD.
* Как настроить гарнитуру Bluetooth.

Прежде чем читать эту главу, необходимо:

* Понимать основы скриптов [.filename]#/etc/rc#.
* Знать основные термины и понятия сетевых технологий.
* Понимать базовые настройки сети в FreeBSD (crossref:network[network,Сеть FreeBSD]).
* Знать, как настроить и установить новое ядро FreeBSD (crossref:kernelconfig[kernelconfig,Настройка ядра FreeBSD]).
* Знать, как устанавливать дополнительное стороннее программное обеспечение (crossref:ports[ports,Установка приложений: Пакеты и Порты]).

[[network-routing]]
== Шлюзы и маршруты

_Маршрутизация_ — это механизм, позволяющий системе находить сетевой путь к другой системе. _Маршрут_ — это определённая пара адресов, представляющих "назначение" и "шлюз". Маршрут указывает, что при попытке достичь указанного назначения пакеты должны отправляться через указанный шлюз. Существует три типа назначений: отдельные хосты, подсети и "маршрут по умолчанию". "Маршрут по умолчанию" используется, если не подходит ни один другой маршрут. Также существует три типа шлюзов: отдельные хосты, интерфейсы (также называемые линками) и аппаратные (MAC) адреса Ethernet. Известные маршруты хранятся в таблице маршрутизации.

В этом разделе представлен обзор основ маршрутизации. Затем показано, как настроить систему FreeBSD в качестве маршрутизатора, и даны некоторые советы по устранению неполадок.

[[network-routing-default]]
=== Основы маршрутизации

Для просмотра таблицы маршрутизации системы FreeBSD используйте man:netstat[1]:

[source, shell]
....
% netstat -r
Routing tables

Internet:
Destination      Gateway            Flags     Refs     Use     Netif Expire
default          outside-gw         UGS        37      418       em0
localhost        localhost          UH          0      181       lo0
test0            0:e0:b5:36:cf:4f   UHLW        5    63288       re0     77
10.20.30.255     link#1             UHLW        1     2421
example.com      link#1             UC          0        0
host1            0:e0:a8:37:8:1e    UHLW        3     4601       lo0
host2            0:e0:a8:37:8:1e    UHLW        0        5       lo0 =>
host2.example.com link#1            UC          0        0
224              link#1             UC          0        0
....

Записи в этом примере следующие:

default::
Первый маршрут в этой таблице указывает маршрут по умолчанию (`default`). Когда локальной системе требуется установить соединение с удалённым узлом, она проверяет таблицу маршрутизации, чтобы определить, существует ли известный путь. Если удалённый узел соответствует записи в таблице, система проверяет, может ли она подключиться, используя интерфейс, указанный в этой записи.
+
Если назначение не соответствует ни одной записи или если все известные пути недоступны, система использует запись для маршрута по умолчанию. Для хостов в локальной сети поле `Gateway` в маршруте по умолчанию указывает на систему, имеющую прямое подключение к Интернету. При чтении этой записи убедитесь, что столбец `Flags` указывает на то, что шлюз доступен (`UG`).
+
Маршрут по умолчанию для машины, которая сама функционирует как шлюз во внешний мир, будет шлюзом провайдера интернет-услуг (ISP).

localhost::
Второй маршрут — это маршрут `localhost`. Интерфейс, указанный в столбце `Netif` для `localhost`, — это [.filename]#lo0#, также известное как loopback-устройство. Это означает, что весь трафик для этого назначения должен быть внутренним, а не отправляться через сеть.

MAC адрес::
Адреса, начинающиеся с `0:e0:`, являются MAC-адресами. FreeBSD автоматически определит любые хосты, например `test0`, в локальной сети Ethernet и добавит маршрут для этого хоста через интерфейс Ethernet [.filename]#re0#. Такой маршрут имеет время жизни, указанное в столбце `Expire`, которое используется, если хост не отвечает в течение определённого времени. В этом случае маршрут к этому хосту будет автоматически удалён. Эти хосты определяются с помощью Протокола маршрутной информации (RIP — Routing Information Protocol), который вычисляет маршруты к локальным хостам на основе определения кратчайшего пути.

subnet::
FreeBSD автоматически добавит маршруты для локальной подсети. В этом примере `10.20.30.255` — это широковещательный адрес для подсети `10.20.30`, а `example.com` — доменное имя, связанное с этой подсетью. Обозначение `link#1` относится к первой Ethernet-карте в машине.
+
Локальные хосты сети и локальные подсети автоматически получают маршруты через демон man:routed[8]. Если он не запущен, будут существовать только маршруты, статически определённые администратором.

host::
Строка `host1` ссылается на хост по его Ethernet-адресу. Поскольку это отправляющий хост, FreeBSD использует loopback-интерфейс ([.filename]#lo0#) вместо Ethernet-интерфейса.
+
Две строки `host2` представляют собой псевдонимы, созданные с помощью man:ifconfig[8]. Символ `=>` после интерфейса [.filename]#lo0# указывает, что помимо loopback-адреса был установлен псевдоним. Такие маршруты отображаются только на хосте, поддерживающем псевдоним, а все остальные хосты в локальной сети будут иметь строку `link#1` для таких маршрутов.

224::
Последняя строка (подсеть назначения `224`) относится к многоадресной рассылке.

Различные атрибуты каждого маршрута можно увидеть в столбце `Flags`. crossref:advanced-networking[routeflags,Часто встречающиеся флаги таблицы маршрутизации] содержит сводку некоторых из этих флагов и их значений:

[[routeflags]]
.Часто встречающиеся флаги таблицы маршрутизации
[cols="1,1", frame="none", options="header"]
|===
| Flag
| Назначение

|U
|Маршрут активен (поднят).

|H
|Целью маршрута является отдельный хост.

|G
|Отправляйте всё для этого назначения на этот шлюз, который разберётся, куда это нужно отправить.

|S
|Этот маршрут был настроен статически.

|C
|Клонирует новый маршрут на основе данного для подключения машин. Такой тип маршрута обычно используется для локальных сетей.

|W
|Маршрут был автоматически настроен на основе локальной сети (клон) маршрута.

|L
|Маршрут включает ссылки на оборудование Ethernet (link).
|===

На системе FreeBSD маршрут по умолчанию может быть определён в [.filename]#/etc/rc.conf# путём указания IP-адреса шлюза по умолчанию:

[.programlisting]
....
defaultrouter="10.20.30.1"
....

Также можно вручную добавить маршрут с помощью `route`:

[source, shell]
....
# route add default 10.20.30.1
....

Обратите внимание, что вручную добавленные маршруты не сохранятся после перезагрузки. Для получения дополнительной информации о ручном управлении таблицами сетевой маршрутизации обратитесь к man:route[8].

[[network-static-routes]]
=== Настройка маршрутизатора со статическими маршрутами

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

Для того чтобы система могла пересылать пакеты между интерфейсами, FreeBSD должна быть настроена как маршрутизатор. Интернет-стандарты и лучшие инженерные практики не позволяют проекту FreeBSD включать эту функцию по умолчанию, но её можно настроить для запуска при загрузке, добавив следующую строку в [.filename]#/etc/rc.conf#:

[.programlisting]
....
gateway_enable="YES"          # Set to YES if this host will be a gateway
....

Чтобы теперь включить маршрутизацию, установите переменную man:sysctl[8] `net.inet.ip.forwarding` в значение `1`. Для отключения маршрутизации сбросьте эту переменную в `0`.

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

[NOTE]
====
Для больших сетей статические маршруты быстро становятся неэффективными. FreeBSD включает стандартный демон маршрутизации man:routed[8], который поддерживает протоколы RIP версий 1 и 2, а также IRDP. Поддержка протоколов маршрутизации BGP и OSPF может быть установлена с помощью пакета package:net/quagga[] или порта.
====

Рассмотрим следующую сеть:

image::static-routes.png[]

В этом сценарии `RouterA` — это машина FreeBSD, которая выступает в качестве маршрутизатора для остальной части Интернета. У нее установлен маршрут по умолчанию на `10.0.0.1`, что позволяет ей соединяться с внешним миром. `RouterB` уже настроен на использование `192.168.1.1` в качестве шлюза по умолчанию.

Прежде чем добавлять статические маршруты, таблица маршрутизации на `RouterA` выглядит следующим образом:

[source, shell]
....
% netstat -nr
Routing tables

Internet:
Destination        Gateway            Flags    Refs      Use  Netif  Expire
default            10.0.0.1           UGS         0    49378    xl0
127.0.0.1          127.0.0.1          UH          0        6    lo0
10.0.0.0/24        link#1             UC          0        0    xl0
192.168.1.0/24     link#2             UC          0        0    xl1
....

С текущей таблицей маршрутизации `RouterA` не имеет маршрута к сети `192.168.2.0/24`. Следующая команда добавляет сеть `Internal Net 2` в таблицу маршрутизации ``RouterA``, используя `192.168.1.2` в качестве следующего прыжка:

[source, shell]
....
# route add -net 192.168.2.0/24 192.168.1.2
....

Теперь `RouterA` может достигать любого узла в сети `192.168.2.0/24`. Однако информация о маршрутизации не сохранится после перезагрузки системы FreeBSD. Если требуется, чтобы статический маршрут был постоянным, добавьте его в [.filename]#/etc/rc.conf#:

[.programlisting]
....
# Add Internal Net 2 as a persistent static route
static_routes="internalnet2"
route_internalnet2="-net 192.168.2.0/24 192.168.1.2"
....

Переменная конфигурации `static_routes` представляет собой список строк, разделённых пробелом, где каждая строка ссылается на имя маршрута. Переменная `route_internalnet2` содержит статический маршрут для этого имени маршрута.

Использование более одной строки в `static_routes` создает несколько статических маршрутов. Ниже приведен пример добавления статических маршрутов для сетей `192.168.0.0/24` и `192.168.1.0/24`:

[.programlisting]
....
static_routes="net1 net2"
route_net1="-net 192.168.0.0/24 192.168.0.1"
route_net2="-net 192.168.1.0/24 192.168.1.1"
....

[[network-routing-troubleshooting]]
=== Устранение неполадок

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

Существует система, которая отслеживает все выделенные адресные пространства и определяет их точку подключения к магистрали Интернета или основным магистральным линиям, передающим интернет-трафик по стране и по всему миру. Каждая машина магистрали имеет копию главного набора таблиц, которые направляют трафик для определённой сети к конкретному магистральному оператору, а оттуда по цепочке поставщиков услуг, пока он не достигнет конкретной сети.

Это задача поставщика услуг — сообщить магистральным узлам, что они являются точкой подключения и, следовательно, путем внутрь для сайта. Это известно как распространение маршрутов.

Иногда возникают проблемы с распространением маршрутов, и некоторые сайты не могут подключиться. Возможно, наиболее полезная команда для выяснения, где происходит разрыв маршрутизации, — это `traceroute`. Она полезна, когда `ping` не срабатывает.

При использовании `traceroute` укажите адрес удаленного хоста для подключения. В выводе будут показаны шлюзы на пути попытки соединения, в конечном итоге достигая целевого хоста или прерываясь из-за отсутствия соединения. Для получения дополнительной информации обратитесь к man:traceroute[8].

[[network-routing-multicast]]
=== Аспекты многоадресной рассылки (multicast)

FreeBSD изначально поддерживает как приложения с многоадресной рассылкой, так и маршрутизацию многоадресной рассылки. Для работы приложений с многоадресной рассылкой на FreeBSD не требуется специальной настройки. Для поддержки маршрутизации многоадресной рассылки необходимо включить следующую опцию в собственном ядре:

[.programlisting]
....
options MROUTING
....

Демон маршрутизации многоадресной рассылки, mrouted, может быть установлен с помощью пакета package:net/mrouted[] или порта. Этот демон реализует протокол маршрутизации многоадресной рассылки DVMRP и настраивается путём редактирования файла [.filename]#/usr/local/etc/mrouted.conf# для настройки туннелей и DVMRP. Установка mrouted также устанавливает map-mbone и mrinfo, а также связанные с ними man-страницы. Обратитесь к ним за примерами конфигурации.

[NOTE]
====
DVMRP во многом заменён протоколом PIM во многих инсталляциях с использованием многоадресной рассылки. Дополнительную информацию можно найти в man:pim[4].
====

[[configtuning-virtual-hosts]]
== Виртуальные узлы

Распространённое использование FreeBSD — это виртуальный хостинг сайтов, когда один сервер представляется в сети как множество серверов. Это достигается путём назначения нескольких сетевых адресов одному интерфейсу.

Указанный сетевой интерфейс имеет один "реальный" адрес и может иметь любое количество "псевдонимных" адресов. Эти псевдонимы обычно добавляются путём размещения записей alias в [.filename]#/etc/rc.conf#, как показано в этом примере:

[source, shell]
....
# sysrc ifconfig_fxp0_alias0="inet xxx.xxx.xxx.xxx netmask xxx.xxx.xxx.xxx"
....

Записи псевдонимов должны начинаться с `alias__0__`, используя последовательные числа, такие как `alias0`, `alias1` и так далее. Процесс настройки остановится при первом пропущенном числе.

Расчёт масок подсети для псевдонимов важен. Для заданного интерфейса должен быть один адрес, который корректно представляет маску подсети сети. Любые другие адреса, попадающие в эту сеть, должны иметь маску подсети, состоящую из всех ``1``, выраженную как `255.255.255.255` или `0xffffffff`.

Например, рассмотрим случай, когда интерфейс `fxp0` подключён к двум сетям: `10.1.1.0` с маской сети `255.255.255.0` и `202.0.75.16` с маской сети `255.255.255.240`. Система должна быть настроена так, чтобы находиться в диапазонах `10.1.1.1`–`10.1.1.5` и `202.0.75.17`–`202.0.75.20`. Только первый адрес в каждом диапазоне должен иметь реальную маску сети. Все остальные (`10.1.1.2`–`10.1.1.5` и `202.0.75.18`–`202.0.75.20`) должны быть настроены с маской `255.255.255.255`.

Для данного сценария правильно настраивают адаптер следующие записи в [.filename]#/etc/rc.conf# :

[source, shell]
....
# sysrc ifconfig_fxp0="inet 10.1.1.1 netmask 255.255.255.0"
# sysrc ifconfig_fxp0_alias0="inet 10.1.1.2 netmask 255.255.255.255"
# sysrc ifconfig_fxp0_alias1="inet 10.1.1.3 netmask 255.255.255.255"
# sysrc ifconfig_fxp0_alias2="inet 10.1.1.4 netmask 255.255.255.255"
# sysrc ifconfig_fxp0_alias3="inet 10.1.1.5 netmask 255.255.255.255"
# sysrc ifconfig_fxp0_alias4="inet 202.0.75.17 netmask 255.255.255.240"
# sysrc ifconfig_fxp0_alias5="inet 202.0.75.18 netmask 255.255.255.255"
# sysrc ifconfig_fxp0_alias6="inet 202.0.75.19 netmask 255.255.255.255"
# sysrc ifconfig_fxp0_alias7="inet 202.0.75.20 netmask 255.255.255.255"
....

Более простой способ выразить это — использовать список диапазонов IP-адресов, разделённых пробелами. Первому адресу будет назначена указанная маска подсети, а дополнительным адресам — маска подсети `255.255.255.255`.

[source, shell]
....
# sysrc ifconfig_fxp0_aliases="inet 10.1.1.1-5/24 inet 202.0.75.17-20/28"
....

[[network-advanced-wireless]]
== Расширенная аутентификация в беспроводной сети

FreeBSD поддерживает различные способы подключения к беспроводной сети. В этом разделе описано, как выполнить расширенную аутентификацию в беспроводной сети.

Для подключения и базовой аутентификации в беспроводной сети раздел crossref:network[wireless-authentication,Подключение и аутентификация в беспроводной сети] в главе "Сеть" описывает, как это сделать.

[[network-wireless-wpa-eap-tls]]
=== WPA с EAP-TLS

Второй способ использования WPA — с сервером аутентификации 802.1X. В этом случае WPA называется WPA Enterprise, чтобы отличать его от менее безопасного WPA Personal. Аутентификация в WPA Enterprise основана на расширяемом протоколе аутентификации (EAP).

EAP не включает в себя метод шифрования. Вместо этого EAP встраивается в зашифрованный туннель. Существует множество методов аутентификации EAP, но наиболее распространены EAP-TLS, EAP-TTLS и EAP-PEAP.

EAP с защитой на транспортном уровне (EAP-TLS) — это широко поддерживаемый протокол аутентификации беспроводных сетей, так как он был первым методом EAP, сертифицированным http://www.wi-fi.org/[Альянсом Wi-Fi]. Для работы EAP-TLS требуется три сертификата: сертификат центра сертификации (CA), установленный на всех машинах, сертификат сервера для сервера аутентификации и один клиентский сертификат для каждого беспроводного клиента. В этом методе EAP и сервер аутентификации, и беспроводной клиент аутентифицируют друг друга, предоставляя свои соответствующие сертификаты, а затем проверяют, что эти сертификаты были подписаны CA организации.

Как и ранее, настройка выполняется через [.filename]#/etc/wpa_supplicant.conf#:

[.programlisting]
....
network={
  ssid="freebsdap" <.>
  proto=RSN  <.>
  key_mgmt=WPA-EAP <.>
  eap=TLS <.>
  identity="loader" <.>
  ca_cert="/etc/certs/cacert.pem" <.>
  client_cert="/etc/certs/clientcert.pem" <.>
  private_key="/etc/certs/clientkey.pem" <.>
  private_key_passwd="freebsdmallclient" <.>
}
....

<.> Это поле указывает имя сети (SSID).
<.> Этот пример использует протокол RSN IEEE(R) 802.11i, также известный как WPA2.
<.> Строка `key_mgmt` указывает на используемый протокол управления ключами. В данном примере это WPA с аутентификацией EAP.
<.> Это поле указывает метод EAP для подключения.
<.> Поле `identity` содержит строку идентификации для EAP.
<.> Поле `ca_cert` указывает путь к файлу сертификата CA. Этот файл необходим для проверки сертификата сервера.
<.> Строка `client_cert` указывает путь к файлу сертификата клиента. Этот сертификат уникален для каждого беспроводного клиента в сети.
<.> Поле `private_key` содержит путь к файлу закрытого ключа клиентского сертификата.
<.> Поле `private_key_passwd` содержит парольную фразу для закрытого ключа.

Затем добавьте следующие строки в [.filename]#/etc/rc.conf#:

[.programlisting]
....
wlans_ath0="wlan0"
ifconfig_wlan0="WPA DHCP"
....

Следующий шаг — поднять интерфейс:

[source, shell]
....
# service netif start
Starting wpa_supplicant.
DHCPREQUEST on wlan0 to 255.255.255.255 port 67 interval 7
DHCPREQUEST on wlan0 to 255.255.255.255 port 67 interval 15
DHCPACK from 192.168.0.20
bound to 192.168.0.254 -- renewal in 300 seconds.
wlan0: flags=8843<UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST> mtu 1500
      ether 00:11:95:d5:43:62
      inet 192.168.0.254 netmask 0xffffff00 broadcast 192.168.0.255
      media: IEEE 802.11 Wireless Ethernet DS/11Mbps mode 11g
      status: associated
      ssid freebsdap channel 1 (2412 Mhz 11g) bssid 00:11:95:c3:0d:ac
      country US ecm authmode WPA2/802.11i privacy ON deftxkey UNDEF
      AES-CCM 3:128-bit txpower 21.5 bmiss 7 scanvalid 450 bgscan
      bgscanintvl 300 bgscanidle 250 roam:rssi 7 roam:rate 5 protmode CTS
      wme burst roaming MANUAL
....

Также можно поднять интерфейс вручную с помощью man:wpa_supplicant[8] и man:ifconfig[8].

[[network-wireless-wpa-eap-ttls]]
=== WPA с EAP-TTLS

С EAP-TLS и сервер аутентификации, и клиент нуждаются в сертификате. С EAP-TTLS сертификат клиента необязателен. Этот метод аналогичен веб-серверу, который создает защищенный SSL-туннель, даже если у посетителей нет клиентских сертификатов. EAP-TTLS использует зашифрованный TLS-туннель для безопасной передачи данных аутентификации.

Требуемая конфигурация может быть добавлена в [.filename]#/etc/wpa_supplicant.conf#:

[.programlisting]
....
network={
  ssid="freebsdap"
  proto=RSN
  key_mgmt=WPA-EAP
  eap=TTLS <.>
  identity="test" <.>
  password="test" <.>
  ca_cert="/etc/certs/cacert.pem" <.>
  phase2="auth=MD5" <.>
}
....

<.> Это поле определяет метод EAP для подключения.
<.> Поле `identity` содержит строку идентификации для аутентификации EAP внутри зашифрованного TLS-туннеля.
<.> Поле `password` содержит парольную фразу для аутентификации EAP.
<.> Поле `ca_cert` указывает путь к файлу сертификата CA. Этот файл необходим для проверки сертификата сервера.
<.> Это поле определяет метод аутентификации, используемый в зашифрованном TLS-туннеле. В данном примере используется EAP с MD5-Challenge. Фаза "внутренней аутентификации" часто называется "phase2".

Далее добавьте следующие строки в [.filename]#/etc/rc.conf#:

[.programlisting]
....
wlans_ath0="wlan0"
ifconfig_wlan0="WPA DHCP"
....

Следующий шаг — поднять интерфейс:

[source, shell]
....
# service netif start
Starting wpa_supplicant.
DHCPREQUEST on wlan0 to 255.255.255.255 port 67 interval 7
DHCPREQUEST on wlan0 to 255.255.255.255 port 67 interval 15
DHCPREQUEST on wlan0 to 255.255.255.255 port 67 interval 21
DHCPACK from 192.168.0.20
bound to 192.168.0.254 -- renewal in 300 seconds.
wlan0: flags=8843<UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST> mtu 1500
      ether 00:11:95:d5:43:62
      inet 192.168.0.254 netmask 0xffffff00 broadcast 192.168.0.255
      media: IEEE 802.11 Wireless Ethernet DS/11Mbps mode 11g
      status: associated
      ssid freebsdap channel 1 (2412 Mhz 11g) bssid 00:11:95:c3:0d:ac
      country US ecm authmode WPA2/802.11i privacy ON deftxkey UNDEF
      AES-CCM 3:128-bit txpower 21.5 bmiss 7 scanvalid 450 bgscan
      bgscanintvl 300 bgscanidle 250 roam:rssi 7 roam:rate 5 protmode CTS
      wme burst roaming MANUAL
....

[[network-wireless-wpa-eap-peap]]
=== WPA с EAP-PEAP

[NOTE]
====
PEAPv0/EAP-MSCHAPv2 является наиболее распространённым методом PEAP. В этой главе термин PEAP используется для обозначения данного метода.
====

Защищенный EAP (PEAP) разработан как альтернатива EAP-TTLS и является наиболее используемым стандартом EAP после EAP-TLS. В сети с разными операционными системами PEAP должен быть наиболее поддерживаемым стандартом после EAP-TLS.

PEAP аналогичен EAP-TTLS, так как использует сертификат на стороне сервера для аутентификации клиентов путем создания зашифрованного TLS-туннеля между клиентом и сервером аутентификации, что защищает последующий обмен аутентификационной информацией. Аутентификация PEAP отличается от EAP-TTLS тем, что передаёт имя пользователя в открытом виде, и только пароль отправляется в зашифрованном TLS-туннеле. EAP-TTLS использует TLS-туннель как для имени пользователя, так и для пароля.

Добавьте следующие строки в [.filename]#/etc/wpa_supplicant.conf# для настройки параметров, связанных с EAP-PEAP:

[.programlisting]
....
network={
  ssid="freebsdap"
  proto=RSN
  key_mgmt=WPA-EAP
  eap=PEAP <.>
  identity="test" <.>
  password="test" <.>
  ca_cert="/etc/certs/cacert.pem" <.>
  phase1="peaplabel=0" <.>
  phase2="auth=MSCHAPV2" <.>
}
....

<.> Это поле определяет метод EAP для подключения.
<.> Поле `identity` содержит строку идентификации для аутентификации EAP внутри зашифрованного TLS-туннеля.
<.> Поле `password` содержит парольную фразу для аутентификации EAP.
<.> Поле `ca_cert` указывает путь к файлу сертификата CA. Этот файл необходим для проверки сертификата сервера.
<.> Это поле содержит параметры для первой фазы аутентификации, TLS-туннеля. В зависимости от используемого сервера аутентификации укажите конкретную метку для аутентификации. В большинстве случаев меткой будет "client EAP encryption", которая устанавливается с помощью `peaplabel=0`. Дополнительную информацию можно найти в man:wpa_supplicant.conf[5].
<.> Это поле определяет протокол аутентификации, используемый в зашифрованном TLS-туннеле. В случае PEAP, это `auth=MSCHAPV2`.

Добавьте следующее в [.filename]#/etc/rc.conf#:

[.programlisting]
....
wlans_ath0="wlan0"
ifconfig_wlan0="WPA DHCP"
....

Затем поднимите интерфейс:

[source, shell]
....
# service netif start
Starting wpa_supplicant.
DHCPREQUEST on wlan0 to 255.255.255.255 port 67 interval 7
DHCPREQUEST on wlan0 to 255.255.255.255 port 67 interval 15
DHCPREQUEST on wlan0 to 255.255.255.255 port 67 interval 21
DHCPACK from 192.168.0.20
bound to 192.168.0.254 -- renewal in 300 seconds.
wlan0: flags=8843<UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST> mtu 1500
      ether 00:11:95:d5:43:62
      inet 192.168.0.254 netmask 0xffffff00 broadcast 192.168.0.255
      media: IEEE 802.11 Wireless Ethernet DS/11Mbps mode 11g
      status: associated
      ssid freebsdap channel 1 (2412 Mhz 11g) bssid 00:11:95:c3:0d:ac
      country US ecm authmode WPA2/802.11i privacy ON deftxkey UNDEF
      AES-CCM 3:128-bit txpower 21.5 bmiss 7 scanvalid 450 bgscan
      bgscanintvl 300 bgscanidle 250 roam:rssi 7 roam:rate 5 protmode CTS
      wme burst roaming MANUAL
....

[[wireless-ad-hoc-mode]]
== Беспроводное соединение в режиме Ad-hoc

Режим IBSS, также называемый ad-hoc режимом, предназначен для соединений точка-точка. Например, чтобы создать ad-hoc сеть между машинами `A` и `B`, выберите два IP-адреса и SSID.

На `A`:

[source, shell]
....
# ifconfig wlan0 create wlandev ath0 wlanmode adhoc
# ifconfig wlan0 inet 192.168.0.1 netmask 255.255.255.0 ssid freebsdap
# ifconfig wlan0
  wlan0: flags=8843<UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST> metric 0 mtu 1500
	  ether 00:11:95:c3:0d:ac
	  inet 192.168.0.1 netmask 0xffffff00 broadcast 192.168.0.255
	  media: IEEE 802.11 Wireless Ethernet autoselect mode 11g <adhoc>
	  status: running
	  ssid freebsdap channel 2 (2417 Mhz 11g) bssid 02:11:95:c3:0d:ac
	  country US ecm authmode OPEN privacy OFF txpower 21.5 scanvalid 60
	  protmode CTS wme burst
....

Параметр `adhoc` указывает, что интерфейс работает в режиме IBSS.

`B` теперь должен иметь возможность обнаруживать `A`:

[source, shell]
....
# ifconfig wlan0 create wlandev ath0 wlanmode adhoc
# ifconfig wlan0 up scan
  SSID/MESH ID    BSSID              CHAN RATE   S:N     INT CAPS
  freebsdap       02:11:95:c3:0d:ac    2   54M -64:-96  100 IS   WME
....

`I` в выводе подтверждает, что `A` находится в режиме ad-hoc. Теперь настройте `B` с другим IP-адресом:

[source, shell]
....
# ifconfig wlan0 inet 192.168.0.2 netmask 255.255.255.0 ssid freebsdap
# ifconfig wlan0
  wlan0: flags=8843<UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST> metric 0 mtu 1500
	  ether 00:11:95:d5:43:62
	  inet 192.168.0.2 netmask 0xffffff00 broadcast 192.168.0.255
	  media: IEEE 802.11 Wireless Ethernet autoselect mode 11g <adhoc>
	  status: running
	  ssid freebsdap channel 2 (2417 Mhz 11g) bssid 02:11:95:c3:0d:ac
	  country US ecm authmode OPEN privacy OFF txpower 21.5 scanvalid 60
	  protmode CTS wme burst
....

Оба `A` и `B` теперь готовы обмениваться информацией.

[[network-wireless-ap]]
=== Хост FreeBSD в роли точки доступа

FreeBSD может функционировать как точка доступа (AP), что устраняет необходимость покупки аппаратной точки доступа или организации ad-hoc сети. Это может быть особенно полезно, когда машина FreeBSD выступает в качестве шлюза к другой сети, например, к Интернету.

[[network-wireless-ap-basic]]
==== Основные настройки

Прежде чем настраивать машину FreeBSD в качестве точки доступа, ядро должно быть сконфигурировано с соответствующей поддержкой сети для беспроводной карты, а также используемых протоколов безопасности. Для получения дополнительной информации см. crossref:advanced-networking[network-wireless-ap-basic, Базовые настройки].

[NOTE]
====
Драйвер-оболочка NDIS для драйверов Windows(R) в настоящее время не поддерживает работу в режиме точки доступа. Только родные беспроводные драйверы FreeBSD поддерживают режим AP.
====

После загрузки поддержки беспроводной сети проверьте, поддерживает ли беспроводное устройство режим точки доступа на основе хоста, также известный как режим hostap:

[source, shell]
....
# ifconfig wlan0 create wlandev ath0
# ifconfig wlan0 list caps
drivercaps=6f85edc1<STA,FF,TURBOP,IBSS,HOSTAP,AHDEMO,TXPMGT,SHSLOT,SHPREAMBLE,MONITOR,MBSS,WPA1,WPA2,BURST,WME,WDS,BGSCAN,TXFRAG>
cryptocaps=1f<WEP,TKIP,AES,AES_CCM,TKIPMIC>
....

Этот вывод показывает возможности карты. Слово `HOSTAP` подтверждает, что эта беспроводная карта может работать как точка доступа. Также перечислены различные поддерживаемые алгоритмы шифрования: WEP, TKIP и AES. Эта информация указывает, какие протоколы безопасности можно использовать на точке доступа.

Беспроводное устройство можно перевести в режим hostap только во время создания сетевого псевдоустройства, поэтому ранее созданное устройство необходимо сначала удалить:

[source, shell]
....
# ifconfig wlan0 destroy
....

затем повторно создать с правильной опцией перед установкой остальных параметров:

[source, shell]
....
# ifconfig wlan0 create wlandev ath0 wlanmode hostap
# ifconfig wlan0 inet 192.168.0.1 netmask 255.255.255.0 ssid freebsdap mode 11g channel 1
....

Используйте man:ifconfig[8] снова, чтобы посмотреть состояние интерфейса [.filename]#wlan0#:

[source, shell]
....
# ifconfig wlan0
  wlan0: flags=8843<UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST> metric 0 mtu 1500
	  ether 00:11:95:c3:0d:ac
	  inet 192.168.0.1 netmask 0xffffff00 broadcast 192.168.0.255
	  media: IEEE 802.11 Wireless Ethernet autoselect mode 11g <hostap>
	  status: running
	  ssid freebsdap channel 1 (2412 Mhz 11g) bssid 00:11:95:c3:0d:ac
	  country US ecm authmode OPEN privacy OFF txpower 21.5 scanvalid 60
	  protmode CTS wme burst dtimperiod 1 -dfs
....

Параметр `hostap` указывает, что интерфейс работает в режиме точки доступа на основе хоста.

Настройка интерфейса может быть выполнена автоматически при загрузке, если добавить следующие строки в [.filename]#/etc/rc.conf#:

[.programlisting]
....
wlans_ath0="wlan0"
create_args_wlan0="wlanmode hostap"
ifconfig_wlan0="inet 192.168.0.1 netmask 255.255.255.0 ssid freebsdap mode 11g channel 1"
....

==== Точка доступа на основе хоста без аутентификации или шифрования

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

После настройки точки доступа выполните сканирование с другого беспроводного устройства для её обнаружения:

[source, shell]
....
# ifconfig wlan0 create wlandev ath0
# ifconfig wlan0 up scan
SSID/MESH ID    BSSID              CHAN RATE   S:N     INT CAPS
freebsdap       00:11:95:c3:0d:ac    1   54M -66:-96  100 ES   WME
....

Клиентская машина обнаружила точку доступа и может быть ассоциирована с ней:

[source, shell]
....
# ifconfig wlan0 inet 192.168.0.2 netmask 255.255.255.0 ssid freebsdap
# ifconfig wlan0
  wlan0: flags=8843<UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST> metric 0 mtu 1500
	  ether 00:11:95:d5:43:62
	  inet 192.168.0.2 netmask 0xffffff00 broadcast 192.168.0.255
	  media: IEEE 802.11 Wireless Ethernet OFDM/54Mbps mode 11g
	  status: associated
	  ssid freebsdap channel 1 (2412 Mhz 11g) bssid 00:11:95:c3:0d:ac
	  country US ecm authmode OPEN privacy OFF txpower 21.5 bmiss 7
	  scanvalid 60 bgscan bgscanintvl 300 bgscanidle 250 roam:rssi 7
	  roam:rate 5 protmode CTS wme burst
....

[[network-wireless-ap-wpa]]
==== Точка доступа WPA2 на основе хоста

Этот раздел посвящён настройке точки доступа на хосте FreeBSD с использованием протокола безопасности WPA2. Подробнее о WPA и настройке беспроводных клиентов на основе WPA можно узнать в crossref:advanced-networking[network-wireless-wpa-eap-tls, WPA с EAP-TLS].

Демон man:hostapd[8] используется для обработки аутентификации клиентов и управления ключами на точке доступа с поддержкой WPA2.

В следующих операциях конфигурации выполняются на машине FreeBSD, выступающей в качестве точки доступа (AP). После того как точка доступа работает корректно, man:hostapd[8] можно автоматически запускать при загрузке, добавив эту строку в [.filename]#/etc/rc.conf#:

[.programlisting]
....
hostapd_enable="YES"
....

Прежде чем пытаться настроить man:hostapd[8], сначала настройте основные параметры, описанные в crossref:advanced-networking[network-wireless-ap-basic, Основные настройки].

===== WPA2-PSK

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

Конфигурация выполняется в [.filename]#/etc/hostapd.conf#:

[.programlisting]
....
interface=wlan0                  <.>
debug=1                          <.>
ctrl_interface=/var/run/hostapd  <.>
ctrl_interface_group=wheel       <.>
ssid=freebsdap                   <.>
wpa=2                            <.>
wpa_passphrase=freebsdmall       <.>
wpa_key_mgmt=WPA-PSK             <.>
wpa_pairwise=CCMP                <.>
....

<.> Беспроводной интерфейс, используемый для точки доступа.
<.> Уровень детализации, используемый во время выполнения man:hostapd[8]. Значение `1` представляет минимальный уровень.
<.> Путь к каталогу, используемому man:hostapd[8] для хранения файлов доменных сокетов для взаимодействия с внешними программами, такими как man:hostapd_cli[8]. В этом примере используется значение по умолчанию.
<.> Группа, которой разрешён доступ к файлам управляющего интерфейса.
<.> Имя беспроводной сети, или SSID, которое будет отображаться при сканировании беспроводных сетей.
<.> Включает WPA и указывает, какой протокол аутентификации WPA будет использоваться. Значение `2` настраивает точку доступа на WPA2 и является рекомендуемым. Установите значение `1` только если требуется устаревший WPA.
<.> ASCII-пароль для аутентификации WPA.
<.> Протокол управления ключами для использования. В этом примере установлен WPA-PSK.
<.> Алгоритмы шифрования, принимаемые точкой доступа. В этом примере принимается только шифр CCMP (AES). CCMP является альтернативой TKIP и настоятельно рекомендуется к использованию, когда это возможно. TKIP следует разрешать только в случае наличия станций, не способных использовать CCMP.

Следующий шаг — запустить man:hostapd[8]:

[source, shell]
....
# service hostapd forcestart
....

[source, shell]
....
# ifconfig wlan0
wlan0: flags=8943<UP,BROADCAST,RUNNING,PROMISC,SIMPLEX,MULTICAST> metric 0 mtu 1500
	ether 04:f0:21:16:8e:10
	inet6 fe80::6f0:21ff:fe16:8e10%wlan0 prefixlen 64 scopeid 0x9
	nd6 options=21<PERFORMNUD,AUTO_LINKLOCAL>
	media: IEEE 802.11 Wireless Ethernet autoselect mode 11na <hostap>
	status: running
	ssid No5ignal channel 36 (5180 MHz 11a ht/40+) bssid 04:f0:21:16:8e:10
	country US ecm authmode WPA2/802.11i privacy MIXED deftxkey 2
	AES-CCM 2:128-bit AES-CCM 3:128-bit txpower 17 mcastrate 6 mgmtrate 6
	scanvalid 60 ampdulimit 64k ampdudensity 8 shortgi wme burst
	dtimperiod 1 -dfs
	groups: wlan
....

После запуска точки доступа клиенты могут подключиться к ней. Подробнее см. в разделе crossref:advanced-networking[network-wireless-ap-basic, Основные настройки]. Список станций, подключённых к точке доступа, можно просмотреть с помощью команды `ifconfig _wlan0_ list sta`.

[[network-usb-tethering]]
== Раздача интернета через USB

Многие мобильные телефоны предоставляют возможность совместного использования своего интернет-подключения через USB (часто называемую "тетеринг, раздача Интернета или режим модема"). Эта функция использует один из протоколов: RNDIS, CDC или проприетарный протокол Apple(R) iPhone(R)/iPad(R).

* Устройства Android(TM) обычно используют драйвер man:urndis[4].
* Устройства Apple(R) используют драйвер man:ipheth[4].
* Старые устройства часто используют драйвер man:cdce[4].

Перед подключением устройства загрузите соответствующий драйвер в ядро:

[source, shell]
....
# kldload if_urndis
# kldload if_cdce
# kldload if_ipheth
....

После подключения устройства ``ue``_0_ будет доступен для использования как обычное сетевое устройство. Убедитесь, что на устройстве включена опция "USB-тетеринг".

Чтобы сделать это изменение постоянным и загружать драйвер как модуль при загрузке, добавьте соответствующую строку из следующих в [.filename]#/boot/loader.conf#:

[source, shell]
....
if_urndis_load="YES"
if_cdce_load="YES"
if_ipheth_load="YES"
....

[[network-bluetooth]]
== Bluetooth

Bluetooth — это беспроводная технология для создания персональных сетей, работающих в нелицензируемом диапазоне 2.4 ГГц, с радиусом действия до 10 метров. Сети обычно формируются на лету из портативных устройств, таких как мобильные телефоны, карманные компьютеры и ноутбуки. В отличие от технологии Wi-Fi, Bluetooth предоставляет сервисы более высокого уровня, такие как FTP-подобные файловые серверы, передача файлов, передача голоса, эмуляция последовательной линии и многое другое.

Этот раздел описывает использование USB Bluetooth адаптера в системе FreeBSD. Затем рассматриваются различные протоколы и утилиты Bluetooth.

=== Загрузка поддержки Bluetooth

Стек Bluetooth в FreeBSD реализован с использованием фреймворка man:netgraph[4]. Широкий спектр Bluetooth USB-адаптеров поддерживается драйвером man:ng_ubt[4]. Устройства Bluetooth на базе Broadcom BCM2033 поддерживаются драйверами man:ubtbcmfw[4] и man:ng_ubt[4]. Карта Bluetooth PC Card 3CRWB60-A от 3Com поддерживается драйвером man:ng_bt3c[4]. Bluetooth-устройства на основе последовательного порта и UART поддерживаются драйвером man:ng_h4[4] и утилитой man:hcseriald[8].

Прежде чем подключить устройство, определите, какой из вышеуказанных драйверов оно использует, затем загрузите драйвер. Например, если устройство использует драйвер man:ng_ubt[4]:

[source, shell]
....
# kldload ng_ubt
....

Если устройство Bluetooth будет подключено к системе во время её загрузки, можно настроить систему на автоматическую загрузку модуля, добавив драйвер в [.filename]#/boot/loader.conf#:

[.programlisting]
....
ng_ubt_load="YES"
....

После загрузки драйвера подключите USB-адаптер. Если загрузка драйвера прошла успешно, на консоли и в [.filename]#/var/log/messages# появится вывод, похожий на следующий:

[source, shell]
....
ubt0: vendor 0x0a12 product 0x0001, rev 1.10/5.25, addr 2
ubt0: Interface 0 endpoints: interrupt=0x81, bulk-in=0x82, bulk-out=0x2
ubt0: Interface 1 (alt.config 5) endpoints: isoc-in=0x83, isoc-out=0x3,
      wMaxPacketSize=49, nframes=6, buffer size=294
....

Для запуска и остановки стека Bluetooth используйте его стартовый скрипт. Рекомендуется остановить стек перед отключением устройства. Запуск стека Bluetooth может потребовать запуска man:hcsecd[8]. При запуске стека вывод должен быть похож на следующий:

[source, shell]
....
# service bluetooth start ubt0
BD_ADDR: 00:02:72:00:d4:1a
Features: 0xff 0xff 0xf 00 00 00 00 00
<3-Slot> <5-Slot> <Encryption> <Slot offset>
<Timing accuracy> <Switch> <Hold mode> <Sniff mode>
<Park mode> <RSSI> <Channel quality> <SCO link>
<HV2 packets> <HV3 packets> <u-law log> <A-law log> <CVSD>
<Paging scheme> <Power control> <Transparent SCO data>
Max. ACL packet size: 192 bytes
Number of ACL packets: 8
Max. SCO packet size: 64 bytes
Number of SCO packets: 8
....

=== Поиск других устройств Bluetooth

Интерфейс Host Controller Interface (HCI) предоставляет единый метод доступа к базовым возможностям Bluetooth. В FreeBSD узел netgraph HCI создается для каждого устройства Bluetooth. Подробнее см. man:ng_hci[4].

Одной из наиболее распространённых задач является обнаружение Bluetooth-устройств в радиусе действия. Эта операция называется _сканирование_ (inquiry). Запрос и другие операции, связанные с HCI, выполняются с помощью man:hccontrol[8]. В приведённом ниже примере показано, как выяснить, какие Bluetooth-устройства находятся в зоне действия. Список устройств должен отобразиться через несколько секунд. Обратите внимание, что удалённое устройство ответит на запрос только в том случае, если оно находится в режиме _обнаруживаемое_ (discoverable).

[source, shell]
....
% hccontrol -n ubt0hci inquiry
Inquiry result, num_responses=1
Inquiry result #0
       BD_ADDR: 00:80:37:29:19:a4
       Page Scan Rep. Mode: 0x1
       Page Scan Period Mode: 00
       Page Scan Mode: 00
       Class: 52:02:04
       Clock offset: 0x78ef
Inquiry complete. Status: No error [00]
....

`BD_ADDR` — это уникальный адрес Bluetooth-устройства, аналогичный MAC-адресу сетевой карты. Этот адрес необходим для дальнейшего взаимодействия с устройством, и ему можно присвоить удобочитаемое имя. Информация об известных Bluetooth-хостах содержится в файле [.filename]#/etc/bluetooth/hosts#. В следующем примере показано, как получить удобочитаемое имя, присвоенное удалённому устройству:

[source, shell]
....
% hccontrol -n ubt0hci remote_name_request 00:80:37:29:19:a4
BD_ADDR: 00:80:37:29:19:a4
Name: Pav's T39
....

Если выполняется запрос к удалённому устройству Bluetooth, компьютер будет обнаружен как "your.host.name (ubt0)". Имя, назначенное локальному устройству, можно изменить в любое время.

Удаленным устройствам могут быть назначены псевдонимы в [.filename]#/etc/bluetooth/hosts#. Дополнительная информация о файле [.filename]#/etc/bluetooth/hosts# может быть найдена в man:bluetooth.hosts[5].

Система Bluetooth обеспечивает соединение точка-точка между двумя устройствами Bluetooth или соединение точка-многоточка, разделяемое между несколькими устройствами Bluetooth. В следующем примере показано, как создать соединение с удалённым устройством:

[source, shell]
....
% hccontrol -n ubt0hci create_connection BT_ADDR
....

`create_connection` принимает `BT_ADDR`, а также псевдонимы хостов в файле [.filename]#/etc/bluetooth/hosts#.

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

[source, shell]
....
% hccontrol -n ubt0hci read_connection_list
Remote BD_ADDR    Handle Type Mode Role Encrypt Pending Queue State
00:80:37:29:19:a4     41  ACL    0 MAST    NONE       0     0 OPEN
....

_Дескриптор соединения (connection handle)_ полезен, когда требуется разрыв базового соединения, хотя обычно это не нужно делать вручную. Стек автоматически разрывает неактивные базовые соединения.

[source, shell]
....
# hccontrol -n ubt0hci disconnect 41
Connection handle: 41
Reason: Connection terminated by local host [0x16]
....

Введите `hccontrol help` для получения полного списка доступных команд HCI. Большинство команд HCI не требуют прав суперпользователя.

=== Сопряжение устройств

По умолчанию Bluetooth-связь не требует аутентификации, и любое устройство может взаимодействовать с любым другим устройством. Устройство Bluetooth, такое как сотовый телефон, может потребовать аутентификацию для предоставления определённой услуги. Аутентификация Bluetooth обычно выполняется с помощью _PIN-кода_ — строки ASCII длиной до 16 символов. Пользователь должен ввести один и тот же PIN-код на обоих устройствах. После ввода PIN-кода оба устройства сгенерируют _ключ связи_. Затем ключ связи может быть сохранен либо в самих устройствах, либо в постоянном хранилище. В следующий раз оба устройства будут использовать ранее сгенерированный ключ связи. Эта процедура называется _сопряжением (pairing)_. Обратите внимание, что если ключ связи будет утерян одним из устройств, спаривание необходимо повторить.

Демон man:hcsecd[8] отвечает за обработку запросов аутентификации Bluetooth. Конфигурационный файл по умолчанию — [.filename]#/etc/bluetooth/hcsecd.conf#. Пример раздела для мобильного телефона с PIN-кодом `1234` приведён ниже:

[.programlisting]
....
device {
        bdaddr  00:80:37:29:19:a4;
        name    "Pav's T39";
        key     nokey;
        pin     "1234";
      }
....

Единственное ограничение PIN-кодов — их длина. Некоторые устройства, например Bluetooth-гарнитуры, могут иметь встроенный фиксированный PIN-код. Ключ `-d` заставляет man:hcsecd[8] оставаться на переднем плане, что упрощает отслеживание происходящего. Настройте удалённое устройство на приём сопряжения и инициируйте Bluetooth-соединение с ним. Удалённое устройство должно подтвердить принятие сопряжения и запросить PIN-код. Введите тот же PIN-код, который указан в [.filename]#hcsecd.conf#. Теперь компьютер и удалённое устройство сопряжены. Также сопряжение можно инициировать с удалённого устройства.

Следующую строку можно добавить в [.filename]#/etc/rc.conf#, чтобы настроить автоматический запуск man:hcsecd[8] при загрузке системы:

[.programlisting]
....
hcsecd_enable="YES"
....

Вот пример вывода демона man:hcsecd[8]:

[.programlisting]
....
hcsecd[16484]: Got Link_Key_Request event from 'ubt0hci', remote bdaddr 0:80:37:29:19:a4
hcsecd[16484]: Found matching entry, remote bdaddr 0:80:37:29:19:a4, name 'Pav's T39', link key doesn't exist
hcsecd[16484]: Sending Link_Key_Negative_Reply to 'ubt0hci' for remote bdaddr 0:80:37:29:19:a4
hcsecd[16484]: Got PIN_Code_Request event from 'ubt0hci', remote bdaddr 0:80:37:29:19:a4
hcsecd[16484]: Found matching entry, remote bdaddr 0:80:37:29:19:a4, name 'Pav's T39', PIN code exists
hcsecd[16484]: Sending PIN_Code_Reply to 'ubt0hci' for remote bdaddr 0:80:37:29:19:a4
....

=== Доступ в сеть с профилями PPP

Профиль Dial-Up Networking (DUN) может использоваться для настройки сотового телефона в качестве беспроводного модема для подключения к серверу доступа в Интернет через коммутируемое соединение. Он также может применяться для настройки компьютера для приёма входящих вызовов передачи данных с сотового телефона.

Доступ к сети с профилем PPP может использоваться для предоставления доступа к LAN для одного устройства Bluetooth или нескольких устройств Bluetooth. Также он может обеспечить соединение между компьютерами с использованием PPP-сетей через эмуляцию последовательного кабеля.

В FreeBSD эти профили реализованы с помощью man:ppp[8] и обёртки man:rfcomm_pppd[8], которая преобразует Bluetooth-соединение в форму, пригодную для использования PPP. Перед использованием профиля необходимо создать новую метку PPP в [.filename]#/etc/ppp/ppp.conf#. Примеры можно найти в man:rfcomm_pppd[8].

В этом примере man:rfcomm_pppd[8] используется для открытия соединения с удалённым устройством с `BD_ADDR` `00:80:37:29:19:a4` на DUNRFCOMM канале:

[source, shell]
....
# rfcomm_pppd -a 00:80:37:29:19:a4 -c -C dun -l rfcomm-dialup
....

Фактический номер канала будет получен с удаленного устройства с использованием протокола SDP. Можно указать канал RFCOMM вручную, и в этом случае man:rfcomm_pppd[8] не будет выполнять запрос SDP. Используйте man:sdpcontrol[8], чтобы узнать канал RFCOMM на удаленном устройстве.

Для предоставления сетевого доступа через службу PPPLAN необходимо, чтобы работал man:sdpd[8], и была создана новая запись для клиентов LAN в файле [.filename]#/etc/ppp/ppp.conf#. Примеры можно найти в man:rfcomm_pppd[8]. Наконец, запустите сервер RFCOMMPPP на допустимом номере канала RFCOMM. Сервер RFCOMMPPP автоматически зарегистрирует службу Bluetooth LAN в локальном демоне SDP. В приведённом ниже примере показано, как запустить сервер RFCOMMPPP.

[source, shell]
....
# rfcomm_pppd -s -C 7 -l rfcomm-server
....

=== Протоколы Bluetooth

Этот раздел предоставляет обзор различных протоколов Bluetooth, их функций и связанных с ними утилит.

==== Logical Link Control and Adaptation Protocol (L2CAP)

Протокол управления логическим соединением и адаптации (L2CAP) предоставляет сервисы передачи данных с установлением соединения и без него для протоколов верхнего уровня. L2CAP позволяет протоколам более высокого уровня и приложениям передавать и принимать пакеты данных L2CAP размером до 64 килобайт.

L2CAP основан на концепции _каналов_. Канал — это логическое соединение поверх базового соединения, где каждый канал связан с одним протоколом по принципу "многие к одному". Несколько каналов могут быть связаны с одним и тем же протоколом, но канал не может быть связан с несколькими протоколами. Каждый полученный L2CAP-пакет на канале направляется соответствующему протоколу более высокого уровня. Несколько каналов могут совместно использовать одно и то же базовое соединение.

В FreeBSD для каждого устройства Bluetooth создается узел netgraph типа L2CAP. Этот узел обычно соединен с нижестоящим узлом Bluetooth HCI и вышестоящими узлами Bluetooth-сокет. По умолчанию узел L2CAP имеет имя "devicel2cap". Для получения дополнительной информации обратитесь к man:ng_l2cap[4].

Полезной командой является man:l2ping[8], которую можно использовать для проверки связи с другими устройствами. Некоторые реализации Bluetooth могут не возвращать все отправленные им данные, поэтому `0 байт` в следующем примере является нормой.

[source, shell]
....
# l2ping -a 00:80:37:29:19:a4
0 bytes from 0:80:37:29:19:a4 seq_no=0 time=48.633 ms result=0
0 bytes from 0:80:37:29:19:a4 seq_no=1 time=37.551 ms result=0
0 bytes from 0:80:37:29:19:a4 seq_no=2 time=28.324 ms result=0
0 bytes from 0:80:37:29:19:a4 seq_no=3 time=46.150 ms result=0
....

Утилита man:l2control[8] используется для выполнения различных операций с узлами L2CAP. Этот пример показывает, как получить список логических соединений (каналов) и список базовых соединений для локального устройства:

[source, shell]
....
% l2control -a 00:02:72:00:d4:1a read_channel_list
L2CAP channels:
Remote BD_ADDR     SCID/ DCID   PSM  IMTU/ OMTU State
00:07:e0:00:0b:ca    66/   64     3   132/  672 OPEN
% l2control -a 00:02:72:00:d4:1a read_connection_list
L2CAP connections:
Remote BD_ADDR    Handle Flags Pending State
00:07:e0:00:0b:ca     41 O           0 OPEN
....

Еще один инструмент диагностики — man:btsockstat[1]. Он похож на man:netstat[1], но предназначен для структур данных, связанных с Bluetooth-сетями. В примере ниже показано то же логическое соединение, что и в man:l2control[8] выше.

[source, shell]
....
% btsockstat
Active L2CAP sockets
PCB      Recv-Q Send-Q Local address/PSM       Foreign address   CID   State
c2afe900      0      0 00:02:72:00:d4:1a/3     00:07:e0:00:0b:ca 66    OPEN
Active RFCOMM sessions
L2PCB    PCB      Flag MTU   Out-Q DLCs State
c2afe900 c2b53380 1    127   0     Yes  OPEN
Active RFCOMM sockets
PCB      Recv-Q Send-Q Local address     Foreign address   Chan DLCI State
c2e8bc80      0    250 00:02:72:00:d4:1a 00:07:e0:00:0b:ca 3    6    OPEN
....

==== Радиочастотная связь (RFCOMM)

Протокол RFCOMM обеспечивает эмуляцию последовательных портов поверх протокола L2CAP. RFCOMM — это простой транспортный протокол с дополнительными возможностями для эмуляции 9 последовательных портов RS-232 (EIATIA-232-E). Он поддерживает до 60 одновременных соединений (каналов RFCOMM) между двумя устройствами Bluetooth.

Для целей RFCOMM полный путь передачи данных включает два приложения, работающие на конечных точках соединения, и сегмент передачи данных между ними. RFCOMM предназначен для приложений, использующих последовательные порты устройств, в которых они работают. Сегмент передачи данных представляет собой прямое Bluetooth-соединение между устройствами.

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

В FreeBSD RFCOMM реализован на уровне сокетов Bluetooth.

==== Протокол обнаружения служб (SDP)

Протокол обнаружения служб (SDP) предоставляет клиентским приложениям возможность обнаруживать существование служб, предоставляемых серверными приложениями, а также атрибуты этих служб. Атрибуты службы включают тип или класс предоставляемой службы, а также информацию о механизме или протоколе, необходимую для использования службы.

SDP включает взаимодействие между сервером SDP и клиентом SDP. Сервер хранит список записей служб, которые описывают характеристики служб, связанных с сервером. Каждая запись службы содержит информацию об отдельной службе. Клиент может получить информацию из записи службы, хранящейся на сервере SDP, отправив запрос SDP. Если клиент или приложение, связанное с клиентом, решает использовать службу, он должен установить отдельное соединение с провайдером службы для её использования. SDP предоставляет механизм для обнаружения служб и их атрибутов, но не предоставляет механизма для использования этих служб.

Обычно клиент SDP ищет услуги на основе определённых желаемых характеристик. Однако бывают случаи, когда необходимо обнаружить, какие типы услуг описаны в записях сервера SDP без какой-либо предварительной информации об этих услугах. Этот процесс поиска любых предлагаемых услуг называется _обзором (browsing)_.

Сервер Bluetooth SDP, man:sdpd[8], и клиент командной строки — man:sdpcontrol[8], включены в стандартную установку FreeBSD. В следующем примере показано, как выполнить запрос обзора SDP.

[source, shell]
....
% sdpcontrol -a 00:01:03:fc:6e:ec browse
Record Handle: 00000000
Service Class ID List:
        Service Discovery Server (0x1000)
Protocol Descriptor List:
        L2CAP (0x0100)
                Protocol specific parameter #1: u/int/uuid16 1
                Protocol specific parameter #2: u/int/uuid16 1

Record Handle: 0x00000001
Service Class ID List:
        Browse Group Descriptor (0x1001)

Record Handle: 0x00000002
Service Class ID List:
        LAN Access Using PPP (0x1102)
Protocol Descriptor List:
        L2CAP (0x0100)
        RFCOMM (0x0003)
                Protocol specific parameter #1: u/int8/bool 1
Bluetooth Profile Descriptor List:
        LAN Access Using PPP (0x1102) ver. 1.0
....

Обратите внимание, что каждая служба имеет список атрибутов, таких как канал RFCOMM. В зависимости от службы пользователю может потребоваться запомнить некоторые из атрибутов. Некоторые реализации Bluetooth не поддерживают обзор служб и могут возвращать пустой список. В этом случае можно выполнить поиск конкретной службы. В примере ниже показано, как выполнить поиск службы OBEX Object Push (OPUSH):

[source, shell]
....
% sdpcontrol -a 00:01:03:fc:6e:ec search OPUSH
....

Предоставление услуг на FreeBSD клиентам Bluetooth осуществляется с помощью сервера man:sdpd[8]. Следующую строку можно добавить в [.filename]#/etc/rc.conf#:

[.programlisting]
....
sdpd_enable="YES"
....

Затем демон man:sdpd[8] можно запустить с помощью:

[source, shell]
....
# service sdpd start
....

Локальное серверное приложение, которое хочет предоставить сервис Bluetooth удалённым клиентам, зарегистрирует сервис в локальном демоне SDP. Примером такого приложения является man:rfcomm_pppd[8]. После запуска оно зарегистрирует сервис Bluetooth LAN в локальном демоне SDP.

Список служб, зарегистрированных на локальном сервере SDP, можно получить, выполнив запрос обзора SDP через локальный управляющий канал:

[source, shell]
....
# sdpcontrol -l browse
....

==== Отправка объектов протоколом OBEX (Object Push — OPUSH)

Обмен объектами (OBEX) — это широко используемый протокол для простой передачи файлов между мобильными устройствами. Основное применение он находит в инфракрасной связи, где используется для передачи файлов общего назначения между ноутбуками или КПК, а также для отправки визитных карточек или записей календаря между сотовыми телефонами и другими устройствами с приложениями для управления персональной информацией (PIM).

Сервер и клиент OBEX реализованы в obexapp, который можно установить с помощью package:comms/obexapp[] или порта.

Клиент OBEX используется для отправки и/или получения объектов с сервера OBEX. Пример объекта — визитная карточка или встреча. Клиент OBEX может получить номер канала RFCOMM от удалённого устройства через SDP. Это можно сделать, указав имя службы вместо номера канала RFCOMM. Поддерживаемые имена служб: `IrMC`, `FTRN` и `OPUSH`. Также можно указать канал RFCOMM в виде числа. Ниже приведён пример сеанса OBEX, в котором объект информации об устройстве получается с мобильного телефона, а новый объект, визитная карточка, отправляется в директорию телефона.

[source, shell]
....
% obexapp -a 00:80:37:29:19:a4 -C IrMC
obex> get telecom/devinfo.txt devinfo-t39.txt
Success, response: OK, Success (0x20)
obex> put new.vcf
Success, response: OK, Success (0x20)
obex> di
Success, response: OK, Success (0x20)
....

Для предоставления службы OPUSH должен быть запущен man:sdpd[8], а также должна быть создана корневая папка, в которой будут храниться все входящие объекты. Путь к корневой папке по умолчанию — [.filename]#/var/spool/obex#. Наконец, запустите сервер OBEX на допустимом номере канала RFCOMM. Сервер OBEX автоматически зарегистрирует службу OPUSH в локальном демоне SDP. В приведённом ниже примере показано, как запустить сервер OBEX.

[source, shell]
....
# obexapp -s -C 10
....

==== Профиль последовательного порта (Serial Port Profile — SPP)

Профиль последовательного порта (SPP) позволяет устройствам Bluetooth эмулировать последовательное соединение. Этот профиль позволяет устаревшим приложениям использовать Bluetooth в качестве замены кабеля через абстракцию виртуального последовательного порта.

В FreeBSD man:rfcomm_sppd[1] реализует SPP, а псевдо-tty используется как абстракция виртуального последовательного порта. В примере ниже показано, как подключиться к сервису последовательного порта удалённого устройства. RFCOMM-канал не обязательно указывать, так как man:rfcomm_sppd[1] может получить его с удалённого устройства через SDP. Чтобы переопределить это, укажите RFCOMM-канал в командной строке.

[source, shell]
....
# rfcomm_sppd -a 00:07:E0:00:0B:CA -t
rfcomm_sppd[94692]: Starting on /dev/pts/6...
/dev/pts/6
....

После подключения псевдотерминал можно использовать как последовательный порт:

[source, shell]
....
# cu -l /dev/pts/6
....

Псевдотерминал выводится в stdout и может быть прочитан обёрточными скриптами:

[.programlisting]
....
PTS=`rfcomm_sppd -a 00:07:E0:00:0B:CA -t`
cu -l $PTS
....

=== Устранение неполадок

По умолчанию, когда хост FreeBSD принимает новое соединение, он пытается выполнить смену роли и стать ведущим. Некоторые старые устройства Bluetooth, которые не поддерживают смену роли, не смогут подключиться. Поскольку смена роли выполняется при установке нового соединения, невозможно запросить у удалённого устройства, поддерживает ли оно смену роли. Однако существует опция HCI для отключения смены роли на локальной стороне:

[source, shell]
....
# hccontrol -n ubt0hci write_node_role_switch 0
....

Для отображения пакетов Bluetooth используйте сторонний пакет hcidump, который можно установить с помощью package:comms/hcidump[] или порта. Эта утилита аналогична man:tcpdump[1] и может использоваться для вывода содержимого пакетов Bluetooth в терминал и для сохранения этих пакетов в файл.

[[network-bridging]]
== Создание моста

Иногда полезно разделить сеть, например, сегмент Ethernet, на части без необходимости создания IP-подсетей и использования маршрутизатора для соединения сегментов. Устройство, которое так соединяет две сети, называется "мостом".

Мост работает, изучая MAC-адреса устройств на каждом из своих сетевых интерфейсов. Он передаёт трафик между сетями только в том случае, если исходный и целевой MAC-адреса находятся в разных сетях. Во многих отношениях мост похож на Ethernet-коммутатор с очень малым количеством портов. Система FreeBSD с несколькими сетевыми интерфейсами может быть настроена как мост.

Мост может быть полезен в следующих ситуациях:

Соединение сетей::
Основная функция моста — объединить два или более сетевых сегмента. Существует множество причин использовать мост на основе хоста вместо сетевого оборудования, таких как ограничения по кабелям или межсетевой экран. Мост также может соединить беспроводной интерфейс, работающий в режиме hostap, с проводной сетью и выступать в качестве точки доступа.

Межсетевой экран с фильтрацией и управлением трафиком::
Мост может использоваться, когда требуется функциональность межсетевого экрана без маршрутизации или преобразования сетевых адресов (NAT).
+
Пример — небольшая компания, подключённая через DSL или ISDN к провайдеру. У неё есть тринадцать публичных IP-адресов от провайдера и десять компьютеров в сети. В этой ситуации использование маршрутизатора с межсетевым экраном затруднено из-за проблем с подсетями. Межсетевой экран на основе моста можно настроить без каких-либо проблем с IP-адресацией.

Ответвитель сетевого трафика (Network Tap)::
Мост может объединить два сетевых сегмента для проверки всех Ethernet-кадров, проходящих между ними, с использованием man:bpf[4] и man:tcpdump[1] на интерфейсе моста, или путем отправки копии всех кадров на дополнительный интерфейс, известный как span-порт.

VPN уровня 2::
Две Ethernet-сети могут быть соединены через IP-канал путем моста между сетями через туннель EtherIP или решение на основе man:tap[4], такое как OpenVPN.

Избыточность уровня 2::
Сеть может быть соединена несколькими каналами и использовать протокол Spanning Tree Protocol (STP) для блокировки избыточных путей.

В этом разделе описывается, как настроить систему FreeBSD в качестве моста с использованием man:if_bridge[4]. Также доступен драйвер моста на основе netgraph, который описан в man:ng_bridge[4].

[NOTE]
====
Фильтрация пакетов может использоваться с любым пакетом межсетевого экрана, который интегрируется в фреймворк man:pfil[9]. Мост может использоваться как шейпер (ограничитель) трафика с man:altq[4] или man:dummynet[4].
====

=== Включение моста

В FreeBSD man:if_bridge[4] — это модуль ядра, который автоматически загружается с помощью man:ifconfig[8] при создании мостового интерфейса. Также можно включить поддержку моста в собственное ядро, добавив `device if_bridge` в конфигурационный файл собственного ядра.

Мост создается с помощью клонирования интерфейса. Чтобы создать интерфейс моста:

[source, shell]
....
# ifconfig bridge create
bridge0
# ifconfig bridge0
bridge0: flags=8802<BROADCAST,SIMPLEX,MULTICAST> metric 0 mtu 1500
        ether 96:3d:4b:f1:79:7a
        id 00:00:00:00:00:00 priority 32768 hellotime 2 fwddelay 15
        maxage 20 holdcnt 6 proto rstp maxaddr 100 timeout 1200
        root id 00:00:00:00:00:00 priority 0 ifcost 0 port 0
....

При создании интерфейса моста ему автоматически назначается случайно сгенерированный Ethernet-адрес. Параметры `maxaddr` и `timeout` определяют, сколько MAC-адресов будет хранить межсетевой экран в своей таблице переадресации и через сколько секунд каждая запись будет удалена после последнего обнаружения. Остальные параметры управляют работой STP.

Далее укажите, какие сетевые интерфейсы добавить в качестве членов моста. Чтобы мост мог передавать пакеты, все интерфейсы-участники и сам мост должны быть включены:

[source, shell]
....
# ifconfig bridge0 addm fxp0 addm fxp1 up
# ifconfig fxp0 up
# ifconfig fxp1 up
....

Мост теперь может передавать Ethernet-кадры между [.filename]#fxp0# и [.filename]#fxp1#. Добавьте следующие строки в [.filename]#/etc/rc.conf#, чтобы мост создавался при загрузке:

[.programlisting]
....
cloned_interfaces="bridge0"
ifconfig_bridge0="addm fxp0 addm fxp1 up"
ifconfig_fxp0="up"
ifconfig_fxp1="up"
....

Если мостовому хосту нужен IP-адрес, установите его на интерфейсе моста, а не на интерфейсах-участниках. Адрес можно задать статически или через DHCP. В этом примере задаётся статический IP-адрес:

[source, shell]
....
# ifconfig bridge0 inet 192.168.0.1/24
....

Также можно назначит IPv6 адрес интерфейсу моста.

Чтобы изменения стали постоянными, добавьте информацию об адресации в [.filename]#/etc/rc.conf#.

Этот пример использует динамический адрес IPv6:

[.programlisting]
....
ifconfig_bridge0_ipv6="inet6 auto_linklocal accept_rtadv"
....

[NOTE]
====
Когда включена фильтрация пакетов, транзитные пакеты будут проходить через фильтр на входящем интерфейсе мостового интерфейса и исходящем на соответствующих интерфейсах. Любой из этапов может быть отключен. Если направление потока пакетов важно, лучше настроить межсетевой экран на интерфейсах-участниках, а не на самом мосте.

Мост имеет несколько настраиваемых параметров для передачи не-IP и IP пакетов, а также межсетевой экран второго уровня с man:ipfw[8]. Подробнее см. man:if_bridge[4].
====

=== Включение протокола островного дерева (STP)

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

Протокол Rapid Spanning Tree (RSTP или 802.1w) обеспечивает обратную совместимость с устаревшим STP. RSTP предоставляет более быструю сходимость и обменивается информацией с соседними коммутаторами для быстрого перехода в режим передачи без создания петель. FreeBSD поддерживает RSTP и STP в качестве режимов работы, причем RSTP является режимом по умолчанию.

STP может быть включен на интерфейсах участников с помощью man:ifconfig[8]. Для моста с интерфейсами [.filename]#fxp0# и [.filename]#fxp1# включите STP командой:

[source, shell]
....
# ifconfig bridge0 stp fxp0 stp fxp1
bridge0: flags=8843<UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST> metric 0 mtu 1500
        ether d6:cf:d5:a0:94:6d
        id 00:01:02:4b:d4:50 priority 32768 hellotime 2 fwddelay 15
        maxage 20 holdcnt 6 proto rstp maxaddr 100 timeout 1200
        root id 00:01:02:4b:d4:50 priority 32768 ifcost 0 port 0
        member: fxp0 flags=1c7<LEARNING,DISCOVER,STP,AUTOEDGE,PTP,AUTOPTP>
                port 3 priority 128 path cost 200000 proto rstp
                role designated state forwarding
        member: fxp1 flags=1c7<LEARNING,DISCOVER,STP,AUTOEDGE,PTP,AUTOPTP>
                port 4 priority 128 path cost 200000 proto rstp
                role designated state forwarding
....

Этот мост имеет идентификатор остовного дерева `00:01:02:4b:d4:50` и приоритет `32768`. Поскольку `root id` совпадает, это указывает на то, что данный мост является корневым для дерева.

Еще один мост в сети также имеет включенный STP:

[source, shell]
....
bridge0: flags=8843<UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST> metric 0 mtu 1500
        ether 96:3d:4b:f1:79:7a
        id 00:13:d4:9a:06:7a priority 32768 hellotime 2 fwddelay 15
        maxage 20 holdcnt 6 proto rstp maxaddr 100 timeout 1200
        root id 00:01:02:4b:d4:50 priority 32768 ifcost 400000 port 4
        member: fxp0 flags=1c7<LEARNING,DISCOVER,STP,AUTOEDGE,PTP,AUTOPTP>
                port 4 priority 128 path cost 200000 proto rstp
                role root state forwarding
        member: fxp1 flags=1c7<LEARNING,DISCOVER,STP,AUTOEDGE,PTP,AUTOPTP>
                port 5 priority 128 path cost 200000 proto rstp
                role designated state forwarding
....

Строка `root id 00:01:02:4b:d4:50 priority 32768 ifcost 400000 port 4` показывает, что корневым мостом является `00:01:02:4b:d4:50` с стоимостью пути `400000` от данного моста. Путь к корневому мосту проходит через `port 4`, которым является [.filename]#fxp0#.

=== Параметры интерфейса моста

Несколько параметров `ifconfig` уникальны для мостовых интерфейсов. В этом разделе приведены некоторые общие варианты использования этих параметров. Полный список доступных параметров описан в man:ifconfig[8].

private::
Приватный интерфейс не передаёт трафик на другие порты, также обозначенные как приватные. Трафик блокируется безусловно, поэтому Ethernet-кадры, включая ARP-пакеты, не будут передаваться. Если требуется выборочная блокировка трафика, следует использовать межсетевой экран.

span::
Порт зеркалирования (SPAN —Switch Port Analyzer) передаёт копию каждого Ethernet-фрейма, полученного мостом. Количество портов зеркалирования, настроенных на мосту, не ограничено, но если интерфейс назначен как порт зеркалирования, он не может использоваться в качестве обычного порта моста. Это наиболее полезно для пассивного мониторинга сети, подключенной к мосту, на другом хосте, подключенном к одному из портов зеркалирования моста. Например, чтобы отправить копию всех фреймов через интерфейс с именем [.filename]#fxp4#:
+
[source, shell]
....
# ifconfig bridge0 span fxp4
....

sticky::
Если интерфейс участника моста помечен как фиксированный (sticky), динамически изученные записи адресов обрабатываются как статические записи в кэше пересылки. Фиксированные записи никогда не удаляются из кэша и не заменяются, даже если адрес обнаружен на другом интерфейсе. Это даёт преимущество статических записей адресов без необходимости предварительного заполнения таблицы пересылки. Клиенты, изученные на определённом сегменте моста, не могут перемещаться на другой сегмент.
+
Пример использования фиксированных адресов — это объединение моста с VLAN для изоляции сетей клиентов без потерь IP-адресного пространства. Предположим, что `CustomerA` находится в `vlan100`, `CustomerB` — в `vlan101`, а мост имеет адрес `192.168.0.1`:
+
[source, shell]
....
# ifconfig bridge0 addm vlan100 sticky vlan100 addm vlan101 sticky vlan101
# ifconfig bridge0 inet 192.168.0.1/24
....
+
В этом примере оба клиента видят `192.168.0.1` в качестве своего шлюза по умолчанию. Поскольку кэш моста устойчив, один узел не может подделать MAC-адрес другого клиента, чтобы перехватить его трафик.
+
Любое взаимодействие между VLAN может быть заблокировано с помощью межсетевого экрана или, как показано в этом примере, частных интерфейсов:
+
[source, shell]
....
# ifconfig bridge0 private vlan100 private vlan101
....
+
Клиенты полностью изолированы друг от друга, и весь диапазон адресов `/24` может быть выделен без разделения на подсети.
+
Количество уникальных исходных MAC-адресов за интерфейсом может быть ограничено. Как только лимит будет достигнут, пакеты с неизвестными исходными адресами будут отбрасываться до тех пор, пока существующая запись в кэше хоста не истечёт или не будет удалена.
+
Следующий пример устанавливает максимальное количество Ethernet-устройств для `CustomerA` на `vlan100` равным 10:
+
[source, shell]
....
# ifconfig bridge0 ifmaxaddr vlan100 10
....

Мостовые интерфейсы также поддерживают режим мониторинга, в котором пакеты отбрасываются после обработки man:bpf[4] и не обрабатываются или передаются дальше. Это можно использовать для мультиплексирования входа двух или более интерфейсов в один поток man:bpf[4]. Это полезно для восстановления трафика сетевых кранов, которые передают сигналы RX/TX через два отдельных интерфейса. Например, чтобы читать входные данные с четырёх сетевых интерфейсов как один поток:

[source, shell]
....
# ifconfig bridge0 addm fxp0 addm fxp1 addm fxp2 addm fxp3 monitor up
# tcpdump -i bridge0
....

=== Мониторинг SNMP

Интерфейс моста и параметры STP можно отслеживать с помощью man:bsnmpd[1], который включён в базовую систему FreeBSD. Экспортируемые MIB моста соответствуют стандартам IETF, поэтому для получения данных можно использовать любой SNMP-клиент или пакет мониторинга.

Чтобы включить мониторинг на мосту, раскомментируйте эту строку в [.filename]#/etc/snmpd.config#, удалив символ `+#+` в начале:

[.programlisting]
....
begemotSnmpdModulePath."bridge" = "/usr/lib/snmp_bridge.so"
....

Другие параметры конфигурации, такие как имена сообществ и списки доступа, возможно, потребуется изменить в этом файле. Подробнее см. в man:bsnmpd[1] и man:snmp_bridge[3]. После сохранения изменений добавьте следующую строку в [.filename]#/etc/rc.conf#:

[.programlisting]
....
bsnmpd_enable="YES"
....

Затем, запустите man:bsnmpd[1]:

[source, shell]
....
# service bsnmpd start
....

Следующие примеры используют программное обеспечение Net-SNMP (package:net-mgmt/net-snmp[]) для запроса моста с клиентской системы. Также можно использовать порт package:net-mgmt/bsnmptools[]. На SNMP-клиенте, где запущен Net-SNMP, добавьте следующие строки в [.filename]#$HOME/.snmp/snmp.conf#, чтобы импортировать определения MIB для моста:

[.programlisting]
....
mibdirs +/usr/share/snmp/mibs
mibs +BRIDGE-MIB:RSTP-MIB:BEGEMOT-MIB:BEGEMOT-BRIDGE-MIB
....

Для мониторинга одного моста с использованием IETF BRIDGE-MIB (RFC4188):

[source, shell]
....
% snmpwalk -v 2c -c public bridge1.example.com mib-2.dot1dBridge
BRIDGE-MIB::dot1dBaseBridgeAddress.0 = STRING: 66:fb:9b:6e:5c:44
BRIDGE-MIB::dot1dBaseNumPorts.0 = INTEGER: 1 ports
BRIDGE-MIB::dot1dStpTimeSinceTopologyChange.0 = Timeticks: (189959) 0:31:39.59 centi-seconds
BRIDGE-MIB::dot1dStpTopChanges.0 = Counter32: 2
BRIDGE-MIB::dot1dStpDesignatedRoot.0 = Hex-STRING: 80 00 00 01 02 4B D4 50
...
BRIDGE-MIB::dot1dStpPortState.3 = INTEGER: forwarding(5)
BRIDGE-MIB::dot1dStpPortEnable.3 = INTEGER: enabled(1)
BRIDGE-MIB::dot1dStpPortPathCost.3 = INTEGER: 200000
BRIDGE-MIB::dot1dStpPortDesignatedRoot.3 = Hex-STRING: 80 00 00 01 02 4B D4 50
BRIDGE-MIB::dot1dStpPortDesignatedCost.3 = INTEGER: 0
BRIDGE-MIB::dot1dStpPortDesignatedBridge.3 = Hex-STRING: 80 00 00 01 02 4B D4 50
BRIDGE-MIB::dot1dStpPortDesignatedPort.3 = Hex-STRING: 03 80
BRIDGE-MIB::dot1dStpPortForwardTransitions.3 = Counter32: 1
RSTP-MIB::dot1dStpVersion.0 = INTEGER: rstp(2)
....

Значение `dot1dStpTopChanges.0` равно двум, что указывает на двукратное изменение топологии STP-моста. Изменение топологии означает, что одна или несколько связей в сети изменились или вышли из строя, и было выполнено перерасчёт дерева. Значение `dot1dStpTimeSinceTopologyChange.0` покажет, когда это произошло.

Для мониторинга нескольких интерфейсов моста можно использовать приватный BEGEMOT-BRIDGE-MIB:

[source, shell]
....
% snmpwalk -v 2c -c public bridge1.example.com
enterprises.fokus.begemot.begemotBridge
BEGEMOT-BRIDGE-MIB::begemotBridgeBaseName."bridge0" = STRING: bridge0
BEGEMOT-BRIDGE-MIB::begemotBridgeBaseName."bridge2" = STRING: bridge2
BEGEMOT-BRIDGE-MIB::begemotBridgeBaseAddress."bridge0" = STRING: e:ce:3b:5a:9e:13
BEGEMOT-BRIDGE-MIB::begemotBridgeBaseAddress."bridge2" = STRING: 12:5e:4d:74:d:fc
BEGEMOT-BRIDGE-MIB::begemotBridgeBaseNumPorts."bridge0" = INTEGER: 1
BEGEMOT-BRIDGE-MIB::begemotBridgeBaseNumPorts."bridge2" = INTEGER: 1
...
BEGEMOT-BRIDGE-MIB::begemotBridgeStpTimeSinceTopologyChange."bridge0" = Timeticks: (116927) 0:19:29.27 centi-seconds
BEGEMOT-BRIDGE-MIB::begemotBridgeStpTimeSinceTopologyChange."bridge2" = Timeticks: (82773) 0:13:47.73 centi-seconds
BEGEMOT-BRIDGE-MIB::begemotBridgeStpTopChanges."bridge0" = Counter32: 1
BEGEMOT-BRIDGE-MIB::begemotBridgeStpTopChanges."bridge2" = Counter32: 1
BEGEMOT-BRIDGE-MIB::begemotBridgeStpDesignatedRoot."bridge0" = Hex-STRING: 80 00 00 40 95 30 5E 31
BEGEMOT-BRIDGE-MIB::begemotBridgeStpDesignatedRoot."bridge2" = Hex-STRING: 80 00 00 50 8B B8 C6 A9
....

Для изменения мониторинга интерфейса моста через поддерево `mib-2.dot1dBridge`:

[source, shell]
....
% snmpset -v 2c -c private bridge1.example.com
BEGEMOT-BRIDGE-MIB::begemotBridgeDefaultBridgeIf.0 s bridge2
....

[[network-aggregation]]
== Агрегация каналов и отказоустойчивость

FreeBSD предоставляет интерфейс man:lagg[4], который может использоваться для объединения нескольких сетевых интерфейсов в один виртуальный интерфейс с целью обеспечения отказоустойчивости и агрегации каналов. Отказоустойчивость позволяет трафику продолжать передаваться, пока хотя бы один из объединённых сетевых интерфейсов имеет установленное соединение. Агрегация каналов наиболее эффективна на коммутаторах, поддерживающих LACP, так как этот протокол распределяет трафик в обоих направлениях, реагируя на отказ отдельных каналов.

Протоколы агрегации, поддерживаемые интерфейсом lagg, определяют, какие порты используются для исходящего трафика и принимает ли конкретный порт входящий трафик. В man:lagg[4] поддерживаются следующие протоколы:

failover::
Этот режим отправляет и получает трафик только через основной порт. Если основной порт становится недоступным, используется следующий активный порт. Первый интерфейс, добавленный в виртуальный интерфейс, является основным портом, а все последующие добавленные интерфейсы используются как устройства резервирования. Если происходит переключение на неосновной порт, исходный порт снова становится основным, как только становится доступным.

loadbalance::
Это обеспечивает статическую настройку и не выполняет согласование агрегации с узлом или обмен кадрами для мониторинга связи. Если коммутатор поддерживает LACP, следует использовать его.

lacp::
Протокол управления агрегацией каналов IEEE(R) 802.3ad (LACP) согласует набор агрегируемых каналов с узлом-партнёром в один или несколько агрегированных групп каналов (LAG). Каждая LAG состоит из портов с одинаковой скоростью, настроенных на полнодуплексный режим работы, а трафик распределяется между портами в LAG с наибольшей общей скоростью. Обычно существует только одна LAG, содержащая все порты. В случае изменений физической связности LACP быстро сходится к новой конфигурации.
+
LACP распределяет исходящий трафик по активным портам на основе хешированной информации заголовков протоколов и принимает входящий трафик с любого активного порта. Хеш включает исходный и целевой Ethernet-адреса, а также, если доступно, тег VLAN и исходный и целевой IPv4 или IPv6 адреса.

roundrobin::
Этот режим распределяет исходящий трафик с помощью циклического планировщика через все активные порты и принимает входящий трафик с любого активного порта. Поскольку этот режим нарушает порядок следования Ethernet-кадров, его следует использовать с осторожностью.

broadcast::
Этот режим отправляет исходящий трафик на все порты, настроенные на интерфейсе lagg, и принимает кадры на любом порту.

=== Примеры конфигурации

В этом разделе показано, как настроить коммутатор Cisco(R) и систему FreeBSD для балансировки нагрузки LACP. Затем демонстрируется настройка двух Ethernet-интерфейсов в режиме отказоустойчивости, а также настройка режима отказоустойчивости между Ethernet и беспроводным интерфейсом.

[[networking-lacp-aggregation-cisco]]
.Агрегация каналов с использованием LACP и коммутатора Cisco(R)
[example]
====
В этом примере два Ethernet-интерфейса man:fxp[4] на машине FreeBSD подключены к первым двум Ethernet-портам коммутатора Cisco(R) в виде единого отказоустойчивого канала с балансировкой нагрузки. Дополнительные интерфейсы могут быть добавлены для увеличения пропускной способности и отказоустойчивости. Замените названия портов Cisco(R), Ethernet-устройств, номер группы каналов и IP-адрес, указанные в примере, в соответствии с вашей конфигурацией.

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

На коммутаторе Cisco(R) добавьте интерфейсы _FastEthernet0/1_ и _FastEthernet0/2_ в группу каналов _1_:

[source, shell]
....
interface FastEthernet0/1
 channel-group 1 mode active
 channel-protocol lacp
!
interface FastEthernet0/2
 channel-group 1 mode active
 channel-protocol lacp
....

На системе FreeBSD создайте интерфейс man:lagg[4], используя физические интерфейсы _fxp0_ и _fxp1_, и поднимите интерфейсы с IP-адресом _10.0.0.3/24_:

[source, shell]
....
# ifconfig fxp0 up
# ifconfig fxp1 up
# ifconfig lagg0 create
# ifconfig lagg0 up laggproto lacp laggport fxp0 laggport fxp1 10.0.0.3/24
....

Далее проверьте состояние виртуального интерфейса:

[source, shell]
....
# ifconfig lagg0
lagg0: flags=8843<UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST> metric 0 mtu 1500
        options=8<VLAN_MTU>
        ether 00:05:5d:71:8d:b8
        inet 10.0.0.3 netmask 0xffffff00 broadcast 10.0.0.255
        media: Ethernet autoselect
        status: active
        laggproto lacp
        laggport: fxp1 flags=1c<ACTIVE,COLLECTING,DISTRIBUTING>
        laggport: fxp0 flags=1c<ACTIVE,COLLECTING,DISTRIBUTING>
....

Порты, помеченные как `ACTIVE`, являются частью LAG, который был согласован с удаленным коммутатором. Через эти активные порты будет передаваться и приниматься трафик. Добавьте `-v` к приведённой выше команде, чтобы просмотреть идентификаторы LAG.

Чтобы проверить статус порта на коммутаторе Cisco(R):

[source, shell]
....
switch# show lacp neighbor
Flags:  S - Device is requesting Slow LACPDUs
        F - Device is requesting Fast LACPDUs
        A - Device is in Active mode       P - Device is in Passive mode

Channel group 1 neighbors

Partner's information:

                  LACP port                        Oper    Port     Port
Port      Flags   Priority  Dev ID         Age     Key     Number   State
Fa0/1     SA      32768     0005.5d71.8db8  29s    0x146   0x3      0x3D
Fa0/2     SA      32768     0005.5d71.8db8  29s    0x146   0x4      0x3D
....

Для получения более подробной информации введите `show lacp neighbor detail`.

Чтобы сохранить эту конфигурацию после перезагрузки, добавьте следующие записи в [.filename]#/etc/rc.conf# на системе FreeBSD:

[.programlisting]
....
ifconfig_fxp0="up"
ifconfig_fxp1="up"
cloned_interfaces="lagg0"
ifconfig_lagg0="laggproto lacp laggport fxp0 laggport fxp1 10.0.0.3/24"
....

====

[[networking-lagg-failover]]
.Режим отказоустойчивости
[example]
====

Режим отказоустойчивости может быть использован для переключения на резервный интерфейс, если соединение на основном интерфейсе потеряно. Для настройки отказоустойчивости убедитесь, что физические интерфейсы активны, затем создайте интерфейс man:lagg[4]. В этом примере _fxp0_ — основной интерфейс, _fxp1_ — резервный интерфейс, а виртуальному интерфейсу назначен IP-адрес _10.0.0.15/24_:

[source, shell]
....
# ifconfig fxp0 up
# ifconfig fxp1 up
# ifconfig lagg0 create
# ifconfig lagg0 up laggproto failover laggport fxp0 laggport fxp1 10.0.0.15/24
....

Виртуальный интерфейс должен выглядеть примерно так:

[source, shell]
....
# ifconfig lagg0
lagg0: flags=8843<UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST> metric 0 mtu 1500
        options=8<VLAN_MTU>
        ether 00:05:5d:71:8d:b8
        inet 10.0.0.15 netmask 0xffffff00 broadcast 10.0.0.255
        media: Ethernet autoselect
        status: active
        laggproto failover
        laggport: fxp1 flags=0<>
        laggport: fxp0 flags=5<MASTER,ACTIVE>
....

Трафик будет передаваться и приниматься через интерфейс _fxp0_. Если соединение на _fxp0_ будет потеряно, активным станет интерфейс _fxp1_. Если соединение на основном интерфейсе восстановится, он снова станет активным.

Чтобы сохранить эту конфигурацию после перезагрузки, добавьте следующие записи в [.filename]#/etc/rc.conf#:

[.programlisting]
....
ifconfig_fxp0="up"
ifconfig_fxp1="up"
cloned_interfaces="lagg0"
ifconfig_lagg0="laggproto failover laggport fxp0 laggport fxp1 10.0.0.15/24"
....

====

[[networking-lagg-wired-and-wireless]]
.Режим автоматического переключения между Ethernet и беспроводным интерфейсом
[example]
====

Для пользователей ноутбуков обычно желательно настроить беспроводное устройство как вторичное, которое используется только при отсутствии Ethernet-подключения. С помощью man:lagg[4] можно настроить отказоустойчивость, отдавая предпочтение Ethernet-подключению как по соображениям производительности, так и безопасности, сохраняя при этом возможность передачи данных через беспроводное соединение.

Это достигается путем замены MAC-адреса Ethernet-интерфейса на MAC-адрес беспроводного интерфейса.

[NOTE]
****
Теоретически, либо Ethernet, либо беспроводной MAC-адрес можно изменить, чтобы они были одинаковыми. Однако некоторые популярные беспроводные интерфейсы не поддерживают переопределение MAC-адреса. Поэтому мы рекомендуем переопределить Ethernet MAC-адрес для этой цели.
****

[NOTE]
****
Если драйвер для беспроводного интерфейса не загружен в `GENERIC` или собственном ядре, и компьютер работает под FreeBSD {rel121-current}, загрузите соответствующий [.filename]#.ko# в [.filename]#/boot/loader.conf#, добавив `*driver_load="YES"*` в этот файл и перезагрузив систему. Другой, более предпочтительный способ — загрузить драйвер в [.filename]#/etc/rc.conf#, добавив его в `kld_list` (подробности см. в man:rc.conf[5]) в этом файле и перезагрузив систему. Это необходимо, потому что в противном случае драйвер ещё не загружен к моменту настройки интерфейса man:lagg[4].
****

В этом примере Ethernet-интерфейс _re0_ является основным, а беспроводной интерфейс _wlan0_ — резервным. Интерфейс _wlan0_ был создан на основе физического беспроводного интерфейса _ath0_, а Ethernet-интерфейс будет настроен с MAC-адресом беспроводного интерфейса. Сначала включите беспроводной интерфейс (замените _FR_ на код вашей страны из 2 букв), но не задавайте IP-адрес. Замените _wlan0_ на имя беспроводного интерфейса вашей системы:

[source, shell]
....
# ifconfig wlan0 create wlandev ath0 country FR ssid my_router up
....

Определите MAC-адрес беспроводного интерфейса, например, так:

[source, shell]
....
# ifconfig wlan0
wlan0: flags=8843<UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST> metric 0 mtu 1500
	ether b8:ee:65:5b:32:59
	groups: wlan
	ssid Bbox-A3BD2403 channel 6 (2437 MHz 11g ht/20) bssid 00:37:b7:56:4b:60
	regdomain ETSI country FR indoor ecm authmode WPA2/802.11i privacy ON
	deftxkey UNDEF AES-CCM 2:128-bit txpower 30 bmiss 7 scanvalid 60
	protmode CTS ampdulimit 64k ampdudensity 8 shortgi -stbctx stbcrx
	-ldpc wme burst roaming MANUAL
	media: IEEE 802.11 Wireless Ethernet MCS mode 11ng
	status: associated
	nd6 options=29<PERFORMNUD,IFDISABLED,AUTO_LINKLOCAL>
....

Строка `ether` будет содержать MAC-адрес указанного интерфейса. Теперь измените MAC-адрес интерфейса Ethernet, чтобы он совпадал:

[source, shell]
....
# ifconfig re0 ether b8:ee:65:5b:32:59
....

Убедитесь, что интерфейс _re0_ включен, затем создайте интерфейс man:lagg[4] с _re0_ в качестве основного с переключением на _wlan0_ в случае отказа:

[source, shell]
....
# ifconfig re0 up
# ifconfig lagg0 create
# ifconfig lagg0 up laggproto failover laggport re0 laggport wlan0
....

Виртуальный интерфейс должен выглядеть примерно так:

[source, shell]
....
# ifconfig lagg0
lagg0: flags=8843<UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST> metric 0 mtu 1500
        options=8<VLAN_MTU>
        ether b8:ee:65:5b:32:59
        laggproto failover lagghash l2,l3,l4
        laggport: re0 flags=5<MASTER,ACTIVE>
        laggport: wlan0 flags=0<>
        groups: lagg
        media: Ethernet autoselect
        status: active
....

Затем запустите DHCP-клиент для получения IP-адреса:

[source, shell]
....
# dhclient lagg0
....

Чтобы сохранить эту конфигурацию после перезагрузки, добавьте следующие записи в [.filename]#/etc/rc.conf#:

[.programlisting]
....
ifconfig_re0="ether b8:ee:65:5b:32:59"
wlans_ath0="wlan0"
ifconfig_wlan0="WPA"
create_args_wlan0="country FR"
cloned_interfaces="lagg0"
ifconfig_lagg0="up laggproto failover laggport re0 laggport wlan0 DHCP"
....

====

[[network-diskless]]
== Запуск системы по сети (PXE) без использования локальных накопителей

Встроенная среда исполнения Intel(R) Preboot eXecution Environment (PXE) позволяет операционной системе загружаться по сети. Например, система FreeBSD может загружаться по сети и работать без локального диска, используя файловые системы, смонтированные с NFS-сервера. Поддержка PXE обычно доступна в BIOS. Чтобы использовать PXE при запуске машины, выберите опцию `Загрузка по сети` в настройках BIOS или нажмите функциональную клавишу во время инициализации системы.

Для предоставления файлов, необходимых для загрузки операционной системы по сети, настройка PXE также требует правильно настроенных серверов DHCP, TFTP и NFS, где:

* Исходные параметры, такие как IP-адрес, имя загружаемого исполняемого файла и его расположение, имя сервера и корневой путь, получаются от сервера DHCP.
* Файл загрузчика операционной системы загружается с использованием TFTP.
* Файловые системы загружаются с использованием NFS.

Когда компьютер загружается по PXE, он получает информацию через DHCP о том, где получить начальный загрузочный файл. После того как хост-компьютер получает эту информацию, он загружает загрузчик через TFTP и затем выполняет его. В FreeBSD загрузочный файл называется [.filename]#/boot/pxeboot#. После выполнения [.filename]#/boot/pxeboot# загружается ядро FreeBSD, и продолжается остальная последовательность загрузки FreeBSD, как описано в crossref:boot[boot,Процесс загрузки FreeBSD].

[NOTE]
====
Для загрузки по PXE на UEFI фактический файл загрузчика, который следует использовать, это [.filename]#/boot/loader.efi#. См. раздел ниже crossref:advanced-networking[_debugging_pxe_problems,Отладка проблем PXE] о том, как использовать [.filename]#/boot/loader.efi#.
====

Этот раздел описывает, как настроить эти службы в системе FreeBSD, чтобы другие системы могли загружаться по PXE в FreeBSD. Дополнительную информацию можно найти в man:diskless[8].

[CAUTION]
====
Как уже упоминалось, система, предоставляющая эти службы, является небезопасной. Она должна находиться в защищённой части сети и не доверяться другим хостам.
====

[[network-pxe-nfs]]
=== Настройка окружения PXE

В этом разделе показаны шаги по настройке встроенных серверов NFS и TFTP. В следующем разделе будет продемонстрировано, как установить и настроить сервер DHCP. В данном примере каталог, который будет содержать файлы, используемые пользователями PXE, называется [.filename]#/b/tftpboot/FreeBSD/install#. Важно, чтобы этот каталог существовал и чтобы одно и то же имя каталога было указано как в [.filename]#/etc/inetd.conf#, так и в [.filename]#/usr/local/etc/dhcpd.conf#.

[NOTE]
====
Примеры команд ниже предполагают использование оболочки man:sh[1]. Пользователям man:csh[1] и man:tcsh[1] потребуется запустить оболочку man:sh[1] или адаптировать команды к синтаксису man:csh[1].
====

[.procedure]
. Создайте корневой каталог, который будет содержать установку FreeBSD для монтирования по NFS:
+
[source, shell]
....
# export NFSROOTDIR=/b/tftpboot/FreeBSD/install
# mkdir -p ${NFSROOTDIR}
....

. Включите сервер NFS, добавив следующую строку в [.filename]#/etc/rc.conf#:
+
[.programlisting]
....
nfs_server_enable="YES"
....

. Экспортируйте корневой каталог бездисковой системы через NFS, добавив следующее в [.filename]#/etc/exports#:
+
[.programlisting]
....
/b -ro -alldirs -maproot=root
....

. Запустите сервер NFS:
+
[source, shell]
....
# service nfsd start
....

. Включите man:inetd[8], добавив следующую строку в [.filename]#/etc/rc.conf#:
+
[.programlisting]
....
inetd_enable="YES"
....

. Раскомментируйте следующую строку в [.filename]#/etc/inetd.conf#, убедившись, что она не начинается с символа `+#+`:
+
[.programlisting]
....
tftp dgram udp wait root /usr/libexec/tftpd tftpd blocksize 1468 -l -s /b/tftpboot
....
+
[NOTE]
====
Указанный размер блока tftp, например, 1468 байт, заменяет стандартный размер 512 байт. Некоторые версии PXE требуют TCP-версию TFTP. В этом случае раскомментируйте вторую строку `tftp`, содержащую `stream tcp`.
====

. Запустите man:inetd[8]:
+
[source, shell]
....
# service inetd start
....

. Установите базовую систему в [.filename]#${NFSROOTDIR}#, либо распаковав официальные архивы, либо пересобрав ядро и пользовательское окружение FreeBSD (подробные инструкции можно найти в crossref:cutting-edge[makeworld,“Обновление FreeBSD из исходного кода”], но не забудьте добавить `DESTDIR=_${NFSROOTDIR}_` при выполнении команд `make installkernel` и `make installworld`).
. Проверьте, что TFTP-сервер работает и может загрузить загрузчик, который будет получен через PXE:
+
[source, shell]
....
# tftp localhost
tftp> get FreeBSD/install/boot/pxeboot
Received 264951 bytes in 0.1 seconds
....

. Отредактируйте файл [.filename]#${NFSROOTDIR}/etc/fstab# и создайте запись для монтирования корневой файловой системы через NFS:
+
[.programlisting]
....
# Device                                         Mountpoint    FSType   Options  Dump Pass
myhost.example.com:/b/tftpboot/FreeBSD/install       /         nfs      ro        0    0
....
+
Замените _myhost.example.com_ на имя хоста или IP-адрес сервера NFS. В этом примере корневая файловая система монтируется в режиме только для чтения, чтобы предотвратить возможное удаление содержимого корневой файловой системы клиентами NFS.
. Установите пароль root в среде PXE для клиентских машин, загружающихся через PXE:
+
[source, shell]
....
# chroot ${NFSROOTDIR}
# passwd
....

. При необходимости разрешите вход root по man:ssh[1] для клиентских машин, загружающихся через PXE, отредактировав [.filename]#${NFSROOTDIR}/etc/ssh/sshd_config# и включив `PermitRootLogin`. Эта опция описана в man:sshd_config[5].
. Выполните другие необходимые настройки PXE-окружения в [.filename]#${NFSROOTDIR}#. Эти настройки могут включать установку пакетов или редактирование файла паролей с помощью man:vipw[8].

При загрузке с корневого тома NFS, [.filename]#/etc/rc# определяет загрузку по NFS и запускает [.filename]#/etc/rc.initdiskless#. В этом случае [.filename]#/etc# и [.filename]#/var# должны быть файловыми системами в памяти, чтобы эти каталоги были доступны для записи, тогда как корневой каталог NFS доступен только для чтения:

[source, shell]
....
# chroot ${NFSROOTDIR}
# mkdir -p conf/base
# tar -c -v -f conf/base/etc.cpio.gz --format cpio --gzip etc
# tar -c -v -f conf/base/var.cpio.gz --format cpio --gzip var
....

При загрузке системы будут созданы и смонтированы файловые системы в памяти для [.filename]#/etc# и [.filename]#/var#, а содержимое файлов [.filename]#cpio.gz# будет скопировано в них. По умолчанию эти файловые системы имеют максимальный размер 5 мегабайт. Если архивы не помещаются, что обычно происходит с [.filename]#/var# при установке бинарных пакетов, укажите больший размер, записав количество необходимых секторов по 512 байт (например, 5 мегабайт — это 10240 секторов) в файлы [.filename]#${NFSROOTDIR}/conf/base/etc/md_size# и [.filename]#${NFSROOTDIR}/conf/base/var/md_size# для файловых систем [.filename]#/etc# и [.filename]#/var# соответственно.

[[network-pxe-setting-up-dhcp]]
=== Настройка DHCP-сервера

Сервер DHCP не обязательно должен быть тем же самым компьютером, что и серверы TFTP и NFS, но он должен быть доступен в сети.

DHCP не является частью базовой системы FreeBSD, но может быть установлен с помощью порта package:net/isc-dhcp44-server[] или пакета.

После установки отредактируйте файл конфигурации [.filename]#/usr/local/etc/dhcpd.conf#. Настройте параметры `next-server`, `filename` и `root-path`, как показано в этом примере:

[.programlisting]
....
subnet 192.168.0.0 netmask 255.255.255.0 {
   range 192.168.0.2 192.168.0.3 ;
   option subnet-mask 255.255.255.0 ;
   option routers 192.168.0.1 ;
   option broadcast-address 192.168.0.255 ;
   option domain-name-servers 192.168.35.35, 192.168.35.36 ;
   option domain-name "example.com";

   # IP address of TFTP server
   next-server 192.168.0.1 ;

   # path of boot loader obtained via tftp
   filename "FreeBSD/install/boot/pxeboot" ;

   # pxeboot boot loader will try to NFS mount this directory for root FS
   option root-path "192.168.0.1:/b/tftpboot/FreeBSD/install/" ;

}
....

Директива `next-server` используется для указания IP-адреса TFTP-сервера.

Директива `filename` определяет путь к [.filename]#/boot/pxeboot#. Используется относительное имя файла, что означает, что [.filename]#/b/tftpboot# не включен в путь.

Опция `root-path` определяет путь к корневой файловой системе NFS.

После сохранения изменений включите DHCP при загрузке, добавив следующую строку в [.filename]#/etc/rc.conf#:

[.programlisting]
....
dhcpd_enable="YES"
....

Затем запустите службу DHCP:

[source, shell]
....
# service isc-dhcpd start
....

=== Отладка проблем PXE

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

Этот раздел содержит несколько советов по устранению неполадок для выявления источника проблемы с конфигурацией, если клиенты не могут загрузиться через PXE.

[.procedure]
****
. Используйте пакет package:net/wireshark[] или порт для отладки сетевого трафика, задействованного в процессе загрузки по PXE, который показан на схеме ниже.
+
.Процесс загрузки PXE с монтированием корневой файловой системы по NFS
image::pxe-nfs.png[]
+
1. Клиент рассылает широковещательное сообщение DHCPDISCOVER.
+
2. Сервер DHCP отвечает с указанием IP-адреса, next-server, filename и значений root-path.
+
3. Клиент отправляет запрос TFTP на next-server, запрашивая получение файла filename.
+
4. Сервер TFTP отвечает и отправляет имя файла клиенту.
+
5. Клиент выполняет файл `pxeboot(8)`, который затем загружает ядро. При запуске ядра корневая файловая система, указанная в `root-path`, монтируется через NFS.
+
. На TFTP-сервере прочитайте [.filename]#/var/log/xferlog#, чтобы убедиться, что [.filename]#pxeboot# загружается из правильного места. Для проверки конфигурации, сделанной для этого примера:
+
[source, shell]
....
# tftp 192.168.0.1
tftp> get FreeBSD/install/boot/pxeboot
Received 264951 bytes in 0.1 seconds
....
+
Разделы `BUGS` в man:tftpd[8] и man:tftp[1] описывают некоторые ограничения TFTP.
. Убедитесь, что корневая файловая система может быть смонтирована через NFS. Для проверки конфигурации из этого примера:
+
[source, shell]
....
# mount -t nfs 192.168.0.1:/b/tftpboot/FreeBSD/install /mnt
....
+
. Для загрузки по PXE на UEFI замените файл [.filename]#boot/pxeboot# на файл [.filename]#boot/loader.efi#:
[source, shell]
....
# chroot ${NFSROOTDIR}
# mv boot/pxeboot boot/pxeboot.original
# cp boot/loader.efi boot/pxeboot
....
****

[[carp]]
== Протокол общей избыточности адресов (CARP)

Протокол общей избыточности адресов (CARP) позволяет нескольким хостам использовать один и тот же IP-адрес и идентификатор виртуального хоста (VHID) для обеспечения _высокой доступности_ одной или нескольких служб. Это означает, что при отказе одного или нескольких хостов остальные хосты прозрачно возьмут на себя их функции, чтобы пользователи не заметили сбоя в работе службы.

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

Высокая доступность с использованием CARP встроена в FreeBSD, хотя шаги по её настройке немного различаются в зависимости от версии FreeBSD. В этом разделе приведён одинаковый пример конфигурации для версий до и начиная с FreeBSD 10.

Этот пример настраивает поддержку отказоустойчивости с тремя хостами, каждый из которых имеет уникальный IP-адрес, но предоставляет одинаковое веб-содержимое. В нём есть два разных основных хоста с именами `hosta.example.org` и `hostb.example.org`, а также общий резервный хост с именем `hostc.example.org`.

Эти машины балансируют нагрузку с помощью конфигурации DNS Round Robin. Основная и резервная машины настроены идентично, за исключением их имён хостов и управляющих IP-адресов. Эти серверы должны иметь одинаковую конфигурацию и запускать одинаковые службы. При возникновении переключения, запросы к службе на общем IP-адресе могут быть корректно обработаны только если резервный сервер имеет доступ к тому же содержимому. Резервная машина имеет два дополнительных интерфейса CARP, по одному для каждого из IP-адресов основного сервера содержимого. При возникновении сбоя, резервный сервер возьмёт IP-адрес вышедшей из строя основной машины.

[[carp-10x]]
=== Использование CARP

Включите поддержку CARP при загрузке, добавив запись для модуля ядра [.filename]#carp.ko# в [.filename]#/boot/loader.conf#:

[.programlisting]
....
carp_load="YES"
....

Чтобы сейчас загрузить модуль без перезагрузки:

[source, shell]
....
# kldload carp
....

Для пользователей, которые предпочитают использовать собственное ядро, добавьте следующую строку в файл конфигурации ядра и скомпилируйте его, как описано в crossref:kernelconfig[kernelconfig,Настройка ядра FreeBSD]:

[.programlisting]
....
device	carp
....

Имя хоста, управляющий IP-адрес и маска подсети, общий IP-адрес и VHID задаются путем добавления записей в [.filename]#/etc/rc.conf#. Этот пример для `hosta.example.org`:

[.programlisting]
....
hostname="hosta.example.org"
ifconfig_em0="inet 192.168.1.3 netmask 255.255.255.0"
ifconfig_em0_alias0="inet vhid 1 pass testpass alias 192.168.1.50/32"
....

Следующий набор записей предназначен для `hostb.example.org`. Поскольку он представляет второй мастер, используется другой общий IP-адрес и VHID. Однако пароли, указанные с помощью `pass`, должны быть идентичными, так как CARP будет принимать и обрабатывать объявления только от машин с правильным паролем.

[.programlisting]
....
hostname="hostb.example.org"
ifconfig_em0="inet 192.168.1.4 netmask 255.255.255.0"
ifconfig_em0_alias0="inet vhid 2 pass testpass alias 192.168.1.51/32"
....

Третья машина, `hostc.example.org`, настроена для обработки перехода на резервный сервер от любого из основных. Эта машина настроена с двумя CARPVHID, по одному для обработки виртуального IP-адреса каждого из основных хостов. Значение advskew (временной сдвиг анонсов CARP) обеспечивает задержку в отправке анонсов резервным сервером по сравнению с основным, поскольку `advskew` контролирует порядок приоритета при наличии нескольких резервных серверов.

[.programlisting]
....
hostname="hostc.example.org"
ifconfig_em0="inet 192.168.1.5 netmask 255.255.255.0"
ifconfig_em0_alias0="inet vhid 1 advskew 100 pass testpass alias 192.168.1.50/32"
ifconfig_em0_alias1="inet vhid 2 advskew 100 pass testpass alias 192.168.1.51/32"
....

Наличие двух настроенных CARPVHID означает, что `hostc.example.org` заметит, если один из главных серверов станет недоступен. Если главный сервер не отправит объявление раньше резервного сервера, резервный сервер возьмёт на себя общий IP-адрес до тех пор, пока главный сервер снова не станет доступен.

[NOTE]
====
Если исходный главный сервер снова станет доступен, `hostc.example.org` не освободит виртуальный IP-адрес автоматически. Чтобы это произошло, необходимо включить вытеснение. Эта функция отключена по умолчанию и управляется через переменную man:sysctl[8] `net.inet.carp.preempt`. Администратор может принудительно вернуть IP-адрес главному серверу с резервного сервера:

[source, shell]
....
# ifconfig em0 vhid 1 state backup
....

====

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

Функциональность CARP может управляться с помощью нескольких переменных man:sysctl[8], описанных в man:carp[4]. Другие действия могут быть запущены при событиях CARP с использованием man:devd[8].

[[network-vlan]]
== Виртуальные сети VLAN

Виртуальные локальные сети (VLAN) — это способ виртуального разделения сети на множество различных подсетей, также называемый сегментированием. Каждый сегмент будет иметь свою собственную широковещательную область и быть изолированным от других VLAN.

На FreeBSD поддержка VLAN должна быть обеспечена драйвером сетевой карты. Чтобы узнать, какие драйверы поддерживают VLAN, обратитесь к странице руководства man:vlan[4].

При настройке VLAN необходимо знать несколько параметров. Во-первых, какой сетевой интерфейс? Во-вторых, какой тег VLAN?

Для настройки VLAN во время выполнения, с сетевой картой `em0` и тегом VLAN `5`, команда будет выглядеть следующим образом:

[source, shell]
....
# ifconfig em0.5 create vlan 5 vlandev em0 inet 192.168.20.20/24
....

[NOTE]
====
Видите, что имя интерфейса состоит из имени драйвера сетевой карты и тега VLAN, разделенных точкой? Это рекомендуемая практика для упрощения работы с конфигурациями VLAN, когда на машине присутствует множество VLAN.
====

[NOTE]
====
При определении VLAN убедитесь, что родительский сетевой интерфейс также настроен и включен. Минимальная конфигурация для приведённого выше примера будет следующей:

[source, shell]
....
# ifconfig em0 up
....
====

Для настройки VLAN при загрузке необходимо обновить файл [.filename]#/etc/rc.conf#. Чтобы повторить приведённую выше конфигурацию, нужно добавить следующее:

[.programlisting]
....
vlans_em0="5"
ifconfig_em0_5="inet 192.168.20.20/24"
....

Дополнительные VLAN могут быть добавлены путём простого дополнения тега в поле `vlans_em0` и добавления дополнительной строки для настройки сети на интерфейсе с этим тегом VLAN.

[NOTE]
====
При определении VLAN в [.filename]#/etc/rc.conf# убедитесь, что родительский сетевой интерфейс также настроен и включен. Минимальная конфигурация для приведённого выше примера будет следующей:

[.programlisting]
....
ifconfig_em0="up"
....
====

Полезно присвоить интерфейсу символическое имя, чтобы при изменении связанного оборудования требовалось обновить лишь несколько переменных конфигурации. Например, камеры наблюдения должны работать через VLAN 1 на `em0`. Позже, если карта `em0` будет заменена на карту с драйвером man:ixgb[4], все упоминания `em0.1` не нужно будет изменять на `ixgb0.1`.

Для настройки VLAN `5` на сетевой карте `em0`, назначения интерфейсу имени `cameras` и присвоения интерфейсу IP-адреса `_192.168.20.20_` с `24`-битным префиксом используйте следующую команду:

[source, shell]
....
# ifconfig em0.5 create vlan 5 vlandev em0 name cameras inet 192.168.20.20/24
....

Для интерфейса с именем `video` используйте следующее:

[source, shell]
....
# ifconfig video.5 create vlan 5 vlandev video name cameras inet 192.168.20.20/24
....

Чтобы применить изменения при загрузке, добавьте следующие строки в [.filename]#/etc/rc.conf#:

[.programlisting]
....
vlans_video="cameras"
create_args_cameras="vlan 5"
ifconfig_cameras="inet 192.168.20.20/24"
....
