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

• Вместо запуска отдельного демона для каждой службы inetd отслеживает заданный набор портов сокетов и при необходимости запускает соответствующие процессы. Таким образом количество выполняющихся процессов в системе снижается.

• Написание серверных программ, запускаемых с помощью inetd, упрощается, поскольку этот демон выполняет определенные действия, которые требуются при запуске любых сетевых серверов.

Поскольку демон inetd следит за диапазоном служб и при необходимости запускает другие серверы, его иногда называют интернет-суперсервером.

В дистрибутивах Linux предоставляется расширенная версия inetd под названием xinetd, которая, помимо всего прочего, обладает целым рядом улучшений, связанных с безопасностью. Информацию об xinetd можно найти на www.xinetd.org.

Принцип работы демона inetd

Обычно демон inetd запускается вместе с системой. Перейдя в фоновый режим (см. раздел 37.2), он выполняет следующие шаги.

1. Для каждой службы, заданной в конфигурационном файле /etc/inetd.conf, демон создает сокет подходящего типа (потоковый или датаграммный) и привязывает его к указанному порту. Для каждого TCP-сокета дополнительно включается поддержка входящих соединений с помощью вызова listen().

2. Используя системный вызов select() (см. подраздел 59.2.1), inetd отслеживает входящие датаграммы или соединения для всех сокетов, созданных в предыдущем шаге.

3. До появления доступной для чтения датаграммы в UDP-сокете или запроса о подключении в TCP-сокете вызов select() блокируется. В случае с TCP-соединением inetd сначала выполняет для соединения вызов accept() и только потом переходит к следующему шагу.

4. Чтобы запустить сервер, указанный для текущего сокета, inetd вызывает fork(), создавая новый процесс, запускающий серверную программу с помощью функции exec(). Но, прежде чем выполнять exec(), дочерний процесс проделывает следующие действия.

• Закрывает все файловые дескрипторы, унаследованные от родителя, за исключением относящегося к сокету, для которого доступна UDP-датаграмма или установлено TCP-соединение.

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

• При необходимости устанавливает запущенному серверу идентификаторы пользователя и группы, соответствующие значениям, указанным в файле /etc/inetd.conf.

5. Если в шаге 3 было принято TCP-соединение, inetd закрывает подключенный сокет (так как он нужен только на серверной стороне).

6. Сервер inetd возвращается к шагу 2.

Файл /etc/inetd.conf

Работа демона inetd управляется с помощью конфигурационного файла; обычно им является /etc/inetd.conf. Каждая строчка в этом файле описывает одну службу, запуском которой занимается inetd. В листинге 56.5 показан пример записей в файле /etc/inetd.conf, поставляющемся вместе с одним из дистрибутивов Linux.

Листинг 56.5. Пример записей в файле /etc/inetd.conf

# echo stream tcp nowait root internal

# echo dgram udp wait root internal

ftp stream tcp nowait root /usr/sbin/tcpd in.ftpd

telnet stream tcp nowait root /usr/sbin/tcpd in.telnetd

login stream tcp nowait root /usr/sbin/tcpd in.rlogind

Первые две строки в листинге 56.5 закомментированы с помощью символа # в начале; мы приводим их здесь, так как они связаны со службой echo, которую рассмотрим чуть ниже.

Каждая запись в файле /etc/inetd.conf состоит из следующих полей, разделенных пробельными символами.

• Имя службы. В этом поле содержится имя службы, в сочетании с протоколом применяемое для поиска по файлу /etc/services с целью определить номер порта, который должен отслеживаться демоном inetd.

Тип сокета. В данном поле определяется тип сокета, используемый службой, например stream или dgram.

Протокол. В этом поле содержится протокол, который будет применен для данного сокета. Здесь можно указывать любые интернет-протоколы, перечисленные в файле /etc/protocols (и задокументированные на странице protocols(5) руководства), но в подавляющем большинстве случаев используется одно из двух значений: tcp (для TCP) или udp (для UDP).

Перейти на страницу:

Похожие книги