6.2. Установка параметров TCP/IP

Описание.  Кандидат должен уметь изменять настройки TCP/IP как временно, так и постоянно, так, чтобы изменения сохранялись после перезагрузки.

Практика. hostname(1), ifconfig(8), route(8), resolv.conf(5), rc.conf(5), hosts(5), hostname.if(5), myname(5), mygate(5), netstart(8)

Комментарий

Теперь мы снова рассмотрим те же утилиты, что и в Раздел 6.1, «Определение существующих установок TCP/IP», но на этот раз с точки зрения управления параметрами. Как и в прошлый раз, мы выйдем за рамки задачи постваленной в данном экзаменационном билете, во имя целостности повествования.

6.2.1. hostname(1) — задание имени машины

Утилита hostname(1) может не только сообщать имя машины, но и устанавливать новое:

$ hostname
myhost.example.org
$ hostname -s
myhost
# hostname other.example.org
$ hostname
other.example.org
  

6.2.2. ifconfig(8) — настройки сетевых интерфейсов

Утилита ifconfig(8) позволяет не только просматривать, но и манипулировать настройками сетевого интерфейса. Причём даже на физическом уровне OSI. (О модели OSI можно прочесть в глоссарии: OSI.)

Здесь описаны не все возможности утилиты ifconfig(8). Существуют некоторые опции, характерные для данных операционных систем и т.д. Сверяйтесь со справкой вашей операционной системы. Например, OpenBSD позволяет объединять интерфейсы вгруппы, а FreeBSD такой особенностью не обладает.

6.2.2.1. Изменение настроек физического уровня

В общем случае, для конфигурирования физических параметров интерфейса надо предварительно изучить справку по соответствующему драйверу. Мы приведём примеры на основе драйвера к распространённому чипсету RealTek. (См. man rl.) Для этого драйвера можно изменять скорость передачи данных (10 или 100 Mbps) и режим передачи (half-duplex — одновременная передача пакетов в обе стороны не поддерживается; или full-duplex — поддерживается одновременная передача пакетов в обе стороны).

$ifconfig rl0
rl0: flags=8843<UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST> mtu 1500
  options=8<VLAN_MTU>
  inet6 fe80::250:22ff:feb0:7f39%rl0 prefixlen 64 scopeid 0x1
  inet 192.168.25.158 netmask 0xffffff00 broadcast 192.168.25.255
  ether 00:50:22:b0:7f:39
  media: Ethernet autoselect (100baseTX <full-duplex>)
  status: active
   

Переведём интерфейс вручную на скорость 10 мегабит в секунду (Mbps):

# ifconfig rl0 media 10baseT/UTP
$ ifconfig rl0
rl0: flags=8843<UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST> mtu 1500
  options=8<VLAN_MTU>
  inet6 fe80::250:22ff:feb0:7f39%rl0 prefixlen 64 scopeid 0x1
  inet 192.168.25.158 netmask 0xffffff00 broadcast 192.168.25.255
  ether 00:50:22:b0:7f:39
  media: Ethernet 10baseT/UTP
  status: active
   

Здесь в командной строке опция media принадлежит команде ifconfig(8), а значение 10baseT/UTP взято из справки по драйверу rl.

Теперь мы можем вручную выставить обратно 100baseTX, командой ifconfig rl0 media 100baseTX, а можем включить назад автоопределение.

# ifconfig rl0 media autoselect
$ ifconfig rl0
rl0: flags=8843<UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST> mtu 1500
  options=8<VLAN_MTU>
  inet6 fe80::250:22ff:feb0:7f39%rl0 prefixlen 64 scopeid 0x1
  inet 192.168.25.158 netmask 0xffffff00 broadcast 192.168.25.255
  ether 00:50:22:b0:7f:39
  media: Ethernet autoselect (none)
  status: no carrier
$ ifconfig rl0
rl0: flags=8843<UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST> mtu 1500
  options=8<VLAN_MTU>
  inet6 fe80::250:22ff:feb0:7f39%rl0 prefixlen 64 scopeid 0x1
  inet 192.168.25.158 netmask 0xffffff00 broadcast 192.168.25.255
  ether 00:50:22:b0:7f:39
  media: Ethernet autoselect (100baseTX <full-duplex>)
  status: active
   

Обратите внимание: после включения автоопределения некоторое время интерфейс был недоступен. При этом флаг UP был установлен, т.е. приложения имели право его использовать, но интерфейс вёл себя так, как буд-то из него вынули провод: status: no carrier. Что неудивитеьно, пока интерфейс не знает на какой скорости вести передачу, о какой несущей может идти речь?

Наконец, переключение дуплекса, здесь нас ждёт некоторая недокументированная неожиданность:

# ifconfig rl0 media 100baseTX
$ ifconfig rl0
rl0: flags=8843<UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST> mtu 1500
  options=8<VLAN_MTU>
  inet6 fe80::250:22ff:feb0:7f39%rl0 prefixlen 64 scopeid 0x1
  inet 192.168.25.158 netmask 0xffffff00 broadcast 192.168.25.255
  ether 00:50:22:b0:7f:39
  media: Ethernet 100baseTX
  status: active
   

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

# ifconfig rl0 mediaopt half-duplex
ifconfig: SIOCSIFMEDIA (mediaopt): Device not configured
   

Что поделаешь, и на солнце есть пятна. Итак, в настоящий момент наш интерфейс пребывает в режиме half-duplex, а для перевода его в full-duplex, мы можем употребить следующую команду:

# ifconfig rl0 mediaopt full-duplex
$ ifconfig rl0
rl0: flags=8843<UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST> mtu 1500
  options=8<VLAN_MTU>
  inet6 fe80::250:22ff:feb0:7f39%rl0 prefixlen 64 scopeid 0x1
  inet 192.168.25.158 netmask 0xffffff00 broadcast 192.168.25.255
  ether 00:50:22:b0:7f:39
  media: Ethernet 100baseTX <full-duplex>
  status: active
   

Сравните это с первым скриншотом:

  ...
  media: Ethernet autoselect (100baseTX <full-duplex>)
  ...
   

Как видно, выставлено всё тоже самое, только отсутствует автоопределение. Если мы не добиваемся какого-то специального эффекта, то лучше оставить автоопределение. Из моего личного опыта: однажды мне пришлось вручную понижать скорость работы интерфейсов, которые были соединены некачественным проводом. Сопротивление в медном проводе было вдвое выше нормы. Интерфейсы договаривались о передаче данных на скорости 100Mbps в режиме full-duplex, но реально вести передачу на такой скорости не могли и их пришлось вручную «тормозить».

6.2.2.2. Изменение настроек канального уровня

6.2.2.2.1. Изменение MAC-адреса:
$ ifconfig rl0
rl0: flags=8843<UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST> mtu 1500
  options=8<VLAN_MTU>
  inet6 fe80::250:22ff:feb0:7f39%rl0 prefixlen 64 scopeid 0x1
  inet 192.168.25.158 netmask 0xffffff00 broadcast 192.168.25.255
  ether 00:50:22:b0:7f:39
  media: Ethernet 100baseTX <full-duplex>
  status: active
# ifconfig rl0 lladdr 40:50:22:b0:7f:39
$ ifconfig rl0
rl0: flags=8843<UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST> mtu 1500
  options=8<VLAN_MTU>
  inet6 fe80::250:22ff:feb0:7f39%rl0 prefixlen 64 scopeid 0x1
  inet 192.168.25.158 netmask 0xffffff00 broadcast 192.168.25.255
  ether 40:50:22:b0:7f:39
  media: Ethernet 100baseTX <full-duplex>
  status: active
   

Здесь для смены аппатарного адреса применяется ключевое слово lladdr, объясняющее, что речь идёт об адресе канального уровня (link-layer address = lladdr), т.е. о MAC-адресе. Этот аргумент работает в FreeBSD и в OpenBSD. В FreeBSD действуют так же синонимы link и ether — смысл тот же. В NetBSD ifconfig(8) не умеет сменить MAC-адрес (!?).

При смене MAC-адреса интерфейс временно отключается, а затем поднимается заново. Неисключено, что в некоторых реализациях ifconfig(8), эти действия надо проделать вручную.

[Важно]Важно

Важно, чтобы в одной сети не было машин с одинаковыми MAC-адресами. Консорциум IEEE выделяет производителям оборудования диапазоны MAC-адресов, так называемые OUI — это первые три байта MAC-адреса. Остальные три байта назначает сам производитель. На сайте IEEE можно узнать какой OUI выделен какому производителю: http://standards.ieee.org/regauth/oui/index.shtml. Таким образом, вы можете по первым трём байтам MAC-адреса узнать производителя устройства.

Из этого есть два следствия: 1) вы не должны менять MAC-адрес без нужды, 2) если вы меняете MAC-адрес, вы должны выставить в единицу второй бит, что означает, что MAC-адрес изменён локально. Таким образом, первый из шести байт MAC-адреса, если вы производите изменения, должен быть в диапазонах от 64 до 127 (в шестнадцатеричной записи от 40 до 7F) или от 192 до 255 (в шестнадцатеричной записи от С0 до FF).

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

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

00-50-22 (hex)  ZONET TECHNOLOGY, INC.
005022  (base 16)   ZONET TECHNOLOGY, INC.
        830 ROOM, BLDG. 53, 195, SEC.4
        CHUNG HSIUNG RD, CHUTUNG
        HSINCHA
        TAIWAN, REPUBLIC OF CHINA
   
6.2.2.2.2. Смена флагов канального уровня

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

up/down
Поднять/опустить интерфейс. Переключается флаг UP
promisc/-promisc
Включить/выключить «неразборчивый» (promiscuous) режим работы интерфейса. Переключается флаг PROMISC. Опция есть в FreeBSD, но отсутствует в OpenBSD и NetBSD.
monitor/-monitor
Интерфейс переводится/выводится в/из режим[а] мониторинга. В режиме мониторинга пакеты не передаются, а все полученные пакеты уничтожаются после обработки bpf(4). Переключается флаг MONITOR. Опция есть во FreeBSD, отсутствует в NetBSD и OpenBSD.
link[0-2]/-link[0-2]
Переключаются флаги LINK0, LINK1 и LINK2. При помощи них можно включить сжатие в интерфейсе SLIP или переключить тип коннектора на некоторых Ethernet картах.
arp/-arp
Включение/выключение поддержки протокола ARP на интерфейсе. По умолчанию ARP включён. Переключает флаг NOARP.
staticarp/-staticarp
Переключает флаг STATICARP. При включённом флаге интерфейс использует только статическую таблицу ARP. Присутствует в FreeBSD, отсутствует в OpenBSD и NetBSD.
debug/-debug
Включение/выключение отладочного режима в драйвере устройства. Обычно приводит к дополнтельным сообщениям в syslog(3). Переключает флаг DEBUG.

Пример:

$ ifconfig rl0
rl0: flags=8843<UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST> mtu 1500
  options=8<VLAN_MTU>
  inet6 fe80::250:22ff:feb0:7f39%rl0 prefixlen 64 scopeid 0x1
  inet 192.168.25.158 netmask 0xffffff00 broadcast 192.168.25.255
  ether 00:50:22:b0:7f:39
  media: Ethernet autoselect (100baseTX <full-duplex>)
  status: active
# ifconfig rl0 -arp
$ ifconfig rl0
rl0: flags=88c3<UP,BROADCAST,RUNNING,NOARP,SIMPLEX,MULTICAST> mtu 1500
  options=8<VLAN_MTU>
  inet6 fe80::250:22ff:feb0:7f39%rl0 prefixlen 64 scopeid 0x1
  inet 192.168.25.158 netmask 0xffffff00 broadcast 192.168.25.255
  ether 00:50:22:b0:7f:39
  media: Ethernet autoselect (100baseTX <full-duplex>)
  status: active
   

6.2.2.3. Изменение настроек сетевого уровня

6.2.2.3.1. MTU

MTU переключается оцией mtu. Снижая mtu вы с одной стороны замедляете работу сети, с другой стороны повышаете вероятность того, что ваши пакеты дойдут до адресата без фрагментирования. (Некоторые брандмауэры отбрасывают фрагментированные пакеты.) Однозначных рекомендаций тут дать невозможно. Даже тезис о том, что снижение MTU приводит к снижению скорости передачи данных, несовсем верен. Безусловно возрастают накладные расходы на протокол TCP, увеличивается удельный вес заголовков и общий трафик, однако Ричард Стивенс [Stevens-2003-ru] приводит убедительный пример того, как фрагментированные пакеты быстрее передаются в сети через серию маршрутизаторов, в силу более равномерного использования каналов связи (пока второй пакет передаётся первому шлюзу, первый пакет уже может быть отправлен второму шлюзу, если бы оба пакета были объединены, участок между первым и вторым шлюзом простаивал бы вдвое дольше).

Ограничение сверху на MTU накладывает природа передающей среды. В сетях Fast Ethernet MTU не может превышать 1500 байт.

По поводу IPv6 и MTU уместно процитировать «википедию» [url://wiki-IPv6-ru]:

В IPv6 пакеты не могут фрагментироваться и собираться маршрутизаторами. Отправитель должен заранее выяснить максимальный размер пакетов (MTU), поддерживаемый на всём пути до получателя, и, при необходимости, выполнить фрагментацию своими силами. Оговаривается, что MTU не может быть меньше 576 байт. Снятие с маршрутизаторов функций фрагментации также способствует повышению эффективности их работы, но усложняет работу оконечных систем.

6.2.2.3.2. IP, маска подсети, широковещательный адрес

Адрес интерфейса и маску подсети можно задавать в традиционном формате, в шестнадчатеричном, а так же в формате CIDR (ifconfig(8) OpenBSD не понимает формат CIDR). Следующие команды эквивалентны:

# ifconfig rl0 172.16.0.0 netmask 255.255.0.0
# ifconfig rl0 172.16.0.0 netmask 0xffff0000
# ifconfig rl0 0xac100000 netmask 0xffff0000
# ifconfig rl0 172.16.0.0/16
   

Последний вариант, повторимся, не работает в OpenBSD.

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

# ifconfig 172.16.0.0 netmask 255.255.0.0 broadcast 172.16.255.253
   

Во всех приведённых примерах неявно подразумевается перед IP ключевое слово inet. (По умолчанию действует оно, а не lladdr, например).

Ключевое слово alias (или add) позволяет добавить к сетевому интерфейсу ещё один адрес, возможно в другой сети.

Можно указывать символьное имя машины, если соответствующая запись есть базе /etc/hosts.

6.2.2.3.3. IPv6

Аналогично добавляются адреса в нотации IPv6, с использованием ключевого слова inet6.

6.2.2.3.4. Другие протоколы сетевого уровня

Команда ifconfig(8) позволяет конфигурировать интерфейс не только для работы со стеком TCP/IP. Вы можете сконфигурировать его для работы с AppleTalk, и другими протоколами. Информация об этом присутствует в справочной странице.

6.2.3. route(8) — настройка таблицы маршрутизации

Команда route(8) служит для управления таблицей маршрутизации. С её помощью можно:

  1. Просматривать маршрут к хосту (команды get и show (последней нет в FreeBSD)).
  2. Следить за изменениями в маршрутной таблице в реальном времени (команда monitor).
  3. Добавить маршрут (команда add).
  4. Удалить маршрут (команда delete).
  5. Изменить маршрут (команда change).
  6. Полностью очистить таблицу маршрутизации (команда flush). Поскольку таблиц маршрутизации несколько для каждого протокола (IP, IPv6, AppleTalk и др.) можно указать какую именно таблицу надо очистить при помощи необязательной опции -inet, -inet6, -atalk и др.

Ключевое слово default означает, что добавляется маршрут поумолчанию. В распечатке команды netstat(1) записи добавленные командой route(8) имеют флаг S, означающий, что они добавлены вручную.

Для явного обозначения сетей, хостов и интерфейсов можно использовать агрументы -host, -net и -interface. Некоторые операционные системы (точно скажу про FreeBSD) могут понимать запись в формате CIDR.

Примеры:

# route add default 192.168.0.1
# route add -net 192.168.0 -interface rl0
# route add -net 192.168.1.0 -netmask 255.255.255.128 -interface rl1
  

6.2.4. resolv.conf(5) — настройка клиента DNS

Файл /etc/resolv.conf нужен для настройки клиента DNS. Когда мы обращаемся к какой-то удалённой машине по имени, первое, что происходит, это преобразование имени в адрес IP (или IPv6). Обычно ситуация устроена следующим образом: сперва система ищет имена в файле /etc/hosts, где записано какие имена имеют машины с тем или иным IP-адресом, а затем, если имя в данном файле ненайдено, осуществляется запрос к серверу DNS. В файле /etc/resolv.conf перечислены DNS серверы, к которым осуществляется запрос. Порядок действий (сперва изучается /etc/hosts, затем делается запрос к DNS) можно изменить, это обсуждается в Раздел 6.7, «Изменение порядка разрешения имён». Синтаксис файла /etc/resolv.conf подробно описан в Раздел 6.1.4, «/etc/resolv.conf(5)».

6.2.5. hosts(5) — локальная база имён

Как было сказано в предыдущем разделе, типичное поведение системы состоит в том, что сперва она пытается разрешить имя используя файл /etc/hosts и только потом обращается к серверу DNS. В файле /etc/hosts на каждой строке имеется некоторый IP (или IPv6) адрес, а затем через пробелы перечислены имена соответствующие ему. Комментарий начинается с решётки (#). Например:

# $FreeBSD: src/etc/hosts,v 1.16 2003/01/28 21:29:23 dbaker Exp $
#
# Host Database
#
# Данный файл должен содержать адреса и алиасы для локальных машин
# Замените 'my.domain' ниже вашим доменом.
#
# В присутствии DNS или NIS данный файл может неиспользоваться вовсе,
# для определеня порядка в котором рассматриваются базы имён смотрите
# файл /etc/nsswitch.conf
#
#
::1      localhost localhost.my.domain
127.0.0.1    localhost localhost.my.domain
#
# Воображаемая сеть.
#10.0.0.2    myname.my.domain myname
#10.0.0.3    myfriend.my.domain myfriend
#
# Согласно RFC 1918 следующие сети можно использовать для приватных
# сетей. Этих адресов не существует в Интернет:
#
#  10.0.0.0  - 10.255.255.255
#  172.16.0.0  - 172.31.255.255
#  192.168.0.0  - 192.168.255.255
#
  

Я перевёл часть комментариев на русский язык, сочтя их полезными.

Обратите внимание: многие сервисы используют файл /etc/hosts для своей работы. Когда вы переносите такие сервисы в среду chroot, вы должны перенести туда же копию данного файла.

6.2.6. Как сохранить установленные сетевые параметры

Увы, это самое мутное место. Кажется нет двух систем BSD с одинаковой системой инициализации.

6.2.6.1. FreeBSD

В FreeBSD все настройки собраны в единый файл /etc/rc.conf, в том числе это касается и настроек сетевых интерфейсов. Если точнее, то имеется системный файл /etc/defaults/rc.conf, который редактироваться не должен (система сделает попытку перезаписать его, если вы выполните процедуру make buildworld, см. Раздел 1.2, «Разбираться какие команды доступны для upgrade'а операционной системы»), а в файле /etc/rc.conf находятся пользовательские настройки, которые имеют больший приоритет. В том или ином виде этот файл существует во всех системах BSD, однако настройки сетевых интерфейсов в OpenBSD и NetBSD вынесены в другие места.

В файле /etc/rc.conf для каждого сетевого интерфейса должна быть строка вида ifconfig_rl0="...". Если для интерфейса нужны дополнительные имена (алиасы), применяется строка вида: ifconfig_rl0_alias0="...", ifconfig_rl0_alias1="...".

Следующая строка объясняет, что интерфейс rl0 надо настроить с использованием DHCP:

ifconfig_rl0="DHCP"
   

В следующем листинге имеется ошибка:

ifconfig_rl0_alias0="inet 172.16.0.1/24"
ifconfig_rl0_alias1="inet 172.16.0.2/24"
ifconfig_rl0_alias2="inet 172.16.0.3/24"
ifconfig_rl0_alias4="inet 172.16.0.4/24"
   

Ошибка состоит в том, что после alias2 сразу описан alias4. К сожалению, это приведёт к тому, что сработают только первые три строки.

Все настройки связанные с функционированием IPv6, ppp, gif(4) и проч. так же должны находиться в файле /etc/rc.conf. С этими настройками можно ознакомиться в справочной системе man rc.conf.

Имя машины и маршрут по умолчанию задаются здесь же, можно здесь же задавать статические маршруты:

hostname="host.example.ru"
defaultrouter="172.16.0.254"
static_routes="somenetwork othernetwork"
route_somenetwork="192.168.0.0/24 172.19.0.14"
route_othernetwork="192.168.1.0/24 172.19.0.25"
   

6.2.6.2. OpenBSD

Для запуска настройки сети в системе OpenBSD используется скрипт Bourne shell /etc/netstart (см netstart(8)). В этом скрипте имя сети и адрес шлюза явно берутся из файлов /etc/myname и /etc/mygate:

.....................
# /etc/myname contains my symbolic name
hostname=`cat /etc/myname`
hostname $hostname
.....................
# /etc/mygate, if it exists, contains the name of my gateway host
# that name must be in /etc/hosts.
if [ -f /etc/mygate ]; then
  route -n add -host default `cat /etc/mygate`
fi
.....................
   

Настройки специфичные для каждого сетевого интерфейса хранятся в файлах /etc/hostname.$if, где $if — имя интерфейса. Уже упоминавшийся скрипт /etc/netstart парсит эти файлы и настраивает соответствующим образом интерфейсы, используя команду ifconfig(8). Строки начинающиеся с решётки (#) являются комментариями, а строки начинающиеся с восклицательного знака (!) — команды Bourne shell. Остальные строки передаются команде ifconfig(8) и, возможно, dhclient(8). Например:

inet 10.0.1.12 255.255.255.0 10.0.1.255 media 100baseTX description Uplink
inet alias 10.0.1.13 255.255.255.255 10.0.1.13
inet alias 10.0.1.14 255.255.255.255 NONE
inet alias 10.0.1.15 255.255.255.255
inet alias 10.0.1.16 0xffffffff
inet6 alias fec0::1 64
inet6 alias fec0::2 64 anycast
# Это пример закомментированной строки
!wicontrol $if -t 2 # Установить скорость 2Mbps
   

$if будет заменено на имя интерфейса.

6.2.6.3. NetBSD

В NetBSD настройки сетевых интерфейсов могут находиться в файлах /etc/ifconfig.$if, где $if — имя интерфейса, либо в файле /etc/rc.conf, аналогично FreeBSD. Но, при этом, алиасы должны быть перечислены в переменной ifconfig_aliases_rl0 как список пар адрес сетевая_маска:

hostname="host.example.ru"
defaultroute="192.168.0.1"
ifconfig_tlp0="192.168.0.2"
ifaliases_tlp0="192.168.1.2 255.255.255.0 192.168.2.2 255.255.255.0"
   

Имя машины и маршрут по умолчанию добавляется тут же. Обратите внимание: в NetBSD надо писать defaultroute, а в FreeBSD — defaultrouter. Правда мило? Каждый раз консультируйтесь со справочной страницей, а ещё лучше со скриптами, которые все эти настройки вызывают.


Обновлено: 12.03.2015