Виртуальный хостинг с PureFTPd и MySQL (включая настройку квот и пропускной способности)

()

Это документ описывает как установить PureFTPd сервер, который использует виртуальных пользователей из базы данных MySQL вместо реальных пользователей системы. Это позволит иметь тысячи пользователей ftp на одной машине. Кроме того, я покажу как использовать квотирование и ограничить входящую/исходящую пропускную способность. Пароли будут записаны в виде зашифрованных MD5 строк в базе данных.

Для администрирования базы данных MySQL вы можете использовать web-интерфейс, такой как phpMyAdmin, установка которого тоже будет описана в этом документе. phpMyAdmin - это удобный графический интерфейс, благодаря которому не надо будет ничего делать из командной строки.

В статье используется Debian Etch (Debian 4.0). У вас уже должна быть установлена базовая система Debian Etch, как это описано в первых шести главах этого учебника.

Эта статья является практической и не содержит теоретических отступлений.

Статья не дает каких-либо гарантий! Я не утверждаю что это единчтвенный способ настройки. Есть много способов, добиться той же цели. И я не гарантирую, что приведенный способ будет работать у вас.

  1. Предварительные комментарии

    В этой статье я использую имя хоста server1.example.com и IP адресом 192.168.0.100. Эти настройки у вас могут быть другими, поэтому вам надо будет заменить их на соответствующие.

  2. Установка MySQL и phpMyAdmin

    Всё можно установить одной командой:

    apt-get install mysql-server mysql-client libmysqlclient15-dev phpmyadmin apache2
    

    Создайте пароль для MySQL пользователя root (замените yourrootsqlpassword на пароль, который хотите использовать):

    mysqladmin -u root password yourrootsqlpassword
    

    Затем с помощью следующей команды проверьте какой адрес слушает MySQL.

    netstat -tap | grep mysql
    

    Если вывод выглядит примерно так:

    tcp        0      0 localhost.localdo:mysql *:*                     LISTEN     2713/mysqld
    

    то это означает, что MySQL слушает только localhost.localdomain, и вы можете безопасно использовать пароль, установленный ранее. Но если вывод выглядит так:

    tcp        0      0 *:mysql *:*                     LISTEN     2713/mysqld
    

    то вам нужно установить пароль MySQL для вашего имени хоста, иначе любой сможет получить доступ к базе данных и изменить данные:

    mysqladmin -h server1.example.com -u root password yourrootsqlpassword
    
  3. Установка PureFTPd с поддержкой MySQL

    Для Debian доступен сконфигурированный пакет pure-ftpd-mysql. Установить его можно так:

    apt-get install pure-ftpd-mysql
    

    Затем создаем ftp группу (ftpgroup) и пользователя (ftpuser), на которых будут ссылаться все наши виртуальные пользователи. Замените group- и userid 2001 на номер, который свободен в вашей системе:

    groupadd -g 2001 ftpgroup
    useradd -u 2001 -s /bin/false -d /bin/null -c "pureftpd user" -g ftpgroup ftpuser
  4. Создание базы данных MySQL для PureFTPd

    Сейчас мы создадим базу данных, которую назовем pureftpd и MySQL пользователя pureftpd, которого демон PureFTPd будет использовать для подключения к базе данных pureftpd.

    mysql -u root -p
    
    CREATE DATABASE pureftpd;
    GRANT SELECT, INSERT, UPDATE, DELETE, CREATE, DROP ON pureftpd.* TO 'pureftpd'@'localhost' IDENTIFIED BY 'ftpdpass';
    GRANT SELECT, INSERT, UPDATE, DELETE, CREATE, DROP ON pureftpd.* TO 'pureftpd'@'localhost.localdomain' IDENTIFIED BY 'ftpdpass';
    FLUSH PRIVILEGES;

    Замените строку ftpdpass на пароль, который вы хотите использовать для пользователя pureftpd. Затем создадим таблицу, которая будет нам нужна:

    USE pureftpd;
    
    CREATE TABLE ftpd (
    User varchar(16) NOT NULL default '',
    status enum('0','1') NOT NULL default '0',
    Password varchar(64) NOT NULL default '',
    Uid varchar(11) NOT NULL default '-1',
    Gid varchar(11) NOT NULL default '-1',
    Dir varchar(128) NOT NULL default '',
    ULBandwidth smallint(5) NOT NULL default '0',
    DLBandwidth smallint(5) NOT NULL default '0',
    comment tinytext NOT NULL,
    ipaccess varchar(15) NOT NULL default '*',
    QuotaSize smallint(5) NOT NULL default '0',
    QuotaFiles int(11) NOT NULL default 0,
    PRIMARY KEY (User),
    UNIQUE KEY User (User)
    ) TYPE=MyISAM;
    quit;
    

    Как вы возможно заметили, командой quit; мы завершаем работу с MySQL.

    Кстати, (я предполагаю, что имя вашего ftp сервера server1.example.com) вы можете получить доступ используя phpMyAdmin по адресу http://server1.example.com/phpmyadmin/ (вы также можете использовать IP адрес вместо server1.example.com) и войти как пользователь pureftpd. После этого вы можете посмотреть на базу данных. Позже вы сможете использовать phpMyAdmin для администрирования вашего PureFTPd сервера.

  5. Конфигурация PureFTPd

    Отредактируйте /etc/pure-ftpd/db/mysql.conf. Это делается примерно так:

    cp /etc/pure-ftpd/db/mysql.conf /etc/pure-ftpd/db/mysql.conf_orig
    cat /dev/null > /etc/pure-ftpd/db/mysql.conf
    vi /etc/pure-ftpd/db/mysql.conf
    MYSQLSocket      /var/run/mysqld/mysqld.sock
    #MYSQLServer localhost
    #MYSQLPort 3306
    MYSQLUser pureftpd
    MYSQLPassword ftpdpass
    MYSQLDatabase pureftpd
    #MYSQLCrypt md5, cleartext, crypt() or password() - md5 is VERY RECOMMENDABLE uppon cleartext
    MYSQLCrypt md5
    MYSQLGetPW SELECT Password FROM ftpd WHERE User="\L" AND status="1" AND (ipaccess = "*" OR ipaccess LIKE "\R")
    MYSQLGetUID SELECT Uid FROM ftpd WHERE User="\L" AND status="1" AND (ipaccess = "*" OR ipaccess LIKE "\R")
    MYSQLGetGID SELECT Gid FROM ftpd WHERE User="\L"AND status="1" AND (ipaccess = "*" OR ipaccess LIKE "\R")
    MYSQLGetDir SELECT Dir FROM ftpd WHERE User="\L"AND status="1" AND (ipaccess = "*" OR ipaccess LIKE "\R")
    MySQLGetBandwidthUL SELECT ULBandwidth FROM ftpd WHERE User="\L"AND status="1" AND (ipaccess = "*" OR ipaccess LIKE "\R")
    MySQLGetBandwidthDL SELECT DLBandwidth FROM ftpd WHERE User="\L"AND status="1" AND (ipaccess = "*" OR ipaccess LIKE "\R")
    MySQLGetQTASZ SELECT QuotaSize FROM ftpd WHERE User="\L"AND status="1" AND (ipaccess = "*" OR ipaccess LIKE "\R")
    MySQLGetQTAFS SELECT QuotaFiles FROM ftpd WHERE User="\L"AND status="1" AND (ipaccess = "*" OR ipaccess LIKE "\R")

    Убедитесь, что заменили ftpdpass настоящим паролем пользователя pureftpd в строке MYSQLPassword!! Убедитесь, что используете md5 как MYSQLCrypt метод, что означает, что мы запоминаем пароли пользователей как MD5 строки, что гораздо безопаснее использования обычного текста!

    Затем создайте файл /etc/pure-ftpd/conf/ChrootEveryone, содержащий строчку yes:

    echo "yes" > /etc/pure-ftpd/conf/ChrootEveryone
    

    Это заставит PureFTPd делать chroot для каждого пользователя в его домашний каталог и он не сможет простматривать файлы и папке вне домашнего каталога.

    Также создайте файл /etc/pure-ftpd/conf/CreateHomeDir, также содержащий строку yes:

    echo "yes" > /etc/pure-ftpd/conf/CreateHomeDir
    

    Это заставит PureFTPd создавать домашний каталог пользователя если его не существует.

    Теперь нам надо сконфигурировать PureFTPd как самостоятельный демон (пока он конторолируется inetd). Чтобы это сделать, мы откроем /etc/default/pure-ftpd-common и изменим значение параметра STANDALONE_OR_INETD на standalone:

    vi /etc/default/pure-ftpd-common
    
    # Configuration for pure-ftpd
    # (this file is sourced by /bin/sh, edit accordingly)

    # STANDALONE_OR_INETD
    # valid values are "standalone" and "inetd".
    # Any change here overrides the setting in debconf.
    STANDALONE_OR_INETD=standalone

    # VIRTUALCHROOT:
    # whether to use binary with virtualchroot support
    # valid values are "true" or "false"
    # Any change here overrides the setting in debconf.
    VIRTUALCHROOT=false

    # UPLOADSCRIPT: if this is set and the daemon is run in standalone mode,
    # pure-uploadscript will also be run to spawn the program given below
    # for handling uploads. see /usr/share/doc/pure-ftpd/README.gz or
    # pure-uploadscript(8)

    # example: UPLOADSCRIPT=/usr/local/sbin/uploadhandler.pl
    UPLOADSCRIPT=

    # if set, pure-uploadscript will spawn $UPLOADSCRIPT running as the
    # given uid and gid
    UPLOADUID=
    UPLOADGID=

    Затем изменим /etc/inetd.conf, замментировав строку ftp:

    vi /etc/inetd.conf
    
    [...]
    #ftp stream tcp nowait root /usr/sbin/tcpd /usr/sbin/pure-ftpd-wrapper
    [...]

    После этого перезапустим Inetd и PureFTPd:

    /etc/init.d/openbsd-inetd restart
    /etc/init.d/pure-ftpd-mysql restart
  6. Заполнение базы данных и тесты

    Для заполнения базы данных вы можете использовать командный интерпритатор MySQL:

    mysql -u root -p
    
    USE pureftpd;
    

    Теперь создадим пользователя exampleuser со статусом 1 (что означает, что его ftp аккаунт - активный), пароль secret (который будет сохранен в заштфрованном виде, используя MySQL функцию MD5), UID и GID 2001 (используйте userid и groupid пользователя/группы, которых вы создали в конце 2 части!), домашний каталог /home/www.example.com, лимит входяшей/исходящей пропускной способности 100 KБ/с (килобайт в секунду), и квоту в 50 MБ:

    INSERT INTO `ftpd` (`User`, `status`, `Password`, `Uid`, `Gid`, `Dir`, `ULBandwidth`, `DLBandwidth`, `comment`, `ipaccess`, `QuotaSize`, `QuotaFiles`) VALUES ('exampleuser', '1', MD5('secret'), '2001', '2001', '/home/www.example.com', '100', '100', '', '*', '50', '0');
    
    quit;
    

    Теперь откройте FTP клиент на своей рабочей станцие (что-нибудь вроде WS_FTP или SmartFTP если у вас Windows или gFTP в Linux) и попробуйте подключиться. В качестве имени используйте server1.example.com (или соответствующий IP адрес), имя пользователя exampleuser и пароль secret.

    Если вам удалось подключиться - поздравляю! Если нет, то что-то пошло не так.

    Теперь, если вы выполните

    ls -l /home
    

    вы должны увидеть, что директория /home/www.example.com (домашний каталог пользователя exampleuser) была автоматически создана, и принадлежит ftpuser и ftpgroup (Пользователь/группа, которых мы создали в конце 2 части):

    server1:/etc/default# ls -l /home
    total 8
    drwxr-xr-x 2 administrator administrator 4096 2007-04-23 14:25 administrator
    drwxr-xr-x 2 ftpuser ftpgroup 4096 2007-04-23 17:26 www.example.com
  7. Администрирование базы данных

    Для большинства людей легче всего использовать графическую оболочку для MySQL; однако так же можете использовать phpMyAdmin (в этом примере по адресу http://server1.example.com/phpmyadmin/) для администрирования базы данных pureftpd.

    Когда вы хотите создать нового пользователя, вам надо создать запись в таблице ftpd. Далее будут описаны все строки этой таблицы:

    Таблица ftpd:

    • User: Имя виртуального пользователя PureFTPd.

    • status: 0 или 1. 0 означает, что аккаунт отключен и пользователь не может подключится.

    • Password: Пароль виртуального пользователя.

    • UID: userid пользователя, который был создан во 2 части.

    • GID: groupid пользователя, который был создан во 2 части.

    • Dir: Домашний каталог виртуального пользователя PureFTPd.

    • ULBandwidth: Скорость закачки для вирткального пользователя и КБ/с. 0 - не ограничена.

    • DLBandwidth: Скорость скачки для вирткального пользователя и КБ/с. 0 - не ограничена.

    • comment: Комментарии. Поле можно оставить пустым.

    • ipaccess: IP адрес, с которого подключаться с данным аккаунтом.

    • QuotaSize: Квота в МБ.

    • QuotaFiles: Количество файлов, которое можно сохранять.0 - не ограничено.

  8. Анонимный FTP

    Если вы хотите создать анонимный аккаунт (аккаунт, с которым любой может подключаться без пароля), вам надо сделать что-то вроде этого:

    Сначала надо создать пользователя ftp (с домашним каталогом /home/ftp) и группу ftp:

    groupadd ftp
    useradd -s /bin/false -d /home/ftp -m -c "anonymous ftp" -g ftp ftp

    Затем создать файл /etc/pure-ftpd/conf/NoAnonymous, содержайщий строку no:

    echo "no" > /etc/pure-ftpd/conf/NoAnonymous
    

    После этого PureFTPd позволит использовать анонимный вход.

    перезапустите PureFTPd:

    /etc/init.d/pure-ftpd-mysql restart
    

    Теперь создадим директорию /home/ftp/incoming, в которую позволим анонимным пользователям закачивать файлы. Дадим директории /home/ftp/incoming права 311 и пользователи смогут закачивать файлы, но не смогут их видеть или скачивать. Директория /home/ftp будет иметь права 555, что позволит видеть и скачивать файлы:

    cd /home/ftp
    mkdir incoming
    chown ftp:nogroup incoming/
    chmod 311 incoming/
    cd ../
    chmod 555 ftp/

    Теперь анонимные пользователи могут подключаться, скачивать файлы из /home/ftp и закачивать в /home/ftp/incoming.

  9. Ссылки

Источник

Ключевые слова: mysql, phpmyadmin, pureftpd.

Комментарии:

MooSE 2007-05-07 08:35:23 (#)

Это всё клёво, однако я предпочитаю всё-таки к физическим логинам пользователей привязывать.

Если их держать в мускуле, то чтобы дать ssh всё равно придётся заводить физического пользователя.

Anonymous 2009-07-12 15:39:00 (#)

ОШИБКА: Затем изменим /etc/inetd.conf, раскомментировав строку ftp:

Должно быть: закомментировав

MooSE 2009-07-12 23:48:31 (#)

Цитата:

ОШИБКА: Затем изменим /etc/inetd.conf, раскомментировав строку ftp:

Должно быть: закомментировав


Спасибо. Поправил.

Anonymous 2009-08-11 23:08:53 (#)

Хорошая статья, может быть подскажете, как, в случае такой организации хранения пользователей ограничить место на диске для их скриптов (пример: юзер pupkin написал кривую скриптину на php, положил на сервер и она начала циклично создавать файлы, превысив квоту пользователя pupkin, т.к. работает от имени www)?

MooSE 2009-08-12 14:32:08 (#)

никак. только к системным привязываться. или привязаться к виртуальным, но отдельные квоты на директории.

короче через бд никакю

Anonymous 2009-11-20 14:11:19 (#)

погодите а для чего тогда ключи

# QuotaSize: Квота в МБ.
# QuotaFiles: Количество файлов, которое можно сохранять.0 - не ограничено.

???

или все равно придеЦа мучаЦа через
http://www.opennet.ru/base/sys/linux_disk_quota2.txt.html
http://www.opennet.ru/base/sys/linux_fs_quota.txt.html

???

MooSE 2009-11-20 16:33:13 (#)

Те ключи укаывают квоту, за которой будет следить pure-ftpd при заливке файлов. процессы того же веб-сервера его не видят и им пофиг.

Anonymous 2011-06-29 21:27:49 (#)

как сделать, чтобы пользователь получал домашней директорией не /home/www.example.com, а скажем /ftp/www.example.com ?
директория ftp создана, права на нее даны ftpuser , а всеравно не может там создавать директории

MooSE 2011-07-01 00:02:29 (#)

Цитата:

как сделать, чтобы пользователь получал домашней директорией не /home/www.example.com, а скажем /ftp/www.example.com ?
директория ftp создана, права на нее даны ftpuser , а всеравно не может там создавать директории


А на что ругается?

Anonymous 2011-07-19 12:54:35 (#)

Предыдущий вопрос снимается, что-то сам накосячил.
Появился новый вопрос.
Значит завел я пользователей. Теперь Вася и Петя могут заходить под своими акаунтами и закачивать и скачивать файлы. Но вот они захотели обменяться файлами. Для этого я сделал следующее. В директориях Васи и Пети создал директории /ftp/vasia/public и /ftp/petia/public соответственно. Отдельно создал директорию /ftp/public . Затем выполнил следующее:
mount --bind /ftp/public /ftp/vasia/public
mount --bind /ftp/public /ftp/petia/public
И выставил chmod 755.
Теперь товарищи могут записывать в директорию public файлы и оба их видеть.
Да вот незадача, хотелось бы сделать так, чтобы закачать файлы в public они могли, а удалять не могли. Выставлял chmod 666, но после этого ни Петя ни Вася в public вообще попасть не могут. Вот собственно вопрос, как решать эту задачу и есть ли альтернативный спосом реализации поставленной задачи, кроме как mount --bind ?

Anonymous 2011-07-19 13:12:58 (#)

В догонку еще один вопрос. Выставил скорость 1000, а ничего даже после рестартов не изменилось, закачивает и скачивает по прежнему на скорости 130 кб/с

Anonymous 2011-07-19 13:18:37 (#)

Цитата:

В догонку еще один вопрос. Выставил скорость 1000, а ничего даже после рестартов не изменилось, закачивает и скачивает по прежнему на скорости 130 кб/с

Извиняюсь, скачивает примерно на 1000, но закачивает на 130

MooSE 2011-07-20 23:36:04 (#)

По директории public ничего посоветовать не могу. По скорости - случайно у тебя не ADSL? :)

Anonymous 2011-07-21 16:29:44 (#)

Цитата:

По директории public ничего посоветовать не могу. По скорости - случайно у тебя не ADSL? :)

Нет, выделенный канал на 1Гб/c.

Anonymous 2011-07-21 16:41:47 (#)

Цитата:

Цитата:

По директории public ничего посоветовать не могу. По скорости - случайно у тебя не ADSL? :)

Нет, выделенный канал на 1Гб/c.

Вопрос снимается, особенности сети из которой я пытался закачивать файлы. Стоит ограничение.

Anonymous 2011-07-26 13:38:02 (#)

Цитата:

Предыдущий вопрос снимается, что-то сам накосячил.
Появился новый вопрос.
Значит завел я пользователей. Теперь Вася и Петя могут заходить под своими акаунтами и закачивать и скачивать файлы. Но вот они захотели обменяться файлами. Для этого я сделал следующее. В директориях Васи и Пети создал директории /ftp/vasia/public и /ftp/petia/public соответственно. Отдельно создал директорию /ftp/public . Затем выполнил следующее:
mount --bind /ftp/public /ftp/vasia/public
mount --bind /ftp/public /ftp/petia/public
И выставил chmod 755.
Теперь товарищи могут записывать в директорию public файлы и оба их видеть.
Да вот незадача, хотелось бы сделать так, чтобы закачать файлы в public они могли, а удалять не могли. Выставлял chmod 666, но после этого ни Петя ни Вася в public вообще попасть не могут. Вот собственно вопрос, как решать эту задачу и есть ли альтернативный спосом реализации поставленной задачи, кроме как mount --bind ?


К недостаткам метода отнесу следующее. Дело в том, что размер директории public включен в учет квоты для пользователя. Это, вообще говоря, проблема, т.к. если Петя забьет public под завязку, то считается, что они оба квоту свою исчерпали. Вывод: надо искать альтернативное решение.
Новый комментарий



© 2006-2016 Вадим Калинников aka MooSE