пятница, 27 ноября 2015 г.

Установка и настройка PureFTPd с ограничением доступа пользователей по ip диапазонам/подсетям

Наш инструментарий

  1. Ubuntu Server
  2. Mysql Server
  3. Pureftpd-mysql

 

Первым делом установим весь необходимый софт

sudo apt-get update
sudo apt-get install mysql-server mysql-client pure-ftpd-mysql


Подготовим MySQL для работы

Создадим базу данных

CREATE DATABASE `PureFTPd` /*!40100 COLLATE 'utf8_general_ci' */;

После чего создадим пользователя с правами на эту базу, уровень привилегий определяйте сами. Для работы сервера будет достаточно и readonly прав.
Я назвал своего пользователя pureftptd.

Таблица для аутентификации пользователей:

CREATE TABLE `ftp` (
    `User` VARCHAR(16) NOT NULL DEFAULT '',
    `status` ENUM('0','1') NOT NULL DEFAULT '1',
    `Password` VARCHAR(64) NOT NULL DEFAULT '',
    `Uid` VARCHAR(11) NOT NULL DEFAULT '2001',
    `Gid` VARCHAR(11) NOT NULL DEFAULT '2001',
    `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` ENUM('*','special') NOT NULL DEFAULT '*',
    `QuotaSize` SMALLINT(5) NOT NULL DEFAULT '0',
    `QuotaFiles` INT(11) NOT NULL DEFAULT '0',
    PRIMARY KEY (`User`),
    UNIQUE INDEX `User` (`User`)
)
COLLATE='utf8_general_ci'
ENGINE=InnoDB
;

 
Таблица, в которой будут добавляться записи ip-range для пользователей

CREATE TABLE `ftp_ipranges` (
    `id` INT(10) UNSIGNED NOT NULL AUTO_INCREMENT,
    `user` VARCHAR(16) NOT NULL,
    `ip_start` VARCHAR(15) NOT NULL,
    `ip_end` VARCHAR(15) NOT NULL,
    `comment` VARCHAR(255) NULL DEFAULT '-',
    PRIMARY KEY (`id`),
    UNIQUE INDEX `UniqFields` (`user`, `ip_start`, `ip_end`)
)
COLLATE='utf8_general_ci'
ENGINE=InnoDB
;


Создадим системного пользователя для работы с FTP


groupadd -g 2001 ftpgroup
useradd -u 2001 -s /bin/false -d /bin/null -c "pureftpd user" -g ftpgroup ftpuser

Приступим к конфигурированию базовых параметров FTP-сервера


#Указываем в каком формате и где будет храниться дополнительный логфайл
#clf - формат Apache
#stats - формат для статических отчетов
#w3c - формат стандарта w3c
echo "clf:/var/log/pure-ftpd/transfer.log" > /etc/pure-ftpd/conf/AltLog

#Автоматически создаем директории пользователя, если она отсутствует
echo "yes" > /etc/pure-ftpd/conf/CreateHomeDir

#Закрываем пользователя в его домашней папке
echo "yes" > /etc/pure-ftpd/conf/ChrootEveryone

#Запрещаем резолвить имена хостов
echo "yes" > /etc/pure-ftpd/conf/DontResolve

#Кодировка файловой системы
echo "UTF-8" > /etc/pure-ftpd/conf/FSCharset

#Слушаем только IPv4 адреса
echo "yes" > /etc/pure-ftpd/conf/IPV4Only

#Минимальный UID, с которым сервер пустит юзера
echo "1000" > /etc/pure-ftpd/conf/MinUID

#Указываем расположение конфига для работы с MySQL
echo "/etc/pure-ftpd/db/mysql.conf" > /etc/pure-ftpd/conf/MySQLConfigFile

#Включаем PAM аутентификацию (если нужна)
echo "yes" > /etc/pure-ftpd/conf/PAMAuthentication

#Указываем диапазон портов для пассивного соединения
echo "49152 65534" > /etc/pure-ftpd/conf/PassivePortRange

#Дефолтная настройка, указывает путь к локальной базе данных юзеров
echo "/etc/pure-ftpd/pureftpd.pdb" > /etc/pure-ftpd/conf/PureDB

#Отключаем системную Unix аутентификацию
echo "no" /etc/pure-ftpd/conf/UnixAuthentication

Настройка PureFTPd для работы с СУБД MYSQL 

Делаем резервную копию конфига
cat /etc/pure-ftpd/db/mysql.conf > /etc/pure-ftpd/db/mysql.conf.bak

Зануляем конфиг
cat /dev/null > /etc/pure-ftpd/db/mysql.conf

Открываем для редактирования файл конфигурации ( nano /etc/pure-ftpd/db/mysql.conf ) и вставляем туда конфиг следующего содержания (директивы доступа к серверу MySQL, естественно используйте свои)

MYSQLServer     localhost

MYSQLPort       3306

MYSQLSocket      /var/run/mysqld/mysqld.sock
 
MYSQLUser       pureftptd
 
MYSQLPassword   pureftptdpass
 
MYSQLDatabase   PureFTPd
 
MYSQLCrypt      md5
 
MYSQLGetPW      SELECT ftp.Password FROM ftp LEFT JOIN ftp_ipranges ON ftp_ipranges.user = ftp.User WHERE ftp.User="\L"  AND status="1" AND (ipaccess = "*" OR ( INET_ATON("\R") >= INET_ATON(ftp_ipranges.ip_start) AND INET_ATON("\R") <= INET_ATON(ftp_ipranges.ip_end) ) ) LIMIT 1
 
MYSQLGetUID     SELECT ftp.Uid FROM ftp LEFT JOIN ftp_ipranges ON ftp_ipranges.user = ftp.User WHERE ftp.User="\L"  AND status="1" AND (ipaccess = "*" OR ( INET_ATON("\R") >= INET_ATON(ftp_ipranges.ip_start) AND INET_ATON("\R") <= INET_ATON(ftp_ipranges.ip_end) ) ) LIMIT 1
 
MYSQLDefaultUID 2001
 
MYSQLGetGID     SELECT ftp.Gid FROM ftp LEFT JOIN ftp_ipranges ON ftp_ipranges.user = ftp.User WHERE ftp.User="\L"  AND status="1" AND (ipaccess = "*" OR ( INET_ATON("\R") >= INET_ATON(ftp_ipranges.ip_start) AND INET_ATON("\R") <= INET_ATON(ftp_ipranges.ip_end) ) ) LIMIT 1
 
MYSQLDefaultGID 2001
 
MYSQLGetDir     SELECT ftp.Dir FROM ftp LEFT JOIN ftp_ipranges ON ftp_ipranges.user = ftp.User WHERE ftp.User="\L"  AND status="1" AND (ipaccess = "*" OR ( INET_ATON("\R") >= INET_ATON(ftp_ipranges.ip_start) AND INET_ATON("\R") <= INET_ATON(ftp_ipranges.ip_end) ) ) LIMIT 1
 
MySQLGetQTAFS   SELECT ftp.QuotaFiles FROM ftp LEFT JOIN ftp_ipranges ON ftp_ipranges.user = ftp.User WHERE ftp.User="\L"  AND status="1" AND (ipaccess = "*" OR  ( INET_ATON("\R") >= INET_ATON(ftp_ipranges.ip_start) AND INET_ATON("\R") <= INET_ATON(ftp_ipranges.ip_end) ) ) LIMIT 1
 
MySQLGetQTASZ  SELECT ftp.QuotaSize FROM ftp LEFT JOIN ftp_ipranges ON ftp_ipranges.user = ftp.User WHERE ftp.User="\L"  AND status="1" AND (ipaccess = "*" OR    ( INET_ATON("\R") >= INET_ATON(ftp_ipranges.ip_start) AND INET_ATON("\R") <= INET_ATON(ftp_ipranges.ip_end) ) ) LIMIT 1
 
MySQLGetBandwidthUL SELECT ftp.ULBandwidth FROM ftp LEFT JOIN ftp_ipranges ON ftp_ipranges.user = ftp.User WHERE ftp.User="\L"  AND status="1" AND (ipaccess = "*" OR     ( INET_ATON("\R") >= INET_ATON(ftp_ipranges.ip_start) AND INET_ATON("\R") <= INET_ATON(ftp_ipranges.ip_end) ) ) LIMIT 1
 
MySQLGetBandwidthDL SELECT ftp.DLBandwidth FROM ftp LEFT JOIN ftp_ipranges ON ftp_ipranges.user = ftp.User WHERE ftp.User="\L"  AND status="1" AND (ipaccess = "*" OR     ( INET_ATON("\R") >= INET_ATON(ftp_ipranges.ip_start) AND INET_ATON("\R") <= INET_ATON(ftp_ipranges.ip_end) ) ) LIMIT 1

После настройки наконец-то можно запустить FTP-сервер командой
sudo service pure-ftpd-mysql restart

Создание пользователей

Создание обычного пользователя:
INSERT INTO `ftp` (`User`, `status`, `Password`, `Uid`, `Gid`, `Dir`, `ULBandwidth`, `DLBandwidth`, `comment`, `ipaccess`, `QuotaSize`, `QuotaFiles`) VALUES ('testUser', '1', MD5('secret'), '2001', '2001', '/ftp/users/testUser', 0, 0, 'user for test', '*', 0, 0);

Создание пользователя, которому разрешен доступ только из сети 10.0.0.0/8
INSERT INTO `ftp` (`User`, `status`, `Password`, `Uid`, `Gid`, `Dir`, `ULBandwidth`, `DLBandwidth`, `comment`, `ipaccess`, `QuotaSize`, `QuotaFiles`) VALUES ('testUser_Special', '1', MD5('secret'), '2001', '2001', '/ftp/users/testSpecialUser', 0, 0, 'special user for test', 'special', 0, 0);
INSERT INTO `ftp_ipranges` (`user`, `ip_start`, `ip_end`, `comment`) VALUES ('testUser_Special', '10.0.0.0', '10.255.255.255', 'Вся локальная сеть'); 

И так, мы видим, что создание  пользователя, на которого накладывается ограничение доступа по ip заключается в изменении флага ipaccess в главной таблице, и созданием нового ip диапазона в таблице ftp_ipranges.

Делаем доступ для Anonymouse

Сконфигурируем сервер для работы с анонимными пользователями:

#Разрешаем анонимных пользователей
echo "no" > /etc/pure-ftpd/conf/NoAnonymous
 
#Запрещаем анонимным пользователям создавать новые директории
echo "no" > /etc/pure-ftpd/conf/AnonymousCanCreateDirs

#Запрещаем анонимным пользователям создавать заливать файлы
echo "no" > /etc/pure-ftpd/conf/AnonymousCantUpload

Делаем новую группу и пользователя
groupadd ftp
useradd -s /bin/false -d /ftp/public -m -c "anonymous ftp" -g ftp ftp

Перезапускаем демон pureftpd
sudo service pure-ftpd-mysql restart

В моем случае анонимусу разрешено только просматривать файлы, по этому тут будет достаточно сменить права доступа к директории анонима
cd /ftp
chmod 555 public/


На сим всё, мы сделали полноценный ftp-сервер, который может весьма гибко управлять доступом, ограничением скорости, дисковой квотой и количеством файлов для каждого пользователя. Дальше можно кастомизировать в любую сторону, тут ограничивает только фантазия.
Вопросы можно задать в комментариях.
При использовании материалов статьи ссылка на источник обязательна!