31.05.2010 ProFTPd+MySQL+Quota+WebAdmin на Gentoo

0.250 Предисловие

Дело было так, попросил меня один из друзей поделиться с ним хостингом. А так как сервак ранее не был приспособлен к этомуто пришлось подумать, как реализовать доступ к хранимым веб-файлам(сам ходил через SSH). Долго рассуждать не стал, пошел в Гугль - он умнее, ему виднее. И наткнулся в очередной раз, на сайт моего коллеги Lissyara.su, где как обычно был ответ на мой вопрос, правда для фрюхи.

0.500 Имею

1) Желание получить безопасный и настраиваемый FTP-сервер
2) И вот такую железку...
# uname -a

Linux ns2 2.6.31-gentoo-r6 #1 SMP Sun Feb 14 00:32:39 Local time zone must be set--see zic  x86_64 Intel(R) Xeon(R) CPU X3430 @ 2.40GHz GenuineIntel GNU/Linux



0.750 Хочу

FTP-сервак на базе ProFTPd с хранением пользователей в базе MySQL, квотированием и красивой веб-мордой. Само собой все это буду делать только на Gentoo, не потому что её люблю, хвалю, лелею, ставлю на любое железо, что попадает под руку, а потому что она быстрая и удобная сволочь. ;-)

1. Начнем

А начать предлагаю с изучения статьи: http://www.lissyara.su/articles/freebsd/programms/proftpd+mysql/

Прочитали? Примерно поняли о чем разговор, теперь переложим все это с гитары на баян.

Обновим Portages

# emerge --sync

Обновили? значит готовы приступить к саомому процессу установки.

2. Установка ProFTPd.

А так как мы собираемся хранить пользователей в MySQL, то соответственно и установим и MySQL.
Смотрим и оцениваем USE-флаги:
# emerge -pv mysql proftpd

These are the packages that would be merged, in order:

Calculating dependencies... done!
[ebuild  N    ] net-ftp/ftpbase-0.01-r1  USE="pam" 0 kB
[ebuild   R   ] dev-db/mysql-5.0.90-r2  USE="berkdb community perl ssl -big-tables -cluster -debug -embedded -extraengine -latin1 -max-idx-128 -minimal -profiling (-selinux) -static -test" 0 kB
[ebuild  N    ] net-ftp/proftpd-1.3.2d  USE="acl ifsession ipv6 ldap mysql ncurses nls pam rewrite softquota ssl tcpd -authfile -ban -case -clamav -deflate -hardened -kerberos -noauthunix -opensslcrypt -postgres -radius (-selinux) -shaper -sitemisc -vroot -xinetd" 2,486 kB


Вносим изменения в "/etc/make.conf"
Все устраивает? - Тогда:
# emerge -pv mysql proftpd


У меня как видно из приведенных строк MySQL уже имеется, а у вас - поставится сам при включении USE-флага "mysql".

3. Пришло время настроить ProFTPd

Далее создаем файл proftpd.conf

Смотрим стандартный файлик /etc/proftpd.conf и вносим изменения как показано ниже:

[proftpd.conf]
# имя сервера - Название вашего сервера или виртуального хоста.
ServerName              "Private FTP server."
# тип сервера (даже не тип самого сервера, а тип его запуска,
# standalone/inetd - сам или через inetd)
ServerType              standalone
# смысл следующей директивы такой: если клиент коннектится не на имя
# а на IP или на виртуальный хост, не описанный в конфиге, то при
# установке в `off` он получит отлуп, если же установлено `on` то
# он будет обслужен `сервером по-умолчанию`
DefaultServer           on
# e-mail администратора (по идее для каждого ВиртуалХоста его можно
# поставить разный - но я делаю один сервер без извращений с
# виртуальными хостами)
ServerAdmin             root@gnu.su
# файло где хранится инфа о сессиях
#ScoreboardFile         /var/run/proftpd.scoreboard
# Поддержка кодировки cp1251
LangEngine on
UseEncoding KOI8-R CP1251
# порт на котором работает сервер
Port                    21
# Маска с которой создаются новые файлы (не совсем маска - маска получается
# из этого значения, путём его вычитания из 777 - т.е. в даном случае получится
# маска 755)
Umask                   022
# никаких действий после входа в течении 600 сек выход
TimeoutIdle 		 600
# отводится на авторизацию 300 сек иначе разрыв
TimeoutLogin 		 300
# вошел, но не начал передачу в течении 300 сек выход
TimeoutNoTransfer	 300
# размер-очереди
tcpBackLog 		 5
# Максимальное количество клиентов
MaxClients              10 "Sorry, the maximum number of allowed users are already connected (%m)"
# Максимальное количество клиентов с одного хоста
MaxClientsPerHost       2  "Sorry, you may not connect more than one time. %m allowed users already connected"
# допускаемое число попыток ввести пароль
MaxLoginAttempts        3
# Максимальное число `детей` (работает только в standalohe режиме)
# необходимо для защиты от атак типа `отказ в обслуживании` да и
# от перегрузки сервера поможет :)
MaxInstances            30
# Юзер от которого работает сервер
User                    proftpd
# группа, под которой работает сервер
Group                   proftpd
# Тип авторизации (на самом деле - в каком виде хрянятся
# пароли в БД - в данном случае - открытым текстом)
SQLAuthTypes            Plaintext
# Кого и как аутентифицируем - on - всех и вся :)
# Но - если поставить `on` то он ломится в БД за группами.
# мне группы никчему. Посему поставил `users`
SQLAuthenticate         users
# инфа для соединения с MySQL сервером:
# имя_базы_данных@хост_где_MySQL:порт имя_пользователя пароль
SQLConnectInfo          proftpd@localhost:3306 proftpd pwd
# в каком порядке вернёт поля запрос - первое поле, это
# имя таблицы, где лежат пользователи
SQLUserInfo             `users_table` `username` `password` `uid` `gid` `homedir` `shell`
# должен ли быть у юзера (для того, чтобы он мог коннектится),
# `реальный` shell описанный в /etc/shells
RequireValidShell off
# лог файл работы с SQL
SQLLogFile      /var/log/proftpd/proftpd.log
# Вот тут моя натура склонная к ведению логов на всё в
# БД MySQL смогла разыграться на полную катушку :)
# Записываем удачные логины в БД. Общий смысл такой - создаём
# именованую кверю, с указанием что мы должны сохранять
SQLLog          PASS            counter_login
SQLNamedQuery   counter_login   UPDATE "`last_login`=UNIX_TIMESTAMP(), \
                                `login_count`=`login_count`+1 WHERE \
                                `username`='%u'" `users_table`
# пишем неудачные логины в БД
SQLLog          ERR_PASS        counter_err
SQLNamedQuery   counter_err     UPDATE "`last_err_login`=UNIX_TIMESTAMP(), \
                                `err_login_count`=`err_login_count`+1 WHERE \
                                `username`='%U'" `users_table`
# логируем что сохраняет и тащщит с сервера:
# переменные
# %u - имя пользователя (с которым залогинился)
# %f - полный путь и имя файла который был скачан
# %b - число байт, которые были скачаны
# %h - имя клиента (из DNS), если не удалось разрешить - IP
# %a - IP-адрес клиента
# %m - имя команды полученной от клиента (RETR/STOR)
# %T - время (секунд) ушедшее на передачу файла клиенту
SQLLog          RETR,STOR               log_story_transfer
SQLNamedQuery   log_story_transfer      INSERT "'',\
                                        UNIX_TIMESTAMP(),'%u',\
                                        '%f', '%b', '%h', \
                                        '%a', '%m', '%T'" \
                                         `xfer_table`
# записываем ошибки при сохранении и чтении файлов
# (в одну строку не влезли - но работает и в таком виде :))
SQLLOG          ERR_RETR,ERR_STOR,ERR_DELE,ERR_RMD,ERR_RNTO\
                                        log_err_modify
SQLNamedQuery   log_err_modify          INSERT "'',\
                                        UNIX_TIMESTAMP(),\
                                        '%u', '%f', '%h', \
                                        '%a', '%m'" `xfer_errors`
# если вылезет проблема, типа тормозов при подключении
# (в момент установления коннекта `задумывается` на 10-20 секунд)
# то раскомментируйте следующие две строки
UseReverseDNS     off
IdentLookups      off
# себе я разрешил шариться по всему серверу
# а остальных за`chroot`ил. Если, например, надо чтобы пользователи
# могли по серверу шариться а анонимоусы нет, то надо указать !users
# также можно указать определённую группу.
DefaultRoot             ~       !ad
# Директории
AllowOverwrite          on
AllowAll
AllowAll
# пользователь от которого анонимоусы шарятся
User            proftp
# группа анонимоусов
Group           proftp
# альясы ананонимоусов (можно будет входить как ftp, а
# не anonymous)
UserAlias       anonymous proftp
# максимально число анонимоусов
MaxClients      10      "Sorry, max %m users - try again later"
# Разрешаем анонимам лить на сервер файлы
##DenyAll
#QuotaEngine on                  # включить квоту
QuotaDirectoryTally on          # директива настраивает mod_quotatab принять каталоге операций (например, создание каталогов, удаление каталога)
                                # во внимание при подсчете
QuotaDisplayUnits Mb            # Отображения информации квоты в мегабайтах
QuotaShowQuotas on              # директиву можно использовать для включения / выключения mod_quotatab
SQLNamedQuery get-quota-limit SELECT "name, quota_type, per_session, limit_type, bytes_in_avail, bytes_out_avail, bytes_xfer_avail, files_in_avail, files_out_
SQLNamedQuery get-quota-tally SELECT "name, quota_type, bytes_in_used, bytes_out_used, bytes_xfer_used, files_in_used, files_out_used, files_xfer_used FROM qu
SQLNamedQuery update-quota-tally UPDATE "bytes_in_used = bytes_in_used + %{0}, bytes_out_used = bytes_out_used + %{1}, bytes_xfer_used = bytes_xfer_used + %{2
SQLNamedQuery insert-quota-tally INSERT "%{0}, %{1}, %{2}, %{3}, %{4}, %{5}, %{6}, %{7}" quotatallies
QuotaLimitTable sql:/get-quota-limit
QuotaTallyTable sql:/get-quota-tally/update-quota-tally/insert-quota-tally
QuotaLog                        /var/log/proftpd/quota.log


Далее создаем файлы логов:

# mkdir /var/log/proftpd
# touch /var/log/proftpd/proftpd.log
# chown proftp.wheel /var/log/proftpd/proftpd.log
# touch /var/log/proftpd/quota.log
# chown proftp.wheel /var/log/proftpd/quota.log


Теперь создаем катологи FTP сервера:

# mkdir /ds/ftp
# mkdir /ds/ftp/user
# mkdir /ds/ftp/user/ad
# mkdir /ds/ftp/guest
# chown proftp.wheel /ds/ftp
# chown proftp.wheel /ds/ftp/*
# chmod 777 /ds/ftp
# chmod 777 /ds/ftp/*
# chown proftp.wheel /ds/ftp/user/*
# chmod 777 /ds/ftp/user/*


Теперь создаем в MySQL бд proftpd c пользователем proftpd и заливаем туда дамп бд:

-- phpMyAdmin SQL Dump
-- version 3.1.1
-- http://www.phpmyadmin.net
--
-- Хост: localhost
-- Время создания: Янв 04 2009 г., 21:46
-- Версия сервера: 5.0.75
-- Версия PHP: 5.2.8
--
-- База данных: `proftpd`
--
-- --------------------------------------------------------
--
-- Структура таблицы `quotalimits`
--
CREATE TABLE IF NOT EXISTS `quotalimits` (
  `name` varchar(30) default NULL,
  `quota_type` enum('user','group','class','all') NOT NULL,
  `per_session` enum('false','true') NOT NULL,
  `limit_type` enum('soft','hard') NOT NULL,
  `bytes_in_avail` float NOT NULL,
  `bytes_out_avail` float NOT NULL,
  `bytes_xfer_avail` float NOT NULL,
  `files_in_avail` int(10) unsigned NOT NULL,
  `files_out_avail` int(10) unsigned NOT NULL,
  `files_xfer_avail` int(10) unsigned NOT NULL
) ENGINE=MyISAM DEFAULT CHARSET=cp1251;
--
-- Структура таблицы `quotatallies`
--
CREATE TABLE IF NOT EXISTS `quotatallies` (
  `name` varchar(30) NOT NULL,
  `quota_type` enum('user','group','class','all') NOT NULL,
  `bytes_in_used` float NOT NULL,
  `bytes_out_used` float NOT NULL,
  `bytes_xfer_used` float NOT NULL,
  `files_in_used` int(10) unsigned NOT NULL,
  `files_out_used` int(10) unsigned NOT NULL,
  `files_xfer_used` int(10) unsigned NOT NULL
) ENGINE=MyISAM DEFAULT CHARSET=cp1251;
--
-- Структура таблицы `users_table`
--
CREATE TABLE IF NOT EXISTS `users_table` (
  `unic_id` int(11) NOT NULL auto_increment,
  `username` varchar(20) NOT NULL,
  `password` varchar(20) NOT NULL,
  `groupname` varchar(24) NOT NULL,
  `uid` int(11) NOT NULL,
  `gid` int(11) NOT NULL,
  `homedir` varchar(50) NOT NULL,
  `shell` varchar(20) NOT NULL,
  `last_login` int(15) NOT NULL,
  `login_count` int(15) NOT NULL,
  `last_err_login` int(15) NOT NULL,
  `err_login_count` int(15) NOT NULL,
  PRIMARY KEY  (`unic_id`)
) ENGINE=MyISAM  DEFAULT CHARSET=cp1251 COMMENT='Таблица пользователей';
--
-- Структура таблицы `xfer_errors`
--
CREATE TABLE IF NOT EXISTS `xfer_errors` (
  `unic_id` int(32) NOT NULL auto_increment,
  `timestamp` int(15) NOT NULL,
  `user_name` varchar(64) NOT NULL,
  `file_and_path` tinytext NOT NULL,
  `client_name` varchar(127) NOT NULL,
  `client_IP` varchar(15) NOT NULL,
  `client_command` varchar(5) NOT NULL,
  PRIMARY KEY  (`unic_id`)
) ENGINE=MyISAM  DEFAULT CHARSET=cp1251 COMMENT='Таблица ошибок при работе';
--
-- Структура таблицы `xfer_table`
--
CREATE TABLE IF NOT EXISTS `xfer_table` (
  `unic_id` int(32) NOT NULL auto_increment,
  `timestamp` int(15) NOT NULL,
  `user_name` varchar(64) NOT NULL,
  `file_and_path` tinytext NOT NULL,
  `bytes` int(15) NOT NULL default '0',
  `client_name` varchar(127) NOT NULL,
  `client_IP` varchar(15) NOT NULL,
  `client_command` varchar(5) NOT NULL,
  `send_time` varchar(9) NOT NULL default '0',
  PRIMARY KEY  (`unic_id`)
) ENGINE=MyISAM  DEFAULT CHARSET=cp1251 COMMENT='Таблица, чё приняли-передали';


Далее в таблицу users_table нужно добавить пользователей я делал через pma:

INSERT INTO `users_table` (`unic_id`, `username`, `password`, `groupname`, `uid`, `gid`, `homedir`, `shell`, `last_login`, `login_count`, `last_err_login`, `err_login_count`) VALUES
(1, 'ad', 'lamer', 'ad', 1001, 1001, '/ds/ftp/user/admin', '/sbin/nologin', 0, 0, 0, 0),
(2, 'proftpd', '', 'proftpd', 1002, 1002, '/ds/ftp/guest', '/sbin/nologin', 0, 0, 0, 0);


Учтите что group & gid & uid должны быть настоящими, созданными в самой системе!!!
Далее можно добавить квоты например для ананимов:
INSERT INTO `quotalimits` (`name`, `quota_type`, `per_session`, `limit_type`, `bytes_in_avail`, `bytes_out_avail`, `bytes_xfer_avail`, `files_in_avail`, `files_out_avail`, `files_xfer_avail`) VALUES
('proftp', 'user', 'false', 'hard', 1.04858e+08, 0, 0, 0, 0, 0);


Для справки 1mb=1048576b указывается в байтах!!!
Пояснения по таблицам:
[user_table]
unic_id: уникальный номер
username: имя пользователя
password: пароль
groupname: группа
uid: uid
gid: gid
homedir: домашний каталог
shell: наличие шелла
last_login: последний вход
login_count: количество входов
last_err_login: последний неудачный вход
err_login_count: количество неудачных входов

[quotalimits]
name: имя виртуального пользователя
quota_type: тип ограничения по (user,qroup,class или all - для всех)
per_session: true - использовать квоту только на текущую сессию, в этом случае ни куда не записывается размер использованной квоты и для каждой новой сессии используется указанная квота. false - в этом случае использование квоты заноситься в базу данных.
limit_type: soft - возможно некоторое превышение квоты
hard - жостко заданная квота, превышение невозможно
bytes_in_avail лимит загрузки в байтах ( если 150 Мб то 157286400 байт) 0 = нет лемита
bytes_out_avail лимит скачивания в байтах. 0 = нет лимита
bytes_xfer_avail: Лимит передачи в байтах.0 = нет лимита
files_in_avail: Лимит количества загружаемых файлов. 0 = нет лимита
files_out_avail: Лимит количесва скачиваемых файлов. 0 = нет лимита
files_xfer_avail: Лимит количесва передачи файлов. 0 = нет лимита

Практически вот и все ,осталось добавить proftpd в уровень запуска default и собственно запустить:
# rc-update add proftpd default
# /etc/init.d/proftpd start

Вот и все можно пользоваться, для красоты можно воспользоваться web-мордой: PROMA ProFTPd MySQL Administrator (Web-морда для ProFTPd)
Настраивается элементарно открываем и редактируем файлик config.inc.php, далее выкладываем админку на один из виртуальных хостов вашего веб-сервера и открываем в браузере http://yourdomain.com/index.php.

Вот собственно и все, будут вопросы - пишите.

Спасибо за внимание ;-)

{TAGS}




Вас также может заинтересовать:

22.05.2010 Использование PackageSet в Gentoo (Или жизнь после установки Gentoo-Way)
Настройка РРТР в GENTOO консольный вариант (PPTP Gentoo-way)
01.05.2010 Установка Gentoo (x86 UTF-8 RUS)
12.06.2010 IPTables Gentoo
25.04.2010 Философия Gentoo
Представлен Gentoo LiveDVD 11.0