Проект переехал на новый домен!  [[ перейти ]]

ProFTPd + MySQL
http://www.proftpd.org/docs/directives/linked/by-name.html
http://www.castaglia.org/proftpd/modules/mod_sql.html
http://www.proftpd.org/docs/contrib/mod_quotatab.html
http://www.proftpd.org/docs/contrib/mod_quotatab_sql.html
http://www.castaglia.org/proftpd/doc/contrib/ProFTPD-mini-HOWTO-NAT.html
http://freebsd-r16.narod.ru/scripts/proftpd-web.html

sh# cd /usr/ports/ftp/proftpd
--------
+CONTROL
+MYSQL
+QUOTA
--------
sh# make install clean ж;)

# Есть целый раздел в 43G его и отведём под фтп...
# А значит все homedir для вирт. юзеров будут со-
# здаваться в этом каталоге...
sh# df -h
-------------------------------------------------
/dev/ad4s1h   46G    4.0K     43G     0%    /work
-------------------------------------------------

ls -l / | grep work
------------------------------------------------------
drwxr-xr-x   4 root  wheel       512 Aug  7 11:55 work
------------------------------------------------------

# Лог есть лог. И без него никак!
sh# touch /var/log/proftpd.log
sh# tail -f /var/log/proftpd.log

sh# cat /conf/proftpd.conf
------------------------------------------------------------------
DebugLevel	9
SyslogLevel	debug
SystemLog	/var/log/proftpd.log

TransferLog	/var/log/proftpd.transfer.log

ServerName	"none"
ServerType	standalone
DefaultServer	on
ScoreboardFile	/var/run/proftpd/proftpd.scoreboard
Port		21
PassivePorts	60000 65535

MaxClients 		10
MaxClientsPerHost	2
MaxLoginAttempts 	3

Umask			011
MaxInstances		30
CommandBufferSize	512

User		nobody
Group		nogroup

DefaultRoot	/work	wheel
DefaultRoot	~

AllowOverwrite		on

SQLBackend		mysql
SQLConnectInfo 		proftpd@localhost proftpd dptforp
SQLAuthenticate		users
SQLAuthTypes		Crypt
SQLUserInfo		accounts user pass uid gid home shell

RequireValidShell	off
CreateHome		on 0777

DefaultTransferMode	binary
------------------------------------------------------------------

# Это главная конструкция БД для хранения пользователей.
sh# cat proftpd.sql
--------------------------------------------------------------------------------
DROP DATABASE IF EXISTS proftpd;
CREATE DATABASE proftpd;

USE proftpd;

CREATE TABLE accounts (
id INT(10) NOT NULL AUTO_INCREMENT,
user VARCHAR(30) NOT NULL,
pass VARCHAR(80) NOT NULL,
uid INT(10) NOT NULL,
gid INT(10) NOT NULL,
home VARCHAR(255) NOT NULL default '/work/',
shell VARCHAR(255) NOT NULL default '/usr/sbin/nologin',
descr VARCHAR(255) NOT NULL default 'empty...',
PRIMARY KEY (id),
UNIQUE KEY (user, uid)
) ENGINE=MyISAM DEFAULT CHARSET=cp1251;

CREATE USER proftpd@localhost IDENTIFIED BY 'dptforp';
GRANT ALL PRIVILEGES ON proftpd.* TO proftpd@localhost IDENTIFIED BY 'dptforp';

FLUSH PRIVILEGES;
--------------------------------------------------------------------------------

# Добавление пользователей будет идти таким запросом, хотя в конечном виде
# панируется написать php-скрипт для добавления юзеров.
sh# user_add.sql
------------------------------------------------------------------------------------------------------------------------
INSERT INTO proftpd.accounts VALUES('','test',ENCRYPT('123'),'1111','1111','/work/test','/usr/sbin/nologin','empty...');
------------------------------------------------------------------------------------------------------------------------

# QUOTA

# Структура БД для квоты!
sh# cat proftpd.quota.sql
------------------------------------------------------------------------
-- #####################################################################
-- Эта таблица для задания квот и прочих ограничений! где,
-- name: имя виртуального пользователя
-- quota_type: тип ограничения по (user,qroup,class или all - для всех)
-- per_session: true - квоту только сессию, false - на постоянно
-- limit_type: soft - возможно превышение, hard - жостко заданная квота
-- bytes_in_avail лимит загрузки в байтах. 0 = нет лемита
-- bytes_out_avail лимит скачивания в байтах. 0 = нет лимита
-- bytes_xfer_avail: Лимит передачи в байтах.0 = нет лимита
-- files_in_avail: Лимит количества загружаемых файлов. 0 = нет лимита
-- files_out_avail: Лимит количесва скачиваемых файлов. 0 = нет лимита
-- files_xfer_avail: Лимит количесва передачи файлов. 0 = нет лимита
-- #####################################################################
CREATE TABLE proftpd.quotalimits (
name VARCHAR(30),
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 UNSIGNED NOT NULL,
files_out_avail INT UNSIGNED NOT NULL,
files_xfer_avail INT UNSIGNED NOT NULL
);

-- ##################################
-- Эта таблица не для редактирования!
-- её модифицирует сам mod_quota_sql
-- В ней хранятся конечные данные об
-- использованом пространстве и т.п.
-- ##################################
CREATE TABLE proftpd.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 UNSIGNED NOT NULL,
files_out_used INT UNSIGNED NOT NULL,
files_xfer_used INT UNSIGNED NOT NULL
);
------------------------------------------------------------------------

Данные о квоте добавляем так:
sh# cat user_quote_add.sql
-----------------------------------------------------------------------------------------------------
INSERT INTO proftpd.quotalimits VALUES('test','user','false','hard','104857600','0','0','0','0','0');
-----------------------------------------------------------------------------------------------------
Пользователю test разрешили закачать 100mb!

И в /conf/proftpd.conf добавляем строки
----------------------------------------------------------------------------------
QuotaEngine		on
QuotaLog		/var/log/proftpd.quota.log
QuotaDirectoryTally	on
QuotaDisplayUnits 	Mb
QuotaShowQuotas		on
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_avail, files_xfer_avail FROM quotalimits WHERE name = '%{0}' AND quota_type = '%{1}'"
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 quotatallies WHERE name = '%{0}' AND quota_type = '%{1}'" 
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}, files_in_used = files_in_used + %{3}, files_out_used = files_out_used + %{4}, files_xfer_used = files_xfer_used + %{5} WHERE name = '%{6}' AND quota_type = '%{7}'" quotatallies
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
----------------------------------------------------------------------------------

sh# touch /var/log/proftpd.quota.log

Проверяем квоту
sh# ftp localhost
--------------------------------------------------------------------
Connected to 127.0.0.1.
220 ProFTPD 1.3.2 Server (none) [127.0.0.1]
Name (192.168.0.4:defspit): test
331 Password required for test
Password:
230 User test logged in
Remote system type is UNIX.
Using binary mode to transfer files.
ftp> quote site quota
200-The current quota for this session are [current/limit]:
 Name: test
 Quota Type: User
 Per Session: False
 Limit Type: Hard
   Uploaded Mb:0.00/5.00
   Downloaded Mb:unlimited
   Transferred Mb:unlimited
   Uploaded files:unlimited
   Downloaded files:unlimited
   Transferred files:unlimited
200 Please contact root@xxx.xxxxx.xx if these entries are inaccurate
ftp> exit
221 Goodbye.
--------------------------------------------------------------------

# LOG + Webalizer (Анализатор логов)

sh# cd /usr/ports/www/webalizer
sh# make WEBALIZER_LANG=russian install clean
sh# mkdir /usr/local/www/ftpstat/

И в /conf/proftpd.conf добавляем строки
---------------------------------------------
TransferLog	/var/log/proftpd.transfer.log
---------------------------------------------
sh# touch /var/log/proftpd.transfer.log

# Стартуем и если всё лады, то прописываем алиас в web-сервер и заносим в крон.
sh# webalizer -F ftp -p -o /usr/local/www/ftpstat/ /var/log/proftpd.transfer.log
-----------------------------------------------------
Webalizer V2.21-02 (FreeBSD 7.0-RELEASE i386) English
Using logfile /var/log/proftpd.transfer.log (ftp)
Creating output in /usr/local/www/ftpstat/
Hostname for reports is 'gw2.fortd.ru'
History file not found...
Generating report for August 2009
Saving history information...
Generating summary report
6 records in 1 seconds, 6/sec
-----------------------------------------------------

sh# ee /etc/crontab
---------------------------------------------------------------------------------------------------------------
*/5 * * * * root /usr/local/bin/webalizer -F ftp -p -q -o /usr/local/www/ftpstat/ /var/log/proftpd.transfer.log
---------------------------------------------------------------------------------------------------------------

# Для IPFW2
ipfw add pass ip from xxx.xxx.xxx.xxx to any via tun0 keep-state
ipfw add pass ip from any to xxx.xxx.xxx.xxx 21,60000-65535 in via tun0

Осталось сделать только php обработчик для работы с юзерами... Но не сегодня!