У истоков APACHE лежит CERN httpd – веб-сервер, написанный на Cи в 1991 в ЦЕРН — Европейской организации по ядерным исследованиям, крупнейшей в мире лаборатории физики высоких энергий.

Сергей Яковлев, Консультант, независимый специалист

Яковлев Сергей — независимый разработчик с многолетним опытом прикладного и системного программирования; вносит вклад в развитие open-source на своем персональном сайте www.iakovlev.org. Консультант.



27.01.2011

У истоков APACHE лежит CERN httpd – веб-сервер, написанный на Cи в 1991 в ЦЕРН — Европейской организации по ядерным исследованиям, крупнейшей в мире лаборатории физики высоких энергий. Разработка программы осуществлялась на компьютере NeXT под управлением операционной системы NeXTSTEP, позже она была перенесена под unix.

Одним из авторов этого веб-сервера является Tim Berners-Lee, который еще в 1984 году начал работать во внутренней сети института и писать программы с использованием Remote Procedure Call (RPC), которые могли вызывать другие программы удаленно на другом компьютере. В 1988 у Тима созрела в голове модель гипертекстовой системы. К тому времени в институте работало 250 человек, и существующих майнфреймов уже не хватало для выполнения всех запросов. В 1990 году Тим привез из штатов компьютер NeXT и получил добро от начальства на разработку проекта под названием WorldWideWeb. Вскоре Тим уже имел прототип работающего браузера (см. рисунок).

Tim Berners-Lee

К проекту подключился Nicola Pellow, который написал текстовой браузер, работающий практически на любой платформе. Был принят формат HTML, который пришел на смену уже существующему формату SGML. Для получения файлов в сети был придуман URL:

	scheme : // host.domain:port / path / path # anchor

К тому времени уже давно существовала доменная система имен - Domain Name System (DNS). Клиент создавал соединение TCP-IP к хосту, используя доменное имя либо ip-адрес. В 1991 году новый веб-сервер работал на X-Workstation, Macintosh и PC. В 1992 году число веб-серверов достигло 50, часть их уже работала в США. В 1993 году сервер компилировался на платформах HP, SGI, Sun, DEC, NeXT, была добавлена авторизация, появилась утилита htadm для работы с файлом паролей, поддержка изображений. В 1994 году перенесен на Solaris, добавлена утилита cgiparse, реализован режим прокси.

Обычно CERN httpd работал на 80-м порту, но мог также выступать в качестве прокси для обслуживания внутренней сети, которая была прикрыта межсетевым. В последнем случае для повышения эффективности этот сервер имел возможность кэшировать документы.

Его достоинством является то, что для уже существующего межсетевого экрана не нужно модифицировать клиентов для таких протоколов, как ftp, gopher и т.д. - управлением такими клиентами справляется сам CERN. В случае прокси CERN выступает одновременно и как сервер, и как клиент: для внутренней сети он является сервером, для внешней - клиентом.

CERN httpd был разработан для обслуживания статических веб-страниц. Он получал из сети URL-запросы с помощью протокола HTTP/0.9 , переводил их в пути и возвращал контент запрашиваемых страниц. На раннем этапе CERN работал с внешними программами для обработки запросов. Была построена система обработки таких запросов, которая вызывала командную оболочку или внешний скрипт. Вывод скрипта перенаправлялся в браузер, в котором страница генерировалась на лету. Эта схема позволяла передавать скрипту список аргументов, создающих поисковую систему.

Сегодня мы рассмотрим:

  1. Конфигурация CERN httpd.
  2. Защита CERN httpd.
  3. CERN httpd в роли прокси-сервера.
  4. CERN httpd и CGI.
  5. CERN httpd и графический контент.
  6. Архитектура CERN httpd.
  7. Тест.

1. Конфигурация CERN httpd

Последняя финальная версия 3.0 была выпущена в 1996 году. Конфигурация CERN осуществлялась привычным образом: есть главный файл httpd.conf , в котором прописывался порт по умолчанию. Пример такого файла:

# домашний каталог
ServerRoot /usr/www 

# полное доменное имя
HostName www.rummidge.ac.uk

# порт 
Port	80

# авторизация: сервер запускается от рута, а потом переключается и 
# работает от имени этого пользователя
UserId	nobody
GroupId	nogroup

# страница по умолчанию
Welcome home.html

# логирование
AccessLog	/where/ever/httpd-log
ErrorLog	/where/ever/httpd-errors

#	домашний каталог ~/public_html
# В этом случае, если будет сделан запрос http://www.host.name/~ a_user/mydir/index.html, 
# он будет транслирован в домашний каталог пользователя a_user:
# /home/a_user/public_html/mydir/index.html
UserDir	public_html

# каталог для запуска cgi-скриптов
Exec	/cgi-bin/*	/your/script/directory/*

# правила трансляции
Pass	/*	/local/Web/*

2. Защита CERN httpd

В CERN существует несколько видов защиты, которые можно разделить на 3 основные группы:

  1. Ограничения по хостам.
  2. Ограничения по пользователям.
  3. Ограничения файловой системы на базе Access Control Lists.

Для ограничения по хостам в конфигурационном файле существует параметр Protect: в примере прописано разрешение для клиентских запросов, которые приходят с хостов, оканчивающихся на "ac.uk" или "ja.net". В этом случае клиент получает доступ к любым документам, урлы которые начинаются с /research-grants/ или /grant-awards/:

	Protection UK_ACADEMIC 
	{
		AuthType Basic
		GetMask @*.ac.uk, @*.ja.net
	}

	Protect /research-grants/* UK_ACADEMIC
	Protect /grant-awards/* UK_ACADEMIC

При этом нужно учитывать тот факт, что если в конфигурационном файле перед командой Protect стоит команда Pass на каталог /research-grants/, то разрешение будет получено в любом случае, независимо от того, есть Protect или нет.

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

	Protection WEBWEAVERS 
	{
		AuthType Basic
		PasswordFile /WWW/Admin/passwd
		GetMask handley, crowcroft
	} 

	Protect /secret/* WEBWEAVERS

Определятся файл с зашифрованными паролями. Работа с файлом паролей выполняется с помощью команды htadm, которая идет в пакете исходников, которую можно применить так:

	htadm -adduser /путь/к/файлу/паролей имя_пользователя

Пользователь должен будет набрать логин и пароль для дальнейшего доступа.

Пользователей можно разбить на группы с помощью специального файла group:

	webweavers: handley, crowcroft
	syspeople: jonathan, barry, ray, steve
	trusted: authors, syspeople, anne
	uclcs: @*.cs.ucl.ac.uk, @128.16.*, @193.63.58.*
	verysecure: trusted@*.cs.ucl.ac.uk

Для них прописываются правила:

	Protection VERYSECURE 
	{
		AuthType Basic
		PasswordFile /WWW/Admin/passwd
		GroupFile /WWW/Admin/group
		GetMask verysecure
	}

	Protect /secret/* VERYSECURE

При этом доступ к каталогу secret будет разрешен только группе trusted.

Доступ на уровне ACL полезен тогда, когда нужно разграничить доступ к отдельным файлам. Создается ACL-файл с именем www_ac:

	ndex.html : GET : @*.cs.ucl.ac.uk
	secret*.html: GET,POST : trusted@*.cs.ucl.ac.uk
	*.html : GET : webweavers

В данном примере для пользователей группы webweavers снимаются вообще все ограничения в доступе.


3. CERN httpd в роли прокси-сервера

CERN httpd в роли прокси-сервера

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

Port 8080
Pass http:*
Pass ftp:*
Pass gopher:*
Pass wais:*

Защита в прокси реализована как по именам:

    Protection  protname  {
        Mask @(*.cern.ch, *.desy.de)
    }

Так и на уровне IP:

    Protection  protname  {
        Mask  @(128.141.*.*, 131.169.*.*)
    }

Для сайтов, которые не находятся в домене UK, прописывается внешний прокси:

	http_proxy http://www.hensa.ac.uk/
	gopher_proxy http://www.hensa.ac.uk/
	ftp_proxy http://www.hensa.ac.uk/
	no_proxy uk

Настраивается суммарное место на диске - 300 метров, каталог для хранения кеша, перидичность очистки кеша:

Caching ON
NoCaching http://www.cs.ucl.ac.uk/*
CacheRoot /cs/research/mice/boom/scratch1/wwwcache
CacheSize 300 M
CacheLastModifiedFactor 0.2
GcDailyGc 2:00

4. CERN httpd и CGI

Начиная с версии 2.15, в CERN появился интерфейс работы с CGI скриптами. Адрес скрипта прописывался прямо в URL и отдавал контент веб-серверу. CGI настраивался в конфигурационном файле с помощью директивы Exec:

        Exec /url-prefix/*  /physical-path/*

Все скрипты лежали в домашней директории ServerRoot.

Такому скрипту можно было с сервера передавать параметры стандартным образом: через QUERY_STRING. Скрипт возвращал серверу результат, который начинался с Content-Type:

        Content-Type: text/html
        <HEAD>
        <TITLE>Script test></TITLE>
        </HEAD>
        <BODY>
        <H1>Привет !</H1>
        ....
        </BODY>

Скрипт также мог вернуть какой-то статический документ с помощью Location:

	Location: http://www.w3.org/pub/WWW/

В исходниках CERN можно найти утилиту cgiparse, которая обрабатывает методы GET и POST. В случае GET читается стандартный QUERY_STRING, в случае POST читается стандартный ввод. Можно написать сценарий на языке shell, который смоделирует работу cgiparse:

	#!/bin/sh
	eval `cgiparse -form`
	$filename=$FORM_pubname
	$doc_root="/cs/research/www/www/htdocs"
	$fullfilename=$doc_root"/misc/uk/london/pubs/auto-"$filename".html"

	#Write the entry to a file in HTML
	echo "<TITLE>"$FORM_pubname"</TITLE>" > $fullfilename
	echo "<H1>"$FORM_pubname"</H1><HR>" > $fullfilename
	echo "<I>"$FORM_pubaddress"</I><P>" > $fullfilename
	echo "<h2>Area:</h2> "$FORM_area"\n" > $fullfilename
	echo -n "<h2>Description:</H2>" > $fullfilename

5. CERN httpd и графический контент

В CERN был реализован механизм просмотра "кликабельных" картинок внутри html-документа. При клике на нее контент возвращала специальная утилита htimage. Для этого нужно было создать специальный файл, в котором прописывались правила нахождения картинок. При этом внутри html-документа нужно было прописать:

		<A HREF="/img/my_image.conf">
			<IMG SRC="Image.gif" ISMAP>
		</A>

В исходниках можно найти утилиту htimage, которая показывает картинку.


6. Архитектура CERN httpd

Исходники CERN версии 3.0 состоят из 2-х частей: библиотеки libwww и, собственно, самого демона httpd. Библиотека libwww была написана в 1992 году в рамках все того же CERN. Эта библиотека написана с прицелом на производительность, имеет модульную структуру и возможность для расширения. Она включает в себя эффективный код для работы с HTTP, URL, может быть использована для создания роботов на стороне клиента, браузеров и т. д. Обработка запросов происходит в асинхронном режиме.

Библиотека libwww имеет модульную архитектуру и состоит из 5 основных частей:

  1. Базовые модули: здесь происходит разделение кода для того, чтобы эта библиотека была платформенно-независимой. Она включает большое количество условных макросов, которые делают библиотеку переносимой.
  2. Ядро: оно невелико по размеру и включает в себя базовые функции для сетевого доступа, анализа сетевых объектов, управления действиями пользователя, выполняет ведение журнала событий. Ядро реализует стандартный интерфейс к пользовательским программам и управляет внешними запросами.
  3. Потоковые модули: данные, передаваемые от приложения в сеть и приходящие обратно, используют потоки. Поток представляет из себя объект в стиле ANSI C файлового потока. Как правило, поток получает входящие данные, обрабатывает их и формирует вывод.

    Модули доступа: протокольно-специфичные модули - HTTP, FTP, Gopher, WAIS, NNTP, Telnet, rlogin, TN3270.

  4. Модули приложений: модули, специфичные для конкретного приложения.

Само приложение при работе с libwww использует напрямую последние 3 группы модулей.

Более подробно мы поговорим о libwww во втором документе нашего Apache-цикла.

CERN httpd на каждый запрос создает новый процесс (fork), который занимает минимальное количество памяти и несет в себе необходимую информацию для системных вызовов. CERN потребляет память в линейной зависимости пропорционально количеству запросов.

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

Главный управляющий файл демона - HTDaemon.c. Инициализация демона происходит следующим образом:

  1. HTDefaultConfig() ( HTConfig.c) - установка конфигурации по умолчанию.
  2. HTFileInit() ( HTSInit.c ) - инициализация таблицы суффиксов.
  3. Обработка аргументов командной строки.
  4. HTServerInit() ( HTConfig.c ) - инициализация таблицы ошибок и иконок.
  5. Вызов функции do_bind() - биндится порт и начинается его прослушивание - вызов стандартных библиотечных функций socket,bind,listen:
    	  socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
    	  if ((setsockopt(master_soc,SOL_SOCKET,SO_KEEPALIVE,...)
  6. Далее всю работу на себя берет базовый цикл server_loop() , в котором вызывается системный вызов select с таймаутом для регистрации запросов. При получении клиентского запроса порождается дочерний процесс с вызовом wait3 с параметром WNOHANG, создается новый сокет, который передается дочернему процессу.
  7. Дочерний процесс вызывает функцию HTHandle(), в которой генерируются структуры для хранения информации о запросе. Запрос разбирается и создается обьект HTRequest. Парсинг запроса осуществляется с помощью модуля HTFormat.c из библиотеки libwww.
  8. Вызывается HTHandle(), который создает выходящий поток, куда записывается результат запроса. Запись в поток выполняет модуль HTWriter.c библиотеки libwww.
  9. HTRetrieve() возвращает с диска запрашиваемый документ.

Этот алгоритм можно представить графически (см. рисунок):

Алгоритм

7. Тест

В тесте был использован Apache Bench (далее AB). Данная стандартная утилита входит во многие пакеты, в том числе и в стандартный дистрибутив Apache.

В качестве подопытных материалов были выбраны 3 дистрибутива:

  1. CERN httpd 2.3
  2. Apache 1.3.42
  3. Apache 2.2.15

Все дистрибутивы были собраны на ядре 2.6.34, и были проведены следующие тесты с использованием статичного html-документ размером в 250 килобайт. Следующая команда выполняет 1000 GET-запросов по локальному адресу с числом одновременно посылаемых сообщений, равным 100:

	ab -n 1000 -c 100 http://127.0.0.1/test_doc.html

Вывод для CERN httpd:

This is ApacheBench, Version 2.3 <$Revision: 655654 $>
Benchmarking 127.0.0.1 (be patient)
Server Software:        CERN/3.0A
Server Hostname:        127.0.0.1
Server Port:            80
Document Length:        252665 bytes

Concurrency Level:      100
Time taken for tests:   6.455 seconds
Complete requests:      1000
Failed requests:        0
Write errors:           0
Total transferred:      253127896 bytes
HTML transferred:       252943528 bytes
Requests per second:    154.92 [#/sec] (mean)
Time per request:       645.489 [ms] (mean)
Time per request:       6.455 [ms] (mean, across all concurrent requests)
Transfer rate:          38295.79 [Kbytes/sec] received

Собранный из исходников apache 1.3.42 с конфигурацией по умолчанию:

Concurrency Level:      100
Time taken for tests:   1.080 seconds
Complete requests:      1000
Failed requests:        0
Write errors:           0
Total transferred:      253626632 bytes
HTML transferred:       253374879 bytes
Requests per second:    926.25 [#/sec] (mean)
Time per request:       107.962 [ms] (mean)
Time per request:       1.080 [ms] (mean, across all concurrent requests)
Transfer rate:          229416.78 [Kbytes/sec] received

Собранный из исходников apache 2.2.15 с конфигурацией по умолчанию:

Concurrency Level:      100
Time taken for tests:   0.709 seconds
Complete requests:      1000
Failed requests:        0
Write errors:           0
Total transferred:      252921000 bytes
HTML transferred:       252665000 bytes
Requests per second:    1410.80 [#/sec] (mean)
Time per request:       70.882 [ms] (mean)
Time per request:       0.709 [ms] (mean, across all concurrent requests)
Transfer rate:          348457.80 [Kbytes/sec] received

Т.е. мы видим, что максимальную производительность в этом статическом тесте показывает второй Apache, и скорость выросла за 15 лет - с момента последнего релиза CERN httpd в 1996 г. - примерно на порядок. Производительность первого Apache меньше второго примерно в полтора раза.


Заключение

Сегодня мы рассмотрели проект CERN httpd, который лежит у истоков Apache.

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

Ресурсы

Комментарии

developerWorks: Войти

Обязательные поля отмечены звездочкой (*).


Нужен IBM ID?
Забыли Ваш IBM ID?


Забыли Ваш пароль?
Изменить пароль

Нажимая Отправить, Вы принимаете Условия использования developerWorks.

 


Профиль создается, когда вы первый раз заходите в developerWorks. Информация в вашем профиле (имя, страна / регион, название компании) отображается для всех пользователей и будет сопровождать любой опубликованный вами контент пока вы специально не укажите скрыть название вашей компании. Вы можете обновить ваш IBM аккаунт в любое время.

Вся введенная информация защищена.

Выберите имя, которое будет отображаться на экране



При первом входе в developerWorks для Вас будет создан профиль и Вам нужно будет выбрать Отображаемое имя. Оно будет выводиться рядом с контентом, опубликованным Вами в developerWorks.

Отображаемое имя должно иметь длину от 3 символов до 31 символа. Ваше Имя в системе должно быть уникальным. В качестве имени по соображениям приватности нельзя использовать контактный e-mail.

Обязательные поля отмечены звездочкой (*).

(Отображаемое имя должно иметь длину от 3 символов до 31 символа.)

Нажимая Отправить, Вы принимаете Условия использования developerWorks.

 


Вся введенная информация защищена.


  • Bluemix

    Узнайте больше информации о платформе IBM Bluemix, создавайте приложения, используя готовые решения!

  • developerWorks Premium

    Эксклюзивные инструменты для построения вашего приложения. Узнать больше.

  • Библиотека документов

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

static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=40
Zone=Open source, Linux
ArticleID=619912
ArticleTitle=У истоков Apache. Часть 1: CERN httpd
publish-date=01272011