Ревизия 180, сборка 20 июня 2008 года.
Copyright © 2006, 2007 Евгений Миньковский
Аннотация
Данная книга задумана как методическое пособие для подготовки к экзамену BSDA. Книга, тем не менее, может быть полезна не только тем кто собирается сдавать этот экзамен, но и просто широкому кругу IT-специалистов, желающих систематизировать свои знания об операционных системах семейства BSD (NetBSD, OpenBSD, FreeBSD, DragonFly BSD).
В формате HTML книга доступна в виде одной большой страницы (данный вариант) и в многостраничном варианте .
Собственно вопросы экзамена BSDA можно посмотреть отдельно.
![]() | Замечание |
|---|---|
Работа ещё только начата, в оглавлении приняты следующие обозначения:
Впрочем, в Москве даже на улицах светофоры не всегда горят правильно, что уж говорить об этом труде... |
Содержание
1. Установка и обновление операционной системы и програмного обеспечения
1.1. Разбираться в программах установки каждой операционной системы
1.2. Разбираться какие команды доступны для upgrade'а операционной
системы
1.3. Понимание разницы между заранее скомпилированными бинарными
дистрибутивами и компиляцией из исходников
1.4. Понимание когда выгодно инсталлировать прекомпилированные
бинарники и как это делать
1.5. Разбираться в методах настройки и компилирования бинарников
1.6. Определять, какое програмное обеспечение инсталлировано в
системе
1.7. Определять, какое програмное обеспечение нуждается в
обновлении
1.8. Обновлять установленное програмное обеспечение
1.9. Определять, какое програмное обеспечение имеет проблемы с
безопасностью
1.10. Следовать инструкциям секьюрити-консультантов и накладывать
security-patch
2. Безопасность в операционной системе
2.1. Определить уровень безопасности системы
2.2. Конфигурирование сервера SSH в соответствии с требованиями
2.3. Конфигурировние SSH сервера для аутентификации по ключу
2.4. Предохранение ключа при обновлении системы
2.5. Разбираться в альтернативных механизмах аутентификации
2.6. Разбираться в альтернативных методах авторизации
2.7. Разбираться в основных рекомендованных методах доступа [до хоста]
2.8. Разбираться в брандмауэрах BSD и синтаксисе конфигурационных файлов
2.9. Разбираться в механизмах использования шифровальных устройств BSD
2.10. Разбираться в методах проверки аутентичности бинарного файла
2.11. Разбираться в способах запуска сервиса в изолированной среде (restraining service)
2.12. Смена алгоритма шифрования используемого для защиты базы с паролями
2.13. Смена приветствия системы
2.14. Защита аутентификационных данных
3. Файлы, файловые системы и диски
3.1. Монтирование и размонтирование файловых систем
3.2. Конфигурирование NFS
3.3. Определение какие файловые системы смонтированы и какие будут смонтированы при загрузке
3.4. Определять ёмкость диска и какие файлы занимают больше места
3.5. Создание и просмотр символических и жёстких ссылок
3.6. Просмотр и изменение ACL
3.7. Просмотр и изменение пермиссий с использованием как символьных, так и восьмеричных мод
3.8. Изменение владельца файла и группы
3.9. Резервное копирование и восстановление файлов и директорий на локальный диск или ленту
3.10. Резервное копирование и восстановление файловой системы
3.11. Знание структуры каталогов системы
3.12. Ручной запуск программы проверки файловой системы и средств её восстановления
3.13. Определение и изменение флагов файлов
3.14. Слежение за состоянием виртуальной памяти системы
4. Пользователи и управление учётными записями
4.1. Создание, изменение и удаление учётных записей
4.2. Создание системных учётных записей
4.3. Отключение или включение учётной записи (lock и unlock)
4.4. Идентификация и членство в группах
4.5. Определение кто сейчас присутствует в системе или последнего времени входа в систему
4.6. Включение слежения за учётными записями и просмотр статистики
4.7. Изменение пользовательской оболочки
4.8. Контролировать какие файлы будут копироваться в новую пользовательскую директорию при создании учётной записи
4.9. Смена пароля
5. Основы системного администрирования
5.1. Определение какой процесс расходует основную часть ресурсов ЦПУ
5.2. Определять активные процессы и посылать им сигналы
5.3. Использование скриптов rc(8) для
определения запущенных сервисов, их запуск, остановка и
перезапуск
5.4. Определение установленного оборудования и его конфигурирование
5.5. Определение какие модули ядра загружены, их загрузка и выгрузка
5.6. Изменение на лету переменных ядра
5.7. Изучение состояния програмного RAID'а (mirror or stripe)
5.8. Определение какой MTA используется системой
5.9. Конфигурирование системы ведения системных журналов
5.10. Просмотр журналов для разрешения проблем и слежения за поведением системы
5.11. Понимание основных проблем с принтером
5.12. Создание или изменение почтовых псевдонимов в Sendmail и Postfix
5.13. Остановка, перезагрузка или перевод системы в однопользовательский режим
5.14. Отличие жёстких ограничений от мягких и изменение существующих системных ограничений
5.15. Знание утилит BSD для регулировки трафика и контроля за полосой пропускания
5.16. Знание распространённых конфигурационных системных файлов и,
возможно, сторонних конфигурационных файлов различных сервисов
5.17. Конфигурирование сервисов для автоматического старта при запуске системы
5.18. Конфигурирование скриптов, нужных для различных задач по обслуживанию системы, для периодического запуска
5.19. Просмотр очереди Sendmail'а или Postfix'а
5.20. Определение когда последний раз была запущена система и какова её загруженность
5.21. Слежение за операциями ввода/вывода на диске
5.22. Работа с занятыми устройствами
5.23. Определение информации характеризующей операционную систему
5.24. Понимание преимуществ использования лицензии BSD
6. Сетевое администрирование
6.1. Определение существующих установок TCP/IP
6.2. Установка параметров TCP/IP
6.3. Определение какие TCP или UDP порты открыты в системе
6.4. Проверка доступности TCP/IP сервиса
6.5. Запрос к серверу DNS
6.6. Определение кто ответственный за зону DNS
6.7. Изменение порядка разрешения имён
6.8. Перевод сетевой маски между системами точечно-десятичной, точечно-шестнадцатеричной или CIDR
6.9. Собирать информацию используя IP адрес и маску подсети
6.10. Понимание теории адресации IPV6
6.11. Демонстрация основных навыков работы с утилитой
tcpdump(1)
6.12. Работа с ARP и кешем найденных соседей
6.13. Конфигурирование системы для использования NTP
6.14. Просмотр и обновление «арендованных» данных DHCP
6.15. Знание как и когда устанавливать или удалять алиасы сетевого интерфейса
7. Базовые навыки работы в Unix
7.1. Перенаправление вывода и использование
tee(1)
7.2. Определение просмотр и изменение переменных окружения
7.3. Навыки работы в vi(1)
7.4. Определение является ли файл бинарным, текстовым или содержащим данные
7.5. Поиск файлов и бинарников в системе
7.6. Поиск файла по заданным атрибутам
7.7. Написание несложных Bourne-скриптов
7.8. Поиск нужной документации
7.9. Понимание различий в страницах man
7.10. Проверка контрольной суммы файла
7.11. Продемонстрировать знакомство с оболочками используемыми по
умолчанию в системе
7.12. Чтение почты на локальной машине
7.13. Использование контроля за задачами (job control)
7.14. Применение регулярных выражений
7.15. Преодоление ограничений на длину командной строки
7.16. Понимание значения термина домен в различных контекстах
7.17. Работа с cron
A. Список команд и файлов обсуждаемых в книге
B. Некоторые сведения о стеке протоколов TCP/IP
C. Пакетный фильтр OpenBSD — pf(4)
D. Пакетный фильтр NetBSD — ipf(8)
E. Брандмауэр FreeBSD — ipfw(8)
F. /etc/login.conf(5)Список таблиц
crypt_default
(FreeBSD) и localcipher,
ypcipher (OpenBSD)crontab(5) для описания
времени выполнения заданийlogin.conf(5)login.conf(5)login.conf(5)login.conf(5) FreeBSDlogin.conf(5) характерные для OpenBSDСписок примеров
Содержание
В 2005 году стартовал проект сертификации BSDA-специалистов. BSDA расшифровывается как BSD Associate и подразумевает под собой совокупность операционных систем семейства BSD: NetBSD, OpenBSD, FreeBSD и DragonFly BSD. В рамках проекта была образована BSD CG — сертификационная группа BSD. Её сайт можно найти по адресу http://www.bsdcertification.org/. К октябрю 2005 года BSD CG разработала список тем для экзаменационных вопросов. Этот труд и лёг в основу данного пособия.
В данной книге, вы, конечно, найдёте не всё, с чем приходится сталкиваться в процессе администрирования систем. Здесь опущены такие важные темы, как администрирование web-сервера Apache, настройка proxy сервера squid, работа с системой samba, администрирование баз данных MySQL или PostgreSQL. В книге затронуты главным образом основные сервисы операционных систем BSDA, поставляемые в составе операционных систем.
Настоящая книга состоит из 7-и глав соответствующих 7-и блокам экзаменационных вопросов BSDA. Далее идут приложения в которых я постараюсь несколько более системно изложить некоторые теоретические вопросы, на которые опираются экзаменационные билеты.
Таблица 1. Легенда (условные обозначения)
| Знак | Значение |
|---|---|
| Обозначения в оглавлении | |
| «Избранный» раздел — автор сам удивлён почему у него всё так хорошо получилось. |
| Раздел написан, но это не значит, что он никогда не подвергнется ревизии. |
| Раздел не окончен. |
| К написанию раздела автор не приступал. |
| Приглашения в листингах | |
| Команда выполнялась в /bin/sh (или /usr/local/bin/bash) непривилегированным пользователем. |
| Команда выполнялась в /bin/sh (или /usr/local/bin/bash) привилегированным пользователем[a]. |
| Команда выполнялась в /bin/csh |
| Принятые шрифты[b] | |
| text | Команда |
text | Опция |
text | Файл |
| text | Акроним |
| Картинки | |
| Текст относится к FreeBSD |
| Текст относится к OpenBSD |
| Текст относится к FreeBSD и OpenBSD |
| Orphus — система, написанная Дмитрием Котеровым (см. http://dklab.ru/chicken/nablas/24.html) для повышения грамотности рунета. Мне, как автору, редко удаётся писать текст сразу без ошибок, увы. Если вы хотите сообщить мне о найденной ошибке, не обязательно орфографической, вы можете просто выделить её в браузере и нажать сочетание клавиш <Ctrl>+<Enter>. |
[a] Если команда выполнена
привилегированным пользователем, это ещё не значит,
что её нельзя выполнить от непривилегированного
пользователя. Например, пакетным фильтром
OpenBSD может управлять
непривилегированный пользователь при наличии
специальных прав на устройство
[b] К сожалению, надо признать, что шрифтовые выделения по тексту расставлены халтурно. И даже данная часть таблицы ещё недописана | |
Касательно подготовки к экзамену по данной книге следует привести уведомление BSD CG:
Содержание
1.1. Разбираться в программах установки каждой операционной системы
1.2. Разбираться какие команды доступны для upgrade'а операционной
системы
1.3. Понимание разницы между заранее скомпилированными бинарными
дистрибутивами и компиляцией из исходников
1.4. Понимание когда выгодно инсталлировать прекомпилированные
бинарники и как это делать
1.5. Разбираться в методах настройки и компилирования бинарников
1.6. Определять, какое програмное обеспечение инсталлировано в
системе
1.7. Определять, какое програмное обеспечение нуждается в
обновлении
1.8. Обновлять установленное програмное обеспечение
1.9. Определять, какое програмное обеспечение имеет проблемы с
безопасностью
1.10. Следовать инструкциям секьюрити-консультантов и накладывать
security-patchОписание: От кандидата BSDA не требуется составить план инсталляции, но он должен уметь начать и закончить инсталляцию операционной системы в соответствии с приведёнными требованиями. Поскольку процедура инсталляции зависит от конкретной системы, кандидату рекомендуется иметь опыт работы со средствами установки каждой BSD системы предлагаемыми в этих системах по умолчанию. Так же ожидается, что кандидат имеет знания об основных релизах (т.е. релизах с номером X.0) и где найти информацию о них на соответствующих сайтах BSD-проектов.
Практика: http://www.bsdinstaller.org для DragonFly BSD, sysinstall(8) для FreeBSD, sysinst на инсталляционном диске NetBSD, и INSTALL.[arch] на инсталляционном диске OpenBSD.
Описание: Кандидат BSDA должен разбираться в утилитах используемых для поддержания операционных систем в актуальном состоянии. Некоторые утилиты общие для разных систем BSD, некоторые утилиты специфичные для конкретной системы доступны в другой в виде стороннего програмного продукта.
Практика: make(1) включая цели "buildworld",
"installworld" и "quickworld" и прочие похожие цели;
mergemaster(8), cvs(1), и
сторонние продукты cvsup и cvsync; build.sh,
etcupdate(8), postinstall(8)
и afterboot(8); src/UPDATING и
src/BUILDING.
Описание: Кандидат должен быть знаком с тем, где по умолчанию находится дерево портов и пакетов (ports collention, pkgsrc collection) и какая из систем BSD какое дерево использует. Кандидат должен уметь определить расширение используемое пакетами. Кандидат должен понимать преимущества и недостатки инсталляции заранее скомпилированных бинарников и преимущества и недостатки сборки бинарников из исходного кода.
Описание: Кандидат BSDA должен понимать, что заранее скомпилированные бинарники просты и быстры в установке, но не дают возможности настройки бинарника к нуждам системы. Кандидат должен знать как установить заранее скомпилированный бинарник из удалённого источника, или с локальной машины, так же как и знать как удалить установленный пакет.
Практика: pkg_add(1), pkg_delete(1)
Описание: Для поддержки опций программы make(1), нужной для компилирования бинарника с нужными функциями, существует множество различных программ. Поскольку все системы BSD используют make(1), кандидат BSDA должен рабираться какая система BSD какие механизмы использует для сохранения опций make(1).
Практика:
Dragonfly BSD: mk.conf(5) или
make.conf(5), PKG_OPTIONS, CFLAGS
FreeBSD: -DWITH_* или WITH_*=,
pkgtools.conf(5),
make.conf(5)NetBSD:
PKG_OPTIONS.<pkg>, CFLAGS, mk.conf(5),
PKG_DEFAULT_OPTIONS OpenBSD:
bsd.port.mk(5)
Описание: Кандидат BSDA должен разбираться как определить какое програмное обеспечение установлено на BSD, проследить зависимости при помощи менеджера пакетов в случае, если программы установлены при помощи портов или пакетов (packages, ports или pkgsrc). Кандидат должен уметь узнать через менеджер пакетов какое програмное обеспечение стоит на машине и какой версии.
Практика: pkg_info(1)
Описание: Кандидат должен понимать важность соблюдения равновесия между сохранением програмого обеспечения в актуальном состоянии и минимизации воздействий на производительность системы. Dragonfly BSD и NetBSD используют pkgsrc предоставляющую утилиты позволяющие определить какое програмное обеспечение устарело. FreeBSD предоставляет pkg_version и сторонние утилиты интегрированные с менеджером пакетов.
Практика: pkgsrc/pkgtool/pkg_chk и make show-downlevel для Dragonfly BSD и NetBSD; pkg_version(1), и сторонняя программа portupgrade(1).
Описание: Кандидат BSDA должен разбираться во встроенных и сторонних средствах обновления установленного програмного обеспечения. В добавок кандидат должен знать какие системы используют pkgsrc.
Практика: DragonFly BSD и NetBSD предлагают pkgsrc/pkgtools/pkg_chk, pkgsrc/pkgtools/pkg_comp, make update и make replace; portupgrade и cvsup доступны как сторонние продукты.
Описание: Кандидат BSDA должен понимать важность слежения за обнаруживаемыми уязвимостями в безопасности програмного обеспечения. Кандидат должен разбираться в сторонних утилитах интегрированных с менеджером пакетов предназначенных для обнаружения програмного обеспечения с уязвимостями в системе безопасности.
Практика: audit-packages для Dragonfly BSD и NetBSD; portaudit и vuxml для FreeBSD и OpenBSD
Описание: Кандидат BSDA должен быть осведомлён о том, что каждый проект BSD сопровождается советниками по безопасности, чьи советы доступны как через Интернет, так и через почтовые списки рассылок. Кандидат должен уметь следовать инструкциям данным в этих советах.
Практика: patch(1), make(1), и fetch(1); ftp(1) и build.sh
Содержание
2.1. Определить уровень безопасности системы
2.2. Конфигурирование сервера SSH в соответствии с требованиями
2.3. Конфигурировние SSH сервера для аутентификации по ключу
2.4. Предохранение ключа при обновлении системы
2.5. Разбираться в альтернативных механизмах аутентификации
2.6. Разбираться в альтернативных методах авторизации
2.7. Разбираться в основных рекомендованных методах доступа [до хоста]
2.8. Разбираться в брандмауэрах BSD и синтаксисе конфигурационных файлов
2.9. Разбираться в механизмах использования шифровальных устройств BSD
2.10. Разбираться в методах проверки аутентичности бинарного файла
2.11. Разбираться в способах запуска сервиса в изолированной среде (restraining service)
2.12. Смена алгоритма шифрования используемого для защиты базы с паролями
2.13. Смена приветствия системы
2.14. Защита аутентификационных данныхПризнаком хорошего системного администратора является осведомлённость о проблемах безопасности и забота о безопасности системы. Ожидается, что кандидат BSDA знаком с распростанёнными средствами обеспечения безопасности системы. Системы BSD реализованы с учётом проблем безопасности и предоставляют множество средств позволяющих администратору подстроить систему к требованиям политики безопасности его организации. Кандидат не может всегда отвечать за реализацию механизмов безопасности, но должен знать о свойствах и этих средств и доступных командах.
Описание: Системы BSD предоставляют несколько предопределённых настроек безопасности, известных как уровни безопасности (securelevels). Кандидат должен знать на каком он уровне безопасности, можно ли поднять или опустить уровень безопасности и как.
Практика: init(8), sysctl(8),
rc.conf(5)
![]() | Замечание |
|---|---|
| Данный текст прислан Дмитрием Орловым, но подвергся моей редактуре. Е.М. |
Функциональность securelevel можно рассматривать как метод защиты ядра, сырых устройств (raw devices), и файловой системы от атак злоумышленника, которому удалось взломать учётную запись суперпользователя. Защита ядра в общем случае включает в себя невозможность загрузки собственных модулей ядра и прослушивания проходящего через систему трафика. Функциональность securelevel/security присуствует во всех BSD системах с небольшими отличиями.
Уровни безопасности служат для ограничения возможностей системы до такой степени, которая соответствует её рабочему окружению (среде работы). В OpenBSD он устанавливается скриптом rc.securelevel(8):
# $OpenBSD: rc.securelevel,v 1.16 2004/07/06 04:05:03 deraadt Exp $
#
# в этом скрипте определяются действия, которые можно осуществить ДО
# того, как система перейдёт в безопасный режим. Действия, которые можно
# совершить ПОСЛЕ того, как будет определён уровень безопасности
# системы, должны помещаться в скрипт /etc/rc.local
# Здесь определяется желаемый уровень безопасности
# XXX
# XXX it is not really acceptable to put this value in a configuration
# XXX file, because locking it down requires immutability on about
# XXX 5 files instead of 2 (the kernel and init)
# XXX
securelevel=1
echo -n 'starting pre-securelevel daemons:'
#
# Сюда следует поместить ваши команды
#
echo '.'
В FreeBSD значение уровня безопасности
выставляется в файле /etc/rc.conf:
kern_securelevel_enable="YES"
kern_securelevel=1
В DragonFly BSD уровень безопасности выставляется так же как в FreeBSD, за исключением того, что переменной kern_securelevel_enable выставлять не надо.
В NetBSD уровень безопасности так же
выставляется через файл /etc/rc.conf:
securelevel=1
Уровень безопасности может быть прочитан или установлен с помощью утиллиты sysctl(8) через переменную kern.securelevel. По окончании процесса загрузки системы вы можете узнать текущий уровень безопасности системы набрав в командной строке:
$ sysctl kern.securelevel
kern.securelevel: -1
Вы можете повысить уровень безопасности командой:
# sysctl -w kern.securelevel=2
В процессе работы уровень безопасности системы может только повышаться. Уменьшение значения переменной ядра kern.securelevel запрещено.
Ядра OpenBSD и NetBSD предоставляют 4 уровня системной безопаности, а FreeBSD и DragonFly BSD — 5. Последний уровень в них разбит на два подуровня.
На NetBSD, в дополнении к сказанному, запрещена трассировка процесса init(8).
/dev/mem,
/dev/kmem и
/dev/io.
/dev/ad0 и т.п.) в смонтированных
файловых системах доступны только для чтения
На OpenBSD, в дополнении к сказанному, действуют следующие ограничения на изменения переменных ядра:
На NetBSD, в дополнении к сказанному, действуют следующие ограничения:
идентичен уровню 1, кроме:
Наивысший уровень безопасности во FreeBSD и DragonFly BSD разбит на два уровня. Невозможность изменения правил pf(8) и NAT вынесены на уровень 3.
Режим повышенной безопасности может показаться драконовским, но он задумывался как последняя линия обороны в случае если учётная запись суперпользователя вскрыта.
Эти эффекты предотвращают обход файловых флагов путем прямой модификации сырых дисковых устройств или стирание файловой системы при помощи команды newfs(8). Далее, они могут ограничить потенциальное разрушающее действие (потенциальный вред от) вскрытого файрвола, путем запрещения модификации правил пакетного фильтра pf(8). Предотвращение перевода системного времени назад помогает при послеаварийном анализе и прибавляет уверенности в корректности журнальных файлов. При этом несколько страдает точность вычисления времени, так как блокировка времени осуществляется немгновенно.
Так как уровень безопасности может быть изменён при помощи отладчика ddb(4), вполне логично заблокировать его работу, как представлено уровнями 1 и 2 (и 3 во FreeBSD и DragonFly BSD). Это обеспечивается установкой переменных ядра ddb.console и ddb.panic в 0.
Не лишним будет упомянуть, что установку переменных на этапе
загрузки можно выполнить в конфигурационном файле
/etc/sysctl.conf. Например:
ddb.console=0
ddb.panic=0
В разных системах семейства BSD придаётся различный смысл различным уровням безопасности. Чтобы получить конкретную информацию по вашей операционной системе, используйте следующие ссылки:
Описание: Кандидат BSDA должен знать как настроить встроенный демон sshd(8) для ограничения доступа к системе через SSH.
Практика: sshd_config(5)
Описание: Кандидат должен понимать теорию публичных/приватных ключей включая: какие протоколы доступны для генерирования пар ключей, выбор подходящего bit size, предоставления "начальной строки"(?) (seed), passphrase, и проверки отпечатка (fingerprint). В дополнение, кандидат должен уметь генерировать свои ключи и использовать их для аутентификации.
Практика: ssh-keygen(1) включая следующие ключевые слова: authorized_keys, id_rsa и id_rsa.pub.
Описание: В добавок к знанию о том как генерируются системные SSH ключи, кандидат BSDA должен знать где расположены системные ключи и как предохранить их при обновлении или замене системы.
Практика: /etc/ssh/ssh_host*_key*
Описание: От кандидата BSDA не требуется знания того как сконфигурировать альтернативный метод аутентификации. Однако кандидат должен понимать основы теории аутентификации, знать, что аутентификация по имени пользователя и паролю — не единственный способ аутентификации в системах BSD. Кандидат должен понимать основы PAM и знать, что он доступен в DragonFly BSD, FreeBSD и NetBSD 3.x. Он должен так же знать основы теории касающейся Kerberos, OTP и RADIUS.
Описание: Кандидат должен понимать основы теории авторизации и как MAC и ACL расширяют стандартные UNIX-пермиссии.
Практика: mac(4) и acl(3) на FreeBSD; systrace(1) на NetBSD и OpenBSD.
Описание: Кандидат BSDA должен быть знаком с обычными для администраторский практики методами снижения рисков связанными с доступом к системе. Включая использование ssh(1) вместо telnet(1), запрещение логина от пользователя root, использование сторонней утилиты sudo(8) вместо su(1) и минимизация использования группы wheel.
Практика: ttys(5), sshd_config(5),
ftpusers(5); сторонняя утилита
sudo(8), включая visudo(8),
suedit(?) и sudoers(5).
Описание: Каждая система BSD снабжена хотя бы одним брандмауэром. Кандидат BSDA должен знать какие брандмауэры в каких системах доступны и какие команды доступны для просмотра набора правил брандмауэра.
Практика: ipfw(8), ipf(8), ipfstate(8), pfctl(8) и firewall(7)
В разных операционных системах BSD доступны разные брандмауэры, с разным синтаксисом и разной идеологией и разными возможностями. Однако операционные системы BSD обмениваются идеями и кодом. Так в настоящий момент в ядре FreeBSD доступно сразу три брандмауэра: «родной» — ipfw(8), пакетный фильтр NetBSD — ipf(8) и пакетный фильтр OpenBSD — pf(4).
Описание брандмауэров BSD настолько обширная тема, что в данной работе она вынесена в отдельные разделы: Приложение C, Пакетный фильтр OpenBSD — pf(4), Приложение D, Пакетный фильтр NetBSD — ipf(8) и Приложение E, Брандмауэр FreeBSD — ipfw(8). В данном разделе обсуждаются лишь некоторые концепции построения брандмауэров и проводится сравнение возможностей брандмауэров BSD.
Описание: Кандидат BSDA должен знать, что в BSD могут использоваться шифровальные устройства и какие утилиты доступны для этого на каких BSD системах.
Практика: gbde(4) и gbde(8) на FreeBSD; cgd(4) на NetBSD; vnd(4) на OpenBSD.
Описание: Кандидат BSDA должен разбираться в утилитах проверки подлинности файла, таких как tripware. Он должен так же разбираться во встроенных методах проверки предлагаемых некоторыми BSD.
Практика: security(7) или (8);
security.conf(5);
veriexecctl(8)
Описание: Кандидат BSDA должен понимать преимущества запуска сервисов в изолированной среде на машинах открытых для Интернет, и какие утилиты предназначены для этого в какой BSD.
Практика: chroot(8); jail(8); systrace(1); Стороннее приложение Xen.
Реалии современного програмного обеспечения таковы, что многие сетевые (и не только сетевые) сервисы могут быть взломаны. Широко известны атаки типа «переполнение буфера». Программа запрашивает некоторый параметр у пользователя и не проверяет какой длины данные ей передали. Таким образом, злоумышленник получает возможность записать данные в область памяти занятую кодом программы, на который в последствии будет передано управление. В результате злоумышленник получает возможность выполнять произвольные действия от имени данной службы.
Чтобы противодействовать данному виду атак, многие службы запускают в изолированной среде — «sandbox» или «песочнице». Существует множество способов построения «песочниц»:
Это, пожалуй, самое радикальное средство изоляции сервисов. Вы запускаете образ машины, устанавливаете на неё любую полюбившуюся операционную систему и выставляете эту «машину» в Интернет. В случае взлома вы просто восстанавливаете её из образа. В этой ситуации риск повреждения материнской системы практически полностью исключён. Однако накладные расходы очень велики — быстродействие виртуальной машины в десятки раз ниже быстродействия материнской.
Известные эмуляторы: vmware — коммерческий продукт выпускающийся под Linux его можно запустить в FreeBSD используя «эмулятор» Linux. Другое решение — qemu. Qemu ставится из портов в любую систему, это OpenSource, но выбор эмулируемого железа в нём ограничен.
Суть явления примерно та же, что и в предыдущем случае, однако псевдоэмулятор не занимается эмуляцией железа. Псевдоэмулятор работает на уровне ядра операционной системы. С одной стороны, это сужает возможности эмулятора, так как вы лишаетесь возможности эмулировать другие архитектуры. С другой стороны вы получаете существенный прирост в производительности. И возможность одновременного запуска нескольких различных операционных систем.
Примером такого рода эмуляции является рассмотренный ниже Xen, реализованный в NetBSD, OpenBSD и FreeBSD.
Это один из самых простых и один из самых древних методов
построения «песочницы». Хотя системый вызов
chroot(2) не входит в стандарт
POSIX, он реализован практически
повсеместно. Приложение выполняет системный вызов chroot(2), после чего любое
обращение к корневому каталогу ядро транслирует в
некоторый другой каталог — корень
«песочницы». Таким образом, приложение лишено
возможности испортить файлы за пределами
«песочницы». В тоже время, приложение работает с
сокетами материнской системы, если мы создаём в песочнице
каталог /dev с файлами устройств, то
оно будет иметь доступ к устройствам на низком уровне и,
при достаточном количестве полномочий может даже вырваться
за пределы песочницы.
Данный метод построения «песочниц» очень распространён. Существуют сервисы, такие как BIND, которые по умолчанию запускаются в окружении chroot(8).
Команда chroot(8) позволяет запускать приложения в ограниченной среде путём смены корневого каталога. Для начала, давайте попробуем запустить в ограниченной среде программу csh(1). В дополнение к ней мы скопируем в ограниченную среду команду tree(1), чтобы с её помощью убедиться что у нас всё получилось. Для этого нам надо выполнить следующие действия:
/bin и /lib.
$mkdir -p sandbox/bin sandbox/lib$ldd /bin/csh/bin/csh: libncurses.so.6 => /lib/libncurses.so.6 (0x280b9000) libcrypt.so.3 => /lib/libcrypt.so.3 (0x280f8000) libc.so.6 => /lib/libc.so.6 (0x28110000)
$ldd /usr/local/bin/tree /usr/local/bin/tree: libc.so.5 => /lib/libc.so.5 (0x2807c000)$cp /lib/libc.so.5 /lib/libncurses.so.6 /lib/libcrypt.so.3 /lib/libc.so.6 sandbox/lib/$cp /bin/csh /usr/local/bin/tree sandbox/bin/![]()
#chroot sandbox/ cshPassword: ELF interpreter /libexec/ld-elf.so.1 not found
Abort trap: 6
$mkdir sandbox/libexec$cp /libexec/ld-elf.so.1 sandbox/libexec/#chroot sandbox/ csh csh: Cannot open /etc/termcap. csh: using dumb terminal settings.![]()
%pwd pwd: Command not found.%tree / / |-- bin | |-- csh | `-- tree |-- lib | |-- libc.so.5 | |-- libc.so.6 | |-- libcrypt.so.3 | `-- libncurses.so.6 `-- libexec `-- ld-elf.so.1 3 directories, 7 files%exit exit
Некоторым приложениям может понадобиться наличие каталога
/dev с файлами устройств. Для систем не
поддерживающих devfs надо создать эти файлы
при помощи команды mknod(8), а для систем
поддерживающих devfs, например для
FreeBSD, понадобится смонтировать в
«песочницу» файловую систему devfs.
Однако при этом вам может понадобиться создать не все, а только
некоторые файлы устройств. Для этого надо воспользоваться
утилитой devfs(8):
$mkdir sandbox/dev#mount_devfs devfs sandbox/dev/ Password:$ls sandbox/dev/acd0 console fd/ nfs4 sysmouse ttyv5 acd0t01 consolectl fd0 nfslock ttyd0 ttyv6 acpi ctty fido null ttyd0.init ttyv7 ad0 cuad0 geom.ctl pass0 ttyd0.lock ttyv8 ad0s1 cuad0.init io pci ttyd1 ttyv9 ad0s1a cuad0.lock kbd0@ psm0 ttyd1.init ttyva ad0s1b cuad1 klog ptyp0 ttyd1.lock ttyvb ad0s1c cuad1.init kmem ptyp1 ttyp0 ttyvc ad0s1d cuad1.lock lpt0 ptyp2 ttyp1 ttyvd agpgart devctl lpt0.ctl ptyp3 ttyp2 ttyve apm devstat mdctl ptyp4 ttyp3 ttyvf ata dri/ mem random ttyp4 urandom@ atkbd0 dsp0.0 mixer0 rtc ttyv0 usb audio0.0 dsp0.1 net/ sndstat ttyv1 usb0 audio0.1 dspW0.0 net1@ stderr@ ttyv2 usb1 bpsm0 dspW0.1 net2@ stdin@ ttyv3 xpt0 cd0 dspr0.1 network stdout@ ttyv4 zero
#devfs -m sandbox/dev/ rule apply hide$ls sandbox/dev/![]()
#devfs -m sandbox/dev/ rule apply path zero unhide#devfs -m sandbox/dev/ rule apply path null unhide#devfs -m sandbox/dev/ rule apply path random unhide$ls sandbox/dev/null random zero
#chroot sandbox/ csh csh: Cannot open /etc/termcap. csh: using dumb terminal settings.%tree / / |-- bin | |-- csh | `-- tree |-- dev| |-- null | |-- random | `-- zero |-- lib | |-- libc.so.5 | |-- libc.so.6 | |-- libcrypt.so.3 | `-- libncurses.so.6 `-- libexec `-- ld-elf.so.1 4 directories, 10 files
%exit exit
Команда jail(8) может рассматриваться как
средство для запуска программы в ограниченном окружении, а может
рассматриваться как средство виртуализации. В первом случае
настройка jail(8) выглядит аналогично
рассмотренному выше chroot(8). К уже
имеющемуся окружению sandbox/ мы добавим
команду ifconfig(8):
# ifconfig rl0 add 172.19.0.234/24
$ ifconfig rl0
rl0: flags=8843<UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST> mtu 1500
options=8<VLAN_MTU>
inet 172.19.0.5 netmask 0xffffff00 broadcast 172.19.0.255
inet 172.19.0.234 netmask 0xffffff00 broadcast 172.19.0.255
ether 4c:00:10:54:dd:8e
media: Ethernet autoselect (100baseTX <full-duplex>)
status: active
lo0: flags=8049<UP,LOOPBACK,RUNNING,MULTICAST> mtu 16384
inet 127.0.0.1 netmask 0xff000000
$ mkdir sandbox/sbin
$ cp /sbin/ifconfig sandbox/sbin
$ ldd /sbin/ifconfig
/sbin/ifconfig:
libipx.so.3 => /lib/libipx.so.3 (0x28082000)
libc.so.6 => /lib/libc.so.6 (0x28085000)
$ cp /lib/libipx.so.3 sandbox/lib
# jail sandbox/ testhostname 172.19.0.234 /bin/csh
csh: Cannot open /etc/termcap.
csh: using dumb terminal settings.
%/sbin/ifconfig
rl0: flags=8843<UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST> mtu 1500
options=8<VLAN_MTU>
inet 172.19.0.234 netmask 0xffffff00 broadcast 172.19.0.255
ether 4c:00:10:54:dd:8e
media: Ethernet autoselect (100baseTX <full-duplex>)
status: active
lo0: flags=8049<UP,LOOPBACK,RUNNING,MULTICAST> mtu 16384
%exit
exit
Если теперь мы добавим адрес 192.168.0.34 как алиас для интерфейса материнской машины, то по нему мы сможем взаимодействовать с внутренней машиной.
Поговорим об использовании jail(8) в качестве эмулятора.
Таблица 2.1. Опции запуска jail(8)
| Опция | Описание |
|---|---|
| Необязательные аргументы | |
-i | Вывести идентификатор созданной «тюрьмы». |
-J JidFile | Создать JidFile, аналогично PidFile. В него записывается jailid, путь к sandbox, hostname, IP адрес, и команда запущенная в jail. |
-l |
Выполнить программу в чистых переменных окружения.
Переменные окружения уничтожаются за исключением
переменных HOME,
SHELL, TERM и
USER. Переменная
TERM импортируется из текущего
окружения, остальные выставляются согласно выполненному
в песочнице логину.
|
-s securelevel |
Устанавливает переменную ядра
kern.securelevel в указанное значение
внутри созданной «тюрьмы». Эта опция появилась
только в FreeBSD 6.2
|
-u username | Имя пользователя от имени которого осуществляется запуск jail(8) |
-U username | Имя пользователя от имени которого выполняется команда внутри jail(8). |
| Обязательные аргументы | |
path | Путь к sandbox |
hostname | hostname внутри jail(8) |
IP | Адрес jail(8). Пока на один jail(8) можно дать только один адрес. |
command | Команда, которая будет выполнена в jail(8) |
Ниже я перечислю нужные для этого команды, естественно удалив их стандартный вывод — он огромен.
$D=/path/to/sandbox$mkdir -p $D$cd /usr/src#make world DESTDIR=$D#make distribution DESTDIR=$D#mount_devfs devfs $D/dev
Таким образом, будет собрана вторая копия
FreeBSD в каталоге
/path/to/sandbox/. Разумеется, если
ваша цель состоит только в запуске какого-то конкретного
сервиса, а не предоставления виртуального хостинга, то
данные действия, мягко говоря, избыточны. вероятно имеет
смысл создать маленькую «тюрьму» и добавлять в неё
файлы, пока она не заработает. Такой путь сложнее чем путь
удаления файлов из «толстой тюрьмы», но приводит к
лучшему результату. Кроме того, монтирование всей файловой
системы devfs, тоже небезопасно, поэтому далее следует
исключить некоторые файлы устройств (как минимум жёсткие
диски) способом описанным выше, в Раздел 2.11.1, «chroot(8)».
Прежде всего, следует исключить ситуацию, когда сервисы
материнской системы слушают адрес присвоенный
jail(8). Некоторые сервисы придётся
отключить, некоторые перенастроить. В частности, надо
заставить суперсервер inetd(8) слушать
некоторый конкретный адрес, принадлежащий материнской
системе. Имеет смысл добавить в файл
/etc/rc.conf следующие строки:
sendmail_enable="NO"
inetd_flags="-wW -a 192.168.11.23"
rpcbind_enable="NO"
Где 192.168.11.23 — адрес материнской системы.
Демоны запущенные не через inetd(8)
должны быть переконфигурированы. Некоторые могут быть
перенастроены при помощи /etc/rc.conf,
некоторые через свои конфигурационные файлы. В некоторых
клинических случаях демонов придётся пересобирать.
Для конфигурирования sshd(8) следует
воспользоваться файлом
/etc/ssh/sshd_config(5).
Для конфигурирования
sendmail(8) —
/etc/mail/sendmail.cf
named(8) —
/etc/namedb/named.conf.
Сервисы, основанные на rpc(3), такие как rpcbind(8), nfsd(8), mountd(8) придётся пересобирать.
Так или иначе, сервисы, которым невозможно объяснить какой они слушают адрес не должны запускаться на материнской системе, если они не должны интерферировать с программами в jail(8).
Первый запуск jail(8) происходит в системе, в которой не настроены сетевые интерфейсы, нет учётных записей пользователей и т.д. Некоторые из этих вещей можно настроить только если у вас запущен виртуальный сервер внутри jail(8). Запустите jail(8):
# jail /data/jail/192.168.11.100 testhostname 192.168.11.100 /bin/sh
Если всё будет в порядке, то теперь в этом окружении можно
выполнить настройку системы при помощи утилиты
/usr/sbin/sysinstall(8) или вручную
отредактировать /etc/rc.conf в
окружении jail(8).
Выполните следующие шаги:
/etc/fstab дабы
избежать сообщений о его отсутствии.
rpcbind_enable="NO" в
/etc/rc.conf)
/etc/resolv.confnetwork_interfaces="" в
/etc/rc.conf)
/usr/share/zoneinfo/Europe/Moscow)
под именем /etc/localtime.
Кроме того, вам возможно понадобится сконфигурировать
какое-нибудь програмное обеспечение внутри
jail(8). Например web-сервер, ssh-сервер
и т.д. Возможно вы захотите чтобы
syslogd(8) материнской системы слушал
сокет в jail(8). В рассматриваемом
примере его надо направить на сокет
/data/jail/192.168.11.100/var/run/log.
После произведённых настроек можно выйти из оболочки запущенной в jail(8).
Теперь вы готовы запускать виртуальный сервер в jail(8). Для этого надо выполнить в jail(8) скрипт /etc/rc.
![]() | Важно |
|---|---|
Если вы собираетесь предоставлять доступ неизвестным
пользователям с правами root в jail(8),
выставите переменную ядра
security.jail.set_hostname_allowed в 0 до
запуска jail(8). В Раздел 2.11.2.1.5, «Управление jail(8)» сказано чем это может
быть полезно.
|
Вот команды для запуска виртуального сервера:
#ifconfig bge0 add 172.19.0.133/24#mount_devfs devfs /opt/sandbox/dev#jail /opt/sandbox/ jail-hp.house.hcn-strela.ru 172.19.0.133 /bin/sh /etc/rc Loading configuration files. jail-hp.house.hcn-strela.ru Setting hostname: jail-hp.house.hcn-strela.ru. Creating and/or trimming log files:. ln: /dev/log: Operation not permitted Starting syslogd. ELF ldconfig path: /lib /usr/lib /usr/lib/compat a.out ldconfig path: /usr/lib/aout /usr/lib/compat/aout Starting local daemons:. Updating motd. Starting sshd. Starting cron. Local package initialization:. Thu Feb 22 11:41:09 MSK 2007$ssh guest@172.19.0.133The authenticity of host '172.19.0.133 (172.19.0.133)' can't be established. DSA key fingerprint is 95:cc:e5:38:e7:19:9e:0a:aa:40:a0:04:80:7b:be:53. Are you sure you want to continue connecting (yes/no)? yes Warning: Permanently added '172.19.0.133' (DSA) to the list of known hosts. Password: Last login: Thu Feb 22 10:58:50 2007 from 172.19.0.33 Copyright (c) 1980, 1983, 1986, 1988, 1990, 1991, 1993, 1994 The Regents of the University of California. All rights reserved. ...............................................................................
$ifconfigfwe0: flags=108802<BROADCAST,SIMPLEX,MULTICAST,NEEDSGIANT> mtu 1500 options=8<VLAN_MTU> ether 02:02:3f:15:33:0c ch 1 dma -1 bge0: flags=8843<UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST> mtu 1500 options=1b<RXCSUM,TXCSUM,VLAN_MTU,VLAN_HWTAGGING> inet 172.19.0.133 netmask 0xffffff00 broadcast 172.19.0.255 ether 00:17:08:2f:a6:90 media: Ethernet autoselect (100baseTX <full-duplex>) status: active plip0: flags=108810<POINTOPOINT,SIMPLEX,MULTICAST,NEEDSGIANT> mtu 1500 lo0: flags=8049<UP,LOOPBACK,RUNNING,MULTICAST> mtu 16384
| Заходим в тюрьму по ssh(1). Учётная запись guest и sshd(8) демон настроены заранее. |
| Это уже команда выполненная внутри тюрьмы. |
Вы получите некоторое количество предупреждений связанных с тем, что внутри jail(8) нельзя выполнить большинство вызовов sysctl(8). Однако всё должно работать. Вы можете увидеть при помощи команды ps(1) процессы запущенные в jail(8) с флагом J.
Можно запускать jail(8) автоматически при
старте системы. Для этого надо вписать строки типа jail_* в
/etc/rc.conf(5).
Например, для того, чтобы при старте системы автоматически
запускалось три jail'а, надо поместить в
/etc/rc.conf(5) следующие строки:
jail_enable="YES"
jail_list="one,two,three"
jail_one_hostname="www.propeller.ru"
jail_two_hostname="www.samovar.ru"
jail_three_hostname="www.avtoclav.ru"
jail_one_ip="192.168.11.100"
jail_two_ip="192.168.11.101"
jail_three_ip="192.168.11.102"
jail_one_rootdir="/data/jail/192.168.11.100"
jail_two_rootdir="/data/jail/192.168.11.101"
jail_three_rootdir="/data/jail/192.168.11.102"
Это программа-минимум. С помощью других опций описанных в
/etc/rc.conf(5) вы можете оговорить
нужно ли перед запуском jail(8)
монтировать внутри него procfs,
devfs, какие устройства нужно
активировать внутри devfs и т.п.
Можно управлять jail(8) при помощи стартового скрипта /etc/rc.d/jail:
#/etc/rc.d/jail start#/etc/rc.d/jail stop#/etc/rc.d/jail start myjail#/etc/rc.d/jail stop myjail
Обычные команды типа shutdown(8), halt(8) или reboot(8) в jail(8) не работают. Вместо них можно зайти в jail(8) и выполнить одну из команд:
#kill -TERM -1#kill -KILL -1
в зависимости от того, что вы хотите сделать. Возможно вы захотите выполнить скрипт /etc/rc.sutdown внутри jail(8).
Если вы находитесь снаружи jail(8) и хотите выполнить команду внутри него, вы можете воспользоваться командой jexec(8):
#jexec 6 kill -KILL -1
Эта команда выполнит команду kill(1) внутри jail с jid=6.
В каталоге /proc, если вы его
используете, в файле
/proc/<pid>/status в последнем
поле находится имя хоста для jail или
знак - если процесс запущен не в
jail. Кроме того, команда
ps(1) показывает знак J если процесс запущен в
jail. Однако hostname может быть изменён
внутри jail и тогда значение из файла
/proc/<pid>/status оказывается ни
с чем не связано. Чтобы запретить смену hostname надо
выставить переменную ядра
security.jail.set_hostname_allowed в 0.
(см. Раздел 5.6, «Изменение на лету переменных ядра»). Это повлияет на всю
«пенитенциарную систему».
Чтобы увидеть список процессов с их Jail ID вы можете выполнить команду
$ ps ax -o pid,jid,args
Чтобы увидеть процессы в jail(8) номер 3, и послать им сигналы, можно использовать команды
$pgrep -lfj 3#pkill -j 3
или
# killall -j 3
Таблица 2.2. Переменные ядра (MIB) связанные с jail(8)
| Переменная | Умолчание | Описание |
|---|---|---|
security.jail.allow_raw_sockets | 0 | Переменная определяет может ли root в «тюрьме» открывать сырые сокеты. Установка переменной в 1 позволит запускать в тюрьме такие утилиты как ping(8) и traceroute(8). |
security.jail.enforce_statfs | 2 | Определяет какая информация о точках монтирования доступна для процессов в jail(8). 0 — все точки монтирования доступны без ограничений; 1 — Доступны только точки монтирвания внутри каталога jail(8), путь к каталогу jail(8) удаляется; 2 — можно работать только с точкой монтирования в которой разположен jail(8). |
security.jail.set_hostname_allowed | 1 | Определяет может ли приложение в jail(8) сменить hostname. |
security.jail.socket_unixiproute_only | 0 | По умолчанию процессы в jail(8) могут взаимодействовать с доменными сокетами UNIX, IPv4 сокетами и routing sockets. Смена данной переменной приведёт к тому, что процессам в jail(8) станут доступны и другие сокеты. |
security.jail.sysvipc_allowed | 0 | Могут ли процессы в jail(8) использовать примитивы System V IPC. Установка этой переменной в 1 позволит процессам в jail(8) взаимодействовать с процессами в других «тюрьмах» и с процессами материнской системы. |
security.jail.chflags_allowed | 0 |
Как взаимодействует root в
jail(8) с флагами выставленными
командой chflags(1).
0 — root считается непривилегированным
пользователем и не может менять этот флаг.
1 — root считается привилегированным
пользователем и может манипулировать флагами
согласно секущему уровню
kern.securelevel.
|
| Существуют две переменные, которые можно менять внутри jail(8) их значение будет действовать только внутри данной «тюрьмы». | ||
kern.securelevel | ||
kern.hostname | ||
jls(8). Программа предоставляет список запущенных тюрем:
$ jls
JID IP Address Hostname Path
6 172.19.0.133 jail-hp.house.hcn-strela.ru /opt/sandbox
jexec(8). Программа позволяет выполнить в jail(8) произвольную команду:
# jexec 6 kill -TERM -1
Эта команда приведёт к остановке 6-й тюрьмы.
security/jailaudit. Порт генерирующий вывод команды portaudit(1) для тюрем.
sysutils/ezjail. Порт предназначенный для облегчения создания и управления тюрьмами.
sysutils/jailadmin. Порт для администрирования тюрьмами.
sysutils/jailctl. Порт для администрирования тюрьмами.
sysutils/jailer. Порт для управления запуском и остановкой тюрем.
sysutils/jailutils. Порт с несколькими программами для манипулирования тюрьмами.
Для получения более подробной информации о портах выполните команду:
$ cat /usr/ports/<category>/<port>/pkg-descr
$ while :; do cat /dev/zero | md5 & done
Описание: Кандидат BSDA должен уметь по данному скриншоту базы паролей определить используемый метод шифрования и знать как его сменить. Кандидат должен иметь базовое понимание того когда надо использовать DES, MD5 и Blowfish.
Практика: login.conf(5); auth.conf(5);
passwd.conf(5) и adduser(8).
Жизнь показывает, что существует множество путей при помощи которых может «утекать» база с паролями пользователей. Один из распространённых случаев — утечка с backup'ами. Главное оружие любого системного администратора, это валидол и backup. Администратор, который понял эту истину может уподобиться белке, которая рассовывает орешки где попало и забывает где их положила. Так же могут быть распределены в системе резервные копии. Особенно, если система резервного копирования написана самим администратором. Такая система, быть может ничем не плоха, но на стадии отладки, пока подбирались опции, на жёстких дисках оказалось несколько копий резервных файлов с правами 644...
Чем это чревато? Злоумышленник может попыться найти базу с
паролями и взломать её. Что может ему помешать? Во первых пароли
должны быть качественными, во вторых, они
должны быть качествено зашифрованы. Надо сразу сказать, что
первое намного важнее второго. Как бы качественно ни был
зашифрован пароль 12345, его вскроют
за доли секунды.
Существует несколько способов шифрования паролей. Так или иначе, используется некоторая необратимая функция, при помощи которой, шифруется пароль. Т.е. система ваш пароль вообще не знает. Когда вы его вводите, она шифрует его заново и сверяет результаты шифрования со своей базой.
В системах BSD можно выбирать несколько алгоритмов шифрования паролей, однако ни один из них не является панацеей от взлома. Иметь стойкий пароль, намного важнее, чем строго его шифровать. Хотя последнее тоже может быть важно.
База с аутентификационными данными состоит из 4-х файлов.
Основной — /etc/master.passwd и
генерирующихся из него при помощи pwd_mkdb(8)
трёх файлов: /etc/passwd(5),
/etc/pwd.db и
/etc/spwd.db.
/etc/master.passwd
В данном файле содержится собственно аутентификационная
информация: зашифрованный пароль, сведения о
пользовательских настройках (т.н. класс пользователя),
срок действия пароля. Ниже приведён фрагмент файла
/etc/master.passwd(5).
user1:*LOCKED*cuqW.GIKHV/xs:1001:1001:russian:0:0:Poluect,a-sys,1234567,7654321,hello_world:/home/user:/usr/sbin/nologin
user2:*LOCKED*76aSxdZIXKXfk:1002:1002:russian:0:0:Poluect,a-sys,1234567,7654321,hello_world:/home/user:/usr/sbin/nologin
user3:*LOCKED*$1$UmWRc8Kh$WyHRN96T7vQ7nZP0ChVjc/:1003:1003:russian:0:0:Poluect,a-sys,1234567,7654321,hello_world:/home/user:/usr/sbin/nologin
user4:*LOCKED*$1$OgtF.3Zb$EafLlWm6H.OZ1sKkheySr.:1004:1004:russian:0:0:Poluect,a-sys,1234567,7654321,hello_world:/home/user:/usr/sbin/nologin
user5:*LOCKED*$2a$04$HXoymCDzRfi9ctGmfrOqeu9Hn16XcWmQuVnA6C3aifKkkM7qrKauO:1005:1005:russian:0:0:Poluect,a-sys,1234567,7654321,hello_world:/home/user:/usr/sbin/nologin
user6:*LOCKED*$2a$04$GO.hiRaXx7wp5cdAfJP9xOAOeXV48/kBYOJ2VaJRhknUg/VWLw/N.:1005:1005:russian:0:0:Poluect,a-sys,1234567,7654321,hello_world:/home/user:/usr/sbin/nologin
user7:*LOCKED*$3$$2d20d252a479f485cdf5e171d93985bf:1006:1006:russian:0:0:Poluect,a-sys,1234567,7654321,hello_world:/home/user:/usr/sbin/nologin
user8:*LOCKED*$3$$2d20d252a479f485cdf5e171d93985bf:1007:1007:russian:0:0:Poluect,a-sys,1234567,7654321,hello_world:/home/user:/usr/sbin/nologin
Здесь имеется 10 полей разделённых двоеточиями. Вот их значение:
Пароль пользователя. Никакой пароль не может содержать
в себе звёздочек, или восклицательных знаков. Поэтому
поле *LOCKED*
свидетельствует о том, что данная учётная запись
заблокирована. Ни один пароль не совпадёт с ней при
процедуре аутентификации. Для блокирования учётной
записи таким способом можно применять команду
pw(8) (см. Раздел 4.1, «Создание, изменение и удаление учётных записей»).
![]() | Внимание |
|---|---|
| Существуют способы войти в систему без проверки пароля, например при аутентификации в ssh(1) по паре сгенерированных ключей (см. Раздел 2.7, «Разбираться в основных рекомендованных методах доступа [до хоста]»). Поэтому такой способ блокирования учётной записи можно считать необходимым, но не достаточным. Кроме этого действия надо ещё сменить пользователю оболочку на /usr/sbin/nologin. |
У всех восьми упомянутых здесь пользователей пароль
одинаковый — qwerty. Однако он приведён в
разных форматах. Всего мы обсудим 4 формата паролей:
Пароль qwerty При
помощи алгоритма DES
шифруется в строку cuqW.GIKHV/xs. Однако
было бы ошибкой дать злоумышленнику
возможность определить у кого из наших
пользователей пароли совпадают, просто на
основании того, что совпадают шифры. Поэтому
при шифровании используется т.н.
«соль». В момент заведения пароля
генерируется случайное число. это число в
символьном виде приписывается к паролю и далее
шифруется пароль вместе с солью. Таким
образом, следующая строка: 76aSxdZIXKXfk это тоже
qwerty.
Алгоритм DES не является достаточно криптостойким. Современная компьютерная техника позволяет взломать эти пароли методом перебора за незначительный промежуток времени. По этой причине большинство современных UNIX-систем шифруют пароли при помощи алгоритма MD5:
Пароль qwerty в
формате MD5 может выглядеть следующим образом:
$1$UmWRc8Kh$WyHRN96T7vQ7nZP0ChVjc/.
В данном примере пароль состоит из трёх полей,
разделённых знаками $:
$1$ —
Указание на алгоритм шифрования MD5;
UmWRc8Kh —
«соль», которая добавляется к
паролю при вычислении MD5 суммы (см. выше,
описание DES).
WyHRN96T7vQ7nZP0ChVjc/ —
собственно зашифрованный пароль.
В интернете можно встретить много истерических замечаний по поводу якобы взломанного алгоритма MD5. Правда на настоящий момент такова: некие китайские(?) математики нашли алгоритм при помощи которого можно находить коллизии в MD5. Т.е. если md5(xm)=y, то существует алгоритм по которому зная y можно найти другой xn, такой, что md5(xn)=md5(xm). Однако, если злоумышленник знает пароль, то знание коллизии к паролю ему уже не нужно. Что касается обратимости, то алгоритм md5 по прежнему необратим, и единственный вид атаки на него, это bruteforce — атака грубой силой, путём перебора паролей. Математики смогли снизить количество вычислений, необходимых для этой атаки на несколько порядков, однако это по прежнему актуальная бесконечность.
$2 в начале строки пароля
свидетельствует о применении данного алгоритма.
Поле $04$ указывает на
то, сколько проходов совершено при шифровании.
(Внимание! Последняя фраза лишь догадка автора.)
$3. Обратите внимание: в
случае использования алгоритма NT-hash соль не
генерируется и хеши одинаковых паролей одинаковы!
Я не знаю устройства этого алгоритма, но результат
просто отвратителен! Данный эксперимент ставился
в системе
FreeBSD 6.1-RELEASE.
/etc/login.conf(5) и устанавливают
переменные окружения или делают иные настройки (см.
Приложение F, /etc/login.conf(5)).
GECOS — информация о пользователе: имя, место работы, рабочий и домашний телефон. Эту и другую информацию использует в работе утилита finger(1):
$ finger user
Login: user Name: Poluect
Directory: /home/user Shell: /usr/sbin/nologin
Office: a-sys, 123-4567 Home Phone: 765-4321
Never logged in.
No Mail.
No Plan.
/etc/passwd(5)
Данный файл нужен, главным образом, для совместимости. Он
присутствует во всех UNIX'ах и везде имеет одинаковую
структуру. В BSD он не первичен, т.е.
генерируется из файла
/etc/master.passwd при помощи команды
pwd_mkdb(8). В файле присутствует
информация о логине пользователя, его оболочке и др. Поля
разделены двоеточиями:
user:*:1001:1001:Poluect,a-sys,1234567,7654321,hello_world:/home/user:/bin/csh
/etc/pwd.db/etc/master.passwd(5) командой
pwd_mkdb(8).
/etc/spwd.db/etc/master.passwd(5) командой
pwd_mkdb(8).
Данный файл является базой данных для различных программ, в том числе для программы login(1). С его помощью можно задавать переменные окружения, настройки учётных записей вроде сроков действия учётных записей, метода шифрования и т.д.
Полное описание формата этого файла можно найти в Приложение F, /etc/login.conf(5).
Файл /etc/login.conf непосредственно
системой не читается. После его редактирования надо создать
бинарную базу /etc/login.conf.db при помощи
команды:
# cap_mkdb /etc/login.conf
Поля в файле /etc/login.conf разделяются
двоеточиями. В первом поле каждой записи указано для кого она
предназначена. Здесь указывается «класс» пользователя
(5-е поле файла master.passwd(5)). Ключевое
слово default соответствует любому
пользователю с ненулевым UID (т.е. не root'у). В
FreeBSD и
DragonFly BSD пользователи могут
заводить свои собственные файлы
~/.login.conf в домашнем каталоге, где они
должны указывать ключевое слово me.
Пример:
default:\
:passwd_format=nth:\
:copyright=/etc/COPYRIGHT:\
:welcome=/etc/motd:\
:setenv=MAIL=/var/mail/$,BLOCKSIZE=K,FTP_PASSIVE_MODE=YES:\
:path=/sbin /bin /usr/sbin /usr/bin /usr/games /usr/local/sbin /usr/local/bin /usr/X11R6/bin ~/bin:\
:nologin=/var/run/nologin:\
:cputime=unlimited:\
............................
:umask=022:
Для смены алгоритма шифрования пароля в
FreeBSD следует поменять значение опции
passwd_format, а в
OpenBSD —
localcipher (и, возможно,
ypcipher). Эти опции описаны в
Приложение F, /etc/login.conf(5), их значения в
Таблица 2.3, «Возможные значения опций crypt_default
(FreeBSD) и localcipher,
ypcipher (OpenBSD)»
В этом файле находятся умолчания, которые ипользует системная
функция crypt_set_format(3). По
хорошему, сюда надо записать что-то вроде:
crypt_default = blf
Однако при заведении новых паролей в этот файл система смотрит в
последнюю очередь, и более важным окажется файл
/etc/login.conf(5) (см. Приложение F, /etc/login.conf(5)).
Таблица 2.3. Возможные значения опций crypt_default
(FreeBSD) и localcipher,
ypcipher (OpenBSD)
| Опция | Описание | OS |
|---|---|---|
des | DES |
|
md5 | MD5 |
|
blf | Blowfish |
|
nth | NT-hash |
|
old | DES |
|
newsalt,<rounds> | Newsalt; rounds — 24-битное целое, минимум 7250 (число проходов алгоритма). |
|
blowfish,<rounds> | Blowfish; rounds — от 4-х до 31-го (логарифм по основанию 2 от числа проходов алгоритма). |
|
Данный файл присутствует только в NetBSD и,
по смыслу похож на /etc/login.conf(5) из
других систем. В файле /etc/passwd.conf
хранится информация о том, какой алгоритм шифроваения для каких
пользователей использовать. Например:
default:
localcipher = md5
ypcipher = old
root:
localcipher = blowfish,5
Здесь мы используем алгоритм md5 для локальных пользователей и старый des для пользователей NIS, а для root используем blowfish, который применяется к паролю 2 в 5-й степени раз (32 раза).
Утилита adduser(8) предназначена для добавления пользователей в систему. Она может работать как интерактивно, так и из скриптов. Основной утилитой по управлению учётными записями является pw(8), она накладывает ограничение на длину пароля и т.п. Интерактивно вызванная утилита спрашивает у администратора имя пользователя, полное имя (GECOS) и др.
![]() | Замечание |
|---|---|
Имя пользователя обычно не должно быть более 16 символов и
должно состоять из букв и цифр. Эти ограничения наложены по
историческим причинам, если вы хотите более длинные имена, вы
можете переопределить переменную UT_NAMESIZE
в <utmp.h> и пересобрать world.
Однако после этого могут быть проблемы с бинарниками
скомпилированными в других системах. Кроме того,
NIS предполагает, что пароли бывают только
8-ми символьные.
|
Суммируя сказанное выше, приведём краткое Blowfish HOWTO: как перевести базу паролей в формат Blowfish:
/etc/login.conf(5) в секции default:\ помещаем строки:
default:\
:passwd_format=blf:\
:passwordtime=48d:\
:mixpasswordcase=true:\
:minpasswordlen=10:\
:idletime=60:
/etc/login.conf(5)).
# cap_mkdb /etc/login.conf
/etc/auth.conf(8) добавляем строку
crypt_default=blf
Описание: Кандидат должен понимать, что приветствие системы зависить от того, каким способом пользователь получил доступ к системе и знать, какие файлы за это отвечают.
Практика: motd(5), login.conf(5),
gettytab(5), sshd_config(5).
Описание: Для предотвращения атак против системы путём взлома базы паролей, системы BSD хранят эти данные в шифрованном виде доступными только системным процессам. BSDA кандидат должен понимать где хранятся эти данные и какие на них должны быть пермиссии (права доступа).
Практика: passwd(5), pwd_mkdb(8)
Содержание
3.1. Монтирование и размонтирование файловых систем
3.2. Конфигурирование NFS
3.3. Определение какие файловые системы смонтированы и какие будут смонтированы при загрузке
3.4. Определять ёмкость диска и какие файлы занимают больше места
3.5. Создание и просмотр символических и жёстких ссылок
3.6. Просмотр и изменение ACL
3.7. Просмотр и изменение пермиссий с использованием как символьных, так и восьмеричных мод
3.8. Изменение владельца файла и группы
3.9. Резервное копирование и восстановление файлов и директорий на локальный диск или ленту
3.10. Резервное копирование и восстановление файловой системы
3.11. Знание структуры каталогов системы
3.12. Ручной запуск программы проверки файловой системы и средств её восстановления
3.13. Определение и изменение флагов файлов
3.14. Слежение за состоянием виртуальной памяти системыОписание: Кандидат BSDA должен свободно ориентироваться в проблемах монтирования и размонтирования локальных файловых систем, включая: как смонтировать/размонтировать конкретную файловую систему, как смонтировать все файловые системы, как сконфигурировать систему для монтирования файловой системы при загрузке. Передача опций команде mount(8), и разрешение ошибок возникших при выполнении mount(8).
Практика: mount(8), umount(8),
fstab(5)
Описание: Кандидат BSDA должен быть знаком с утилитами связанными с NFS и знать о проблемах с безопасностью, которые могут возникнуть при открытии RPC через брандмауэр. Кандидат должен уметь конфигурировать NFS сервер или клиент в соответствии с указанными требованиями к доступности данных.
Практика: exports(5), nfsd(8),
mountd(8), rpcbind(8) или
portmap(8), rpc.lockd(8),
rpc.statd(8), rc.conf(5) и
mount_nfs(8)
Описание: Кандидат должен уметь определять какие файловые системы смонтированы и какие будут смонтированы при загрузке.
Практика: mount(8), du(1),
fstab(5)
Описание: Кандидат BSDA должен уметь работать с UNIX утилитами для быстрого определения какой файл занял много места на жёстком диске.
Практика: du(1), df(1), find(1), sort(1), systat(1)
Описание: Кандидат должен знать разницу между символьными и жёсткими ссылками, как их создавать просматривать и удалять. Кандидат должен уметь временно разрешить проблему с нехваткой дискового пространства через использование символьных ссылок.
Практика: ln(1), ls(1), rm(1), stat(1)
Описание: Кандидат BSDA должен уметь определить использует ли FreeBSD ACL и если да, то на каких файловых системах. Кандидат должен уметь просматривать и изменять файловые ACL на FreeBSD.
Практика: mount(8), ls(1), getfacl(1)
Описание: Ожидается, что кандидат BSDA знаком с традиционными UNIX пермиссиями включая: как просмотреть и изменить пермиссии, почему sticky-bit важен на каталоге /tmp и других каталогах общего пользования, определять и использовать SUID и SGID биты, понимать разницу между символьным и восьмеричным представлением пермиссий. Вдобавок кандидат должен понимать откуда оболочка берёт умолчальные пермиссии для вновь создаваемых файлов и каталогов, по заданному значению umask определять с какими пермиссиями будет создан файл.
Практика: ls(1), chmod(1), umask(1) или (2)
Описание: Кандидат BSDA должен уметь сменить владельца файла как требуется. Кандидат должен понимать как важно проверить кем он является в системе, до того как создать файл.
Практика: chown(8), chgrp(1); su(1), mtree(8)
Описание: Кандидат должен иметь опыт работы с распространёнными в UNIX утилитами командной строки для резервного копирования. Кандидат должен знать имена устройств для ленточных ностителей.
Практика: tar(1), cpio(1), pax(1), cp(1), cpdup(1)
Описание: Кандидат должен разбираться в утилитах используемых для резервного копирования всей файловой системы в целом и различных уровнях утилиты dump(1).
Практика: dump(8), restore(8), dd(1)
Описание: Кандидат BSDA должен быстро ориентироваться в структуре каталогов системы BSD.
Практика: hier(7)
Описание: Кандидат BSDA должен знать утилиты для проверки содержимого файловой системы и использовать их.
Практика: fsck(8)
Описание: Кандидат BSDA должен понимать как флаги расширяют традиционные пермиссии UNIX и знать как посмотреть и изменить флаги неизменяемости, "дописываемости" и неудаляемости (immutable, append-only, undelete).
Практика: ls(1), chflags(1)
Описание: Виртуальная память имеет важное значение для производительности системы. Кандидат BSDA должен уметь конфигурировать устройство swap и следить за его использованием.
Практика: pstat(8), systat(1), top(1), vmstat(8); swapctl(8), swapinfo(8)
Содержание
4.1. Создание, изменение и удаление учётных записей
4.2. Создание системных учётных записей
4.3. Отключение или включение учётной записи (lock и unlock)
4.4. Идентификация и членство в группах
4.5. Определение кто сейчас присутствует в системе или последнего времени входа в систему
4.6. Включение слежения за учётными записями и просмотр статистики
4.7. Изменение пользовательской оболочки
4.8. Контролировать какие файлы будут копироваться в новую пользовательскую директорию при создании учётной записи
4.9. Смена пароляОписание: Важная часть системного администрования — манипулирование учётными записями. Кандидат BSDA должен быть знаком с различными утилитами для манипулирования учётными записями и уметь использовать их в соответствии с поставленными задачами.
Практика: vipw(8); pw(8),
adduser(8), adduser.conf(5),
useradd(8), userdel(8),
rmuser(8), userinfo(8),
usermod(8), и user(8)
![]() | Замечание |
|---|---|
| Данный текст прислан Дмитрием Орловым, но подвергся моей незначительной редактуре. Е.М. |
После установки системы требуется перейти к задаче управления локальными пользователями системы. Даже в том случае, если вы единственный пользователь, системы семейства BSD настоятельно рекомендуют завести некоего пользователя и пользоваться привилегированным аккаунтом при помощи команды su(8), что предохранит вас от неожиданного разрушения собственной системы. Существует другая крайность, это создание множества пользователей с административными правами, что может привести как минимум к нестабильности системы, к ее вскрытию злоумышленниками или даже разрушению.
Можно выделить три основных типа учётных записей: суперпользователь, системные пользователи, и учётные записи пользователей. Учётная запись суперпользователя, обычно называемая root, используется для управления системой без ограничения привилегий. Системные пользователи запускают сервисы и, как правило, не могут входить (login) в систему. Учётные записи пользователей необходимы остальным для входа в систему, чтения почты, работы с документами, создания приложений и так далее.
С каждой учётной записью в системе *BSD связана определённая идентификационная информация:
Имя пользователя в том виде, в каком оно вводится в
приглашение login:. Имена пользователей должны быть
уникальны в пределах одного компьютера; не может быть двух
пользователей с одинаковым именем пользователя. Существует
множество правил для создания правильных имён
пользователей, документированных в
passwd(5); вы как правило будете
использовать имена пользователей, состоящие из восьми или
меньшего количества символов, все символы в нижнем
регистре.
Вообще-то это не является какой-то догмой. Но некоторый софт расчитывает, что на имя пользователя наложены некоторые ограничения. Так, старые реализации системы NIS расчитывали, то имя пользователя состоит не более чем из восьми символов. В настоящий момент вы можете не соблюдать это ограничение. Почтовая система sendmail(8) при доставке почты переводит символы в нижний регистр. Поэтому пользователь в имени которого есть буквы из верхнего регистра будет лишён почты. Многие файловые форматы расчитывают на то, что в имени нет двоеточия и т.п. Если по каким-то причинам вы хотите, чтобы в имени были большие буквы, точки и т.п. Вам надо подумать над архитектурой програмного обеспечения. Например, если вы хотите, чтобы в вашем домене существовали электронные адреса типа Mikhail.Kutuzov@borodino.ru, вам слеует хранить почтовые аккаунты, например, в базе данных PostgreSQL, а не в виде учётных записей UNIX.
login.conf(5),
passwd(5), см. так же Приложение F, /etc/login.conf(5)).
/home/username. Пользователи хранят
личные файлы в домашнем каталоге и в любых подкаталогах,
создаваемых внутри домашнего каталога.
Самый простой и интерактивный способ добавить нового пользователя, это использовать команду adduser(8) (нет в NetBSD). Пример использования adduser(8). (Скопировано из OpenBSD FAQ).
#adduser Use option ``-silent'' if you don't want to see all warnings and questions. Reading /etc/shells Reading /etc/login.conf Check /etc/master.passwd Check /etc/group Ok, let's go. Don't worry about mistakes. I will give you the chance later to correct any input.Enter username []:testuserEnter full name []:Test FAQ UserEnter shell csh ksh nologin sh [sh]:kshUid [1002]:EnterLogin group testuser [testuser]:guestLogin group is ``guest''. Invite testuser into other groups: guest no [no]:noLogin class auth-defaults auth-ftp-defaults daemon default staff [default]:<Enter>Enter password []:<Набираете пароль и нажимаете Enter>Enter password again []:<Набираете пароль и нажимаете Enter> Name: testuser Password: **** Fullname: Test FAQ User Uid: 1002 Gid: 31 (guest) Groups: guest Login Class: default HOME: /home/testuser Shell: /bin/kshOK? (y/n) [y]:y Added user ``testuser'' Copy files from /etc/skel to /home/testuserAdd another user? (y/n) [y]:n Goodbye!
Значения по умолчанию для adduser(8) можно создать в файле
/etc/adduser.conf
# adduser -config_create
Вот пример файла /etc/adduser.conf:
# Конфигурационный файл для утилиты adduser(8).
# ЗАМЕЧАНИЕ: only *some* variables are saved.
# Последнее изменение Fri Mar 30 14:04:05 EST 2004.
defaultLgroup=
defaultclass=
defaultgroups=
passwdtype=yes
homeprefix=/home
defaultshell=/bin/csh
udotdir=/usr/share/skel
msgfile=/etc/adduser.msg
disableflag=
upwexpire=91d # Срок годности паролей истекает через 91 день
Скрипт adduser(8) вначале читает
/etc/group,
/etc/passwd,
/etc/shells и другие конфигурационные файлы
на предмет целостности и инициализации значений по умолчанию, а
так же получения допустимых значений. Добавляет домашнюю
директорию и создает пользователя, а так же заносит его в
требуемые группы. Интересующиеся тонкостями могут просмотреть
сам скрипт /usr/sbin/adduser.
В OpenBSD и NetBSD в командной строке пользователя можно дабавить при помощи утилиты user(8). Метод достаточно прост и полезен для использования в сценариях. Следует только учитывать, когда заводится пользователь данной командой, то используется УЖЕ шифрованный пароль. Таким образом, для вышеописанного пользователя мы получаем следующую последовательность действий (пример сделан в OpenBSD):
#encrypt -p -b 6Enter string:$2a$06$YOdOZM3.4m6MObBXjeZtBOWArqC2.uRJZXUkOghbieIvSWXVJRzlq#user add -p '$2a$06$YOdOZM3.4m6MObBXjeZtBOWArqC2.uRJZXUkOghbieIvSWXVJRzlq' -u 1002 \ -s /bin/ksh -c "Test FAQ User" -m -g guest testuser
В FreeBSD и DragonFly BSD для этих целей используется утилита pw(8)
BSD системы поддерживают «классический», древнейший
способ изменения пользовательской информации —
vipw(8).Использование этой утилиты весьма
удобно, так как после рабоиы vipw(8)
проверяет синтаксис файла и, если администратор не совершил
никаких ошибок, обновляет данные в файле
/etc/master.passwd, строит из него
/etc/passwd и бинарные базы
/etc/pwd.db и
/etc/spwd.db. (См. Раздел 2.12.1, «Устройство базы паролей».)
Однако, этот способ следует рекомендовать лишь в том случае,
если вы понимаете формат файла
/etc/master.passwd. Поэтому начинающие и
ине только начинающие администраторы используют команду
chpass(1).
При запуске chpass(1) запускает редактор vi(1) (см. Раздел 7.3, «Навыки работы в vi(1)») и предлагает изменить следующие настройки учётной записи:
# chpass testuser
Changing user database information for testuser.
Login: testuser
Encrypted password:$2a$06$YOdOZM3.4m6MObBXjeZtBOWArqC2.uRJZXUkOghbieIvSWXVJRzlq
Uid [#]: 1002
Gid [# or name]: 31
Change [month day year]:
Expire [month day year]:
Class:
Home directory: /home/testuser
Shell: /bin/ksh
Full Name: Test FAQ User
Office Location:
Office Phone:
Home Phone:
В случе если команда вызвана непривилегированным поьзователем, она позволяет изменить информацию только в рамках полномочий пользователя:
$ chpass
#Changing user information for paakai.
Shell: /usr/local/bin/bash
Full Name: Paakai Sudoer
Office Location:
Office Phone:
Home Phone:
Other information:
После успешного изменения информации о пользователе,
chpass(8) вызывает
pwd_mkdb(8) для актуализации изменений в
базах данных пользователей
(/etc/master.passwd и
/etc/passwd).
Другие, команды для изменения информации о пользователях: user mod, usermod, pw usermod.
Быстро и эффективно удалить пользователя можно с помощью команды
rmuser(8). rmuser(8)
старается удалить всё, относящееся к указанному пользователю:
домашнюю директорию, письма, задачи в
crontab(1)/at(1),
уничтожает запущенные процессы этого пользователя, созданные им
временные файлы в /tmp и, разумеется,
удаляет его из /etc/master.passwd и
/etc/group.
#rmuserEnter login name for user to remove:testuser Matching password entry: testuser:$2a$06$YOdOZM3.4m6MObBXjeZtBOWArqC2.uRJZXUkOghbieIvSWXVJRzlq:1002 :31::0:0:Test FAQ User:/home/testuser:/bin/kshIs this the entry you wish to remove?yRemove user's home directory (/home/testuser)?y Updating password file, updating databases, done. Updating group file: done. Removing user's home directory (/home/testuser): done.
Для удаления пользователя так же можно вопользоваться командами: userdel, user del, pw userdel.
К сожалению, в UNIX (да и вообще, наверное ни в одной операционной системе) не существует абсолютно надёжного метода удалить пользователя. Никто не может гарантировать вам, что этот пользователь не прикопал своих файлов где-то вне своего домашнего каталога. Что никто не выдал ему прав на ресурсы используя метод ACL. rmuser(8) не в силах удалить связанные с пользователем почтовые алиасы. Если спустя время вы заведёте нового пользователя, то ему может быть выдан UID старого пользователя и он завладеет брошенными файлами. Если имя нового пользователя совпадёт с именем удалённого, то он завладеет почтовыми алиасами и др.
В связи со сказанным, в ряде случаев блокирование пользователей оказывается более желательно, чем удаление их учётных записей.
Описание: Кандидат должен понимать, что многие сервисы требуют учётных записей и что эти записи должны быть недоступны для логина.
Практика: nologin(8); использование * в поле пароля в
passwd(5)
![]() | Замечание |
|---|---|
| Данный текст прислан Дмитрием Орловым, спасибо. |
Системные пользователи создаются для запусков сервисов (демонов), таких как DNS, почта, веб-серверы и так далее, и не могут быть использованы для входа в систему. Это необходимо по соображениям безопасности: если сервис работает с правами суперпользователя, он может действовать без ограничений, а значит, в случае взлома сервиса злоумыленником, последний получает полный контроль над атакованной системой.
nobody это классический непривилегированный системный пользователь. Тем не менее, необходимо помнить, что чем больше сервисов используют nobody, тем больше файлов и процессов ассоциировано с этим пользователем, и следовательно тем больше прав появляется у этого пользователя.
Для системных пользователей в качестве оболочки указывается
/sbin/nologin, который при попытке входа в
систему, выдаёт сообщение "This account is currently not
available", или же то, которое вы укажите в файле
/etc/nologin.txt (например, "Daemons are
deathless"). Если же при помощи vipw(8)
вместо пароля указать "*", то мы не получим даже такого
политкорректного nologin сообщения, нам сразу
скажут — "Login incorrect".
Описание: Кандидат BSDA должен знать как определить включены ли учётная запись и как её включить.
Практика: vipw(8); chpass(1), chfn(1), chsh(1), pw(8), user(8)
Описание: В системе пермиссий UNIX важно уметь определить кем вы являетесь и каково ваше членство в группах. Кандидат должен это уметь.
Практика: id(1), groups(1), who(1), whoami(1), su(1)
Описание: Системы BSD поддерживают базы данных с детальной информацией о логинах. Кандидат BSDA должен знать что это за базы, где они хранятся и какими утилитами можно воспользоваться, чтобы получить информацию о логинах.
Практика: wtmp(5), utmp(5),
w(1), who(1),
users(1), last(1),
lastlogin(8), lastlog(5),
finger(1)
Описание: Кандидат BSDA должен быть осведомлён когда следует включить систему сбора статистики об учётных записях (accaunting), знать какие для этого нужны утилиты и как просматривать собранную статистику.
Практика: ac(8), sa(8), accton(8), lastcomm(1), last(1)
Описание: Кандидат должен знать какая оболочка по умолчанию у пользователя и у суперпользователя. Он должен знать как сменить оболочку в каждой из операционных систем.
Практика: vipw(8); chpass(1), chfn(1), chsh(1), pw(8), user(8)
Описание:
Системы BSD используют каталог skel
содержащий файлы, которые должны быть скопированы при создании
домашнего каталога пользователя при заведении учётной записи.
Кандидат BSDA должен знать где в какой системе
находиться данный каталог и как отменить его копирование при
создании учётной записи.
Практика: pw(8), adduser.conf(5),
useradd(8) и
usermgmt.conf(5)
Содержание
5.1. Определение какой процесс расходует основную часть ресурсов ЦПУ
5.2. Определять активные процессы и посылать им сигналы
5.3. Использование скриптов rc(8) для
определения запущенных сервисов, их запуск, остановка и
перезапуск
5.4. Определение установленного оборудования и его конфигурирование
5.5. Определение какие модули ядра загружены, их загрузка и выгрузка
5.6. Изменение на лету переменных ядра
5.7. Изучение состояния програмного RAID'а (mirror or stripe)
5.8. Определение какой MTA используется системой
5.9. Конфигурирование системы ведения системных журналов
5.10. Просмотр журналов для разрешения проблем и слежения за поведением системы
5.11. Понимание основных проблем с принтером
5.12. Создание или изменение почтовых псевдонимов в Sendmail и Postfix
5.13. Остановка, перезагрузка или перевод системы в однопользовательский режим
5.14. Отличие жёстких ограничений от мягких и изменение существующих системных ограничений
5.15. Знание утилит BSD для регулировки трафика и контроля за полосой пропускания
5.16. Знание распространённых конфигурационных системных файлов и,
возможно, сторонних конфигурационных файлов различных сервисов
5.17. Конфигурирование сервисов для автоматического старта при запуске системы
5.18. Конфигурирование скриптов, нужных для различных задач по обслуживанию системы, для периодического запуска
5.19. Просмотр очереди Sendmail'а или Postfix'а
5.20. Определение когда последний раз была запущена система и какова её загруженность
5.21. Слежение за операциями ввода/вывода на диске
5.22. Работа с занятыми устройствами
5.23. Определение информации характеризующей операционную систему
5.24. Понимание преимуществ использования лицензии BSDОписание: Кандидат BSDA должен уметь следить за работой процессов и заметить ненормально высокую загруженность CPU. Кандидат должен уметь завершить процесс или изменить его приоритет.
Практика: top(1), systat(1), ps(1), nice(1), renice(1), kill(1)
Описание:
Кандидат должен знать названия и номера наиболее употребляемых в
UNIX'е сигналов и знать как послать сигнал
активному процессу. Кандидат должен знать разницу между
SIGTERM и SIGKILL.
Практика: ps(1); kill(1); killall(1); pkill(1); pgrep(1)
Описание: В дополнении к тому, чтобы знать как непосредственно послать сигнал процессу, кандидат BSDA должен знать, что системы BSD поставляют скрипты, которые могут быть использованы для того, чтобы проверить состояние процесса, остановить, запустить или перезапустить процесс. Кандидат должен знать где в какой системе находятся эти скрипты. Эта тема не относится к OpenBSD.
Практика: rc(8), rc.conf(5)
Описание: Операционные системы BSD поставляются со множеством утилит для определения установленного оборудования. Кандидат BSDA должен знать как определить какое оборудование было обнаружено при загрузке и какие специфичные для BSD утилиты могут быть использованы для разрешения проблем и манипулирования PCI, ATA и устройствими SCSI.
Практика: dmesg(8), /var/run/dmesg.boot, pciconf(8), atacontrol(8) и camcontrol(8); atactl(8) и /kern/msgbuf; scsictl(8) или scsi(8)
Утилита dmesg(8) предназначена для вывода
на экран последних сообщений ядра. В процессе загрузки
операционной системы ядро определяет оборудование. Информация
об этом может быть найдена при помощи данной утилиты. Однако в
процессе работы системы информация помещённая в
dmesg(8) может быть вытеснена новыми
сообщениями ядра. Чтобы всегда иметь доступ к начальним,
«загрузочным» сообщениям ядра, мы можем обратиться к
файлу /var/run/dmesg.boot. Так же
сегодняшний и вчерашний журнал сообщений ядра можно найти в
файлах /var/log/dmesg.today и
/var/log/dmesg.yesterday соответственно.
Copyright (c) 1992-2008 The FreeBSD Project.
Copyright (c) 1979, 1980, 1983, 1986, 1988, 1989, 1991, 1992, 1993, 1994
The Regents of the University of California. All rights reserved.
FreeBSD is a registered trademark of The FreeBSD Foundation.
FreeBSD 7.0-RELEASE #0: Fri Feb 29 12:05:47 MSK 2008
root@ws-505-287.infosec.ru:/usr/obj/usr/src/sys/GENERIC
Timecounter "i8254" frequency 1193182 Hz quality 0
CPU: Intel(R) Celeron(R) CPU 2.40GHz (2394.01-MHz 686-class CPU)
Origin = "GenuineIntel" Id = 0xf34 Stepping = 4
Features=0xbfebfbff<FPU,VME,DE,PSE,TSC,MSR,PAE,MCE,CX8,APIC,SEP,MTRR,PGE,MCA,CMOV,PAT,PSE36,CLFLUSH,DTS,ACPI,MMX,FXSR,SSE,SSE2,SS,HTT,TM,PBE>
Features2=0x441d<SSE3,RSVD2,MON,DS_CPL,CNXT-ID,xTPR>
real memory = 502464512 (479 MB)
avail memory = 477736960 (455 MB)
ACPI APIC Table: <A M I OEMAPIC >
ioapic0 <Version 2.0> irqs 0-23 on motherboard
kbd1 at kbdmux0
kqemu version 0x00010300
kqemu: KQEMU installed, max_locked_mem=238924kB.
ath_hal: 0.9.20.3 (AR5210, AR5211, AR5212, RF5111, RF5112, RF2413, RF5413)
hptrr: HPT RocketRAID controller driver v1.1 (Feb 29 2008 12:05:13)
acpi0: <A M I OEMXSDT> on motherboard
acpi0: [ITHREAD]
acpi0: Power Button (fixed)
acpi0: reservation of 0, a0000 (3) failed
acpi0: reservation of 100000, 1def0000 (3) failed
Timecounter "ACPI-fast" frequency 3579545 Hz quality 1000
acpi_timer0: <24-bit timer at 3.579545MHz> port 0x808-0x80b on acpi0
cpu0: <ACPI CPU> on acpi0
p4tcc0: <CPU Frequency Thermal Control> on cpu0
pcib0: <ACPI Host-PCI bridge> port 0xcf8-0xcff on acpi0
pci0: <ACPI PCI bus> on pcib0
vgapci0: <VGA-compatible display> port 0xefe0-0xefe7 mem 0xf0000000-0xf7ffffff,0xfe780000-0xfe7fffff at device 2.0 on pci0
agp0: <Intel 82865G (865G GMCH) SVGA controller> on vgapci0
agp0: detected 32636k stolen memory
agp0: aperture size is 128M
uhci0: <Intel 82801EB (ICH5) USB controller USB-A> port 0xef00-0xef1f irq 16 at device 29.0 on pci0
uhci0: [GIANT-LOCKED]
uhci0: [ITHREAD]
usb0: <Intel 82801EB (ICH5) USB controller USB-A> on uhci0
usb0: USB revision 1.0
uhub0: <Intel UHCI root hub, class 9/0, rev 1.00/1.00, addr 1> on usb0
uhub0: 2 ports with 2 removable, self powered
uhci1: <Intel 82801EB (ICH5) USB controller USB-B> port 0xef20-0xef3f irq 19 at device 29.1 on pci0
uhci1: [GIANT-LOCKED]
uhci1: [ITHREAD]
usb1: <Intel 82801EB (ICH5) USB controller USB-B> on uhci1
usb1: USB revision 1.0
uhub1: <Intel UHCI root hub, class 9/0, rev 1.00/1.00, addr 1> on usb1
uhub1: 2 ports with 2 removable, self powered
uhci2: <Intel 82801EB (ICH5) USB controller USB-C> port 0xef40-0xef5f irq 18 at device 29.2 on pci0
uhci2: [GIANT-LOCKED]
uhci2: [ITHREAD]
usb2: <Intel 82801EB (ICH5) USB controller USB-C> on uhci2
usb2: USB revision 1.0
uhub2: <Intel UHCI root hub, class 9/0, rev 1.00/1.00, addr 1> on usb2
uhub2: 2 ports with 2 removable, self powered
uhci3: <Intel 82801EB (ICH5) USB controller USB-D> port 0xef80-0xef9f irq 16 at device 29.3 on pci0
uhci3: [GIANT-LOCKED]
uhci3: [ITHREAD]
usb3: <Intel 82801EB (ICH5) USB controller USB-D> on uhci3
usb3: USB revision 1.0
uhub3: <Intel UHCI root hub, class 9/0, rev 1.00/1.00, addr 1> on usb3
uhub3: 2 ports with 2 removable, self powered
ehci0: <Intel 82801EB/R (ICH5) USB 2.0 controller> mem 0xfe77bc00-0xfe77bfff irq 23 at device 29.7 on pci0
ehci0: [GIANT-LOCKED]
ehci0: [ITHREAD]
usb4: EHCI version 1.0
usb4: companion controllers, 2 ports each: usb0 usb1 usb2 usb3
usb4: <Intel 82801EB/R (ICH5) USB 2.0 controller> on ehci0
usb4: USB revision 2.0
uhub4: <Intel EHCI root hub, class 9/0, rev 2.00/1.00, addr 1> on usb4
uhub4: 8 ports with 8 removable, self powered
pcib1: <ACPI PCI-PCI bridge> at device 30.0 on pci0
pci1: <ACPI PCI bus> on pcib1
fxp0: <Intel 82801BA (D865) Pro/100 VE Ethernet> port 0xdf00-0xdf3f mem 0xfe5ff000-0xfe5fffff irq 20 at device 8.0 on pci1
miibus0: <MII bus> on fxp0
inphy0: <i82562ET 10/100 media interface> PHY 1 on miibus0
inphy0: 10baseT, 10baseT-FDX, 100baseTX, 100baseTX-FDX, auto
fxp0: Ethernet address: 00:11:d8:12:79:a8
fxp0: [ITHREAD]
isab0: <PCI-ISA bridge> at device 31.0 on pci0
isa0: <ISA bus> on isab0
atapci0: <Intel ICH5 UDMA100 controller> port 0x1f0-0x1f7,0x3f6,0x170-0x177,0x376,0xfc00-0xfc0f at device 31.1 on pci0
ata0: <ATA channel 0> on atapci0
ata0: [ITHREAD]
ata1: <ATA channel 1> on atapci0
ata1: [ITHREAD]
atapci1: <Intel ICH5 SATA150 controller> port 0xefa8-0xefaf,0xefa4-0xefa7,0xef68-0xef6f,0xefa0-0xefa3,0xeed0-0xeedf irq 18 at device 31.2 on pci0
atapci1: [ITHREAD]
ata2: <ATA channel 0> on atapci1
ata2: [ITHREAD]
ata3: <ATA channel 1> on atapci1
ata3: [ITHREAD]
pci0: <serial bus, SMBus> at device 31.3 (no driver attached)
pci0: <multimedia, audio> at device 31.5 (no driver attached)
acpi_button0: <Power Button> on acpi0
atkbdc0: <Keyboard controller (i8042)> port 0x60,0x64 irq 1 on acpi0
atkbd0: <AT Keyboard> irq 1 on atkbdc0
kbd0 at atkbd0
atkbd0: [GIANT-LOCKED]
atkbd0: [ITHREAD]
sio0: configured irq 4 not in bitmap of probed irqs 0
sio0: port may not be enabled
sio0: configured irq 4 not in bitmap of probed irqs 0
sio0: port may not be enabled
sio0: <16550A-compatible COM port> port 0x3f8-0x3ff irq 4 flags 0x10 on acpi0
sio0: type 16550A
sio0: [FILTER]
sio1: configured irq 3 not in bitmap of probed irqs 0
sio1: port may not be enabled
sio1: configured irq 3 not in bitmap of probed irqs 0
sio1: port may not be enabled
sio1: <16550A-compatible COM port> port 0x2f8-0x2ff irq 3 on acpi0
sio1: type 16550A
sio1: [FILTER]
fdc0: <floppy drive controller (FDE)> port 0x3f0-0x3f5,0x3f7 irq 6 drq 2 on acpi0
fdc0: [FILTER]
fd0: <1440-KB 3.5" drive> on fdc0 drive 0
pmtimer0 on isa0
ppc0: <Parallel port> at port 0x378-0x37f irq 7 on isa0
ppc0: SMC-like chipset (ECP/EPP/PS2/NIBBLE) in COMPATIBLE mode
ppc0: FIFO with 16/16/9 bytes threshold
ppbus0: <Parallel port bus> on ppc0
ppbus0: [ITHREAD]
plip0: <PLIP network interface> on ppbus0
lpt0: <Printer> on ppbus0
lpt0: Interrupt-driven port
ppi0: <Parallel I/O> on ppbus0
ppc0: [GIANT-LOCKED]
ppc0: [ITHREAD]
sc0: <System console> at flags 0x100 on isa0
sc0: VGA <16 virtual consoles, flags=0x300>
vga0: <Generic ISA VGA> at port 0x3c0-0x3df iomem 0xa0000-0xbffff on isa0
ums0: <vendor 0x1267 USB Mouse, class 0/0, rev 1.00/2.30, addr 2> on uhub1
ums0: 3 buttons and Z dir.
Timecounter "TSC" frequency 2394009873 Hz quality 800
Timecounters tick every 1.000 msec
hptrr: no controller detected.
acd0: CDROM <TEAC CD-552G/74S2> at ata0-master UDMA33
ad4: 76319MB <Seagate ST380817AS 3.42> at ata2-master SATA150
Trying to mount root from ufs:/dev/ad4s2a
Данный листинг показывает список устройств обнаруженных при старте системы. Каждая строка в этом листинге начинается с имени устройства с номером. Устройства в BSD называются по имени дрйвера, поэтому информацию о том или ином устройстве можно получить с соответствующей страницы man(1):
$ man 4 ums
Таким образом, можно получить детальную информацию о типе устройства и наборе чипсетов поддерживаемых подгруженным драйвером.
Описание: Кандидат BSDA должен понимать разницу между статически скомпилированным ядром и ядром использующим подгружаемые модули. Кандидат должен уметь просматривать список загруженных модулей, загружать и выгружать модули, однако он должен знать, что в системах NetBSD и OpenBSD использование модулей ядра не одобряется.
Практика: kldstat(8), kldload(8),
kldunload(8), и
loader.conf(5); modstat(8),
modload(8), modunload(8), и
lkm.conf(5)
Описание: Системы BSD используют переменные ядра MIB, что позволяет системному администратору просматривать и изменять состояние ядра на работающей системе. Кандидат должен уметь изменять эти переменные как на лету во время работы системы, так и постоянно, выставляя начальные значения действующие в момент загрузки системы. Кандидат должен понимать как изменить переменную MIB доступную только для чтения.
Практика: sysctl(8), sysctl.conf(5)
Описание: В дополнении к тому, что системы BSD предоставляют драйвера к аппаратным RAID контроллерам, BSD предоставляет встроенный програмный RAID. Кандидат должен знать разницу между RAID уровня 0, 1, 3 и 5 и какие утилиты доступны в различных системах BSD для конфигурирования програмного RAID'а.
Практика: vinum(8), gmirror(8), gstripe(8), graid3(8), raidctl(8), ccdconfig(8)
Описание: Кандидат BSDA должен понимать роль MTA, определять какой(ие) MTA доступен(ны) во время установки системы, какой конфигурационный файл указывает на то, какой MTA используется системой. Кандидат должен знать разницу между форматами хранения почты mailbox и maildir.
Практика: mailer.conf
Описание: Кандидат BSDA должен знать, что система автоматически создаёт и манипулирует множеством журнальных файлов. Кандидат должен уметь настраивать ротацию журнальных файлов по времени или размеру, понимать термины «средство» и «важность», смотреть сжатые журнальные файлы. (К сожалению, в русском языке закрепилась традиция перевода термина syslog facilities как средства syslog. Перевод крайне неудачный, но такова традиция — прим. переводчика.)
Практика: newsyslog(8),
newsyslog.conf(5),
syslog.conf(5), zmore(1),
bzcat(1)
Описание: Кандидат должен знать насколько важно регулярно просматривать журнальные файлы и как просматривать их во время решения проблем.
Практика: tail(1), /var/log/*,
syslog.conf(5), grep(1),
dmesg(8)
Описание:
Кандидат BSDA должен уметь просмотреть очередь печати и
манипулировать заданиями в очереди. Кандидат должен понимать
значение первых двух полей в файле
/etc/printcap.
Практика: lpc(8), lpq(1),
lprm(1), printcap(5)
Описание: Кандидат BSDA должен понимать когда надо создать почтовый псевдоним (алиас) и как это сделать в Sendmail и в Postfix
Практика: newaliases(1), aliases(5),
postaliases(1)
Описание: Кандидат BSDA должен понимать последствия связанные с остановкой, перезагрузкой ли переводом системы в однопользовательский режим, понимать когда это необходимо и как минимизировать при этом воздействие на сервер.
Практика: shutdown(8)
Описание: Кандидат должен понимать, что ограничения ресурсов наследуются от оболочки и уметь изменять их постоянно или временно. Кандидат должен понимать разницу между мягким и жёстким ограничением.
Практика: limit(1), limits(1),
login.conf(5), sysctl(8)
на NetBSD
Описание: Кандидат должен понимать когда следует создать политики для контроля ширины полосы пропускания для доступа к некоторым сервисам. Кандидат должен знать какие средства доступны для контроля ширины полос пропускания.
Практика: ipfw(8), altq(4), dummynet(4), altq(9),
altqd(8), altq.conf(5)
Описание: Системы BSD часто используют для предоставления услуг Интернет. Кандидата BSDA могут попросить найти, рассмотреть и сделать какие-нибудь изменения в конфигурационных файлах каких-нибудь сервисов. Кандидат должен знать как называются конфигурационные файлы и с какими они связаны сервисами.
Практика: httpd.conf(5),
sendmail.cf, master.cf,
dhcpd.conf(5),
named.conf(5), smb.conf(5)
Описание: Кандидат BSDA должен знать, что в процессе загрузки BSD не используются уровни запуска (runlevels из SystemV — примечание переводчика). Для того, чтобы минимизировать воздействие на систему перезагрузок, кандидат должен уметь сконфигурировать систему так, чтобы сервисы стартовали при загрузке системы автоматически. Причём сделать это надо собственными средствами BSD.
Практика: rc.conf(5), rc(8),
inetd(8)
Описание: Системы BSD предоставляют множество скриптов для управления и проверки системы. Если требуется, кандидат BSDA должен уметь найти эти скрипты и запустить вручную, а так же уметь сделать так, чтобы они запускались регулярно раз в день, еженедельно, ежемесячно, на любой системе BSD.
Практика: periodic.conf(5) и
periodic(8) на
DragonFly BSD и
FreeBSD; security.conf(5),
daily.conf(5),
weekly.conf(5) и
monthly.conf(5) на NetBSD;
daily(8), weekly(8) и
monthly(8) на OpenBSD
Описание: Кандидат BSDA должен уметь просмотреть почтовую очередь, чтобы определить какое письмо застряло. Если необходимо, надо уметь заставить MTA заново обработать почту, или очистить её.
Практика: mailq(1), postqueue(1)
Описание: Кандидат BSDA должен уметь определить загруженность системы за последнюю минуту, 5 и 15 минут, а так же время прошедшее с последней перезагрузки.
Практика: uptime(1), w(1), top(1)
Описание: Операции ввода/вывода на диске сильно влияют на производительность системы. Кандидат BSDA должен знать какие утилиты доступны на системах BSD для контроля за операциями дискового ввода/вывода и как интерпретировать их результаты.
Практика: iostat(8), stat(1), vmstat(1), nfsstat(1)
Описание: Кандидат BSDA должен понимать что может вызвать зависание процесса, как обнаружить такой процесс и что делать в сложившейся ситуации.
Практика: ps(1), fstat(1), kill(1), umount(8) и сторонняя утилита lsof(8)
Описание: Кандидат BSDA должен уметь определить тип и версию установленной операционной системы.
Практика: uname(1), sysctl(1);
/etc/release на NetBSD.
Содержание
6.1. Определение существующих установок TCP/IP
6.2. Установка параметров TCP/IP
6.3. Определение какие TCP или UDP порты открыты в системе
6.4. Проверка доступности TCP/IP сервиса
6.5. Запрос к серверу DNS
6.6. Определение кто ответственный за зону DNS
6.7. Изменение порядка разрешения имён
6.8. Перевод сетевой маски между системами точечно-десятичной, точечно-шестнадцатеричной или CIDR
6.9. Собирать информацию используя IP адрес и маску подсети
6.10. Понимание теории адресации IPV6
6.11. Демонстрация основных навыков работы с утилитой
tcpdump(1)
6.12. Работа с ARP и кешем найденных соседей
6.13. Конфигурирование системы для использования NTP
6.14. Просмотр и обновление «арендованных» данных DHCP
6.15. Знание как и когда устанавливать или удалять алиасы сетевого интерфейса
В данной главе содержится краткий материал изложенный в стиле «шпаргалки». Более систематично вопросы работы сети обсуждаются в Приложение B, Некоторые сведения о стеке протоколов TCP/IP. Предполагается, что содержание данной главы будет полезно тем, кто овладел материалом изложенным в указанном приложении.
Описание. Кандидат BSDA должен уметь определить IP адреса системы, маску подсети, шлюз, первичный и вторичный сервер DNS и имя хоста.
Практика. ifconfig(8), netstat(1),
resolv.conf(5), route(8),
hostname(1)
Итак, в этом разделе речь идёт не о настройке сети, а лишь об определении текущих настроек. Разберёмся в возможностях упомянутых здесь утилит.
Во имя целостности повествования мы выйдем за рамки задач поставленных в экзаменационном билете. Надеюсь читатель не останется внакладе.
Утилита ifconfig(8) предназначена для настройки сетевых интерфейсов и диагностики текущих настроек. Как мы и договаривались, в данном разделе мы изучаем только возможности по диагностике, а настройкой займёмся в другом разделе (См. Раздел 6.2.2, «ifconfig(8) — настройки сетевых интерфейсов»).
MAC-адрес (он же hardware address);
IP-адрес;
IPv6-адрес;
Вот пример того, как может выглядеть вывод команды ifconfig(8):
$ifconfig -arl0:
flags=8802<BROADCAST,SIMPLEX,MULTICAST> mtu 1500
options=8<VLAN_MTU>
inet xxx.yyy.zzz.180 netmask 0xffffff80 broadcast xxx.yyy.zzz.255
ether 00:80:48:2d:f7:15
media: Ethernet autoselect (100baseTX <full-duplex>)
status: active
rl1: flags=8843<UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST> mtu 1500 options=8<VLAN_MTU> inet 172.16.0.1 netmask 0xfffffffc broadcast 172.16.0.3 inet 192.168.0.1 netmask 0xffffff00 broadcast 192.168.0.255
ether 4c:00:10:13:15:1d media: Ethernet autoselect (100baseTX <full-duplex>) status: active pflog0: flags=141<UP,RUNNING,PROMISC> mtu 33208
pfsync0: flags=0<> mtu 2020 lp0: flags=8851<UP,POINTOPOINT,RUNNING,SIMPLEX,MULTICAST> mtu 1500
inet 10.0.0.1 --> 10.0.0.2 netmask 0xff000000 lo0: flags=8049<UP,LOOPBACK,RUNNING,MULTICAST> mtu 16384
inet 127.0.0.1 netmask 0xff000000
|
Команде ifconfig(8) необходимо указать по
каким интерфейсам она должна вывести сведения. Если вместо
этого указать аргумент -a будут выведены
сведения обо всех интерфейсах, с опцией -u
только об интерфейсах активных в данный момент, точнее об
интерфейсах с установленным флагом UP (в данном случае rl1,
pflog0 и lo0). В NetBSD и
OpenBSD флаг -u
отстутствует. В FreeBSD интерфейс
указывать необязательно: если вы вызываете
ifconfig(8) без аргументов, по умолчанию
подразумевается ключ -a. В
NetBSD и OpenBSD
обязательно надо указать или интерфейс или ключ
-a.
|
| Указание на то, что следующий абзац относится к интерфейсу rl0. Специально для поклонников Linux отметим: в BSD принято называть интерфейсы по именам отвечающих за них драйверов. За сетевые карты на чипсете RealTek отвечает драйвер rl(4). Узнать о специфических настройках для устройств на остове этого чипсета можно из справочной страницы man 4 rl. |
| Флаги в угловых скобках подробно описаны ниже. В них собрана информация о возможностях интерфейса и текущем режиме его работы. mtu — maximum transfer unit в байтах. |
| |
| Характеристики интерфейса на сетевом уровне: IP-адрес, маска подсети и широковещательный адрес. Характреристики в адресном пространстве IPv6 сообщаются отдельной строкой и здесь непоказаны. |
| Аппаратный адрес (он же MAC-адрес) устройства. (Канальный уровень.) |
| media — характеристики передающей среды (физический уровень). Ethernet autoselect — скорость обмена данными автоматически определяется при взаимодействии с устройством на противоположном конце провода, выбирается наивысшая скорость из поддерживаемых обоими устройствами, если среда не поддерживает сигнал на этой скорости (например сопротивление в проводе слишком большое) а оба устройства договорились о передаче на большой скорости, необходимо хотя бы одно из них вручную перевести на более низкую скорость передачи данных; 100baseTX: 100 — выбрана скорость передачи данных 100 Мб/сек, base — для передачи используется вся частотная полоса (у ADSL-модема это не так: он может одновременно на одной частоте передавать обычный телефонный сигнал, а на другой интернет-трафик), TX — для передачи используется витая пара (twisted pair); full-duplex — возможна одновременная передача данных в обе стороны, если это не так, будет написано half-duplex. |
| Физическая характеристика — наличие несущей в проводе. Возможные значения active или no carrier. В последнем случае, это значит, что провод вышел из гнезда, или его разорвал экскаватор, или прибор с той стророны выключен. |
| Здесь показан пример того, как выглядит конфигурация интерфейса, когда на нём поднято одновременно несколько IP-адресов (алиасов). В Linux в этом случае заводится новое устройство (например в дополнение к интерфейсу eth0 появляется eth0:0, eth0:1 и т.д.), что в ряде случаев бывает удобно. Так, если мы какому-нибудь сервису предписываем посылать пакеты через интерфейс rl1 неочевидно какой IP он будет использовать. |
| Это пример виртуального интерфейса. Данный интерфейс используется пакетным фильтром OpenBSD — pf(4). (В настоящий момент данный брандмауэр используется не только в OpenBSD, но так же и в FreeBSD начиная с версии 5.3 и в NetBSD.) |
| Это параллельный порт сконфигурированный для связи типа точка-точка. |
| И, наконец, кольцевой интерфейс. |
Флаги сетевых интерфейсов (информацию о некоторых флагах можно получить из девятой страницы man(1), см. ifnet(9). Более полно флаги описаны в книге [McKusick-2004]):
-u,
мы выводим информацию именно об интерфейсах с этим флагом.
Здесь упомянуты не все возможные флаги, а лишь флаги упомянутые в [McKusick-2004]. В [Stevens-2003-ru] можно найти упоминание других флагов, например NOTRAILERS — управление концевой инкапсуляцией при формировании кадра из пакета. Полный обозор флагов не входит в наши цели.
Каждый флаг это некоторый бит в числе характеризующем состояние интерфейса. Это число приведено перед списком флагов в угловых скобках В ШЕСТНАДЦАТЕРИЧНОМ представлении. Так число 8843 переводится в двоичную систему как 1000100001000011 и означает набор флагов <UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST>. Здесь за флаг UP отвечает самый правый бит, BROADCAST — второй справа, RUNNING — 7-й справа. Переключая флаги нетрудно вычислить какой бит чему соответствует. Легко видеть, что для того, чтобы интерфейс работал, необходимо (но недостаточно), чтобы число было нечётным.
Некоторые флаги поддерживаются не во всех операционных системах, что связано, возможно (это мои домыслы), с разрядностью числа характеризующего состояние сетевого интерфейса в них. Так флаг STATICARP (20-й бит справа) есть только в FreeBSD и отсутствует в OpenBSD и NetBSD. То же относится к флагу MONITOR (19-й бит).
Утилита netstat(1) предназначена для диагностики работы TCP/IP стека. Она выводит разнообразную информацию о работе сетевых интерфейсов на сетевом и транспортном уровнях:
$ netstat -nr
Routing tables
Internet:
Destination Gateway Flags Refs Use Netif Expire
default xxx.yyy.zzz.254 UGS 0 1056785 rl0
127.0.0.1 127.0.0.1 UH 0 39839 lo0
172.16/30 link#2 UC 0 0 rl1
172.16.0.2 4c:00:10:54:dd:8e UHLW 0 30428 rl1 1045
xxx.yyy.zzz.128/25 link#1 UC 0 0 rl0
xxx.yyy.zzz.254 00:50:8b:5c:98:4f UHLW 1 1888 rl0 1189
Аргумент -r заставил команду
netstat(1) напечатать таблицу маршрутизации,
а -n заставил не заменять IP-адреса хостов на
их имена.
Рассмотрение этой таблицы начнём с третьего столбца: флаги. Мы видим, что во всех строках стоит флаг U, это значит, что все марршруты в настоящий момент активны (Up). В строках посвящённых адресам 127.0.0.1, 172.16.0.2 и xxx.yyy.zzz.254 имеется флаг H, это значит, что данный адрес относится не к сети, а к хосту (Host). Такие маршруты имеют приоритет перед маршрутом к сети, таким образом, мы можем жёстко прописать маршрут к некоторой машине, даже если маршрут к сети в которой она находится — иной. Флаг G означает, что данная машина является шлюзом, поэтому при обращении к ней надо при инкапсулировании пакета в кадр заменить MAC-адрес машины которой предназначен пакет, на MAC-адрес шлюза (если MAC-адрес назначения почему-то известен). Дальнейшей маршрутизацией этого пакета будет заниматься шлюз. В данном разделе мы не обсуждаем вопрос откуда берутся маршруты.
Итак, пусть у нас есть три пакета, первый предназначен машине 172.16.0.2, второй xxx.yyy.zzz.200 и третий xxx.yyy.zzz.100.
Для первого пакета машина сразу находит запись с флагом H, понимает, что его надо отправить через интерфейс rl1, формирует Ethernet-кадр дописывая к IP пакету MAC-адрес машины 172.16.0.2 (4c:00:10:54:dd:8e) и интерфейса rl1 и отправляет пакет.
Для второго пакета запись в таблице маршрутизации с флагом H ненайдена, но найдена сеть xxx.yyy.zzz.128/25, которой принадлежит машина xxx.yyy.zzz.200. Флаг G отсутствует, поэтому формируется кадр с MAC адресом получающей стороны, и MAC-адресом интерфейса rl0. В таком виде кадр отсылается с интерфейса rl0.
Для третьего пакета, увы не найдено никаких маршрутов — хост xxx.yyy.zzz.100 машине неизвестен и ни одной сети он не принадлежит. Поэтому он направляется на маршрут по умолчанию — default xxx.yyy.zzz.254. Этот маршрут помечен флагом G, поэтому даже если мы знаем MAC-адрес получателя, что маловероятно, но вполне реально, мы заменяем его на MAC-адрес шлюза xxx.yyy.zzz.254 (00:50:8b:5c:98:4f), дописываем MAC-адрес интерфейса rl0 и отсылаем, в надежде на то, что шлюз знает что делать с этим пакетом.
В колонке «Use»сказано сколько пакетов прошло по тому или иному маршруту.
Маршрут действует в течение некоторого периода времени, после которого он должен быть или выброшен из таблицы маршрутизации или продлён. Оставшееся время жизни маршрута указывается в колонке «Expire» в секундах.
$netstat -ni
Name Mtu Network Address Ipkts Ierrs Opkts Oerrs Coll
rl0 1500 <Link#1> 00:80:48:2d:f7:15 51129385 0 1081628 0 0
rl0 1500 xxx.yyy.zzz.1 xxx.yyy.zzz.180 459392 - 421556 - -
rl1 1500 <Link#2> 4c:00:10:13:15:1d 4116747 0 7617322 1 0
rl1 1500 172.16/30 172.16.0.1 1604297 - 6705688 - -
pflog 33208 <Link#3> 0 0 0 0 0
pfsyn 2020 <Link#4> 0 0 0 0 0
lo0 16384 <Link#5> 39988 0 39988 0 0
lo0 16384 your-net 127.0.0.1 39863 - 39863 - -
Как и раньше, аргумент -n подавляет раскрытие
адресов в имена. Из этой таблицы мы можем определить сколько
пакетов было передано через тот или иной сетевой интерфейс в
ту или иную стророну. Чтобы измерить трафик в байтах можно
добавить ещё два аргумента: -b чтобы выводить
информацию в байтах и -d чтобы сообщать об отброшенных
(droped) пакетах:
$ netstat -nibd
Name Mtu Network Address Ipkts Ierrs Ibytes Opkts Oerrs Obytes Coll Drop
rl0 1500 <Link#1> 00:80:48:2d:f7:15 51141983 0 1282650574 1082806 0 221186433 0 0
rl0 1500 xxx.yyy.zzz.1 xxx.yyy.zzz.180 459467 - 295420865 421634 - 136159516 - -
rl1 1500 <Link#2> 4c:00:10:13:15:1d 4117877 0 3436868162 7618633 1 1263505336 0 0
rl1 1500 172.16/30 172.16.0.1 1604327 - 3270648640 6705718 - 168875424 - -
pflog 33208 <Link#3> 0 0 0 0 0 0 0 0
pfsyn 2020 <Link#4> 0 0 0 0 0 0 0 0
lo0 16384 <Link#5> 39992 0 4836343 39992 0 4836343 0 0
lo0 16384 127 127.0.0.1 39867 - 4803206 39867 - 4803206 - -
Итак, через интерфейс rl0 на машину с MAC-адресом 00:80:48:2d:f7:15 (как мы видели раньше, это шлюз) прошло наружу 1082806 пакетов, или 221186433 байт. В обратном направлении пришло 51141983 пакета или 1282650574 байт.
Обратите так же внимание на столбец «Coll» — это счётчик коллизий. В сетях Ethernet 10BaseTX, 100BaseTX и 1000BaseTX, построенных на коммутаторах, а не повторителях (на свитчах, а не на хабах), в принципе не может быть никаких коллизий, так как домен коллизий сводится всего к двум машинам благодаря коммутации на канальном уровне, а две машины не могут совершить коллизию, так как они соединены многожильным кабелем и TX/RX сигналы разнесены по разным парам проводов.
Мы можем смотреть как меняется статистика во времени. Если мы
укажем команде netstat(1) в аргументе
-w период обновления в секундах.
$ netstat -w2
input (Total) output
packets errs bytes packets errs bytes colls
51 0 4077 1 0 178 0
46 0 3676 1 0 178 0
49 0 3794 1 0 178 0
51 0 3779 1 0 178 0
^C
Здесь программа netstat(1) каждые две секунды отчитывается о том, сколько пакетов и байт входит в машину через все интерфесы вместе.
Запустив в фоновом режиме утилиту ping(8), посылающую ICMP-пакеты через интерфейс rl1, мы можем видеть эти пакеты командой netstat(1)
$ping 172.16.0.2 > /dev/null &$netstat -w2 -I rl1 input (rl1) output packets errs bytes packets errs bytes colls 2 0 196 2 0 196 0 2 0 196 2 0 196 0 2 0 196 2 0 196 0 2 0 196 2 0 196 0 ^C$fg ping 172.16.0.2 > /dev/null ^C
Утилита ping(8) посылает пакеты раз в
секунду, поэтому netstat(1) с опцией
-w2, добавляя по строке раз в две секунды,
каждый раз видит по 2 пакета.
![]() | Замечание |
|---|---|
| Аналогичную информацию можно получить так же при помощи программы sockstat(1). См Раздел 6.3.2, «sockstat(1)» |
При запуске утилиты netstat(1) без каких
либо аргументов, можно получить информацию об открытых
сокетах. Мы запустим утилиту как всегда с опцией
-n с тем, чтобы адреса не преобразовывались в
имена, и номера сервисов тоже были бы представлены числами:
$netstat -n Active Internet connections Proto Recv-Q Send-Q Local Address Foreign Address (state) tcp4 0 52 194.87.141.180.22 62.117.108.7.1833 ESTABLISHEDtcp4 0 0 194.87.141.180.22 62.117.108.7.64544 ESTABLISHED tcp4 0 0 172.16.0.1.53882 172.16.0.2.22 ESTABLISHED tcp4 0 0 194.87.141.180.22 62.117.108.7.64344 ESTABLISHED tcp4 0 0 194.87.141.180.22 62.117.108.7.64286 ESTABLISHED tcp4 0 0 194.87.141.180.22 62.117.108.7.64242 ESTABLISHED udp4 0 0 127.0.0.1.123 *.*
udp4 0 0 172.16.0.1.123 *.* udp4 0 0 194.87.141.180.123 *.* udp4 0 0 127.0.0.1.53 *.* udp4 0 0 172.16.0.1.53 *.* udp4 0 0 194.87.141.180.53 *.* udp4 0 0 172.16.0.1.706 172.16.0.2.2049
udp4 0 0 172.16.0.1.743 172.16.0.2.2049 udp4 0 0 172.16.0.1.690 172.16.0.2.2049 udp4 0 0 172.16.0.1.633 172.16.0.2.2049 udp4 0 0 172.16.0.1.701 172.16.0.2.2049 udp4 0 0 172.16.0.1.887 172.16.0.2.2049 udp4 0 0 172.16.0.1.991 172.16.0.2.2049 udp4 0 0 172.16.0.1.852 172.16.0.2.2049 Active UNIX domain sockets Address Type Recv-Q Send-Q Inode Conn Refs Nextref Addr c10897a8 stream 0 0 0 c1089af0 0 0 c1089af0 stream 0 0 0 c10897a8 0 0 c10892bc stream 0 0 0 c10899d8 0 0 c10899d8 stream 0 0 0 c10892bc 0 0 c10888c0 stream 0 0 0 c1089ec4 0 0 c1089ec4 stream 0 0 0 c10888c0 0 0 c108971c stream 0 0 0 c1088af0 0 0 c1088af0 stream 0 0 0 c108971c 0 0 c1089834 stream 0 0 0 c10894ec 0 0 c10894ec stream 0 0 0 c1089834 0 0 c1088834 stream 0 0 0 c1089a64 0 0 /var/run/dovecot/login/default
c1089a64 stream 0 0 0 c1088834 0 0 c1089c94 stream 0 0 0 c1089604 0 0 c1089604 stream 0 0 0 c1089c94 0 0 c1089e38 stream 0 0 0 c10887a8 0 0 /var/run/dovecot/login/default c10887a8 stream 0 0 0 c1089e38 0 0 c1089460 stream 0 0 0 c10891a4 0 0 c10891a4 stream 0 0 0 c1089460 0 0 c1209000 stream 0 0 0 c108894c 0 0 /var/run/dovecot/login/default c108894c stream 0 0 0 c1209000 0 0 c108994c stream 0 0 0 c108871c 0 0 c108871c stream 0 0 0 c108994c 0 0 c10893d4 stream 0 0 c1867738 0 0 0 /var/run/dovecot/auth-worker.53422 c1088a64 stream 0 0 0 c1089118 0 0 c1089118 stream 0 0 0 c1088a64 0 0 c1209118 stream 0 0 c1ac0c60 0 0 0 /var/run/dovecot/login/default c1089b7c stream 0 0 c138f738 0 0 0 /tmp/mysql.sock c1089d20 stream 0 0 c11fed68 0 0 0 /var/run/cgisock.536 c10882bc stream 0 0 0 c1088230 0 0 c1088230 stream 0 0 0 c10882bc 0 0 c108808c stream 0 0 0 c1088000 0 0 c1088000 stream 0 0 0 c108808c 0 0 c1088c08 stream 0 0 c10b4a50 0 0 0 /var/run/rpcbind.sock c1089000 stream 0 0 c1078d68 0 0 0 /var/run/devd.pipe c10883d4 dgram 0 0 0 c1088e38 0 c1089348 c1089348 dgram 0 0 0 c1088e38 0 c1088460 c10884ec dgram 0 0 0 c1088dac 0 0 c1088460 dgram 0 0 0 c1088e38 0 c1088348 c1088348 dgram 0 0 0 c1088e38 0 c10881a4 c10881a4 dgram 0 0 0 c1088e38 0 c1088118 c1088118 dgram 0 0 0 c1088e38 0 c1088604 c1088604 dgram 0 0 0 c1088e38 0 c1088b7c c1088b7c dgram 0 0 0 c1088e38 0 c1088c94 c1088c94 dgram 0 0 0 c1088e38 0 0 c1088d20 dgram 0 0 c108a108 0 0 0 /var/named/var/run/log c1088dac dgram 0 0 c108a210 0 c10884ec 0 /var/run/log c1088e38 dgram 0 0 c108a318 0 c10883d4 0 /var/run/logpriv c1088ec4 dgram 0 0 c1078210 0 0 0 /var/run/log
Отчёт команды netstat(1) состоит из двух частей: в первой перечислены открытые в настоящий момент соединения интернет, а во второй перечислены используемые системой сокеты.
Программа netstat(1) выводит сведения о состоянии TCP (см. флаг ESTABLISHED выше), согласно [RFC-793]. Что такое «состояние TCP» и какие они бывают, мы описываем в Раздел B.1.4.3.4, «Состояние соединения TCP». Подробное обсуждение этой темы можно найти в [Stevens-2003-ru].
При помощи флага -a можно получить информацию
обо всех сокетах, в том числе пребывающих в состоянии LISTEN.
# netstat -na | grep LISTEN
tcp4 0 0 *.587 *.* LISTEN
tcp4 0 0 *.25 *.* LISTEN
tcp4 0 0 *.22 *.* LISTEN
tcp4 0 0 *.80 *.* LISTEN
tcp4 0 0 *.143 *.* LISTEN
tcp4 0 0 *.965 *.* LISTEN
tcp4 0 0 *.2049 *.* LISTEN
tcp4 0 0 *.701 *.* LISTEN
tcp4 0 0 *.730 *.* LISTEN
tcp4 0 0 *.111 *.* LISTEN
tcp4 0 0 127.0.0.1.953 *.* LISTEN
tcp4 0 0 127.0.0.1.53 *.* LISTEN
tcp4 0 0 172.19.0.2.53 *.* LISTEN
Таким образом, можно узнать какие порты прослушиваются нашей машиной.
Видимо необходимо некоторое пояснение к термину «состояние сокета». Рассмотрим как осуществляется открытие и закрытие соединения TCP:
Пусть клиент открывает соединение с сервером. Тогда говорят, что клиент осуществляет активное открытие соединения, а сервер пассивное открытие соединения. Изначально сервер находится в состоянии LISTEN.
Теперь стороны могут обмениваться данными в обе стороны, в состоянии ESTABLISHED, обе стороны высылают друг другу пакеты с данными, время от времени присылая подтверждения о получении этих пакетов, причём в одном подтверждении может подтверждаться получение большого числа пакетов.
Процесс открытия соединения часто называется тройным рукопожатием, так как происходит обмен тремя пакетами в обеих направлениях. (См. так же Раздел B.1.4.3.2, «Открытие соединения TCP, тройное рукопожатие».)
Пусть клиент закрывает соединение с сервером. Тогда говорят, что клиент выполняет активное закрытие, а сервер пассивное закрытие. Изначально оба хоста пребывают в состоянии ESTABLISHED.
Утилита route(8) больше предназначена для управления таблицей маршрутизации, однако с её помощью тоже можно получить некоторую диагностическую информацию. Допустим нам надо узнать маршрут к машине с адресом 192.168.3.4
$ route get 192.168.3.4
route to: 192.168.3.4
destination: default
mask: default
gateway: xxx.yyy.zzz.254
interface: rl0
flags: <UP,GATEWAY,DONE,STATIC>
recvpipe sendpipe ssthresh rtt,msec rttvar hopcount mtu expire
0 0 0 0 0 0 1500 0
В NetBSD и OpenBSD есть так же команда show, которая заставляет route(8) распечатать таблицу маршрутизации целиком, подобно netstat -r:
$ route -n show
Routing tables
Internet:
Destination Gateway Flags
default ************** UG
127.0.0.0 localhost UG
************** localhost UGH
192.168.26.0 link#1 U
************** 0:10:e0:0:e9:cd UH
192.168.26.2 0:10:e0:0:7c:46 UH
192.168.26.7 0:e:a6:66:2d:c5 UH
BASE-ADDRESS.MCA localhost U
Internet6:
Destination Gateway Flags
default ****************** UG
default ****************** UG
**************** ****************** UH
::127.0.0.0 ****************** UG
::224.0.0.0 ****************** UG
::255.0.0.0 ****************** UG
::ffff:0.0.0.0 ****************** UG
2002:: ****************** UG
2002:7f00:: ****************** UG
2002:e000:: ****************** UG
2002:ff00:: ****************** UG
fe80:: ****************** UG
fe80::%le0 link#1 U
fe80::%lo0 fe80::1%lo0 U
fec0:: ****************** UG
ff01:: ****************** U
ff02::%le0 link#1 U
ff02::%lo0 fe80::1%lo0 U
При помощи команды route monitor можно следить за изменениями маршрутной таблицы в реальном времени.
Когда машине надо обратиться к некоторому адресу в интернет, она
должна преобразовать символьное имя машины (такое, как
example.ru), в IP (или IPv6) адрес. Осуществляется это при
помощи библиотечной функции gethostbyname(3). Типичное поведение
этой функции выглядит так: 1) изучается файл
/etc/hosts в котором перечислено какие
имена соответствуют некоторым адресам; 2) затем, если поиск не
дал результатов, при помощи resolver(3)'а осуществляются запросы
к серверам DNS. На порядок этих действий можно влиять при помощи
файла /etc/nsswitch.conf, это описано в
Раздел 6.7, «Изменение порядка разрешения имён».
За работу resolver'а отвечает настроечный файл
/etc/resolv.conf. Вот его мы и рассмотрим в
данном разделе.
Файл /etc/resolv.conf является настроечным
файлом для клиентской части системы DNS —
resolver'а. Синтаксис файла предельно прост: в нём перечисляются
DNS сервера в порядке убывания приоритета. Перед IP адресом
сервера DNS указывается ключевое слово nameserver.
nameserver 127.0.0.1
nameserver 192.168.0.1
search somewhere.ru ru ua org
Здесь сказано, что для разрешения имён в IP-адреса, нужно сперва обратиться к локальной машине (предполагается, что на ней запущен свой собственный named(8)), а если обратиться к нему неудастся (если он не запущен), обратиться к DNS на машине 192.168.0.1. Здесь сервер DNS на машине 127.0.0.1 называется первичным DNS-сервером (primary), а 192.168.0.1 — вторичным (secondary). Обратите внимание: если первичный сервер DNS не сможет разрешить имя, он вернёт отрицательный ответ и запрос к вторичному серверу выполнен не будет (ведь ответ пришёл, просто он отрицательный).
resolver использует для работы первые три сервера DNS.
Допустим, мы хотим разрешить имя host, а в нашем файле
/etc/resolv.conf имеются только записи типа
nameserver. В этом случае resolver попытается найти машину
host., такой машины конечно же нет, следующее действие
resolver'а будет таким: он возьмёт имя домена в котором
находится наша машина и допишет этот домен. Если наша машина
имеет имя client.somewhere.ru, то resolver попытается разрешить
имя host.somewhere.ru.
На это поведение можно влиять двумя способами: 1) с помощью директивы domain указать какой-нибудь другой домен и тогда поиск будет осуществляться в нём.
2) при помощи директивы search явно перечислить через пробел домены в которых следует производить поиск, как это показано в листинге выше. В нашем примере если resolver не сможет разрешить имя host, то он допишет к нему домен «somewhere.ru» и попробует разрешить имя host.somewhere.ru, затем будет осуществлена попытка разрешить имя host.ru, host.ua и host.org:
$host -v host Trying domain "somewhere.ru"rcode = 3 (Non-existent domain), ancount=0 Trying domain "ru"
rcode = 0 (Success), ancount=1 The following answer is not authoritative: The following answer is not verified as authentic by the server: host.ru 1800 IN A 195.2.70.38 For authoritative answers, see: host.ru 1800 IN NS dns1.zenon.net host.ru 1800 IN NS dns2.zenon.net Additional information: dns1.zenon.net 1412 IN A 195.2.64.38 dns2.zenon.net 1412 IN A 195.2.83.38
| Здесь осуществлена попытка разрешить имя host.somewhere.ru. Эта попытка завершилась неудачей — такого хоста нет. |
| Теперь система пытается разрешить имя host.ru. Такое имя существует, машина с этим именем имеет IP 195.2.70.38, за неё отвечает два сервера DNS: dns1.zenon.net и dns2.zenon.net с IP адресами 195.2.64.38 и 195.2.83.38. (Про команду host(1) мы будем говорить в Раздел 6.5, «Запрос к серверу DNS».) |
Попробуем обнаружить машину соответствующую озеру Леприндо, расположенному в Читинской области на БАМе у подножия горного массива Кодар:
$ host -v leprindo
Trying domain "somewhere.ru"
rcode = 3 (Non-existent domain), ancount=0
Trying domain "ru"
rcode = 3 (Non-existent domain), ancount=0
Trying domain "ua"
rcode = 3 (Non-existent domain), ancount=0
Trying domain "org"
rcode = 3 (Non-existent domain), ancount=0
Host not found.
Как видим, resolver выполнил 4 запроса к DNS, попытавшись обнаружить машины leprindo.somewhere.ru, leprindo.ru, leprindo.ua и leprindo.org, и потерпел неудачу.
Наконец, в этом файле можно задавать некоторые опции. Следующая строка во-первых, включает режим отладки, а во-вторых объявляет, что надо пытаться разрешить имя при помощи списка из директивы search, если в нём менее 2-х точек (а не одной, как по умолчанию). Т.е. по умолчанию, если в имени нет точек, то оно сперва ищется в списке доменов из директивы search, а со включённой ниже опцией это поведение распространяется на имена содержащие одну точку.
options debug ndots:2
После редактирования файла /etc/resolv.conf
никаких специальных действий не требуется, изменения немедленно
вступают в силу.
Описание. Кандидат должен уметь изменять настройки 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», но на этот раз с точки зрения управления параметрами. Как и в прошлый раз, мы выйдем за рамки задачи постваленной в данном экзаменационном билете, во имя целостности повествования.
Утилита hostname(1) может не только сообщать имя машины, но и устанавливать новое:
$hostname myhost.example.org$hostname -s myhost#hostname other.example.org$hostname other.example.org
Утилита ifconfig(8) позволяет не только просматривать, но и манипулировать настройками сетевого интерфейса. Причём даже на физическом уровне OSI. (О модели OSI можно прочесть в глоссарии: OSI.)
Здесь описаны не все возможности утилиты ifconfig(8). Существуют некоторые опции, характерные для данных операционных систем и т.д. Сверяйтесь со справкой вашей операционной системы. Например, OpenBSD позволяет объединять интерфейсы вгруппы, а FreeBSD такой особенностью не обладает.
В общем случае, для конфигурирования физических параметров интерфейса надо предварительно изучить справку по соответствующему драйверу. Мы приведём примеры на основе драйвера к распространённому чипсету 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, но реально вести передачу на такой скорости не могли и их пришлось вручную «тормозить».
$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
Выше был приведён перечень флагов канального уровня, характеризующих работу сетевого интерфейса. Некоторые из этих флагов можно переключать используя команду ifconfig(8).
up/downpromisc/-promiscmonitor/-monitorlink[0-2]/-link[0-2]arp/-arpstaticarp/-staticarpdebug/-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
MTU переключается оцией mtu. Снижая mtu вы
с одной стороны замедляете работу сети, с другой стороны
повышаете вероятность того, что ваши пакеты дойдут до
адресата без фрагментирования. (Некоторые брандмауэры
отбрасывают фрагментированные пакеты.) Однозначных
рекомендаций тут дать невозможно. Даже тезис о том, что
снижение MTU приводит к снижению скорости передачи данных,
несовсем верен. Безусловно возрастают накладные расходы на
протокол TCP, увеличивается удельный вес заголовков и общий
трафик, однако Ричард Стивенс
[Stevens-2003-ru] приводит убедительный
пример того, как фрагментированные пакеты быстрее передаются
в сети через серию маршрутизаторов, в силу более
равномерного использования каналов связи (пока второй пакет
передаётся первому шлюзу, первый пакет уже может быть
отправлен второму шлюзу, если бы оба пакета были объединены,
участок между первым и вторым шлюзом простаивал бы вдвое
дольше).
Ограничение сверху на MTU накладывает природа передающей среды. В сетях Fast Ethernet MTU не может превышать 1500 байт.
По поводу IPv6 и MTU уместно процитировать «википедию» [url://wiki-IPv6-ru]:
В IPv6 пакеты не могут фрагментироваться и собираться маршрутизаторами. Отправитель должен заранее выяснить максимальный размер пакетов (MTU), поддерживаемый на всём пути до получателя, и, при необходимости, выполнить фрагментацию своими силами. Оговаривается, что MTU не может быть меньше 576 байт. Снятие с маршрутизаторов функций фрагментации также способствует повышению эффективности их работы, но усложняет работу оконечных систем.
Адрес интерфейса и маску подсети можно задавать в традиционном формате, в шестнадчатеричном, а так же в формате 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.
Аналогично добавляются адреса в нотации IPv6, с
использованием ключевого слова inet6.
Команда route(8) служит для управления таблицей маршрутизации. С её помощью можно:
-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
Файл /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)».
Как было сказано в предыдущем разделе, типичное поведение
системы состоит в том, что сперва она пытается разрешить имя
используя файл /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, вы должны перенести
туда же копию данного файла.
Увы, это самое мутное место. Кажется нет двух систем BSD с одинаковой системой инициализации.
В 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"
Для запуска настройки сети в системе
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 будет заменено на имя
интерфейса.
В 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. Правда мило? Каждый раз консультируйтесь со справочной страницей, а ещё лучше со скриптами, которые все эти настройки вызывают.
Описание. Кандидат BSDA должен уметь использовать программы входящие в состав BSD, а так же сторонние программы, для определения того, какие порты в системе открыты, и какие порты видны через брандмауэр.
Практика. netstat(1), services(5),
fstat(1); sockstat(1) и
сторонное продукты nmap и
lsof.
Как было показано выше (см. Раздел 6.1.2.3, «Работающие интернет сервисы и открытые сокеты»), команда netstat(1) пригодна для того, чтобы определить открытые tcp/udp соединения и их состояние. Другим средством для определения состояния файлов и сокетов являются команды fstat(1) и sockstat(1). Первая позволяет понять какие файловые дескрипторы какими пользователями открыты, вторая перечисляет открытые сокеты.
Жизнедеятельность всех программ выполняемых в пространстве
пользователя может быть отслежена при помощи обращения к
устройствам /dev/mem и
/dev/kmem, предоставляющим информацию
непосредственно из ядра системы. Файловой системы
/proc в системах BSD
нет. (Если она нужна для совместимости с какими-то программами,
её можно специально смонтировать, при условии, что в ядре
имеется поддержка PROCFS.) Программы
fstat(1) и sockstat(1)
берут информацию из упомянутых устройств.
В некоторых случаях названия протоколов употребляются символьные
(вроде ssh, imap), в других случаях явно номера
портов (22, 143). Соответствие символьных названий
протоколов и их номеров указано в файле
/etc/services.
Команда fstat(1) выводит информацию обо всех открытых файловых дескрипторах. С её помощью можно получить информацию обо всех запущенных программах, так как каждая из них имеет по нескольку открытых файловых дескрипторов или сокетов, даже если в данный момент она не выполняет никакой работы. Пример, приведённый ниже, сильно урезан, так как всего в выводе команды fstat(1) было более семисот строк.
$fstat > fstat-output$cat fstat-output USER CMD PID FD MOUNT INUM MODE SZ|DV R/W emin fstat 84130 root / 2 drwxr-xr-x 512 remin fstat 84130 wd /usr 5958657 drwxr-xr-x 2048 r emin fstat 84130 text /usr 447995 -r-xr-sr-x 14716 r emin fstat 84130 0 /dev 68 crw--w---- ttyp0 rw emin fstat 84130 1 /usr 5958902 -rw-r--r-- 0 w emin fstat 84130 2 /dev 68 crw--w---- ttyp0 rw emin fstat 84130 3 /dev 20 crw-r----- mem r emin fstat 84130 4 /dev 21 crw-r----- kmem r emin fstat 84130 5 / 8381 -rw-r--r-- 40960 r ...... root getty 633 root / 2 drwxr-xr-x 512 r
root getty 633 wd / 2 drwxr-xr-x 512 r root getty 633 text /usr 565434 -r-xr-xr-x 21016 r root getty 633 0 /dev 39 crw------- ttyv7 rw root getty 633 1 /dev 39 crw------- ttyv7 rw root getty 633 2 /dev 39 crw------- ttyv7 rw ...... root getty 626 root / 2 drwxr-xr-x 512 r root getty 626 wd / 2 drwxr-xr-x 512 r root getty 626 text /usr 565434 -r-xr-xr-x 21016 r root getty 626 0 /dev 32 crw------- ttyv0 rw root getty 626 1 /dev 32 crw------- ttyv0 rw root getty 626 2 /dev 32 crw------- ttyv0 rw ...... root devd 242 root / 2 drwxr-xr-x 512 r root devd 242 wd / 2 drwxr-xr-x 512 r root devd 242 text / 112 -r-xr-xr-x 281208 r root devd 242 0 /dev 8 crw-rw-rw- null rw root devd 242 1 /dev 8 crw-rw-rw- null rw root devd 242 2 /dev 8 crw-rw-rw- null rw root devd 242 3 /dev 5 crw------- devctl r root devd 242 4* local stream c1089000 root adjkerntz 179 root / 2 drwxr-xr-x 512 r root adjkerntz 179 wd / 2 drwxr-xr-x 512 r root adjkerntz 179 text / 117 -r-xr-xr-x 6912 r root adjkerntz 179 0 - - bad - root adjkerntz 179 1 - - bad - root adjkerntz 179 2 - - bad - root init 1 root / 2 drwxr-xr-x 512 r
root init 1 wd / 2 drwxr-xr-x 512 r root init 1 text / 47 -r-x------ 485892 r
|
Прежде всего, конечно, отметилась сама программа
fstat(1). Видно, что от имени
пользователя
а если в pipe, то вывод будет выглядеть так:
Видно, что fstat(1) открыл pipe с
номерами сокетов
Вернёмся к примеру. Второй файловый дескриптор направлен,
как видно, на консоль ttyp0 (Это поток
Дескрипторы 3 и 4 общаются с устройствами
Перед перечнем файловых дескрипторов с номерами, мы видим
три строки (самые первые) с отметками в поле файлового
дескриптора
Зная точку монтирования и номер inod можно найти к чему
относятся приведённые значения
Синтаксис программы find(1) обсуждается в Раздел 7.6, «Поиск файла по заданным атрибутам». Команда lsof(1), обсуждающаяся ниже, печатает в выводе не только номера inod, но и имена файлов, которые она берёт из кеша ядра. |
|
Здесь, для примера, приведены записи о 8-ми экземплярах
команды getty(8), которые открыты на
терминалах ttyv0—ttyv7 и ждут логина пользователя. (Мы
прошли на машину по ssh(1), поэтому ни
один из терминалов неиспользован).
|
| В конце приведены сведения о процессе init(8) — родительском процессе для всех прочих процессов. |
Программа sockstat(1) предоставляет информацию о сокетах, как сетевых, так и сокетах доступных в виде файлов.
$ sockstat
USER COMMAND PID FD PROTO LOCAL ADDRESS FOREIGN ADDRESS
emin sshd 84087 3 stream -> ??
emin sshd 84087 4 tcp4 xxx.yyy.zzz.180:22 xyz.yzx.zxy.yxz:56325
root sshd 84084 4 tcp4 xxx.yyy.zzz.180:22 xyz.yzx.zxy.yxz:56325
root sshd 84084 5 stream -> ??
dovecot imap-login 72803 0 tcp4 *:143 *:*
dovecot imap-login 72803 3 stream -> ??
dovecot imap-login 72803 8 stream -> /var/run/dovecot/login/default
dovecot imap-login 63557 0 tcp4 *:143 *:*
dovecot imap-login 63557 3 stream -> ??
dovecot imap-login 63557 8 stream -> /var/run/dovecot/login/default
dovecot imap-login 59983 0 tcp4 *:143 *:*
dovecot imap-login 59983 3 stream -> ??
dovecot imap-login 59983 8 stream -> /var/run/dovecot/login/default
www httpd 58349 3 tcp4 *:80 *:*
www httpd 58348 3 tcp4 *:80 *:*
www httpd 58347 3 tcp4 *:80 *:*
www httpd 46549 3 tcp4 *:80 *:*
www httpd 11184 3 tcp4 *:80 *:*
www httpd 81458 3 tcp4 *:80 *:*
www httpd 32934 3 tcp4 *:80 *:*
root dovecot-au 53422 0 stream -> ??
root dovecot-au 53422 3 stream /var/run/dovecot/login/default
root dovecot-au 53422 7 stream /var/run/dovecot/login/default
root dovecot-au 53422 8 stream /var/run/dovecot/login/default
root dovecot-au 53422 9 stream /var/run/dovecot/login/default
root dovecot 53421 5 tcp4 *:143 *:*
root dovecot 53421 6 dgram -> /var/run/logpriv
root dovecot 53421 9 stream /var/run/dovecot/login/default
root dovecot 53421 10 stream -> ??
root dovecot 53421 11 stream -> ??
root dovecot 53421 13 stream -> ??
root dovecot 53421 14 stream /var/run/dovecot/auth-worker.53422
root dovecot 53421 15 stream -> ??
www httpd 39377 3 tcp4 *:80 *:*
mysql mysqld 636 3 tcp4 *:3306 *:*
mysql mysqld 636 4 stream /tmp/mysql.sock
www httpd 612 3 tcp4 *:80 *:*
www httpd 609 3 tcp4 *:80 *:*
www httpd 606 3 stream /var/run/cgisock.536
root httpd 536 3 tcp4 *:80 *:*
root cron 499 6 dgram -> /var/run/logpriv
smmsp sendmail 484 3 dgram -> /var/run/log
root sendmail 480 3 dgram -> /var/run/logpriv
root sendmail 480 4 tcp4 *:25 *:*
root sendmail 480 5 tcp4 *:587 *:*
root sshd 475 3 tcp4 *:22 *:*
root ntpd 454 3 dgram -> /var/run/logpriv
root ntpd 454 4 udp4 *:123 *:*
root ntpd 454 5 udp4 xxx.yyy.zzz.180:123 *:*
root ntpd 454 6 udp4 172.16.0.1:123 *:*
root ntpd 454 7 udp4 127.0.0.1:123 *:*
daemon rpc.lockd 409 3 udp4 *:901 *:*
daemon rpc.lockd 409 4 tcp4 *:803 *:*
daemon rpc.lockd 409 5 dgram -> /var/run/logpriv
daemon rpc.lockd 409 7 udp4 *:797 *:*
_pflogd pflogd 402 5 stream -> ??
root pflogd 400 4 stream -> ??
root pflogd 400 5 dgram -> /var/run/logpriv
root rpc.lockd 390 3 udp4 *:901 *:*
root rpc.lockd 390 4 tcp4 *:803 *:*
root rpc.lockd 390 5 dgram -> /var/run/logpriv
root rpc.lockd 390 6 udp4 *:720 *:*
root rpc.lockd 390 7 udp4 *:797 *:*
root rpc.statd 385 4 udp4 *:743 *:*
root rpc.statd 385 5 tcp4 *:966 *:*
root rpc.statd 385 6 dgram -> /var/run/logpriv
root nfsd 375 3 tcp4 *:2049 *:*
root mountd 373 4 udp4 *:891 *:*
root mountd 373 5 tcp4 *:925 *:*
root rpcbind 351 5 stream /var/run/rpcbind.sock
root rpcbind 351 6 dgram -> /var/run/logpriv
root rpcbind 351 7 udp4 *:111 *:*
root rpcbind 351 8 udp4 *:796 *:*
root rpcbind 351 9 tcp4 *:111 *:*
bind named 279 3 dgram -> /var/run/logpriv
bind named 279 20 udp4 xxx.yyy.zzz.180:53 *:*
bind named 279 21 tcp4 xxx.yyy.zzz.180:53 *:*
bind named 279 22 udp4 172.16.0.1:53 *:*
bind named 279 23 tcp4 172.16.0.1:53 *:*
bind named 279 24 udp4 127.0.0.1:53 *:*
bind named 279 25 tcp4 127.0.0.1:53 *:*
bind named 279 26 udp4 *:59517 *:*
bind named 279 27 tcp4 127.0.0.1:953 *:*
root syslogd 264 3 dgram /var/run/log
root syslogd 264 4 dgram /var/run/logpriv
root syslogd 264 5 dgram /var/run/log
root syslogd 264 6 dgram /var/named/var/run/log
root syslogd 264 7 udp4 *:514 *:*
root devd 242 4 stream /var/run/devd.pipe
Здесь запись типа xxx.yyy.zzz.180:53
означает, что система слушает интерфейс с адресом IP
xxx.yyy.zzz.180, порт 53 (из файла
/etc/services узнаём, что это сервер DNS).
Запись типа *:22 означает, что на
22-м порту запущен демон sshd.
Вот некоторые полезные опции данной команды:
-l-c-4, -6-n-u-p 21-23,25,80,110Аналогичную информацию можно получить при анализе вывода программы netstat(1). См. Раздел 6.1.2, «netstat(1)» и Раздел 6.1.2.3, «Работающие интернет сервисы и открытые сокеты».
Это тоже очень полезная программа, которая умеет рассказывать об открытых сокетах, сетевых соединениях и открытых файлах. Данная программа не входит в состав BSD, а доступна исключительно ввиде стороннего продукта (порта или пакета).
С опцией -i она может рассказать об открытых
интернет-соединениях:
$ lsof -i -n | head
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
syslogd 306 root 5u IPv4 0xc18cc708 0t0 UDP *:syslog
ntpd 439 root 4u IPv4 0xc18cc654 0t0 UDP *:ntp
ntpd 439 root 5u IPv4 0xc18cc5a0 0t0 UDP 192.168.0.4:ntp
ntpd 439 root 6u IPv4 0xc18cc4ec 0t0 UDP 192.168.0.6:ntp
ntpd 439 root 7u IPv4 0xc18cc438 0t0 UDP 127.0.0.1:ntp
sshd 470 root 3u IPv4 0xc18fade0 0t0 TCP *:ssh (LISTEN)
sendmail 476 root 4u IPv4 0xc18fac24 0t0 TCP 127.0.0.1:smtp (LISTEN)
mysqld 570 mysql 3u IPv4 0xc18fa8ac 0t0 TCP *:3306 (LISTEN)
mysqld 570 mysql 3u IPv4 0xc18fa8ac 0t0 TCP *:3306 (LISTEN)
Здесь в скобках показано состояние соединения TCP (расшифровку см. выше). Сделав поиск по слову ESTABLISHED мы можем узнать соединения, по которым в данный момент могут передаваться данные:
$ lsof -i -n | grep ESTABLISHED | head
sshd 53540 root 4u IPv4 0xc28ae1bc 0t0 TCP xxx.yyy.zzz.xyz:ssh->xxx.yyy.zzz.zyx:52954 (ESTABLISHED)
sshd 53542 emin 4u IPv4 0xc28ae1bc 0t0 TCP xxx.yyy.zzz.xyz:ssh->xxx.yyy.zzz.zyx:52954 (ESTABLISHED)
httpd 47448 www 66u IPv4 0xc1f296f0 0t0 TCP xxx.yyy.zzz.xyz:http->**************:31825 (ESTABLISHED)
httpd 51286 www 66u IPv4 0xc2407378 0t0 TCP xxx.yyy.zzz.xyz:http->***********:2381 (ESTABLISHED)
httpd 51314 www 66u IPv4 0xc21c3534 0t0 TCP xxx.yyy.zzz.xyz:http->*************:11009 (ESTABLISHED)
httpd 51316 www 66u IPv4 0xc1b6dde0 0t0 TCP xxx.yyy.zzz.xyz:http->************:3664 (ESTABLISHED)
httpd 52426 www 66u IPv4 0xc2407a68 0t0 TCP xxx.yyy.zzz.xyz:http->************:10555 (ESTABLISHED)
httpd 53595 www 66u IPv4 0xc208ec24 0t0 TCP xxx.yyy.zzz.xyz:http->*************:55420 (ESTABLISHED)
httpd 53666 www 66u IPv4 0xc43adde0 0t0 TCP xxx.yyy.zzz.xyz:http->**************:3339 (ESTABLISHED)
httpd 53778 www 66u IPv4 0xc1fa8534 0t0 TCP xxx.yyy.zzz.xyz:http->*************:33735 (ESTABLISHED)
Следующий скрипт отслеживает количество соединений с web-сервером apache, и печатает статистику, по которой можно установить с какого IP пришло слишком много запросов.
#!/bin/sh
while :
do
echo "========== `/bin/date` =========="
/usr/local/bin/lsof -i -n |\
/usr/bin/awk '/^httpd.*ESTABLISHED/{print $9}' |\
/usr/bin/sed 's/.*->\([0-9.]*\):.*/\1/' |\
/usr/bin/sort | /usr/bin/uniq -c | /usr/bin/sort -n -k1,1
/bin/sleep 5
done
Ту же задачу, впрочем, можно решить и при помощи команды netstat(1):
#!/bin/sh
while :
do
echo "========== `/bin/date` =========="
/usr/bin/netstat -n | /usr/bin/awk '/62\.117\.108\.4\.80 .*ESTABLISHED/{print $5}' |\
/usr/bin/sed 's/\.[0-9]*$//' |\
/usr/bin/sort | /usr/bin/uniq -c | /usr/bin/sort -n -k1,1
/bin/sleep 5
done
Без опции -i программа
lsof(1) выводит информацию об открытых
файлах. Вывод её несколько удобнее, чем у программы
fstat(1), так как включает в себя не только
номера inod'ов, но и имена файлов, которые она берёт из кеша
ядра.
Программа nmap(1) сканирует порты, доступные на системе, иногда позволяет по fingerprint'у определить тип операционной системы на изучаемой системе:
$ nmap scanme.nmap.org
Starting Nmap 4.00 ( http://www.insecure.org/nmap/ ) at 2006-03-24 18:56 MSK
Interesting ports on scanme.nmap.org.48.153.217.205.in-addr.arpa (205.217.153.62):
(The 1660 ports scanned but not shown below are in state: filtered)
PORT STATE SERVICE
22/tcp open ssh
25/tcp closed smtp
53/tcp open domain
70/tcp closed gopher
80/tcp open http
113/tcp closed auth
135/tcp open msrpc
136/tcp open profile
137/tcp open netbios-ns
138/tcp open netbios-dgm
139/tcp open netbios-ssn
445/tcp open microsoft-ds
Nmap finished: 1 IP address (1 host up) scanned in 258.100 seconds
Программа nmap(1) имеет различные опции указывающие каким образом она должна смотреть открыт ли порт. Разумеется программа эта может быть использована как во благо (тестирование своего собственного брандмауэра), так и во вред. Тем более администратор должен знать о её возможностях.
По умолчанию программа занимается тем, что по очереди перебирает
порты и посылает по ним SYN пакеты, а в ответ на SYN/ACK пакет
высылается пакет RST (см. Раздел B.1.4.3, «TCP»).
Возможны и другие способы сканирования, путём отсылки ACK
пакетов, UDP пакетов и др. Всё это подробным образом освещяется
в справочной странице по nmap(1). По
необъяснимой для меня причине столь разрушительная программа в
портах FreeBSD устанавливается так, что
запустить её может кто угодно. На мой взгляд, первое, что должен
выполнить администратор после установки такой программы, это
команду: chmod 500
/usr/local/bin/nmap. Я конечно понимаю, что
пользователь всё равно может собрать её локально, но зачем же
его к этому подталкивать? Это я понять немогу.
В следующем разделе я расскажу о неменее разрушительной программе hping(8), которая, почему-то не входит в курс BSDA.
Описание. Кандидат BSDA должен уметь определить доступна ли удалённая система через TCP/IP и, если да, уметь при помощи telnet(1) убедиться отвечает ли сервис на клиентские запросы.
Практика. ping(8), traceroute(8), telnet(1), nc(1) на FreeBSD и OpenBSD
Утилита ping предназначена для того, чтобы при помощи отправки
ICMP пакетов убедиться в работоспособности хоста. Утилита
настолько широкоизвестна, что наверное нет необходимости
подробно
о ней говорить. Заметим только, то, о чём многие порой забывают:
у утилиты ping(8) есть масса разных
аргументов, и её можно использовать для разнообразнейшей
диагностики. В скриптах полезно бывает применять опцию
-c при помощи которой можно сказать после
какого числа посланных и принятых (или не принятых) ICMP пакетов
работа программы остановится (по умолчанию, она работает
бесконечно, пока пользователь не нажмёт сочетание клавиш
Ctrl+C). Опция -i позволяет задать интервал
времени между пакетами (по умолчанию 1 секунда). Опция
-I позволяет задать конкретный интерфейс, с
которого будет отправлен пакет (если вопреки таблице
маршрутизации его надо послать куда-то в другое место).
-S позволяет задать некоторый конкретный IP
адрес источника пинга. Очень разрушительная опция, но весьма
полезная в диагностике состояния сети —
-f позволяет совместно с опцией
-c отправить одновременно множество ICMP пакетов
(устроить так называемый флуд (flood — наводнение,
поток, жарг. болтовня)). В случае наличия помех в сети часть
пакетов будет потеряна, при нормальном пинге пакеты скорее всего
пройдут полностью. Ниже дан пример такой «атаки»
совершённой в сети с некачественным оборудованием (не
качественным на физическом уровне).
$ ping -f -c 10000 192.168.0.12
Password:
PING 192.168.0.12 (192.168.0.12): 56 data bytes
...............................................
--- 192.168.0.12 ping statistics ---
10000 packets transmitted, 6301 packets received, 36% packet loss
round-trip min/avg/max/stddev = 0.159/0.173/0.594/0.017 ms
Как видим, 36% пакетов было потеряно. В нормальной локальной сети, с хорошими проводами и не перенапряжёнными коммутаторами, такая «атака» не должна приводить к значительным потерям пакетов.
Ещё один «необычный» способ использования программы ping(8) может состоять в том, чтобы пинговать широковещательный адрес сети. В этом случае на пинги могут начать отвечать разные машины в сети (а могут и не отвечать, это зависит от их настроек). Таким образом можно попытаться получить информацию о том, какие машины в локальной сети в настоящий момент включены.
Не все хосты обязаны отвечать на запросы программы ping(8). Обычно программа ping(8) посылает пакеты, которые называются ECHO_REQUEST и ожидает получить пакет ECHO_RESPONSE. Однако варианты ответов могут быть разными. Ниже показан вариант с ответом «Destination Port Unreachable». Такой ответ, однако, означает, что на той стороне есть «живая» машина.
$ ping -c1 192.168.25.24
PING cube.mccme.ru (192.168.25.24): 56 data bytes
92 bytes from cube.mccme.ru (192.168.25.24): Destination Port Unreachable
Vr HL TOS Len ID Flg off TTL Pro cks Src Dst
4 5 00 5400 f8d6 0 0000 40 01 fcfe 192.168.25.158 192.168.25.24
--- 192.168.25.24 ping statistics ---
1 packets transmitted, 0 packets received, 100% packet loss
Немного напоминает знаменитый диалог Винни-Пуха и Пятачка:
Тут он наклонился, сунул голову в нору и крикнул:
— Эй! Кто-нибудь дома?
Вместо ответа послышалась какая-то возня, а потом снова стало тихо.
— Я спросил: «Эй! Кто-нибудь дома?» — повторил Пух громко-громко.
— Нет! — ответил чей-то голос. — И незачем так орать, — прибавил он, — я и в первый раз прекрасно тебя понял.
— Простите! — сказал Винни-Пух. — А что, совсем-совсем никого нет дома?
— Совсем-совсем никого! — отвечал голос. Тут Винни-Пух вытащил голову из норы и задумался.
Он подумал так: «Не может быть, чтобы там совсем-совсем никого не было! Кто-то там всё-таки есть — ведь кто-нибудь должен же был сказать: «Совсем-совсем никого!»»
Не путайте ответы «Destination Port Unreachable» и «Destination Host Unreachable». Последний генерируется маршрутизатором (или, в частном случае вашей собственной машиной), если он не знает куда послать пакет:
$ ping -c1 192.168.25.1
PING 192.168.25.1 (192.168.25.1): 56 data bytes
36 bytes from gateway (172.16.0.1): Destination Host Unreachable
Vr HL TOS Len ID Flg off TTL Pro cks Src Dst
4 5 00 5400 9514 0 0000 40 01 5fd9 172.16.0.2 192.168.25.1
--- 192.168.25.1 ping statistics ---
1 packets transmitted, 0 packets received, 100% packet loss
В первом («Винни-Пуховском») примере мы получили ответ от машины, которую мы и пинговали, следовательно она всё-таки включена. А во втором примере, пакет не был доставлен машине, так как она не была найдена (в приведённом примере не была найдена не только машина, но даже сеть, в которой она должна находиться).
Команда traceroute(1) в некоторых случаях позволяет выяснить маршрут от одного компьютера до другого. Для этого она посылает пакеты на целевую машину последовательно увеличивая параметр TTL (time to live). В норме TTL должен уменьшаться на единицу на каждом маршрутизаторе, пока не станет равным нулю. Если он обнулится, пакет будет отброшен, а отославшей его стороне вернётся пакет ICMP TIME_EXCEEDED. В этом пакете будет присутствовать IP маршрутизатора, который его послал. По этой информации traceroute(1) сможет перечислить машины, через которые идут пакеты до целевой машины.
![]() | Замечание |
|---|---|
| Имейте ввиду: не все маршрутизаторы уменьшают TTL. Некоторые из них могут оказаться прозрачными для traceroute(1). |
Для примера, попробуем выяснить маршрут к несуществующей сети:
$ traceroute -n 10.0.0.1
traceroute to 10.0.0.1 (10.0.0.1), 64 hops max, 40 byte packets
1 172.16.0.1 0.418 ms 0.781 ms 0.228 ms
2 172.16.0.1 1.703 ms !H 0.585 ms !H 0.491 ms !H
Здесь мы выполняли команду traceroute(1) на машине 172.16.0.2. Она не знает маршрута к хосту 10.0.0.1 и пересылает пакет на машину 172.16.0.1 — свой маршрутизатор по умолчанию, а тот вернул ответ «Destination Host Unreachable», о чём свидетельствует флаг !H. Эта строка появилась потому, что брандмауэр на маршрутизаторе 172.16.0.1 не выпускает пакеты предназначенные для приватных сетей на свой дефолтный маршрутизатор возвращая ICMP пакет с сообщением об ошибке. Строка с номером 1 это результат работы первого пакета ICMP, в котором TTL был выставлен в 1. Этот пакет достиг машины 172.16.0.1, но дальнейшей маршрутизации не претерпел, так как у него истёк срок жизни, поэтому сообщение об ошибке сгенерировано не было. И только следующий пакет ICMP с TTL=2, породил сообщение об ошибке.
Далее идут несколько умозрительные примеры, почёрпнутые из справки по команде traceroute(1).
$ traceroute -n 192.168.2.1
traceroute to 192.168.5.1 (192.168.5.1), 64 hops max, 40 byte packet
1 172.16.0.1 0.418 ms 0.781 ms 0.228 ms
2 192.168.0.1 39 ms 39 ms 19 ms
3 192.168.0.1 39 ms 39 ms 19 ms
4 192.168.1.1 39 ms 40 ms 39 ms
5 192.168.2.1 39 ms 39 ms 39 ms
Заметьте, что строки 2 и 3 совпадают — это происходит потому, что на втором маршрутизаторе имеются ошибки в ядре — система 4.3BSD маршрутизирует пакет с нулевым TTL.
$ traceroute -n 192.168.9.1
traceroute to 192.168.9.1 (192.168.9.1), 64 hops max
1 172.16.0.1 0.418 ms 0.781 ms 0.228 ms
2 192.168.0.1 39 ms 39 ms 19 ms
3 192.168.0.1 39 ms 39 ms 19 ms
4 192.168.1.1 39 ms 40 ms 39 ms
5 192.168.2.1 39 ms 39 ms 39 ms
6 * * *
7 192.168.4.1 259 ms 499 ms 279 ms
8 * * *
9 * * *
10 * * *
11 * * *
12 192.168.9.1 339 ms 279 ms 279 ms
Шлюзы 6, 8, 9, 10 и 11 либо не высылают нам ICMP с сообщением «time exceeded», либо у их сообщений слишком маленький TTL и оно нас не достигает. В точности нельзя сказать, что происходит на маршрутизаторе 12. Например, это может быть следствием ошибок в ядре 4.[23]BSD: BSD 4.x (x меньше либо равен 3) высылали сообщение об ошибке используя TTL оригинального пакета. Таким образом, ICMP «time exceeded» принципиально не мог до нас добраться.
У программы traceroute(1) есть ещё один
полезный аргумент: -P [TCP|UDP|ICMP|...], с
помощью которого можно задать используемый протокол. По
умолчанию в системах BSD (и в
Linux тоже) traceroute(1)
высылает пакеты UDP направленные на абстрактный верхний порт.
Такие пакеты могут резать брандмауэры, поэтому и предусмотрена
возможность выбора протокола. Опция -I включает
протокол ICMP. С её помощью traceroute(1)
работает так же, как утилита tracert в
Windows.
Ещё большую функциональность предлагает команда hping(8), описанная ниже.
Данная программа не входит в курс BSDA, тем не менее я очень советую с ней поупражняться. Как и программа nmap(1), hping(8) мощное средство тестирования брандмауэров, с её помощью можно генерировать разнообразный «неправильный» трафик.
![]() | Важно |
|---|---|
| При помощи команды hping(8) можно сделать так называемую «back door» — чёрный ход. Команда hping(8) может запускаться только с правами суперпользователя. При этом, у неё есть режим в котором она ищет в приходящих пакетах некоторую метку и выполняет команды, которые встретятся после метки. Таким образом, если злоумышленник взломает вашу машину и сможет собрать и запустить hping(8) с нужными аргументами, то потом он сможет выполнять на атакованной системе произвольный код с полномочиями суперпользователя не осуществляя никаких операций связанных с аутентификацией. |
Часто машина не отвечает на пакеты ECHO_REQUEST, но при этом на ней успешно работает web-сервер и она отвечает на попытку установить соединение с 80-м портом. Программа hping(8) может «пинговать» хосты не только при помощи ICMP пакетов, которые часто отвергаются брандмауэрами, но так же и при помощи TCP и UDP пакетов.
Так же программа hping(8) позволяет при помощи TCP пакетов с плавно изменяющимся TTL выяснить маршрут к хосту, даже если это не смогла сделать программа traceroute(1). Принцип работы тот, же, но TCP пакеты, мягко говоря, реже уничтожаются брандмауэрами.
Проделаный ниже эксперимент проводился с хорошо известным в нашей стране интернет-магазином, который работает круглосуточно, но на пинги не откликается. Все имена в распечатке заменены, так как мне неизвестно из каких соображений администрация магазина выбрала такую политику безопасности.
$ping -c1 example.org PING example.org (192.0.34.166): 56 data bytes --- example.org ping statistics --- 1 packets transmitted, 0 packets received, 100% packet loss#hping -p 80 -S -c 1 example.org HPING example.org (rl0 192.0.34.166) S set, 40 headers + 0 data bytes len=46 ip=192.0.34.166 ttl=121 id=47606 sport=80 flags=SA seq=0 win=16384 rtt=18.6 ms --- example.org hping statistic --- 1 packets tramitted, 1 packets received, 0% packet loss round-trip min/avg/max = 18.6/18.6/18.6 ms$traceroute example.org traceroute to example.org (192.0.34.166), 64 hops max, 40 byte packets 1 ****** (***.***.***.***) 0.432 ms 0.244 ms 4.614 ms 2 ****** (***.***.***.***) 0.751 ms 10.655 ms 1.809 ms 3 ****** (***.***.***.***) 0.859 ms 5.817 ms 10.049 ms 4 ****** (***.***.***.***) 13.455 ms 13.785 ms 17.565 ms 5 ****** (***.***.***.***) 18.931 ms 19.907 ms 18.807 ms 6 ****** (***.***.***.***) 25.173 ms 20.845 ms 20.466 ms 7 * * * 8 * * * ^C#hping -p 80 -S -c 8 --traceroute example.org HPING example.org (rl0 192.0.34.166): S set, 40 headers + 0 data bytes hop=1 TTL 0 during transit from ip=***.***.***.*** name=****** hop=1 hoprtt=0.4 ms hop=2 TTL 0 during transit from ip=***.***.***.*** name=****** hop=2 hoprtt=0.7 ms hop=3 TTL 0 during transit from ip=***.***.***.*** name=****** hop=3 hoprtt=1.4 ms hop=4 TTL 0 during transit from ip=***.***.***.*** name=****** hop=4 hoprtt=11.9 ms hop=5 TTL 0 during transit from ip=***.***.***.*** name=****** hop=5 hoprtt=28.3 ms hop=6 TTL 0 during transit from ip=***.***.***.*** name=****** hop=6 hoprtt=40.0 ms len=46 ip=192.0.34.166 ttl=121 id=48766 sport=80 flags=SA seq=6 win=16384 rtt=20.3 ms len=46 ip=192.0.34.166 ttl=121 id=8660 sport=80 flags=SA seq=7 win=16384 rtt=32.5 ms --- example.org hping statistic --- 8 packets tramitted, 8 packets received, 0% packet loss round-trip min/avg/max = 0.4/16.9/40.0 ms
Как видим, если послать «пинг» при помощи пакета TCP на порт 80 с выставленным флагом SYN, на него приходит ответ. (Иначе не мог бы функционировать магазин). Таким же образом, мы можем выяснить и маршрут до него. При этом ни команда ping(8), ни traceroute(8) с задачей не справляются.
Подробное описание программы hping имеется в работе Николая Малых [url://Malyh-hping2-2005].
Основное назначение программы telnet(1) заключается в том, что она предоставляет удалённый терминал, позволяя управлять машиной на расстоянии. К сожалению, программа telnet(1) не шифрует трафик и даже пароли передаёт в открытом виде. Мы покажем чем это опасно, когда будем обсуждать программу tcpdump(1).
![]() | Важно |
|---|---|
| Использовать программу telnet(1) по назначению — дурной тон. Это крайне небезопасно! Вместо неё следует использовать программу ssh(1). |
Однако программу telnet(1) можно использовать для того, чтобы провести диалог с удалённым сервером, проверить работу сервиса прослушивающего соответствующий порт. Например, при передаче почты, устанавливается связь с 25-м портом почтового сервера и далее идут команды SMTP протокола. Ниже приведён короткий пример такого диалога. Здесь символ | означает, что на этой строке приведено служебное сообщение программы telnet(1), > — строка которую мы вводим с клавиатуры, т.е. её клиент отсылает серверу, < — ответ сервера.
$ telnet mxs.mail.ru 25
| Trying 194.67.23.20...
| Connected to mxs.mail.ru.
| Escape character is '^]'.
< 220 Mail.Ru ESMTP
> HELO somewhere.org
< 250 mx8.mail.ru ready to serve
> QUIT
< 221 mx8.mail.ru closing connection
| Connection closed by foreign host.
Обратите внимание на фразу Escape character is '^]'. Если по каким-то причинам вы не можете дождаться ответа сервера и вам надо разорвать соединение, нажмите клавиши <Ctrl>+] и перед вами появится командная строка telnet(1). В ней вы можете набрать команду quit и завершить сеанс:
$telnet mxs.mail.ru 25 Trying 194.67.23.20... Connected to mxs.mail.ru. Escape character is '^]'. 220 Mail.Ru ESMTP ^]telnet>quit Connection closed.
Работа с telnet(1) может быть неудобна тем, что вы не всегда можете отредактировать свой текст в случае ошибки, к тому же некоторые сервисы, расчитанные на работу с роботом могут завершить соединение по таймауту, если вы набираете команды недостаточно быстро. Наконец, telnet(1) невозможно использовать в скриптах.
Чтобы преодолеть эти недостатки, вместо
telnet(1) можно использовать программу
nc(1) (netcat). В следующем примере, мы
делаем тоже, что и в предыдущем, но две команды SMTP (HELO example.org и QUIT) мы посылаем на стандартный ввод
команде nc(1), а на STDOUT
мы получаем ответы почтового сервера (вместо команды
echo, использована команда
printf(1), для того, чтобы напечатать
команды HELO и QUIT на двух разных строках):
$ printf 'HELO example.org\nQUIT' | nc mxs.mail.ru 25
220 Mail.Ru ESMTP
250 mx19.mail.ru ready to serve
Конечно программой nc(1) можно пользоваться и
интерактивно, если не назначить ей STDIN,
она, как и положено любой UNIX программе, будет брать
STDIN с клавиатуры:
$ nc msx.mail.ru 25
< 220 Mail.Ru ESMTP
> HELO somehere.ru
< 250 mx18.mail.ru ready to serve
> QUIT
< 221 mx18.mail.ru closing connection
В качестве примера скрипта использующего программу nc(1) приведём программу, которая пытается определить правильность некоторого адреса email. Приведённая программа первым делом разбирает адрес email, находя в нём часть отвечающую за имя сервера. Затем делает запрос к серверу DNS при помощи программы dig(1) определяя имя почтового сервера. И, наконец, при помощи nc(1) проводит диалог с этим сервером пытаясь при помощи команды SMTP RCPT определить существование почтового адреса на данной машине. Почтовый сервер на эту команду должен дать положительный ответ (код больше двухсот, но меньше трёхсот) и надпись <Recipient ok>. Но может и не дать никакого ответа по соображениям безопасности (смотря как настроен почтовый сервер). Тонкости работы команды dig(1) рассмотрены в Раздел 6.5, «Запрос к серверу DNS». Программирование в Bourne shell в Раздел 7.7, «Написание несложных Bourne-скриптов».
#!/bin/sh
if [ $# -lt 1 ]
then
echo "Usage mailtest.sh user@server"
exit 1
fi
# Вычленяем имя сервера из почтового адреса
server=`echo $1 | sed s/.*@//`
# Определяем почтовый сервер ответственный за передачу писем на
# сервер $server
mxserver=$( dig $server MX |\
egrep 'MX[[:space:]]+[0-9]+[[:space:]]+[^[:space:]]+\.' |\
sort -n -k5,5 |\
head -1 | awk '{print $6}' | sed 's/\.$//' )
echo Investigate: $1
echo Server: $server
echo MX server: $mxserver
# Пытаемся провести SMTP диалог с почтовым сервером
nc $mxserver 25 << EOF
HELO example.org
MAIL From: postmaster@example.org
RCPT To: $1
QUIT
EOF
Программа nc(1) штатно присутствует в FreeBSD и OpenBSD, а в DragonFly BSD и NetBSD её надо ставить отдельно, как сторонний продукт.
В Раздел C.2.1.6.4.3, «TCP proxy» можно найти пример в котором nc(1) используется в качестве прокси-сервера.
Описание. Кандидат BSDA должен понимать основы теории DNS, включая типы DNS записей обратное преобразование имён и перенос зон. Кандидат должен уметь посылать запросы серверу DNS о записях нужного типа, понимать какой сервер авторитетен за зону и понимать готов ли сервер к пересылке зоны.
Практика. dig(1), host(1), nslookup(1), ping(8), telnet(1)
Литература по настройке серверов DNS чрезвычайно обильна. Я пройдусь по теме насколько это возможно кратко.
Итак, протоколы IP и IPv6 устроены таким образом, что адресация
происходит при помощи числовых адресов. Нельзя сказать, что
человека это должно как-то напрягать, ведь никто не протестует
против применения семизначных, десятизначных и даже более
длинных телефонных номеров. Однако иметь более мнемоничные
адреса несомненно удобнее. Почти сразу, как только появился
интернет, появились таблицы соответствия IP адресов и символьных
имён машин. Эти таблицы и по сей день хранятся в файле
/etc/hosts. Однако задача синхронизации
данного файла между машинами очень скоро стала непомерно
сложной. В настоящий момент можно с уверенностью сказать, что
она вообще нереальна. Для решения этой проблемы возникла система
DNS — распределённая база данных.
Распределённая, значит ни один сервер не содержит в себе сведений обо всём пространстве имён Интернета. Каждый сервер ответственен за свой участок этого пространства. Говорят, что данный сервер авторитетен для данной зоны.
Таким образом, пространство имён Интернета поделено на зоны. Каждый сервер может отвечать за ноль и более зон. Рассмотрим, что происходит когда некоторой машине надо узнать IP адрес машины www.dragonflybsd.org.
/etc/hosts, затем, в случае неудачи,
будет изучен файл /etc/resolv.conf.
Дополнительную информацию об этих этапах можно узнать из Раздел 6.1.4, «/etc/resolv.conf(5)» и Раздел 6.7, «Изменение порядка разрешения имён».
Сейчас нам важно, что в итоге мы сделали запрос к некоторому
серверу DNS.
Сервер DNS должен самостоятельно узнать адрес машины
www.dragonflybsd.org. и сообщить его клиенту даже если он не
является авторитетным для зоны в которой находится данная
машина (т.е. зоны dragonflybsd.org.). Сервер, который в
состоянии выполнить всю работу по розыску адреса, задав все
вопросы другим серверам DNS самостоятельно называется
рекурсивным. В /etc/resolv.conf можно
указывать только рекурсивные сервера DNS.
Первым делом наш сервер посылает запрос одному из корневых серверов DNS. Разумеется ни один из корневых серверов не знает ответа на этот вопрос. Больше того, ни один из них и не будет разбираться в вопросе, т.е. ни один из них не является рекурсивным. Зато они знают, какие сервера ответственны за зону org. И этой информацией делятся.
Вся информация полученная нашим сервером DNS надолго помещается в его кеш. Время хранения в кеше, зависит от настроек зоны, т.е. определяется не нашим DNS сервером, а теми серверами, которые ответственны за зону (в самом деле, только они могут знать насколько надёжны предоставленные ими данные). Некоторые серверы DNS могут существовать исключительно ради своего кеша и не иметь ни одной зоны, за которую они бы отвечали (так называемы кеширующие серверы).
Заметьте, что есть чёткая иерархия зон, но нет иерархии серверов DNS. Сервер DNS первым делом осуществляет запрос к корневому серверу, а вовсе не к «своему начальнику». Понятие старшинства среди серверов отсутствует, оно есть только для зон. Конечно сервер должен задать кому-то самый первый вопрос. Этот вопрос он задаёт корневому серверу. Адреса корневых серверов он берёт из специальной зоны подсказок, которая распространяется с исходным кодом сервера. Ниже я покажу как получить эту информацию.
![]() | Замечание |
|---|---|
Иерархию серверов DNS можно создать искуственно при помощи опции
forwarders и зон типа forward.
Это может быть полезно, если на предприятии поднимаеться свой
локальный «национальный» домен типа
local. и в нём поддомены типа
finans.local., kb.local., где
будут хосты типа glavbuh.finans.local.,
ingeneer.finans.local., причём на зоны втророго
уровня ответственны свои DNS сервера, отличные от центрального
сервера, ответственного за зону local..
|
В каждой зоне могут быть записи следующих типов:
Таблица 6.1. Типы записей в файле зоны DNS
| Запись | Описание |
|---|---|
| SOA | Определение параметров зоны DNS (таймауты, адрес ответственного лица) |
| NS | Определение DNS-серверов ответственных (авторитетных) за зоны, делегирование полномочий поддоменам. |
| Записи типа SOA и NS обязательны, остальных записей может не быть вовсе. | |
| A | Преобразование имени в IP адрес |
| AAAA или A6 | Преобразование имени в IPv6 адрес |
| PTR | Преобразование IP адреса в имя |
| MX | Указание почтового сервера ответственного за зону |
| KEY | Открытый ключ шифрования для имени DNS |
| CNAME | Псевдоним, алиас, синоним. |
| SRV | Распределение нагрузки на сервис |
| TXT | Текстовая запись используется с самой разной целью |
| HINFO | Информация о машине, например архитектура и операционная система. |
В каждой зоне обязательно должны присутствовать записи типа SOA и NS. Если для домена example.org. почту принимает машина mx.example.org., то для неё должна существовать специальная MX запись. Почтовых машин отвечающих за домен может быть несколько. В записи типа MX упоминается их приоритет. Почту принимает машина с наименьшим значением приоритета, а если она недоступна, то следующая. Если запись MX для домена example.org. отсутствует, то эту почту принимает машина example.org.
Полное описание работы с сервером BIND выходит за рамки данного раздела. Мы лишь опишем настройку файла зоны, с тем, чтобы администратор мог сознательно применять утилиты host(1), dig(1) и nslookup(1).
Сначала зона должна быть объявлена в конфигурационном файле
сервиса named(8) —
named.conf(5). Этот конфигурационный
файл может находиться в файле
/etc/namedb/named.conf, а может в
/var/named/etc/namedb/named.conf.
Сервис named(8) часто запускается в
окружении chroot(8) в каталоге
/var/named/, однако для удобства
администрирования всё равно оставляют мягкую ссылку
/etc/namedb/named.conf.
Зона, оъявленная в BIND, может иметь один из следующих типов: master, slave, hint или forward. Зона hint содержит в себе адреса корневых серверов DNS, с которых начинает опрос рекурсивный сервер DNS. Эта зона практически не подвержена никаким изменениям и обычно не должна редактироваться администратором.
Зона типа master должна быть описана в файле. Файл описания зоны мы рассмотрим ниже, а сейчас взглянем на объявление зоны типа master:
...skip...
options {
directory "/etc/namedb";
...skip...
}
...skip...
zone "example.org." {
type master;
file "master/example.zone";
};
...skip...
Здесь сказано, что зона example.org. описана в файле
master/example.zone. Этот адрес дан
относительно каталога /etc/namedb (см.
опцию directory).
Зону типа master редактирует администратор, но за эту зону может отвечать несколько серверов DNS. Для того, чтобы все они обладали одинаковой согласованной информацией, на всех прочих серверах DNS поднимается зона типа slave, которая синхронизируется с зоной типа master. Зона типа slave объявляется следующим образом:
zone "example.org." {
type slave;
file "slave/example.zone";
masters {
192.168.1.1;
};
};
Здесь сказано, что зона имеет тип slave, а сервер, с
которого надо брать информацию о ней (master) имеет адрес
192.168.1.1. Информация о зоне (файл зоны) будет
сохраняться в файле slave/example.zone.
Последняя опция необязательна, если файл не указан,
информация будет храниться в памяти и при перезагрузке
сервера DNS пропадёт.
Зона типа forward применяется в редких случаях, когда надо заставить наш сервер DNS делать запрос о зоне для которой он не авторитетен не к одному из корневых серверов, перечисленных в зоне hint, а к некоторому конкретному серверу. Например, пусть DNS A, расположенный на некотором предприятии, описывает локальную зону local. и делегирует зону finans.local. серверу DNS B. Поскольку сервер A не авторитетен для зоны finans.local., при попытке разрешить имя major-buhg.finans.local., он обратится к корневому серверу DNS (несмотря на то, что он сам делегировал зону finans.local. серверу B) и потерпит неудачу, так как зоны local. с точки зрения корневых серверов не существует. Поэтому на сервере A мы должны описать зону finans.local. типа forward для того, чтобы он переадресовывал запросы к этой зоне на авторитетный для неё сервер B:
zone "local." {
type master;
file "master/local.zone";
};
zone "finans.local." {
type forward;
masters {
192.168.1.2; // server B
};
};
В свою очередь, на сервере B нам, вероятно, надо указать
опцию forwarders, в которой указать сервер
A, тогда опрос сервер B будет производить не с корневых
серверов, а с сервера A и разрешение имён находящихся в зоне
local. будет работать корректно. Кроме того, такое действие
полезно, если на предприятии поднято несколько серверов DNS,
а выход в Интернет на брандмауэре разрешён только серверу A.
...skip...
options {
directory "/etc/namedb";
forwarders {
192.168.1.1; // server A
};
...skip...
}
Файл зоны состоит из перечня записей различного типа. Типы записей в файле зоны были перечислены в Таблица 6.1, «Типы записей в файле зоны DNS». Как уже говорилось, обязательных записей в этом файле всего две: запись типа SOA и запись типа NS в которой указан сервер DNS ответственный за данную зону.
В каждой записи имеется необязательное поле, в котором
указывается время жизни данной записи в кешах серверов DNS.
Чтобы не указывать эту величину в каждой строке (как правило
нет никакого смысла делать различные времена жизни для
разных записей) её можно указать в самом начале файла, задав
переменную $TTL.
Все адреса в файле зоны должны заканчиваться на точку (т.н.
формат FQDN: fully qualified domain
name — полностью описанное имя домена). Если имя
не кончается на точку, к нему дописывается содержимое
переменной $ORIGIN. Если данная
переменная не задана явно, то в ней содержится имя зоны,
т.е. то, что объявлено в файле
named.conf(5).
Другая интересная переменная — $INCLUDE позволяет включить внутрь
одного файла зоны другой файл.
Комментарии в файле зоны начинаются с символа ;.
Первая запись в файле зоны — запись типа SOA. помимо необязательного поля TTL в записи SOA имеется десять обязательных полей, поэтому записать её в одну строку весьма затруднительно. Для того, чтобы запись типа SOA можно было написать в несколько строк, применяются круглые скобки. запись не кончится, пока не закроется круглая скобка.
Вот пример файла зоны с описанием:
$TTL 36000
@ IN SOA ns.example.ru. root.example.ru. (
2006011700 ; Serial
3600 ; Refresh
900 ; Retry
3600000 ; Expire
3600 ) ; Minimum
IN NS ns.example.ru.
IN NS ns1.example.ru.
IN NS ns2.otherplace.ru.
IN MX 5 smtp.example.ru.
IN MX 15 smtp.otherplace.ru.
ns IN A 192.168.0.1
ns1 IN A 192.168.0.2
smtp IN A 192.168.0.1
www IN A 192.168.0.3
site1 IN CNAME www
site2 IN CNAME www
В приведённом примере сперва задана переменная $TTL, затем сделано двенадцать
записей: первая запись типа SOA, три типа NS, две типа MX,
четыре типа A и две типа CNAME.
@ будет
заменён на содержимое переменной $ORIGIN, но мы могли бы написать
явно example.ru..
@
применяться в файле зоны не может (как уже было сказано,
он заменяется на переменную $ORIGIN), вместо него
используется точка. данная запись выглядит как доменное
имя. Можно написать просто root, в этом случае имя будет
достроено до FQDN из переменной $ORIGIN, и первая точка будет
заменена на знак @. Таким
образом, запись root в данном поле превратится в адрес
root@example.ru.
В записи типа NS, в данном примере, отсутствует первое поле. Это значит, что оно будет взято из предыдущей записи. Таким образом, все три записи NS относятся к зоне example.ru. и описывают три сервера авторитетных для данной зоны. Два из них будут slave, а один, упомянутый в записи SOA — master.
Поле с классом записи (IN) так же как и TTL необязательное, и тоже, как и TTL могло бы отсутствовать.
В остальном синтаксис достаточно прост, назначение данной записи — перечислить ответственные за зону сервера DNS, поэтому обязательных полей здесь два: тип записи и имя сервера.
Разумеется сервер DNS не обязан находиться в описываемой зоне. В данном случае упомянут один сервер DNS из другой зоны otherplace.ru. Если сервер находится в нашей зоне, мы должны ниже, в записи типа A указать его адрес, если он в другой зоне, то его адрес должны указать там. Тем не менее нет никаких причин не включить этот сервер ещё и в нашу зону. Это удобнее, так как мы, в этом случае можем сами указать соответствующий IP.
![]() | Замечание |
|---|---|
| Не следует в данной записи указывать IP или имена заданные в записях типа CNAME. Указанные здесь имена должны быть описаны ниже в записи типа A или AAAA. |
![]() | Важно |
|---|---|
| Хотя согласно правилам построения системы DNS для зоны достаточно иметь один сервер DNS (поэтому запись типа NS обязательна, но может быть единственной), если вы описываете домен второго уровня внутри зоны ru., то по правилам RIPE вы обязаны иметь не менее двух серверов DNS в различных сетях класса C. Т.е. у этих двух серверов обязан отличаться как минимум третий байт в адресе IPv4. |
Здесь описано какие хосты ответственны за приём почты направляющейся в домен example.ru. Если такой записи нет вообще, то почту будет принимать машина с именем example.ru. Если таких записей много, то сперва будет предпринята попытка доставить почту на машину с самым низким значением поля с приоритетом, затем, в случае неуспеха, на машину со следующим приоритетом и так далее.
Итак, данная запись отличается только тем, что в ней добавлено поле с приоритетом записи, сразу после типа записи MX.
![]() | Важно |
|---|---|
| Не следует в данной записи указывать IP или имена заданные в записях типа CNAME. Указанные здесь имена должны быть описаны ниже в записи типа A или AAAA. |
Данная запись указывает соответствие между именем и адресом IP. В случае, если в файле зоны имеется несколько записей с одинаковым именем, но разными адресами, например:
www IN A 192.168.0.1
www IN A 192.168.0.2
www IN A 192.168.0.3
...адреса будут выдаваться сервером DNS циклически: в ответ на первый запрос о имени www.example.ru сервер DNS даст адрес 192.168.0.1, следующему клиенту дадут адрес 192.168.0.2 и дальше по кругу. Это один из способов распределения нагрузки между различными серверами. К сожалению, это не самый удачный способ распределения нагрузки: при аварии на одном из серверов, даже если принять оперативные меры по редактированию файла зоны, в многочисленных кешах ещё долго будет сидеть информация о неработающем сервере и треть клиентов продолжит получать неправильную информацию. Снижение TTL на данные записи приведёт к увеличению нагрузки на систему DNS и в конечном итоге приведёт к замедлению обслуживания клиентов.
Запись этого типа нужна для того, чтобы клиентское програмное обеспечение могло самостоятельно разыскивать машину, на которой поднят нужный сервис и осуществлять распределение нагрузки. К сожалению, немногие браузеры могут похвастать поддержкой этого типа записи в файле зоны. И всё же:
;; _служба._протокол.имя [ttl] IN SRV приоритет вес порт сервер
_http._tcp.www IN SRV 0 1 80 www.server.ru.
IN SRV 0 3 8080 old.server.ru.
В приведённом примере браузер должен осуществить запрос с целью определить на каком сервере и на каком порту обслуживают злужбу http по протоколу tcp. Как результат он получает информацию о том, что эти запросы обслуживают две машины: www.server.ru и old.server.ru. Причём первая обслуживает 25% запросов и работает на порту 80, а вторая обслуживает 75% запросов и работает на порту 8080. Распределение нагрузки осуществляется на основе поля «вес» на добровольной основе, т.е. дано на откуп клиенту.
Поле «приоритет» имеет то же значение, что и для записи MX. Клиент должен обращаться к записи с наименьшим числом в поле «приоритет», и переходить к записи с большим приоритетом, только если сервера из записей с меньшим недоступны.
Имя службы и протокола должно начинаться с подчерка, чтобы не перепутать их с обычными именами. Имена служб и протоколов описаны в [RFC-1700].
Текстовая запись. В ней может находиться самая разнообразная информация. Например стихи:
poem IN TXT ( "The Road goes ever on and on"
"Down from the door where it began."
"Now far ahead the Road has gone,"
"And I must follow, if I can,"
"Purshuing it with eager feet,"
"Until it joins some larger way"
"Where many paths and errands meet."
"And whither then? I cannot say." )
Ёмкость этой записи — пара килобайт. Мы
вполне можем использовать её для хранения коротких
стихотворений, создав доменные имена для разных
поэтов... Однако у этой записи есть множество других,
более полезных применений. В некоторых случаях в ней
хранят публичные ключи. Старые версии BIND хранили в
записях TXT информацию о том, кому можно отвечать на
запросы к зоне (в новых версиях это делается при
помощи директивы allow-query).
Итак, администратор должен уметь не только определять IP адрес машины, но и запрашивать записи о зоне определённого типа. Для осуществления этих запросов существует три команды: host(1), dig(1), nslookup(1).
![]() | Замечание |
|---|---|
Имейте ввиду, все три утилиты работают с системой DNS и ни одна
из них не проверяет файл /etc/hosts. Таким
образом, информация полученная при помощи данных утилит не
обязательно даёт ответ на вопрос «почему мой веб-браузер
идёт на адрес XYZ, когда я ввожу URL http://xyz.org/?».
|
Программа host(1) существует во многих вариантах. В FreeBSD она умеет сообщать практически ту же информацию, что и dig(1), но в других системах это может быть не так. Здесь мы приведём примеры на базе FreeBSD, как наиболее полные.
Запрос IP по адресу:
$ host mail.ru
mail.ru has address 194.67.57.26
mail.ru mail is handled (pri=10) by mxs.mail.ru
Как видно, нам сообщили не только IP машины mail.ru, но и некоторую дополнительную информацию (имя почтовой машины и её приоритет). Эта информация приходит от сервера DNS в том же UDP пакете и её получение не требует со стороны программы host(1) никаких специальных действий. И всё же, некоторые варианты этой программы могут не сообщать всей информации.
Программе можно явно указать сервер DNS, в этом случае запрос будет сделан к нему:
$ host mail.ru 194.67.23.130
Using domain server 194.67.23.130:
mail.ru has address 194.67.57.26
mail.ru mail is handled (pri=10) by mxs.mail.ru
И наконец, можно запросить конкретный тип записи:
$host -t NS mail.ru mail.ru name server ns2.mail.ru mail.ru name server ns3.mail.ru mail.ru name server ns4.mail.ru mail.ru name server ns5.mail.ru mail.ru name server ns.mail.ru mail.ru name server ns1.mail.ru$host -t SOA mail.ru mail.ru start of authority ns.mail.ru hostmaster.mail.ru ( 3209013119 ;serial (version) 300 ;refresh period 900 ;retry refresh this often 172800 ;expiration period 300 ;minimum TTL )
Опция -v включает режим verbose.
$host -t NS -v mail.ru Trying null domain rcode = 0 (Success), ancount=6 The following answer is not authoritative: The following answer is not verified as authentic by the server: mail.ru 16141 IN NS ns4.mail.ru mail.ru 16141 IN NS ns5.mail.ru mail.ru 16141 IN NS ns.mail.ru mail.ru 16141 IN NS ns1.mail.ru mail.ru 16141 IN NS ns2.mail.ru mail.ru 16141 IN NS ns3.mail.ru Additional information: ns.mail.ru 153899 IN A 194.67.23.130 ns1.mail.ru 299802 IN A 194.67.57.103 ns2.mail.ru 167593 IN A 194.67.57.104 ns3.mail.ru 278118 IN A 194.67.23.17 ns4.mail.ru 278118 IN A 194.67.57.4 ns5.mail.ru 278118 IN A 194.67.23.232$host -t SOA -v mail.ru Trying null domain rcode = 0 (Success), ancount=1 The following answer is not authoritative: The following answer is not verified as authentic by the server: mail.ru 21455 IN SOA ns.mail.ru hostmaster.mail.ru ( 3209013119 ;serial (version) 300 ;refresh period 900 ;retry refresh this often 172800 ;expiration period 300 ;minimum TTL ) For authoritative answers, see: mail.ru 15127 IN NS ns.mail.ru mail.ru 15127 IN NS ns1.mail.ru mail.ru 15127 IN NS ns2.mail.ru mail.ru 15127 IN NS ns3.mail.ru mail.ru 15127 IN NS ns4.mail.ru mail.ru 15127 IN NS ns5.mail.ru Additional information: ns.mail.ru 152885 IN A 194.67.23.130 ns1.mail.ru 298788 IN A 194.67.57.103 ns2.mail.ru 166579 IN A 194.67.57.104 ns3.mail.ru 277104 IN A 194.67.23.17 ns4.mail.ru 277104 IN A 194.67.57.4 ns5.mail.ru 277104 IN A 194.67.23.232
В последнем случае нам даже явно рекомендуют обращаться за
информацией на авторитетные серверы и указывают их адреса. С
опцией -v отчёт программы
host(1) становится похож на отчёт
dig(1) (см. ниже) и начинает повтрять
синтаксис файла зоны.
Утилита dig(1) более «разговорчива». Одна из особенностей её отчётов состоит в том, что они даются сразу в формате файла зоны:
$ dig mail.ru
; <<>> DiG 8.3 <<>> mail.ru
;; res options: init recurs defnam dnsrch
;; got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 9099
;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 6, ADDITIONAL: 6
;; QUERY SECTION:
;; mail.ru, type = A, class = IN
;; ANSWER SECTION:
mail.ru. 1h56m42s IN A 194.67.57.26
;; AUTHORITY SECTION:
mail.ru. 4h21m12s IN NS ns2.mail.ru.
mail.ru. 4h21m12s IN NS ns3.mail.ru.
mail.ru. 4h21m12s IN NS ns4.mail.ru.
mail.ru. 4h21m12s IN NS ns5.mail.ru.
mail.ru. 4h21m12s IN NS ns.mail.ru.
mail.ru. 4h21m12s IN NS ns1.mail.ru.
;; ADDITIONAL SECTION:
ns.mail.ru. 1d18h37m10s IN A 194.67.23.130
ns1.mail.ru. 3d11h8m53s IN A 194.67.57.103
ns2.mail.ru. 1d22h25m24s IN A 194.67.57.104
ns3.mail.ru. 3d5h7m29s IN A 194.67.23.17
ns4.mail.ru. 3d5h7m29s IN A 194.67.57.4
ns5.mail.ru. 3d5h7m29s IN A 194.67.23.232
;; Total query time: 9 msec
;; FROM: aluminum.mccme.ru to SERVER: 62.117.108.2
;; WHEN: Wed Apr 5 14:37:57 2006
;; MSG SIZE sent: 25 rcvd: 244
Символ ; в файле зоны является
комментарием. Заметим, что мы не требовали от программы
dig(1) информацию о серверах NS, и всё же
он запросил её у сервера DNS. Разумеется, это не вся информация
о зоне.
Попробуем запросить информацию о записях SOA и MX.
$dig MX mail.ru ; <<>> DiG 8.3 <<>> MX mail.ru ;; res options: init recurs defnam dnsrch ;; got answer: ;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 28695 ;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 6, ADDITIONAL: 7 ;; QUERY SECTION: ;; mail.ru, type = MX, class = IN ;; ANSWER SECTION: mail.ru. 4h6m37s IN MX 10 mxs.mail.ru. ;; AUTHORITY SECTION: mail.ru. 4h6m37s IN NS ns2.mail.ru. mail.ru. 4h6m37s IN NS ns3.mail.ru. mail.ru. 4h6m37s IN NS ns4.mail.ru. mail.ru. 4h6m37s IN NS ns5.mail.ru. mail.ru. 4h6m37s IN NS ns.mail.ru. mail.ru. 4h6m37s IN NS ns1.mail.ru. ;; ADDITIONAL SECTION: mxs.mail.ru. 2h4m39s IN A 194.67.23.20 ns.mail.ru. 1d18h22m35s IN A 194.67.23.130 ns1.mail.ru. 3d10h54m18s IN A 194.67.57.103 ns2.mail.ru. 1d22h10m49s IN A 194.67.57.104 ns3.mail.ru. 3d4h52m54s IN A 194.67.23.17 ns4.mail.ru. 3d4h52m54s IN A 194.67.57.4 ns5.mail.ru. 3d4h52m54s IN A 194.67.23.232 ;; Total query time: 2 msec ;; FROM: aluminum.mccme.ru to SERVER: 62.117.108.2 ;; WHEN: Wed Apr 5 14:52:31 2006 ;; MSG SIZE sent: 25 rcvd: 264$dig SOA mail.ru ; <<>> DiG 8.3 <<>> SOA mail.ru ;; res options: init recurs defnam dnsrch ;; got answer: ;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 59976 ;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 6, ADDITIONAL: 6 ;; QUERY SECTION: ;; mail.ru, type = SOA, class = IN ;; ANSWER SECTION: mail.ru. 5h51m47s IN SOA ns.mail.ru. hostmaster.mail.ru. ( 3209013119 ; serial 5M ; refresh 15M ; retry 2D ; expiry 5M ) ; minimum ;; AUTHORITY SECTION: mail.ru. 4h6m19s IN NS ns5.mail.ru. mail.ru. 4h6m19s IN NS ns.mail.ru. mail.ru. 4h6m19s IN NS ns1.mail.ru. mail.ru. 4h6m19s IN NS ns2.mail.ru. mail.ru. 4h6m19s IN NS ns3.mail.ru. mail.ru. 4h6m19s IN NS ns4.mail.ru. ;; ADDITIONAL SECTION: ns.mail.ru. 1d18h22m17s IN A 194.67.23.130 ns1.mail.ru. 3d10h54m IN A 194.67.57.103 ns2.mail.ru. 1d22h10m31s IN A 194.67.57.104 ns3.mail.ru. 3d4h52m36s IN A 194.67.23.17 ns4.mail.ru. 3d4h52m36s IN A 194.67.57.4 ns5.mail.ru. 3d4h52m36s IN A 194.67.23.232 ;; Total query time: 6 msec ;; FROM: aluminum.mccme.ru to SERVER: 62.117.108.2 ;; WHEN: Wed Apr 5 14:52:50 2006 ;; MSG SIZE sent: 25 rcvd: 275
Для запроса к конкретному серверу DNS его адрес необходимо предварять символом at:
$ dig mail.ru @194.67.23.130
; <<>> DiG 8.3 <<>> mail.ru @194.67.23.130
; (1 server found)
;; res options: init recurs defnam dnsrch
;; got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 62910
;; flags: qr aa rd; QUERY: 1, ANSWER: 1, AUTHORITY: 6, ADDITIONAL: 6
;; QUERY SECTION:
;; mail.ru, type = A, class = IN
;; ANSWER SECTION:
mail.ru. 6H IN A 194.67.57.26
;; AUTHORITY SECTION:
mail.ru. 6H IN NS ns.mail.ru.
mail.ru. 6H IN NS ns1.mail.ru.
mail.ru. 6H IN NS ns2.mail.ru.
mail.ru. 6H IN NS ns4.mail.ru.
mail.ru. 6H IN NS ns5.mail.ru.
mail.ru. 6H IN NS ns3.mail.ru.
;; ADDITIONAL SECTION:
ns.mail.ru. 6H IN A 194.67.23.130
ns1.mail.ru. 6H IN A 194.67.57.103
ns2.mail.ru. 6H IN A 194.67.57.104
ns4.mail.ru. 6H IN A 194.67.57.4
ns5.mail.ru. 6H IN A 194.67.23.232
ns3.mail.ru. 6H IN A 194.67.23.17
;; Total query time: 91 msec
;; FROM: aluminum.mccme.ru to SERVER: 194.67.23.130
;; WHEN: Wed Apr 5 15:05:16 2006
;; MSG SIZE sent: 25 rcvd: 244
Заметьте, что в этом запросе размеры таймаутов стали более «круглыми» — ровно по 6 часов. Причина в том, что мы задали вопрос авторитетному за эту зону серверу. Ответы, которые мы получали до сих пор мы брали из кешей неавторитетных серверов, поэтому в качестве TTL мы получали время указывающее на то, сколько осталось жить в кеше той или иной записи.
Давайте попробуем узнать с помощью команды dig(1) адреса серверов отвечающих за корневую зону (.) и время жизни записей о корневых серверах.
$ dig NS .
; <<>> DiG 8.3 <<>> NS .
;; res options: init recurs defnam dnsrch
;; got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 5359
;; flags: qr rd ra; QUERY: 1, ANSWER: 13, AUTHORITY: 0, ADDITIONAL: 1
;; QUERY SECTION:
;; ., type = NS, class = IN
;; ANSWER SECTION:
. 5d1h8m12s IN NS F.ROOT-SERVERS.NET.
. 5d1h8m12s IN NS G.ROOT-SERVERS.NET.
. 5d1h8m12s IN NS H.ROOT-SERVERS.NET.
. 5d1h8m12s IN NS I.ROOT-SERVERS.NET.
. 5d1h8m12s IN NS J.ROOT-SERVERS.NET.
. 5d1h8m12s IN NS K.ROOT-SERVERS.NET.
. 5d1h8m12s IN NS L.ROOT-SERVERS.NET.
. 5d1h8m12s IN NS M.ROOT-SERVERS.NET.
. 5d1h8m12s IN NS A.ROOT-SERVERS.NET.
. 5d1h8m12s IN NS B.ROOT-SERVERS.NET.
. 5d1h8m12s IN NS C.ROOT-SERVERS.NET.
. 5d1h8m12s IN NS D.ROOT-SERVERS.NET.
. 5d1h8m12s IN NS E.ROOT-SERVERS.NET.
;; ADDITIONAL SECTION:
J.ROOT-SERVERS.NET. 6d1h8m12s IN A 192.58.128.30
;; Total query time: 2 msec
;; FROM: aluminum.mccme.ru to SERVER: 62.117.108.2
;; WHEN: Thu Apr 6 11:37:56 2006
;; MSG SIZE sent: 17 rcvd: 244
Очень хорошо, теперь мы знаем что думает о корневых серверах, в настоящий момент обслуживающий нас сервер DNS. Мы видим, что время жизни информации о корневых серверах истечёт через пять дней, один час, восемь минут, двенадцать секунд. Кстати нам, кроме имён корневых серверов, в разделе ADDITIONAL SECTION сказали ещё и адрес одного из серверов. Давайте зададим этот вопрос снова, но теперь не нашему серверу DNS, а сервру j.root-servers.net. с адресом IP 192.58.128.30. Он авторитетен за корневую зону и полученная от него информация будет истиной в последней инстанции.
$ dig NS . @192.58.128.30
; <<>> DiG 8.3 <<>> NS . @192.58.128.30
; (1 server found)
;; res options: init recurs defnam dnsrch
;; got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 50893
;; flags: qr aa rd; QUERY: 1, ANSWER: 13, AUTHORITY: 0, ADDITIONAL: 13
;; QUERY SECTION:
;; ., type = NS, class = IN
;; ANSWER SECTION:
. 6D IN NS E.ROOT-SERVERS.NET.
. 6D IN NS D.ROOT-SERVERS.NET.
. 6D IN NS A.ROOT-SERVERS.NET.
. 6D IN NS H.ROOT-SERVERS.NET.
. 6D IN NS C.ROOT-SERVERS.NET.
. 6D IN NS G.ROOT-SERVERS.NET.
. 6D IN NS F.ROOT-SERVERS.NET.
. 6D IN NS B.ROOT-SERVERS.NET.
. 6D IN NS J.ROOT-SERVERS.NET.
. 6D IN NS K.ROOT-SERVERS.NET.
. 6D IN NS L.ROOT-SERVERS.NET.
. 6D IN NS M.ROOT-SERVERS.NET.
. 6D IN NS I.ROOT-SERVERS.NET.
;; ADDITIONAL SECTION:
E.ROOT-SERVERS.NET. 5w6d16h IN A 192.203.230.10
D.ROOT-SERVERS.NET. 5w6d16h IN A 128.8.10.90
A.ROOT-SERVERS.NET. 5w6d16h IN A 198.41.0.4
H.ROOT-SERVERS.NET. 5w6d16h IN A 128.63.2.53
C.ROOT-SERVERS.NET. 5w6d16h IN A 192.33.4.12
G.ROOT-SERVERS.NET. 5w6d16h IN A 192.112.36.4
F.ROOT-SERVERS.NET. 5w6d16h IN A 192.5.5.241
B.ROOT-SERVERS.NET. 5w6d16h IN A 192.228.79.201
J.ROOT-SERVERS.NET. 5w6d16h IN A 192.58.128.30
K.ROOT-SERVERS.NET. 5w6d16h IN A 193.0.14.129
L.ROOT-SERVERS.NET. 5w6d16h IN A 198.32.64.12
M.ROOT-SERVERS.NET. 5w6d16h IN A 202.12.27.33
I.ROOT-SERVERS.NET. 5w6d16h IN A 192.36.148.17
;; Total query time: 299 msec
;; FROM: aluminum.mccme.ru to SERVER: 192.58.128.30
;; WHEN: Thu Apr 6 11:44:56 2006
;; MSG SIZE sent: 17 rcvd: 436
Как видим, истинное время жизни составляет без малого шесть недель (1000 часов). При помощи такого большого TTL сервера пытаются снизить нагрузку на себя.
Поскольку команда dig(1) выдаёт информацию в формате файла зоны, если мы вдруг почему-то потеряли файл с настройками зоны hint, мы можем сохранить вывод данной команды в файл и использовать его.
Наконец, мы можем сделать запрос записи типа TXT, содержащей короткое стихотворение. Это стихотворение мы записали в файл зоны раньше.
$ dig TXT poem.house.hcn-strela.ru
; <<>> DiG 9.3.2 <<>> TXT poem.house.hcn-strela.ru
;; global options: printcmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 8468
;; flags: qr aa rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 3, ADDITIONAL: 1
;; QUESTION SECTION:
;poem.house.hcn-strela.ru. IN TXT
;; ANSWER SECTION:
poem.house.hcn-strela.ru. 36000 IN TXT "The Road goes ever on
and on" "Down from the door where it began." "Now far ahead the
Road has gone," "And I must follow, if I can," "Purshuing it
with eager feet," "Until it joins some larger way" "Where many
paths and errands meet." "And whither then? I cannot say."
;; AUTHORITY SECTION:
house.hcn-strela.ru. 36000 IN NS ns.hcn-strela.ru.
house.hcn-strela.ru. 36000 IN NS ns1.hcn-strela.ru.
house.hcn-strela.ru. 36000 IN NS ns.house.hcn-strela.ru.
;; ADDITIONAL SECTION:
ns.house.hcn-strela.ru. 36000 IN A 83.102.236.196
;; Query time: 3 msec
;; SERVER: 127.0.0.1#53(127.0.0.1)
;; WHEN: Sat Feb 17 12:05:09 2007
;; MSG SIZE rcvd: 376
nslookup(1) самая древняя программа из этих трёх. Кроме всего прочего она интересна ещё и тем, что входит в стандартную поставку большинства операционных систем компании MicroSoft.
Её синтаксис несколько напоминает синтаксис команды host(1):
$nslookup mail.ru Server: ns.mccme.ru Address: 62.117.108.2 Non-authoritative answer: Name: mail.ru Address: 194.67.57.26$nslookup mail.ru 194.67.23.130 Server: ns.mail.ru Address: 194.67.23.130 Name: mail.ru Address: 194.67.57.26
Но главная изюминка nslookup(1) состоит в том, что она умеет работать интерактивно:
$nslookup Default Server: ns.mccme.ru Address: 62.117.108.2>server 194.67.23.130 Default Server: ns.mail.ru Address: 194.67.23.130>set type=MX>mail.ru Server: ns.mail.ru Address: 194.67.23.130 mail.ru preference = 10, mail exchanger = mxs.mail.ru mail.ru nameserver = ns.mail.ru mail.ru nameserver = ns1.mail.ru mail.ru nameserver = ns2.mail.ru mail.ru nameserver = ns4.mail.ru mail.ru nameserver = ns5.mail.ru mail.ru nameserver = ns3.mail.ru mxs.mail.ru internet address = 194.67.23.20 ns.mail.ru internet address = 194.67.23.130 ns1.mail.ru internet address = 194.67.57.103 ns2.mail.ru internet address = 194.67.57.104 ns4.mail.ru internet address = 194.67.57.4 ns5.mail.ru internet address = 194.67.23.232 ns3.mail.ru internet address = 194.67.23.17>set type=SOA>mail.ru Server: ns.mail.ru Address: 194.67.23.130 mail.ru origin = ns.mail.ru mail addr = hostmaster.mail.ru serial = 3209013119 refresh = 300 (5M) retry = 900 (15M) expire = 172800 (2D) minimum ttl = 300 (5M) mail.ru nameserver = ns.mail.ru mail.ru nameserver = ns1.mail.ru mail.ru nameserver = ns2.mail.ru mail.ru nameserver = ns4.mail.ru mail.ru nameserver = ns5.mail.ru mail.ru nameserver = ns3.mail.ru ns.mail.ru internet address = 194.67.23.130 ns1.mail.ru internet address = 194.67.57.103 ns2.mail.ru internet address = 194.67.57.104 ns4.mail.ru internet address = 194.67.57.4 ns5.mail.ru internet address = 194.67.23.232 ns3.mail.ru internet address = 194.67.23.17>exit
Описание. Кандидат должен уметь выполнить обратный DNS запрос для определения сети, в которой находится машина с данным IP адресом и собрать информацию об этой сети.
Практика. dig(1), whois(1)
Обратное преобразование имён, это преобразование IP адреса в имя машины. Для данного преобразования существует специальная PTR запись в файле зоны. Ответственен за эту зону провайдер, выделивший адрес IP в зоне типа C. Зона устроена следующим образом: в корневом домене имеется зона in-addr.arpa. внутри которой делают зоны для адресов класса A, внутри которых зоны для адресов класса B внутри которых зоны для адресов класса C. Когда вы при помощи команды host(1) пытаетесь разрешить IP адрес, он записывается задом наперёд, к нему добавляется справа домен in-addr.arpa. и делается DNS запрос о соответствующем адресе. Для команды dig(1) надо оформить запрос более конкретно:
$host 194.87.0.50 50.0.87.194.in-addr.arpa domain name pointer www.ru.$dig PTR 50.0.87.194.in-addr.arpa ; <<>> DiG 9.3.1 <<>> PTR 50.0.87.194.in-addr.arpa ;; global options: printcmd ;; Got answer: ;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 8640 ;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 3, ADDITIONAL: 4 ;; QUESTION SECTION: ;50.0.87.194.in-addr.arpa. IN PTR ;; ANSWER SECTION: 50.0.87.194.in-addr.arpa. 85912 IN PTR www.ru. ;; AUTHORITY SECTION: 87.194.in-addr.arpa. 85912 IN NS ns1.demos.net. 87.194.in-addr.arpa. 85912 IN NS ns.ripe.net. 87.194.in-addr.arpa. 85912 IN NS ns.demos.su. ;; ADDITIONAL SECTION: ns.ripe.net. 172314 IN A 193.0.0.193 ns.demos.su. 38415 IN A 194.87.0.8 ns.demos.su. 38415 IN A 194.87.0.9 ns1.demos.net. 60316 IN A 194.58.241.26 ;; Query time: 13 msec ;; SERVER: 172.16.0.1#53(172.16.0.1) ;; WHEN: Sun Apr 9 11:09:48 2006 ;; MSG SIZE rcvd: 200
Сервис whois(1) предназначен для работы с доменами первого уровня. С его помощью можно узнать кто ответственен за тот или иной домен:
$ whois yandex.ru
% By submitting a query to RIPN's Whois Service
% you agree to abide by the following terms of use:
% http://www.ripn.net/about/servpol.html#3.2 (in Russian)
% http://www.ripn.net/about/en/servpol.html#3.2 (in English).
domain: YANDEX.RU
type: CORPORATE
nserver: ns1.yandex.ru. 213.180.193.1
nserver: ns2.yandex.ru. 213.180.199.34
nserver: ns4.yandex.ru. 213.180.202.100
nserver: ns5.yandex.ru. 213.180.204.1
state: REGISTERED, DELEGATED
org: YANDEX, LLC.
phone: +7 495 9743555
fax-no: +7 495 9743565
e-mail: noc@yandex.net
registrar: RUCENTER-REG-RIPN
created: 1997.09.23
paid-till: 2006.10.01
source: TC-RIPN
Last updated on 2006.04.09 11:03:15 MSK/MSD
Используя данную информацию можно, например, узнать давно ли существует тот или иной интернет-магазин, какие DNS серверы ответствены за его зону. Понимая сегодняшние реалии пространства .ru я не стал бы принимать указанные телефоны близко к сердцу. Хотя, надо признать, что ситуация в домене .ru много лучше, чем в зоне .com. В нашей стране, при регистрации домена на физическое лицо, требуют хотя бы паспорт. Поэтому компетентные органы имеют хоть какой-то шанс найти ответственное лицо.
Описание. Кандидат BSDA должен уметь определить в каком порядке опрашиваются различные системы при разрешении имён и знать в каком конфигурационном файле это определяется
Практика. ping(8), telnet(1),
nsswitch.conf(5),
resolv.conf(5), host.conf(5)
По умолчанию имена хостов просматриваются сперва в локальной
базе /etc/hosts, затем в распределённой
базе DNS. Можно считать, что это и то и другое это одна большая
база данных, состоящая из двух источников: локального файла и
удалённой системы. За то в каком порядке опрашивать эти
источники отвечает системный вызов
nsdispatch(3), который конфигурируется при
помощи файла nsswitch.conf(5). Диспетчер
имён nsdispatch(3) отвечает не только за
порядок опроса источников в базе имен хостов (т.е. за работу
системного вызова gethostbyname(3)) Но и за
работу некоторых других баз (см. ниже). Далее фрагментарно дан
перевод к соответствующей странице man(1)
выполненный мною.
Файл nsswitch.conf(5) служит для
конфигурирования системы nsdispatch(3).
Данный конфигурационный файл управляет процессами разрешения
имён в базах данных хостов, пользователей, групп и т.д. Каждая
база данных состоит из нескольких источников (локальные файлы,
DNS, NIS), а порядок просмотра этих источников задаётся в
nsswitch.conf(5).
Каждая запись в nsswitch.conf(5) состоит из
имени базы и списка источников разделённых пробелами.
Поле с источниками может включать следующие имена:
/etc/hosts,
/etc/passwd и проч.
Поддерживаются следующие базы данных:
![]() | Замечание |
|---|---|
Всё сказанное в настоящем разделе верно для
FreeBSD, NetBSD и
DragonFly BSD, но не для
OpenBSD. В OpenBSD файла
nsswitch.conf(5) нет. В BSD
nsswitch.conf(5) впервые появился в
NetBSD, затем перекочевал в
FreeBSD и
DragonFly BSD.
|
Описание. Кандидат BSDA должен знать как устроена адресация IPv4 и как конвертировать адреса и сетевые маски из одного формата в другой.
Кому-то это может показаться странным, но на экзамене CISCO CCNA требуется умение в уме, без помощи калькулятора, переводить десятичные числа в двоичные. Люди могут попытаться возразить: как же так, уж у администратора всегда под рукой есть, не только калькулятор, но целый компьютер! Что тут можно сказать, элементарные навыки устного счёта входят в необходимый багаж знаний каждого жителя современного мегаполиса, а перевод подсетей из одного формата в другой, входит в необходимые культурные навыки каждого администратора. Не уметь в уме перевести маску подсети ***/26 в 255.255.255.192, это всё равно что в театре в носу ковырять, простите.
Однако жить вообще без калькулятора так же глупо, как глупо не уметь обходиться без него. Тем, кому нужен подобный сервис можно порекомендовать порт ipcalc:
$ ipcalc 192.168.0.1/26
Address: 192.168.0.1 11000000.10101000.00000000.00 000001
Netmask: 255.255.255.192 = 26 11111111.11111111.11111111.11 000000
Wildcard: 0.0.0.63 00000000.00000000.00000000.00 111111
=>
Network: 192.168.0.0/26 11000000.10101000.00000000.00 000000
HostMin: 192.168.0.1 11000000.10101000.00000000.00 000001
HostMax: 192.168.0.62 11000000.10101000.00000000.00 111110
Broadcast: 192.168.0.63 11000000.10101000.00000000.00 111111
Hosts/Net: 62 Class C, Private Internet
В данном разделе я опишу что такое маска подсети, формат CIDR, а затем опишу удобные приёмы устного пересчёта десятичных чисел в двоичные.
При помощи маски подсети система роутинга определяет находится ли данный адрес IP в данной подсети. Для этого используется операция побитового сложения. Маска подсети обязана состоять из некоторого количества единиц идущих подряд и следом за ними нулей. Маска подсети однозначно определяет насколько много адресов может быть в данной сети. Адрес находится в нашей подсети, если после побитового сложения с маской подсети, он дал адрес подсети (или т.н. базовый IP-адрес).
Рассмотрим пример: Пусть у нас есть адреса 192.168.0.1 и 192.168.0.65, какой из них находится в подсети 192.168.0.0 с маской 255.255.255.192 (Или в нотации CIDR 192.168.0.0/26). Побитовое сложение: 1+1=1 (истина и истина = истина), 1+0=0+1=0, 0+0=0.
192.168.0.1 = 11000000.10101000.00000000.00000001
255.255.255.192 = 11111111.11111111.11111111.11000000
сумма = 11000000.10101000.00000000.00000000 = 192.168.0.0
192.168.0.65 = 11000000.10101000.00000000.01000001
255.255.255.192 = 11111111.11111111.11111111.11000000
сумма = 11000000.10101000.00000000.01000000 = 192.168.0.64
Как видно, адрес 192.168.0.65 при сложении с маской подсети дал другую подсеть, он находится в подсети 192.168.0.64/26.
Как видно, маска подсети обязана состоять из некоторого количества единиц и следующих за ними нулей. В десятичной записи, маска подсети должна состоять из 0 и более байтов 255, и следующего за ними байта 0, либо 128 (1000 0000), либо 192 (1100 0000), либо 224, либо 240, либо 248, 252 (1111 1100). Бит 254 невозможен, так как в этом случае не останется адресов ни для одного хоста (в такой сети будет возможно только два адреса, при этом один будет соостветствовать адресу сети, а другой широковещательному адресу).
Таким образом, интересна не сама маска, а её длина. В нотации CIRD указывается сколько бит занимает маска подсети. Например, маска 255.255.255.192 занимает 8+8+8+2 бита и равна 26. Записывают её через дробь с адресом подсети: 192.168.0.0/26. Следующая подсеть с такой же маской — 192.168.0.64/26. Если адрес сети заканчивается на нули, то иногда их не указывают. Ряд приложений может понять запись 192.168/26, дополнив недостающие байты нулями, другие могут и не понять. (И вообще, запись CIDR, понимают далеко не все программы, увы.)
Операции устного сложения и вычитания даются человеку легче, чем операции умножения и деления, поэтому не стоит пытаться последовательно делить десятичное число на степени двойки, вычисляя остатки. Лучше сразу вычитать из числа степени двойки. Конечно вы можете избрать любой удобный для вас алгоритм, я делаю это так:
Пусть надо представить в двоичном формате число 170.
Для начала нам понадобится таблица степеней двойки:
| 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 |
| 1 | 2 | 4 | 8 | 16 | 32 | 64 | 128 |
Теперь мы будем последовательно сравнивать наше число со степенями двойки, если число больше либо равно степени, мы записываем единицу, и вычитаем из числа степень двойки, если меньше, записываем ноль и идём дальше:
170>128 ⇒ 1 170-128=42
42<64 ⇒ 0
42>32 ⇒ 1 42-32=10
10<16 ⇒ 0
10>8 ⇒ 1 10-8=2
2<4 ⇒ 0
2=2 ⇒ 1 2-2=0
0<1 ⇒ 0
Итого: 170 = 10101010
Обратное преобразование делается ещё проще: надо просто сложить те степени двойки, которым соответствуют единицы в двоичном числе.
Описание: Зная IP адрес и маску подсети кандидат должен уметь определить адрес подсети, широковещательный адрес, адреса хостов возможные в данной подсети.
Для начала ещё раз сошлёмся на работу утилиты ipcalc:
$ ipcalc 192.168.0.1/26
Address: 192.168.0.1 11000000.10101000.00000000.00 000001
Netmask: 255.255.255.192 = 26 11111111.11111111.11111111.11 000000
Wildcard: 0.0.0.63 00000000.00000000.00000000.00 111111
=>
Network: 192.168.0.0/26 11000000.10101000.00000000.00 000000
HostMin: 192.168.0.1 11000000.10101000.00000000.00 000001
HostMax: 192.168.0.62 11000000.10101000.00000000.00 111110
Broadcast: 192.168.0.63 11000000.10101000.00000000.00 111111
Hosts/Net: 62 Class C, Private Internet
Эта тема обсуждалась в Раздел 6.8.1, «Что такое маска подсети». Для определения адреса подсети надо побитово сложить маску подсети с IP-адресом:
192.168.0.1 = 11000000.10101000.00000000.00000001
255.255.255.192 = 11111111.11111111.11111111.11000000
сумма = 11000000.10101000.00000000.00000000 = 192.168.0.0
Переводу десятичных чисел в двоичные был посвящён Раздел 6.8.3, «Перевод десятичных чисел в двоичные».
Таким образом, мы вручную вычислили строку, которая в листинге команды ipcalc начиналась со слова Network.
Возьмём адрес подсети и заполним единицами те поля, которым в маске подсети соответствуют нули:
192.168.0.0 = 11000000.10101000.00000000.00000000
255.255.255.192 = 11111111.11111111.11111111.11000000
11000000.10101000.00000000.00111111 = 192.168.0.63
![]() | Замечание |
|---|---|
| Для того, чтобы удобно в уме перевести число 111111 в десятичную систему, не надо складывать 20+21+22+23+24+25. Это тоже самое, что 26-1. |
Таким образом, мы понимаем, что в подсети 192.168.0.0/26 возможны адреса от 192.168.0.0 до 192.168.0.63. При этом два адреса уйдут на адрес сети 192.168.0.0 и широковещательный адрес.
Какой адрес будет широковещательным? Быстрый ответ на этот вопрос — 192.168.0.63. Именно его мы видим в листинге команды ipcalc в строке озаглавленной Broadcast. Именно поэтому мы видим в этом листинге диапазон допустимых адресов машин от 192.168.0.1 до 192.168.0.62. Да, в подавляющем большинстве случаев это так, но тут есть одно лукавство:
Строго говоря, такого явления как широковещательный адрес IP вообще не существует. Широковещательная передача осуществляется на канальном уровне модели OSI. Широковещательный пакет, это пакет, у которого указан MAC-адрес назначения ff:ff:ff:ff:ff:ff. Т.е. аппаратный адрес назначения состоит только из единиц. Только такой пакет будет доставлен коммутаторами (работающими на канальном уровне OSI) ко всем сетевым интерфейсам.
Что же до широковещательного адреса IP, то это такой адрес, которому ваш сетевой интерфейс при маршрутизации (т.е. процессе выбора MAC-адреса назначения) поставит в соответствие широковещательный MAC-адрес. Какой именно IP будет соответствовать широковещательной передаче, это ваше личное дело. В подавляющем большинстве случаев выбирается последний адрес из доступного диапазона, т.е. в нашем случае 192.168.0.63, но это не догма.
![]() | Замечание |
|---|---|
| Конечно, существуют операционные системы, которые не в состоянии назначить нестандартный широковещательный IP, но BSD (да и Linux) не из их числа. |
Описание. Кандидат BSDA должен понимать основы адресации IPv6, включая: компоненты адреса IPv6; поддержку нескольких адресов (link, local, global) на интерфейсе; различные способы записи адреса: запись префикса (aaaa:bbbb::dddd/17) и адресный формат (48 бит на префикс, 16 бит на подсеть и 64 бита на хост). В дополнение кандидат должен понимать процесс автоконфигурирования когда маршрутизатор отсылает префиксы или опрашивается, и как хост добавляет 64 бита, которые получаются из MAC-адреса. Наконец, кандидат должен уметь решать проблемы связи по протоколу IPv6.
Практика. ifconfig(8), ping6(8), rtsol(8)
Вот уже более 10 лет нам пророчат пришествие протокола IPv6 в замен IPv4, а между тем его всё нет как нет. Между тем закрывать на него глаза и дальше становится просто опасно. Во многих операционных системах в той или иной степени поддержка IPv6 уже включена и BSD из их числа. Многие администраторы, к сожалению, закрывают глаза на то, что в их IPv4 сетях уже фактически поднята сеть IPv6, а они об этом даже не подозревают. Закрывают брандмауэром порты по протоколу IPv4, а трафик IPv6 просто не видят. Видимо правильным решением было бы отключение данного протокола на уровне ядра, в случае, если он не поднят в сети. В системе FreeBSD для этого можно закомментировать в ядре опцию
options INET6 # IPv6 communications protocols
О проблемах безопасности связанных с появлением протокола IPv6 можно прочитать в статье Натальи Мельниковой [url://IPv6-security].
Что касается документации по IPv6, как ни странно, её довольно мало. В основном речь идёт о переводах RFC. Оригинальная документация на английском языке (список, конечно, неполный):
Что до переводов на русский язык, я могу порекомендовать читателю замечательную статью А.Ю. Семёнова [url://Семёнов-IPv6], которая на 98% представляет собой перевод упомянух RFC. А так же своеобразный HOWTO из FreeBSD-handbook [url://FB-handbook-IPv6-ru], который, в части касающейся документации IPv6 так же является цитатой из упомянутых RFC. Фактически никакой другой документации в настоящий момент в сети нет. (А может и не надо.)
Адреса в IPv6 настолько длинные, что их запись в привычной десятичной нотации становится весьма неудобной (128 бит = 16 байт). Поэтому их записывают в шестнадцатеричном формате. Но даже и в этом случае адреса оказываются слишком длинными, поэтому придуманы некоторые способы сокращённой записи.
Итак, адреса делят на 8 пар байт символом двоеточия: FEDC:BA98:7654:3210:FEDC:BA98:7654:3210.
Лидирующие нули в паре байт можно не записывать, нулевые пары
байт можно заменять на ::. Таким
образом, следующие три строки обозначают один и тот же адрес:
1080:0000:0000:0000:0008:0800:200C:417A,
1080:0:0:0:8:800:200C:417A, 1080::8:800:200C:417A. Разумеется в
адресе может встретиться только один знак :: иначе возникнет неоднозначность.
Допустимо записывать часть адреса в десятичном формате,
разделяя десятичные знаки точками: ::FFFF:129.144.52.38. Такая форма
удобна в случаях, когда адрес IPv4 является частью адреса IPv6
(см. ниже).
Левая часть адреса IPv6 может являться префиксом сети. В этом случае её длина в битах записывается через дробь, подобно записи CIDR.
Варианты правильного написания префикса 12AB00000000CD3: 12AB:0000:0000:CD30:0000:0000:0000:0000/60,
12AB::CD30:0:0:0:0/60, 12AB:0:0:CD30::/60.
А вот так писать нельзя:
12AB:0:0:CD3/6012AB::CD30/6012AB:0000:0000:0000:0000:000:0000:CD3012AB::CD3/6012AB:0000:0000:0000:0000:000:0000:0CD3