ProFTPD: мастер своего дела
Серверы FTP, несмотря на то, что они предоставляют один из древнейших сервисов глобальной сети, по-прежнему остаются крайне популярными. Разработчики ПО постоянно стараются реализовать всё новые возможности в тесных рамках протокола FTP. И один из наиболее ярких представителей этой плеяды - проект ProFTPD.
Введение
При разработке FTP-сервера ProFTPD особое внимание уделялось безопасности и максимальной гибкости настроек. Практически во всём прослеживается влияние проекта Apache – от структуры конфигурации и файлов .ftpaccess до модульной архитектуры. Сервер полностью поддерживает базовый протокол FTP, определённый в RFC 959, а также многие функции, описанные в RFC 1123.
Приставка «Pro», фигурирующая в названии, полностью оправдывает себя - это действительно профессиональный сервер, с помощью которого вы можете реализовать практически всё, что может потребоваться от FTP-сервера.
Конечно, все его возможности в рамках одной статьи охватить невозможно, но наиболее важные моменты я постараюсь осветить…
Инсталляция
Установка выполняется достаточно традиционно. Пользователи Linux наверняка (учитывая большую популярность данной программы) найдут предкомпилированный пакет для своего дистрибутива. Для FreeBSD стандартная рекомендация – установить сервер из коллекции портов. Ну и, естественно, вы всегда можете вручную собрать ProFTPD из исходных кодов.
В дальнейшем все примеры будут относиться к FreeBSD (для конкретики), так что приступим к установке. Обновив коллекцию портов, даём команду:
root# /usr/local/sbin/portinstall proftpd
Можно, конечно, и традиционно (cd /usr/ports/ftp/proftpd; make install), но утилита portupgrade предоставляет целый ряд дополнительных возможностей, так что от себя порекомендую установить её в любом случае
Запустив установку порта впервые, вы получите изображённое на рисунке 1 диалоговое окно, где нужно будет отметить дополнительные модули, с которыми вы желаете собрать ProFTPD. Если коротко, то эти модули выполняют следующие функции:
- IPV6: поддержка шестой версии протокола IP
- LDAP: поддержка аутентификации пользователей на LDAP-сервере
- MYSQL: поддержка СУБД MySQL для хранения учётных записей пользователей
- POSTGRESQL: аналогичная поддержка для PostgreSQL
- OPENSSL: поддержка шифрованных соединений
- QUOTA: позволяет настраивать лимиты для пользователей на используемое дисковое пространство
- IFSESSION: поддержка ограничений для конкретных сессий
- README: позволяет выводить сообщения об изменениях в каталогах
- RATIO: управление соотношением загрузок/скачиваний
- REWRITE: поддержка перезаписи имён запрашиваемых файлов/каталогов на основе регулярных выражений
- WRAP: ограничение входящих соединений по IP-адресу источника (замена механизму TCPWrapper, используемому сервером inetd, при работе в автономном режиме)
- RADIUS: поддержка авторизации на RADIUS-серверах
О некоторых из них мы ещё поговорим, но вам уже сейчас нужно будет определиться с тем, какие модули вам понадобятся, так как при необходимости добавить что-то к уже работающему серверу вам придётся пересобирать ProFTPD с новыми параметрами. Но и включать всё, что есть, про запас, тоже не стоит - «меньше ставишь - лучше спишь».
Кстати, запустив в следующий раз установку этого порта (например, чтобы изменить список модулей или обновить версию), вы уже не увидите этот диалог - ваш нынешний ответ будет сохранён в файле /var/db/ports/proftpd/options. Так что вам нужно будет либо удалить этот файл (вместе с каталогом proftpd), либо выполнить нужные правки прямо в нём.
Пользователям Linux нужно будет подыскать подходящий пакет, собранный с нужными модулями, либо ставить из исходных кодов, указав нужные расширения с помощью параметра with-modules в команде ./configure, например, так:
./configure --with-modules=mod_rewrite:mod_postgresql
Более подробно о параметрах сборки можно, как обычно, узнать, введя команду:
./configure --help
Посмотреть полный список подключенных модулей (включая модули, собираемые по умолчанию) можно с помощью следующей команды (вводить её следует после инсталляции):
serg$ /usr/local/sbin/proftpd -l
Compiled-in modules:
mod_core.c
mod_xfer.c
mod_auth_unix.c
mod_auth_file.c
mod_auth.c
mod_ls.c
mod_log.c
mod_site.c
mod_delay.c
mod_auth_pam.c
mod_ratio.c
mod_readme.c
mod_rewrite.c
mod_wrap.c
mod_sql.c
mod_sql_postgres.c
mod_ifsession.c
В зависимости от того, какой из способов установки вы выберете, вам может понадобиться выполнить вручную некоторые действия:
создать учётную запись пользователя, от имени которого будет работать сервер (традиционно, это пользователь ftp, и обычно он уже присутствует в системе; по умолчанию используется nobody, однако повсеместное его использование может приблизить его по полномочиям к root);
создать каталог(и) для размещения файлов, которые вы хотели бы предоставлять пользователям вашего сервера;
создать конфигурационный файл proftpd.conf (обычно базовый файл создается автоматически во время инсталляции);
обеспечить возможность автоматического старта сервиса при перезагрузках компьютера.
В случае FreeBSD от вас потребуется только подготовить рабочие каталоги и добавить в /etc/rc.conf строчку «proftpd_enable = YES», чтобы получить возможность управлять сервисом с помощью сценария /usr/local/etc/rc.d/proftpd.sh, который, заодно, обеспечивает и автозапуск демона при загрузке системы. Но прежде чем запускать наш FTP-сервер, проследуем в конфигурационный файл (/usr/local/etc/proftpd.conf) и посмотрим, нет ли в настройках по умолчанию чего-то такого, о чём мы могли бы пожалеть в дальнейшем.
Структура конфигурационного файла
Сразу же бросается в глаза его синтаксическая схожесть с httpd.conf - конфигурационным файлом Apache. В файле proftpd.conf можно выделить следующие секции (области действия директив):
- секция <Global>: общие настройки для всех виртуальных серверов;
- секция <VirtualHost>: параметры виртуальных хостов (таких секций может быть произвольное число, см. далее раздел про организацию виртуального хостинга);
- секция <Anonymous>: настройка анонимного доступа (см. ниже);
- секция <Directory>: параметры, относящиеся к файлам конкретного каталога;
- секция <Limit>: ограничения на работу с командами протокола FTP и ограничения авторизации;
- «внешние» директивы: не включены в какую-либо секцию, действуют на весь сервер (директивы внутри секций переопределяют общие настройки для своей секции).
Кроме конфигурационного файла, некоторые настройки могут быть выполнены в файлах .ftpaccess (если не запрещено переопределение параметров директивой «AllowOverride off»). Действие данного файла распространяется на каталог, в котором он размещён, и на все вложенные каталоги.
Приоритетом будет пользоваться та директива, «вложенность» которой больше, т.е. та, действие которой охватывает меньшую область сервера.
Директивы можно условно разделить на две категории: «параметрические», которые требуют указать некоторый параметр (например, IP-адрес), и «логические», которые в качестве параметра принимают ключевое слово «on» или «off», соответственно включая или отключая действие директивы. В дальнейшем в данной статье для параметрических директив будет приводиться синтаксис их параметров; логические директивы будут указаны без параметров (за исключением случаев, когда требуется подчеркнуть необходимость установить конкретное значение).
Некоторые сведения о режимах работы
В первую очередь нужно будет определиться с тем, как ваш сервер должен работать. Поддерживается два режима - inetd и standalone, что определяется параметром ServerType. В первом режиме, как следует из его названия, proftpd будет запускаться суперсервером inetd (это же относится и к xinetd, более популярному в современных дистрибутивах Linux). Это может быть разумно в том случае, если inetd у вас запущен (в последнее время хорошим тоном стало отказываться от его использования) и нагрузка на FTP крайне низка, что не оправдывает постоянное присутствие в памяти ещё одного демона. В данном случае управлять установлением соединений будет inetd (он прослушивает 21-й порт и принимает решение о том, принять или отклонить запрос на соединение, руководствуясь файлами /etc/hosts.allow и /etc/hosts.deny), однако возможности ProFTPD в этом режиме существенно ограничены (в частности, нельзя создавать виртуальные серверы).
Помимо параметра «ServerType inetd» следует в файле /etc/inetd.conf закомментировать строки, относящиеся к «родному» серверу ftpd (чтобы не было конфликтов) и добавить строку для активации proftpd при получении запроса на 21-й порт (впрочем, вы можете использовать и нестандартный порт, если очень хочется):
# ftp stream tcp nowait root /usr/libexec/ftpd ftpd -l
# ftp stream tcp6 nowait root /usr/libexec/ftpd ftpd -l
ftp stream tcp nowait root /usr/local/sbin/proftpd proftpd
Обязательно проверьте правильность пути к исполнимому файлу: на некоторых системах proftpd может быть установлен в /usr/sbin или в /usr/local/libexec.
Автономный режим (standalone) оправдывает себя во всех остальных случаях. Теперь proftpd постоянно присутствует в памяти, самостоятельно прослушивая нужные адреса и порты и управляя всеми входящими соединениями. Кстати говоря, и время реакции на запрос пользователя в этом случае будет меньше, т.к. не придётся каждый раз считывать программу с диска и создавать новый процесс. Именно режим standalone используется по умолчанию, так что не будем ничего менять. Убедитесь, что в inetd.conf не активирован никакой сервис, обслуживающий порт, на котором будет работать proftpd, чтобы исключить конфликты.
Ну и пока мы здесь, можно указать имя нашего сервера в параметре ServerName - оно будет выводиться в баннере приветствия при установке соединения.
Управление соединениями
ProFTPD предоставляет широчайшие возможности по управлению TCP-соединениями. Рассмотрим некоторые наиболее полезные параметры (напомню, что мы рассматриваем standalone-режим; в режиме inetd будет работать далеко не всё):
- DefaultAddress IP-адрес: Задаёт для сервера IP-адрес интерфейса, на котором следует ожидать входящие соединения.
- Port порт: Номер порта, на котором сервер будет ожидать входящие соединения.
- PassivePorts нач. кон.: Крайне полезная для работы за межсетевым экраном опция. Позволяет задать конкретный диапазон «высоких» портов, которые серверу будет разрешено использовать в пассивном режиме. Например: PassivePorts 60000 61999
- SocketBindTight: Логическая директива, включающая «умное» прослушивание интерфейсов. Если она отключена, то каждый порт будет связываться со всеми обслуживаемыми интерфейсами.
- Timeout*: Группа директив, управляющих разрывом соединений на различных этапах установления связи в случае неактивности клиента. Подробности см. в документации.
- UseReverseDNS: Включает или отключает определение доменного имени клиента по IP-адресу («обратный» DNS). Если из-за проблем в работе DNS ваши клиенты жалуются на то, что подключение выполняется с большой задержкой, данную опцию можно отключить.
- MaxClients*: Группа опций, управляющая максимальным количеством клиентов, которым разрешается одновременно работать с сервером. Вы можете ограничивать как общее число соединений (MaxClients число [сообщение]), так и число соединений с одного хоста (MaxClientsPerHost число [сообщение]) или под одним именем пользователя (MaxClientsPerUser число [сообщение]). Необязательный параметр «сообщение» позволяет указать конкретную фразу, которая будет возвращаться клиенту в случае запроса на соединение, когда лимиты превышены.
- MaxConnectionRate запросов [сообщение]: Задается максимальное число запросов на соединение, обслуживаемое в одну секунду.
На самом деле параметров конфигурации значительно больше, ознакомиться со всем многообразием вы сможете в документах, ссылки на которые приведены в конце статьи.
Здесь же рассмотрим два модуля: mod_wrap и mod_ratio.
Модуль mod_wrap предназначен для обеспечения функциональности, которую в случае inetd реализует TCPWrapper. Собрав ProFTPD с поддержкой данного модуля, вы сможете указать файлы allow и deny, которыми сервер будет руководствоваться, принимая решение о том, обслуживать соединение с данного адреса или нет. Вы можете указывать эти файлы как для всех пользователей, так и для конкретных:
TCPAccessFiles /etc/hosts.allow /etc/hosts.deny
TCPUserAccessFiles admin /etc/admin.allow /etc/admin.deny
С помощью символа «~» вы можете подключить для каждого пользователя свои wrap-файлы, размещаемые в их домашних каталогах:
TCPAccessFiles ~/.allow ~/.deny
Формат файлов аналогичен /etc/allow.host, в качестве имени службы используется proftpd (можно задать другое с помощью TCPServiceName).
Модуль mod_ratio позволяет вам устанавливать ограничения на соотношение скачиваемых файлов и загружаемых на сервер (грубо говоря, контролировать отношение исходящего трафика ко входящему). Рассмотрим следующую директиву:
Ratios on
UserRatio ftp 10 5 20 256000
Здесь мы для пользователя ftp ввели следующие ограничения: он должен скачать в десять раз больше файлов, чем загрузит на сервер (первое число, 10, означает, что соотношение download/upload = 10/1); первые 5 файлов можно закачать «в кредит»; для размера файлов установлено соотношение 20/1; «кредит» - 250 кб.
Помимо этого, вы можете устанавливать соотношения для хостов (HostRatio), групп (GroupRatio), анонимных пользователей (AnonRatio). Символ «*» можно использовать в значении «все» (например, все пользователи). Установка какого-либо параметра в 0 означает снятие ограничений.
Права доступа и анонимные серверы
Если сравнивать proftpd со стандартным ftpd, входящим в поставку FreeBSD, то в первую очередь следует отметить гораздо большие возможности первого в вопросах управления учётными записями и правами доступа. ProFTPD в полном объёме поддерживает стандартные средства управления доступом (авторизация по системному файлу паролей, использование файлов /etc/shells, чтобы предоставлять доступ только тем пользователям, которые имеют действительную командную оболочку, и т.п.). Помимо этого, к вашим услугам ряд других замечательных возможностей, о которых и поговорим.
Прежде всего, отметим возможность использовать базу LDAP для аутентификации пользователей. Также вы можете вести базу виртуальных пользователей в обычном текстовом файле или в СУБД (поддерживаются MySQL и PostgreSQL).
Для использования текстового файла, содержащего данные учётных записей, используются директивы AuthUserFile и AuthGroupFile. В данном случае ProFTPD будет руководствоваться данными этих файлов, как если бы пользователи, описанные в них, были обычными, зарегистрированными в системе. Формат файлов должен соответствовать системным, за исключением того, что пароль указывается в этом же файле (аналога shadow нет), так что предельно внимательно отнеситесь к ограничению прав доступа к этому файлу.
Кроме того, вы можете указать требуемый логин и пароль непосредственно в конфигурационном файле proftpd с помощью директивы UserPassword. Как здесь, так и в файле, определенном директивой AuthUserFile, должны использоваться хешированные пароли (если верить ряду проведённых экспериментов, сервер самостоятельно определяет тип хеша по его виду; поддерживается DES и «стандартный» MD5, причём допускается их совмещение в одном файле). Для управления паролями можно использовать, например, входящую в состав Apache утилиту htpasswd (для формирования DES-паролей; то, что формирует эта утилита с ключом -m, сервером ProFTPD не распознаётся как MD5-хеш). Также существует аналогичная утилита ftpasswd, разработанная специально для нужд ProFTPD, но в стандартную поставку, по крайней мере, во FreeBSD, она почему-то не включена. (Почитать про неё можно здесь: http://www.castaglia.org/proftpd/contrib/ftpasswd.html, а по этому адресу находится собственно текст данной утилиты, написанной на языке Perl: http://www.castaglia.org/proftpd/contrib/ftpasswd),
Рассмотрим также хранение информации об учётных записях пользователей в базе данных на примере PostgreSQL. Прежде всего, убедитесь, что ваш proftpd собран с поддержкой модулей mod_sql и mod_sql_postgres. Теперь подготовим базу данных (назовём её proftpdb), в которой создадим две таблицы - users и groups:
serg$ psql -U serg
serg=# create database proftpdb owner serg;
CREATE DATABASE
serg=# \c proftpdb serg
Вы подсоединились к базе данных "proftpdb" как пользователь "serg".
proftpdb=> create table users (username text, pass text, uid numeric,
proftpdb(> gid numeric, home text, shell text);
CREATE TABLE
proftpdb=> create table groups (groupname text, gid numeric, members text);
CREATE TABLE
proftpdb=> insert into groups values('admins', 1000, 'admin');
INSERT 227037 1
proftpdb=> insert into users values ('admin', 'adminpassword', 1000,
proftpdb(> 1000, '/home/admin', '/bin/sh');
INSERT 227038 1
proftpdb=> \q
Как видите, структура таблиц очень напоминает структуру файла /etc/passwd. Вам следует соблюдать уникальность имён пользователя и группы, а также уникальность uid в файле users и gid в файле groups. Если пользователей предполагается не слишком много, то об этом можно заботиться и вручную. В противном случае следует установить на соответствующие поля признак UNIQUE, чтобы СУБД сама следила за их уникальностью.
Последними двумя командами мы создаём группу «admins» и пользователя «admin». Теперь нужно указать ProFTPD, как использовать эти данные:
### Настройка авторизации в PostgreSQL
# Данные для подключения, формат: база@хост:порт логин пароль
SQLConnectInfo proftpdb@localhost:5432 serg sergpassword
# Поддерживаемые типы авторизации (в данном случае - открытый текст)
SQLAuthTypes plaintext
# Имя таблицы пользователей и далее - имена полей
SQLUserInfo users username pass uid gid home shell
# Имя таблицы групп и далее - имена полей
SQLGroupInfo groups groupname gid members
# Сюда выводится отладочная информация (полезно на этапе настройки)
SQLLogFile /var/log/proftpd.log
Теперь вы можете входить на сервер под именем «admin», хотя такого системного пользователя и нет. Главное - чтобы его домашний каталог реально существовал, если вы используете директиву DefaultRoot ~. Обратите внимание, что после авторизации процесс, обслуживающий соединение, получит uid и gid, указанные в базе, так что вам следует позаботиться об отсутствии пересечений с системными пользователями. Также учитывайте этот факт в контексте прав доступа к тем или иным файлам (заметьте, что вы можете дать на любой файл или каталог права несуществующего пользователя, указав любые нужные вам идентификаторы, например, так: chown 9999:9999 /home/admin).
Для организации анонимного доступа используется секция <Anonymous каталог>, где каталог - это имя каталога (абсолютный путь или с использованием символа ~), доступ в который будет осуществляться без обязательного знания пароля. Типичный пример приведён ниже:
<Anonymous ~ftp> # Анонимный доступ в каталог ~ftp
User ftp # Пользователь и группа, с правами
Group ftp # которых будет работать процесс
UserAlias anonymous ftp # Псевдоним anonymous = ftp
<Limit WRITE> #
DenyAll # Запрещаем запись
</Limit> #
</Anonymous> #
Если в секции <Anonymous> вы укажете директиву AnonRequirePassword off, то вход на сервер будет выполняться сразу после ввода имени пользователя (в нашем случае - ftp или anonymous). Если же использовать значение «on», то у пользователя будет запрошен адрес электронной почты в качестве пароля (хотя ввести он сможет там всё, что угодно).
Более подробного рассмотрения заслуживает упомянутая выше секция <Limit>. С её помощью вы можете вводить ограничения как для всех пользователей (как в приведённом выше примере), так и для конкретных пользователей или групп. Вы можете налагать ограничения на использование конкретных команд FTP-протокола (например, <Limit STOR> будет управлять использованием команды STOR). Существует несколько «макросов», охватывающих целые наборы FTP-команд (например, WRITE (группа команд записи), READ (группа команд чтения), DIRS (работа с каталогами). Секция <Limit LOGIN> определяет возможность выполнять процедуру входа на сервер.
Также нужно сказать пару слов о директиве AllowOverwrite, с помощью которой вы можете полностью запрещать (off) или разрешать (on) перезапись существующих на сервере файлов (дополнительно пользователь, пытающийся выполнить такую перезапись, должен обладать достаточными системными правами).
Ну и последнее, о чём следует упомянуть, говоря о процедуре входа в систему, это о приветственных сообщениях, которые будут выводиться пользователю в том или ином случае (при входе на сервер, при переходе в тот или иной каталог и т.д.). ProFTPD позволяет довольно гибко управлять этими сообщениями, благодаря чему вы сможете сделать работу на сервере достаточно простой и понятной. Конечно, большинство FTP-клиентов просто игнорируют подобные сообщения, но для работы с помощью консольного клиента они могут быть полезны. Если вам захочется изменить то или иное сообщение, обратитесь к документации (см. директивы AccessDenyMgs, AccessGrantMsg, группу опций Display*), и вы наверняка найдёте способ сделать это.
Виртуальные серверы
Виртуальный FTP-сервер? А почему бы, собственно, и нет! Конечно, это будет не то же самое, что мы привыкли видеть в Apache, когда на один IP-адрес «навешивается» несколько десятков, а то и тысяч «народных» сайтов. Всё дело в том, что в протоколе FTP нет того «волшебного» параметра заголовка – Host, – который позволяет web-серверу, поддерживающему протокол HTTP версии 1.1, разобраться, что же на самом деле клиент желает увидеть на экране своего монитора.
В случае FTP каждый виртуальный сервер всё же должен иметь свой собственный IP-адрес, по которому к нему будет осуществляться доступ. Для тех, кто испытывает дефицит адресного пространства (а разве бывает так, чтобы IP-адресов всегда хватало?), есть обходной маневр – то, что в Apache называют «port-based vhosts». Вы можете настроить ProFTPD таким образом, что каждый виртуальный сервер будет прослушивать свой порт. Очевидно, что это непригодно для коммерческого хостинга, когда каждый клиент ожидает получить «стандартный» сервер, который будет отвечать на запросы, адресованные на 21-й порт. Однако для личных нужд (например, когда FTP используется для доступа к корню web-сервера) такой метод может оказаться вполне пригодным. Так что мы уделим внимание и ему.
Итак, виртуальный сервер задаётся секцией <VirtualHost IP-адрес>. Вместо адреса можно указать и доменное имя. В данной секции допускаются очень многие директивы, управляющие работой сервера - вы можете задать отдельного пользователя, с чьими правами он будет работать; настраивать анонимный доступ; установить собственный способ авторизации; вводить различные ограничения. Общие для всех виртуальных хостов опции можно вынести в секцию <Global>.
Пример конфигурации см. ниже, в решении задачи 5.
Другие директивы, которые могут быть полезны
Существует масса директив, которые отвечают за запись информации в лог-файлы, за фильтрацию запросов с помощью регулярных выражений (например, чтобы установить ограничения на файлы с определённым расширением), за специальную обработку файлов (например, можно автоматически добавлять префикс ко всем загружаемым на сервер файлам или управлять правами доступа с помощью Umask), и т.д.
Вы можете управлять дисковыми квотами (модуль mod_quota, директивы DefaultQuota, QuotaType, UserQuota, GroupQuota и др.), скоростью скачивания, и проч.
В общем, ознакомьтесь с документацией - там много интересного.
Несколько практических примеров
Ну и для закрепления рассмотрим несколько небольших примеров, демонстрирующих решение некоторых задач, связанных с настройкой FTP-сервера.
Пример 1. Конфигурация, близкая к стандартной
Постановка задачи: Необходимо с помощью FTP администратору (пользователь admin) открыть доступ ко всему дереву каталогов сервера; нескольким «своим» пользователям, входящим в группу wheel, - доступ в их домашние каталоги с правом записи; пользователям, работающим через коммутируемые соединения (группа dialup) дать доступ на чтение в один из каталогов (для всех членов группы он установлен как домашний); всем остальным доступ по FTP запретить.
Решение: Эту задачу можно решить за два этапа - во-первых, ограничим доступ домашними каталогами всем пользователям, кроме пользователя admin (первая строка примера). Поскольку пользователи dialup не имеют реальной командной оболочки, то второй строкой отключим проверку наличия shell пользователя в файле /etc/shells. Ну и, во-вторых, в секциях <Limit> «отсекаем» возможность входить на сервер (LOGIN) и писать в каталоги (WRITE) для всех, кто не входит в перечисленные в директиве AllowGroup группы:
DefaultRoot ~ !admin
RequireValidShell off
<Limit LOGIN>
AllowGroup wheel,dialup
</Limit>
<Limit WRITE>
AllowGroup wheel
</Limit>
Теперь admin будет свободно «бродить» по всему дереву каталогов, а члены групп wheel и dialup смогут работать в своих домашних каталогах. Заметьте, что пользователь admin должен быть членом одной из указанных групп (скорее всего, он уже входит в wheel), иначе ему не позволят авторизоваться.
Пример 2. Несколько анонимных каталогов
Постановка задачи: Требуется настроить на одном FTP-сервере три анонимных каталога - для разработчиков, для тестеров и для пользователей.
Решение: В данном случае проще всего создать три секции <Anonymous> для разных пользователей, имена которых должны вводиться при подключении. Для определенности, разработчикам нужно будет входить под именем developer, тестерам - tester, остальным пользователям - под стандартными anonymous/ftp (ну и для общности добавим ещё один псевдоним - user):
<Anonymous ~developer>
User developer
Group project
</Anonymous>
<Anonymous ~tester>
User tester
Group project
</Anonymous>
<Anonymous ~user>
User user
Group project
UserAlias ftp user
UserAlias anonymous user
</Anonymous>
Заметьте, что имя каталога, указанного в теге <Anonymous>, не обязательно должно совпадать с именем пользователя - оно может указывать на любой существующий каталог. Имя же пользователя, при вводе которого осуществляется анонимный вход, задаётся директивой User, причём указанный пользователь должен существовать в системе (в случае виртуальных пользователей для них должны быть указаны uid и gid, под которыми будет запущен процесс). В последней секции мы указываем два псевдонима, чтобы в этот каталог можно было попасть не только под именем user, но и как ftp или anonymous.
Пример 3. Общий каталог
Постановка задачи: Есть группа пользователей, которым нужно предоставить полный доступ каждому в свой домашний каталог, а также в общий для всех каталог только на чтение.
Решение: Сразу напрашивается идея использовать символьную ссылку на общий каталог из домашних каталогов пользователей, а затем «запереть» всех с помощью DefaultRoot ~. Однако выход за пределы корневого (в данном случае - домашнего для пользователя) каталога по символьной ссылке запрещён. Так что нужно искать обходной путь, например, такой:
DefaultRoot /home !admin
<Directory /home>
HideNoAccess on
</Directory>
Чтобы это сработало, должны выполняться некоторые ограничения - все домашние каталоги пользователей должны размещаться в /home, кроме того, на них должны быть выставлены права 0700 (доступ только владельцу каталога). Общий каталог также должен располагаться в /home, но с правами, позволяющими любому пользователю читать его содержимое. В этом случае события будут развиваться следующим образом:
- после успешной авторизации процесс, обслуживающий соединение, получит права авторизованного пользователя - владельца одного из каталогов;
- поскольку прав на чтение чужих домашних каталогов у данного пользователя нет, то сервер ProFTPD в соответствии с директивой HideNoAccess скроет их и не представит по команде LIST (теоретически, доступ в скрытые каталоги возможен, но в данном случае он будет предотвращаться системными правами);
- общий каталог скрыт не будет, и пользователь, поднявшись из своего каталога (куда он попадёт автоматически) в каталог /home, увидит его и сможет в него перейти.
Собственно, чего мы и добивались.
Пример 4. Запись без права чтения
Постановка задачи: Разрешить анонимным пользователям загрузку файлов на сервер. Чтобы избежать злоупотреблений (когда ваш анонимный сервер превратится в средство обмена «пиратскими» файлами), чтение из данного каталога необходимо запретить (в дальнейшем администратор будет просматривать файлы и публиковать нужные в других каталогах).
Решение: Здесь всё достаточно просто - на рассматриваемый каталог нужно установить соответствующие ограничения (в секции LIMIT):
<Anonymous ~ftp>
User ftp
Group ftp
<Limit WRITE>
DenyAll
</Limit>
<Directory ~ftp/upload>
<Limit WRITE>
AllowAll
</Limit>
<Limit READ>
DenyAll
</Limit>
</Directory>
</Anonymous>
То есть для каталога upload мы выставляем «инверсные» права - разрешаем запись, но запрещаем чтение.
Пример 5. Виртуальные серверы
Постановка задачи: Есть два «очень важных» клиента, которым необходимо предоставить виртуальные FTP-серверы на стандартном порту (21), при этом администратор должен иметь возможность работать с сервером с помощью третьего FTP-сервера. При этом реальных адресов на сервере - всего два.
Решение: Поскольку «очень важных» клиентов ущемлять в правах нельзя, придется им давать «нормальный» хостинг на реальных IP-адресах. Страдать, как обычно, будет администратор, которому придётся довольствоваться работой через нестандартный порт (для красоты выберем порт 2121):
DefaultAddress user1.mydomain.ru
Port 2121
SocketBindTight on
<VirtualHost user1.mydomain.ru>
ServerName “User1 Virtual Host”
Port 21
.. .. ..
</VirtualHost>
<VirtualHost user2.mydomain.ru>
ServerName “User2 Virtual Host”
Port 21
.. .. ..
</VirtualHost>
Что здесь нужно пояснить: вне секций мы описываем параметры «административного» сервера, который будет привязан к домену user1.mydomain.ru и порту 2121. Директива «SocketBindTight on» требует от ProFTPD «разумного» подхода к созданию сокетов, когда порты прослушиваются только на тех адресах, где это необходимо, а не на всех обнаруженных интерфейсах. Ну и секциями <VirtualHost> вводим наши пользовательские серверы (показаны только директивы, отвечающие за создание виртуальных серверов).
Напутствие
Пожалуй, приведённых сведений должно быть достаточно, чтобы начать работать с ProFTPD. Но, как вы можете увидеть в документации, существуют ещё десятки (если не сотни) опций, с помощью которых можно добиться от сервера почти всего, что вам может понадобиться. Как говорится, нет предела совершенству.
Дополнительную информацию вы всегда можете получить по ссылкам, приведённым ниже. Ну и, само собой, «рулит» Google (для патриотов - Яndex).
Удачи вам и настойчивости, чтобы преодолеть всё!
Дополнительная информация:
1. Официальный сайт проекта ProFTPD - http://www.proftpd.org
2. ProFTPD mini-HOWTO - http://devil.st.vstu.edu.ru/ftpd/howto/
3. С. Богомолов, «FTP-сервер ProFTPD: установка, настройка и использование» - http://bog.pp.ru/work/ProFTPD.html
4. А. Лаврентьев, «Маленькие нюансы при установке и настройке ProFTPD» - http://opennet.ru/base/net/adv_proftpd.txt.html
5. С. Великанов, «Ограничение доступа на сервере proftpd при помощи mod_wrap» - http://www.opennet.ru/base/net/proftpd_mod_wrap.txt.html
6. Д. Бочкарёв, «Настройка ProFTPD на сервере под управлением FreeBSD» - http://opennet.ru/base/net/proftpd_setup.txt.html
7. «Настройка связки proftpd + mysql» - http://fr33man.ru/proftpd.html
На врезку:
Вспомогательные утилиты
В составе пакета ProFTPD вы найдёте несколько утилит, которые могут быть весьма полезны для мониторинга работы вашего FTP-сервера и поиска в его работе «узких мест»:
ftpcount - выводит число подключённых в данный момент клиентов (с разбивкой по серверам).
ftpdctl - позволяет управлять запущенным сервером proftpd
ftptop - аналог команды top для процессов proftpd
ftpwho - выводит список подключённых к серверу пользователей
ftpshut - позволяет выполнить останов всех запущенных proftpd-серверов в указанное время (аналог системной команды shutdown).
Для каждой команды есть подробная страница справки (man).
Подпись к рисунку:
Рисунок 1: Диалог выбора дополнительных модулей ProFTPD
Рисунок 2: Модульная архитектура ProFTPD (показаны не все модули)