Запуск CGI-скриптов в Apache при помощи SuExec на сервере Ubuntu
Apache – самый популярный веб-сервер в мире. Он обслуживает статический и динамический контент сайтов в различных контекстах.
Один из самых распространённых способов генерирования динамического контента – это использование интерфейса CGI (Common Gateway Interface, общий шлюзовой интерфейс), который позволяет выполнять генерирующие веб-контент скрипты, написанные на разных языках программирования.
Однако запуск любого исполняемого кода в веб-пространстве всегда влечёт за собой определенный риск.
Это руководство поможет запустить CGI-скрипт при помощи модуля suexec, который позволяет запускать сценарии, не расширяя привилегий пользователя без крайней необходимости.
Требования
- Настроенный сервер Ubuntu 12.04;
- Предварительно установленный стек LAMP.
Поддержка CGI
В Ubuntu веб-сервер Apache поддерживает отдельный каталог CGI-скриптов, который пуст по умолчанию.
В целом, CGI-скрипт – это любая программа, способная возвращать HTML и любые другие объекты или форматы, которые можно визуализировать в браузере.
Если открыть каталог настроек Apache и просмотреть включенные модули в каталоге mods-enabled, можно найти файл, отвечающий за поддержку CGI:
less /etc/apache2/mods-enabled/cgi.load
LoadModule cgi_module /usr/lib/apache2/modules/mod_cgi.so
Этот файл содержит директиву, которая включает модуль CGI.
Модуль уже загружен, но пока что он не обслуживает скрипты; для этого его нужно включить в определенной среде.
Откройте стандартный файл виртуального хоста:
sudo nano /etc/apache2/sites-enabled/000-default
Сначала в нем нужно указать ServerName:
ServerName домен_или_IP_адрес_сервера
ServerAdmin email_адрес
. . .
Немного ниже в файле находится раздел, который отвечает за поддержку скриптов CGI:
ScriptAlias /cgi-bin/ /usr/lib/cgi-bin/
AllowOverride None
Options +ExecCGI -MultiViews +SymLinksIfOwnerMatch
Order allow,deny
Allow from all
Рассмотрим его подробнее.
Директива ScriptAlias указывает каталог, из которого Apache может запускать скрипты. В данном случае это каталог /usr/lib/cgi-bin. Второй аргумент задаёт путь к каталогу скриптов, а первый (/cgi-bin/) – это URL.
Это значит, что скрипт по имени script.pl, хранящийся в каталоге /usr/lib/cgi-bin, будет запускаться по ссылке:
Его вывод вернётся в браузер и будет визуализирован на этой странице.
Раздел Directory содержит правила работы каталога /usr/lib/cgi-bin. Обратите внимание на:
Эта опция на самом деле не нужна, поскольку все настройки предназначены для каталога скриптов CGI, указанного в ScriptAlias. Однако она не повредит конфигурацию, потому её можно оставить.
Чтобы иметь возможность размещать CGI-скрипты вне каталога ScriptAlias, нужно добавить в раздел Directory следующие опции:
Options +ExecCGI
AddHandler cgi-script .pl .rb [extensions to be treated as CGI scripts]
Сохраните и закройте файл. Если вы внесли в него какие-либо поправки, перезапустите веб-сервер:
sudo service apache2 restart
Тестовый CGI-скрипт
Теперь попробуйте создать тестовый CGI-скрипт.
Как указано в настройках, для хранения скриптов CGI предназначен отдельный каталог /usr/lib/cgi-bin. Пользователи без прав root не имеют права на запись в этом каталоге, потому нужно открыть следующий файл с sudo:
sudo nano /usr/lib/cgi-bin/test.pl
Этот файл имеет расширение .pl, потому что это Perl-скрипт; Apache будет запускать все файлы в этом каталоге и передавать их соответствующим программам.
Укажите, что этот файл нужно выполнять в Perl, добавив в начало скрипта:
После этого необходимо указать тип генерируемого контента. Это нужно для того, что веб-браузер понимал, как отображать полученный вывод. К примеру, данный скрипт будет выводить контент HTML (text/html) при помощи стандартной функции Perl.
print «Content-type: text/html\n\n»;
После этого можно добавлять любые функции, необходимые для генерирования соответствующего контента для сайта. В данном примере будет использоваться только простой HTML; самостоятельно вы можете разработать и более сложный скрипт.
Добавьте к первым двум обязательным строкам следующий набор компонентов. В результате получится такой скрипт:
#!/usr/bin/perl
print «Content-type: text/html\n\n»;
print «
print ««;
print «
Hello, World.
«;
print «
This is some regular text.
«;
print «
The possibilities are great.
«;
print ««;
Сохраните и закройте файл.
Сделайте его исполняемым:
sudo chmod 755 /usr/lib/cgi-bin/test.pl
Если теперь открыть в браузере домен и каталог CGI, а затем добавить имя скрипта, на экране появится вывод данного скрипта.
your_domain.com/cgi-bin/test.pl
Hello, World.
This is some regular text.
The possibilities are great.
Как видите, эта простейшая страница правильно отображается.
При попытке просмотреть исходник страницы на экране появятся только аргументы для отображения, без типа контента:
Hello, World.
This is some regular text.
The possibilities are great.
Включение модуля SuExec
Создавая скрипт, который может выполнить любой пользователь, вы подвергаете безопасность сервера некоторому риску. В идеале, право на запуск скриптов должно быть только у одного заблокированного пользователя. Для этого и предназначен модуль suexec.
Установите модифицированную версию модуля suexec, которая позволяет настраивать поддерживаемые каталоги (раньше эту функцию можно было получить только путём перекомпиляции модуля из исходного кода).
sudo apt-get install apache2-suexec-custom
sudo a2enmod suexec
Создайте нового пользователя, которому будут принадлежать все права на файлы скрипта. Если сервер обслуживает несколько сайтов, создайте отдельного пользователя для каждого из них.
sudo adduser script_user
Можно пропустить все запросы данных (включая запрос на установку пароля).
Создайте каталог скриптов в домашнем каталоге нового пользователя:
sudo mkdir /home/script_user/scripts
Модуль suexec требует очень строгого контроля над правами на запись в каталоге. Передайте права на каталог пользователю script_user и измените права доступа, чтобы никто не мог писать в нем:
sudo chown script_user:script_user /home/script_user/scripts
sudo chmod 755 /home/script_user/scripts
Теперь создайте скрипт-файл, а затем скопируйте и вставьте в него созданный ранее скрипт:
sudo -u script_user nano /home/script_user/scripts/attempt.pl
#!/usr/bin/perl
print «Content-type: text/html\n\n»;
print «
print ««;
print «
Hello, World.
«;
print «
This is some regular text.
«;
print «
The possibilities are great.
«;
print ««;
Сделайте файл исполняемым. Все права на файл должны быть только у пользователя script_user; их можно настроить при помощи модуля suexec:
sudo chmod 700 /home/script_user/scripts/attempt.pl
После этого отредактируйте настройки виртуального хоста Apache, чтобы новый пользователь мог запускать скрипт.
sudo nano /etc/apache2/sites-enabled/000-default
Сначала настройте каталог CGI; вместо директивы ScriptAlias используйте директиву Alias в комбинации с опцией ExecCGI и директивой SetHandler.
Добавьте в файл:
Теперь можно получить доступ к скриптам, перейдя в подкаталог /scripts. Чтобы включить эти функции suexec, добавьте следующую строку вне раздела Directory, но в рамках раздела VirtualHost.
SuexecUserGroup script_user script_user
Сохраните и закройте файл.
Теперь нужно задать каталоги, которые модуль suexec будет считать валидными (это та функция, которая отсутствует в стандартной версии модуля). Откройте конфигурационный файл suexec.
sudo nano /etc/apache2/suexec/www-data
В начале файла нужно указать путь к каталогу scripts.
Сохраните и закройте файл.
Теперь перезапустите веб-сервер.
sudo service apache2 restart
Откройте в браузере ссылку:
И на экране появится:
Hello, World.
This is some regular text.
The possibilities are great.
Обратите внимание: после настройки модуля suexec обычный каталог CGI не работает; такое поведение предназначено для контроля привилегий скриптов.
Заключение
Теперь вы можете создавать сценарии CGI и запускать их относительно безопасным способом. Скрипты CGI очень полезны, так как позволяют быстро добавить на сайт динамический контент. А при помощи модуля suexec можно защитить эти скрипты.
Однако будьте предельно внимательны при работе с модулем suexec! Неправильная настройка модуля может создать дополнительные уязвимости безопасности. Чтобы выяснить потенциальные уязвимости suexec, изучите конфигурацию модуля.
Как включить cgi в apache
Если у Вас от чего-то все работает, то очень СТРАННО. Как правило новичку, чтобы запустить скрипт приходится попотеть. Какие же основные проблемы возникают при запуске скрипта ?
Настройки сервера
Первой, но не главной причиной может послужить неправильная настройка сервера. Скорее всего попросту он не имеет права запускать скрипты из этой директории. Я всегда рассматриваю только Web-сервер Apache, поэтому приведу настройки для него. Кстати сегодня в ComputerWorld(8.02.2000) опубликовали результаты исследований RUNet‘a. Оказалось, что Apache установлен на 78% всех серверов, веб-сервера от Microsoft — 19%, доля остальных серверов составляет по 1%. Так что я опять говорю, лучше Apache Вы не найдете .
Ладно отвлеклись от темы. Все настройки Apache для каждой директории задаются с помощью файла .htaccess. Если такового в вашей директории не имеется, то создавайте его. В него запишите следующее:
Options ExecCGI
Или даже посоветую обратиться к документации, но думаю она не понадобится.
Теперь любые скрипты в этом каталоге будут загружаться без проблем.
Неверные атрибуты на файле скрипта
Если на вашем сервере установлена система подобная Windows, то эта проблема вас не касается, так как все программы *.exe «эта» система загружает без вопросов.
В случае если Ваша система Unix, то вам повезло меньше, особенно если Вы до этого видели только Windows.
В кратце поясню. Во всех системах Unix для каждого файла устанавливаются атрибуты файлов. Этих атрибутов (как правило) девять. Даю список таковых.
Owner Read Owner Write Owner Execute Group Read Group Write Group Execute Other Read Other Write Other Execute
Если кратко, то в Unix системах создаются пользователи и разделяются на группы. Вы вот при входе в систему набираете свой логин и пароль, т.е. Вы являетесь пользователем. Также по FTP и т.д. Все кто имеет доступ к системе является ее пользователем.
Атрибуты типа Owner задают параметры для Вас, т.е. для владельца файлов. Атрибуты Group определяют уровень доступа для вашей группы, т.е. если Вы принадлежите к группе Webmasters, то при установке атрибута Group Write любой другой пользователь, который принадлежит к группе Webmasters сможет записывать в этот файл информацию. Думаю для чего Other понятно, это значит всем остальным.
При записывании файла через FTP атрибуты файла устанавливаются по умолчанию
rw.r..r..
Т.е. Вы можете писать и читать, а остальные могут только читать. Как видите ни один атрибут не указывает на то, что файл загружаемый. Вы должны добиться такого:
rwxr.xr.x
Т.е. установить атрибут Execute во всех группах.
Как это сделать это другой вопрос, давайте рассмотрим с вами работу с некоторыми FTP клиентами. Сразу скажу, что не использую никакие Виндовые программы, т.е. графические «проги» рассчитанные на любителей делать все одним кликом мыши.
Я пользуюсь нашим, т.е. российским файловым менеджером FAR, если у вас его нет, то Вы много потеряли. И я вам сочувствую.
Так вот в нем надо нажать Ctrl-A на том файле, который Вы закачали на сервер (только делаете это не на локальном диске, а на FTP, а то увидите вместо атрибутов Unix атрибуты Досовской файловой системы) Делаете следующую картинку:
R W X R W X R W X [x][x][x] [x][ ][x] [x][ ][x]
И нажимаете Okey. Теперь все классно.
Если у Вас нет FAR, то у Вас ОБЯЗАНА быть программа в системе, которая занимается сервисом FTP. В большинстве систем (и в Винде) такая программа называется ftp. Запустите ее. Наверняка она обладает только командной строкой, так что потейте. 🙂 Я рассмотрю программу ftp.exe, которая входит в виндовс.
Первое, что надо сделать открыть Ваш сайт, делается это командой open
ftp> open www.mjk.msk.ru Связь с mjk. 220 mjk-gw.mjk.msk.ru FTP server (Version wu-2.4.2-academ[BETA-18](1) Mon Aug 3 19:17:20 EDT 1998) ready. Пользователь (mjk:(none)): dron 331 Password required for dron. Пароль: 230-Please read the file README.linux 230- it was last modified on Sat Feb 5 16:31:50 2000 - 3 days ago 230 User dron logged in. ftp>
Теперь Вы в системе. Наберите help для получения основных команд. Попробуйте набрать dir. Пример вывода:
200 PORT command successful. 150 Opening ASCII mode data connection for /bin/ls. total 48 drwx------ 3 dron mjkusers 1024 Feb 6 16:58 . drwxr-xr-x 75 root root 2048 Feb 1 00:03 .. -rw-r--r-- 1 dron mjkusers 1155 Jun 24 1999 .Xdefaults -rw------- 1 dron mjkusers 24 Jan 8 11:35 .bash_history -rw-r--r-- 1 dron mjkusers 24 Jun 24 1999 .bash_logout -rw-r--r-- 1 dron mjkusers 230 Jun 24 1999 .bash_profile -rw-r--r-- 1 dron mjkusers 124 Jun 24 1999 .bashrc -rw-r--r-- 3 dron mjkusers 1324 Jan 8 11:32 123.cgi -rw-r--r-- 1 dron mjkusers 37165 Feb 5 16:31 README.linux 226 Transfer complete. 691 байт получено за 0.33 с (2.09 КБ/с)
Мне например надо теперь установить атрибут загрузки на файл 123.cgi, как видите у него такого атрибута нет. Такую возможность ftp.exe не предоставляет, зато он может посылать команды непосредственно FTP — серверу, т.е. что нам и требуется. Если вы вызывали помощь, то знаете, что такую функцию выполняет команда quote. Чтобы Вам особо не разбираться просто приведу команду.
quote SITE CHMOD 755 123.cgi
Теперь на файле 123.cgi будут установлены необходимые атрибуты. Если Ваш файл располагается в другой директории, то пользуйтесь командой cd (change directory).
Неправильный атрибут на каталоге скрипта
Многие скрипты не только выводят какую-то информацию, но и еще записывают что-то в определенные папки или файлы. Тут надо предусмотреть правильный доступ к этим ресурсам. Любой Web-сервер работает не от вашего имени, а от другого, поэтому запуская скрипт он не предоставляет ему Ваши возможности. Вы должны поставить атрибуты на директорию, в которую записан скрипт, для полного доступа, т.е. для записи всем кому угодно. Для установки таких атрибутов в FAR’е поставьте все крестики. В ftp.exe команда такая
quote SITE CHMOD 777
Хочу Вас также предостеречь, делая полный доступ на директорию помните, что любой «злоумышленник» может вам подпортить жизнь, стереть Ваш скрипт и например записать свой, или записывать неправильные данные в ваши файлы. Короче он может делать, что угодно. Особенно опасно делать полный доступ к директории в которой лежит страничка, потому как рано или поздно вы ее там не обнаружите :-(.
Поэтому СОВЕТ. Создавайте специально для скриптов отдельные каталоги и используйте их для записи данных. А лучше всего делать доступ только отдельному файлу (в этом случае маска доступа не 777, а 666 . ) Причем думаю не плохо было бы позаботиться и о шифровании, т.к. любой скрипт может записывать конфиденциальную информацию, такую как номера кридитных карт, почтовые адреса, имена и фамилии. Любой «спаммер» или «хакер» скажет вам большое спасибо за такой подарок, хотя скорее всего «спасибо» вам скажут «дяди в погонах».
Вобщем-то все, надеюсь у Вас все заработает 🙂
Как настроить Python в качестве CGI модуля в Apache на Debian (Ubuntu, Linux Mint)
Перезапустите веб-сервер, чтобы изменения вступили в силу:
sudo systemctl restart apache2
Создайте файл /usr/lib/cgi-bin/test.py:
sudo gedit /usr/lib/cgi-bin/test.py
Скопируйте в этот файл следующее содержимое:
#!/usr/bin/python3 print ("Content-type: text/html") print ("") print ("") print ("") print ("") print ("") print ("Hello.") print ("")
Сделайте этот файл исполнимым:
sudo chmod +x /usr/lib/cgi-bin/test.py
Если всё настроено правильно, то вы должны увидеть в веб-браузере строку
Hello.
Примечание: Если вместо директории /usr/lib/cgi-bin/ вы хотите для CGI скриптов использовать другую папку, то укажите её в файле /etc/apache2/conf-enabled/serve-cgi-bin.conf.
Настройка Python CGI для всего веб-сервера
Выполните команду для включения модуля CGI:
sudo a2enmod cgi
Откройте файл /etc/httpd/conf/httpd.conf — конфигурационный файл веб-сервера:
sudo gedit /etc/httpd/conf/httpd.conf
Найдите там группу строк
Options Indexes FollowSymLinks AllowOverride None Require all granted
и замените их на
Options Indexes FollowSymLinks ExecCGI AllowOverride None Require all granted
ВНИМАНИЕ: набор опций у вас может быть другим.
В конец файла добавьте следующую строку:
AddHandler cgi-script .cgi .py
Перезапустите веб-сервер, чтобы изменения вступили в силу:
sudo systemctl restart apache2
Создайте файл /var/www/html/test.py:
sudo gedit /var/www/html/test.py
Скопируйте в этот файл следующее содержимое:
#!/usr/bin/python3 print ("Content-type: text/html") print ("") print ("") print ("") print ("") print ("") print ("Hello.") print ("")
Сделайте этот файл исполнимым:
sudo chmod +x /var/www/html/test.py
Если всё настроено правильно, то вы должны увидеть в веб-браузере строку
Apache и CGI скрипты
CGI Apache — способ обработки скриптов самым популярным веб-сервером. В режиме CGI можно обрабатывать и выводить результат в браузер скрипты, написанные на bash, perl и python. Это может быть очень удобно особенно при создании админских инструментов — например, веб-интерфейсов.
CGI Apache настройка отдачи cgi скриптов
Потребуется написать простейший CGI скрипт — сделаем это на bash, также нужно активировать соответствующий модуль Apache.
Прежде всего приводим конфигурационный файл стандартного виртуального хоста apache2 в соответствие приведенному ниже образцу
ServerName www.example.com
ServerAdmin webmaster@localhost
DocumentRoot /var/www/html
ErrorLog $/error.log
CustomLog $/access.log combined
ScriptAlias /cgi-bin/ /var/www/cgi-bin/
Options +Indexes
Options +ExecCGI
AddHandler cgi-script .cgi
# vim: syntax=apache ts=4 sw=4 sts=4 sr noet
Опционально — в /etc/hosts добавляем строку, согласно которой при обращении к www.example.com будет задействоваться виртуальный хост на локальной машине
127.0.01 www.example.com
Включаем модуль веб-сервера и перезапускаем сервер
Создаем каталог, в котором будут размещаться скрипты и переходим в него
Далее нужно написать какой-то скрипт. Пусть он выводит слово hello и актуальное время обращения к скрипту
#!/bin/bash
echo Content-type: text/plain
echo ‘ ‘
echo ‘hello‘
Как любой bash скрипт он должен быть исполняемым
Настройка CGI Apache на этом завершена — теперь в браузере достаточно обратиться по адресу localhost/cgi-bin/script.cgi чтобы увидеть результат.
Поскольку ранее в /etc/hosts добавили нужное правило тот же вывод можно получить обратившись к www.example.com/cgi-bin/script.cgi
CGI скрипты требуют прав на исполнение и небезопасны, если скрипт написан плохо ему можно передать любые параметры и получить доступ к хост системе сервера.
CGI в настоящее время используется ограниченно, в основном для скриптов, для сайтов применяется более безопасный способ исполнения — fastcgi