Настройка сервера FTP с виртуальной базой пользователей

Возникла необходимость организовать сервер FTP с поддержкой SSL/TLS, дисковых квот и управления базой пользователей через интерфейс Web. Для этих целей был выбран ProFTPD, который имеет встроенные средства работы с СУБД MySQL. Устанавливать будем под ОС LinuxDebian v7.XX. Нижеизложенный материал является творческой переработкой опыта двух других авторов:
http://www.howtoforge.com/virtual-hosting-with-proftpd-and-mysql-incl-quota-for-arch-linux
http://demon.of.by/blog/linux-admin/how-to-setup-proftpd-with-users-in-mysql-debian/
Начнем с установки и настройки ProFTPD и СУБД MySQL:

apt-get install mysql-server mysql-client proftpd proftpd-mod-mysql

Во время инсталляции ProFTPD автоматически будет создан системный пользователь "proftpd". Необходимо уточнить его uid, в моем случае он оказался равен 106. Это значение потребуется в дальнейшем.
Создадим необходимые данные в СУБД MySQL. Подключаемся к ней с помощью утилиты командной строки "mysql":

mysql -uroot -p

Создадим пустую БД "ftp" и настроим доступ к ней. Пароль измените по своему усмотрению:

create database ftp;
GRANT SELECT, INSERT, UPDATE, DELETE ON ftp.* TO 'proftpd'@'localhost' IDENTIFIED BY 'XXXXXXXX';
GRANT SELECT, INSERT, UPDATE, DELETE ON ftp.* TO 'proftpd'@'127.0.0.1' IDENTIFIED BY 'XXXXXXXX';
FLUSHPRIVILEGES;

Создадим таблицы. Если значение uid системного пользователя "proftpd" у вас отлично от 106, скорректируйте соответствующим образом запрос SQL:

use ftp;
CREATE TABLE `ftpgroup` ( `groupname` varchar(16) NOT NULL DEFAULT '',
`gid` smallint(6) unsigned NOT NULL DEFAULT '65534',
`members` varchar(16) NOT NULL DEFAULT '',
KEY `groupname` (`groupname`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 COMMENT='ProFTP group table';

CREATE TABLE `ftpquotalimits` ( `name` varchar(30) NOT NULL DEFAULT '',
`quota_type` enum('user','group','class','all') NOT NULL DEFAULT
'user', `per_session` enum('false','true') NOT NULL DEFAULT 'false',
`limit_type` enum('soft','hard') NOT NULL DEFAULT 'soft',
`bytes_in_avail` bigint(10) unsigned NOT NULL DEFAULT '0',
`bytes_out_avail` bigint(10) unsigned NOT NULL DEFAULT '0',
`bytes_xfer_avail` bigint(10) unsigned NOT NULL DEFAULT '0',
`files_in_avail` int(10) unsigned NOT NULL DEFAULT '0',
`files_out_avail` int(10) unsigned NOT NULL DEFAULT '0',
`files_xfer_avail` int(10) unsigned NOT NULL DEFAULT '0', PRIMARY KEY (`name`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;

CREATE TABLE `ftpquotatallies` ( `name` varchar(30) NOT NULL DEFAULT '',
`quota_type` enum('user','group','class','all') NOT NULL DEFAULT
'user', `bytes_in_used` bigint(10) unsigned NOT NULL DEFAULT '0',
`bytes_out_used` bigint(10) unsigned NOT NULL DEFAULT '0',
`bytes_xfer_used` bigint(10) unsigned NOT NULL DEFAULT '0',
`files_in_used` int(10) unsigned NOT NULL DEFAULT '0',
`files_out_used` int(10) unsigned NOT NULL DEFAULT '0',
`files_xfer_used` int(10) unsigned NOT NULL DEFAULT '0'
) ENGINE=MyISAM DEFAULT CHARSET=utf8;

CREATE TABLE `ftpuser` ( `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`userid` varchar(32) NOT NULL DEFAULT '', `passwd` varchar(32) NOT NULL DEFAULT '',
`uid` smallint(6) unsigned NOT NULL DEFAULT '106',
`gid`smallint(6) unsigned NOT NULL DEFAULT '65534',
`homedir` varchar(255) NOT NULL DEFAULT '',
`shell` varchar(16) NOT NULL DEFAULT '/sbin/nologin',
`count` int(11) NOT NULL DEFAULT '0',
`accessed` datetime NOT NULL DEFAULT '0000-00-00 00:00:00',
`modified` datetime NOT NULL DEFAULT '0000-00-00 00:00:00',
`email` varchar(64) DEFAULT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `userid` (`userid`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 COMMENT='ProFTP user table';

Отключаемся от СУБД MySQL. Займемся настройкой ProFTPD. Первым делом необходимо в файле "/etc/proftpd/modules.conf" обеспечить загрузку модулей: "mod_sql.c", "mod_sql_mysql.c", "mod_quotatab_sql.c". Также, дабы не получать излишних сообщений об ошибках, рекомендую отключить следующие: "mod_radius.c", "mod_quotatab_radius.c" и "mod_tls_memcache.c". Переключаемся на основной файл настроек "/etc/proftpd/proftpd.conf":

#
# /etc/proftpd/proftpd.conf -- This is a basic ProFTPD configuration file.
# To really apply changes, reload proftpd after modifications, if
# it runs in daemon mode. It is not required in inetd/xinetd mode.
#

# Includes DSO modules
Include /etc/proftpd/modules.conf

# Set off to disable IPv6 support which is annoying on IPv4 only boxes.
UseIPv6                   off
# If set on you can experience a longer connection delay in many cases.
IdentLookups              off

ServerName           "FTP Server"
ServerType           standalone
ServerIdent                     off
DeferWelcome              on

UseReverseDNS                   off

MultilineRFC2228          on
DefaultServer             on
ShowSymlinks              off

TimeoutNoTransfer         600
TimeoutStalled            600
TimeoutIdle               1200
TimeoutLogin              600

tcpBackLog 5

DisplayLogin                   welcome.msg
DisplayChdir                   .message true
ListOptions                   "-lah"

DenyFilter           \*.*/
PathDenyFilter                "(\\.quota$)|(\\.ftpaccess$)"

# Use this to jail all users in their homes
DefaultRoot             ~

# Users require a valid shell listed in /etc/shells to login.
# Use this directive to release that constrain.
# RequireValidShell       off

# Port 21 is the standard FTP port.
Port                 21

# In some cases you have to specify passive ports range to by-pass
# firewall limitations. Ephemeral ports can be used for that, but
# feel free to use a more narrow range.
PassivePorts                 30000 35000

# If your host was NATted, this option is useful in order to
# allow passive tranfers to work. You have to use your public
# address and opening the passive ports used on your firewall as well.
# MasqueradeAddress       1.2.3.4

# This is useful for masquerading address with dynamic IPs:
# refresh any configured MasqueradeAddress directives every 8 hours
<IfModule mod_dynmasq.c>
# DynMasqRefresh 28800
</IfModule>

# To prevent DoS attacks, set the maximum number of child processes
# to 30. If you need to allow more than 30 concurrent connections
# at once, simply increase this value. Note that this ONLY works
# in standalone mode, in inetd mode you should use an inetd server
# that allows you to limit maximum number of processes per service
# (such as xinetd)
MaxInstances              30
MaxClientsPerHost               10             "Only %m connections per host allowed"
MaxClients                     15             "Only %m total simultanious logins allowed"
MaxHostsPerUser                 3
MaxLoginAttempts          3

# Set the user and group that the server normally runs at.
User                 proftpd
Group                nogroup

# Umask 022 is a good standard umask to prevent new files and dirs
# (second parm) from being group and world writable.
Umask                003 002
# Normally, we want files to be overwriteable.
AllowOverwrite            on

# Uncomment this if you are using NIS or LDAP via NSS to retrieve passwords:
# PersistentPasswd        off

# This is required to use both PAM-based authentication and local passwords
# AuthOrder               mod_auth_pam.c* mod_auth_unix.c

# Be warned: use of this directive impacts CPU average load!
# Uncomment this if you like to see progress and transfer rate with ftpwho
# in downloads. That is not needed for uploads rates.
#
# UseSendFile             off

TransferLog /var/log/proftpd/xferlog
SystemLog   /var/log/proftpd/proftpd.log

LogFormat                       default         "%h %l %u %t \"%r\" %s %b"
LogFormat                       auth           "%v [%P] %h %t \"%r\" %s"
LogFormat                       write           "%h %l %u %t \"%r\" %s %b"
ExtendedLog                     /var/log/proftpd/access.log   WRITE,READ write
ExtendedLog                     /var/log/proftpd/auth.log     AUTH auth
ExtendedLog                    /var/log/proftpd/paranoid.log ALL default

# Logging onto /var/log/lastlog is enabled but set to off by default
UseLastlog off

WtmpLog                         off

DirFakeUser                     on nobody
DirFakeGroup                   on nogroup
DirFakeMode                     0640

DeleteAbortedStores             on
AllowStoreRestart               on
AllowRetrieveRestart           on

LangDefault                     en_US
LangEngine                     on
UseEncoding                     on

# In order to keep log file dates consistent after chroot, use timezone info
# from /etc/localtime. If this is not set, and proftpd is configured to
# chroot (e.g. DefaultRoot or <Anonymous>), it will use the non-daylight
# savings timezone regardless of whether DST is in effect.
SetEnv TZ :/etc/localtime

#<IfModule mod_quotatab.c>
#QuotaEngine off
#</IfModule>

<IfModule mod_ratio.c>
Ratios off
</IfModule>

# Delay engine reduces impact of the so-called Timing Attack described in
# http://www.securityfocus.com/bid/11430/discuss
# It is on by default.
<IfModule mod_delay.c>
DelayEngine on
</IfModule>

<IfModule mod_ctrls.c>
ControlsEngine       off
ControlsMaxClients   2
ControlsLog           /var/log/proftpd/controls.log
ControlsInterval     5
ControlsSocket       /var/run/proftpd/proftpd.sock
</IfModule>

<IfModule mod_ctrls_admin.c>
AdminControlsEngine off
</IfModule>

<IfModule mod_cap.c>
# Allow root to use chown(2)
CapabilitiesEngine off
CapabilitiesSet -CAP_CHOWN
</IfModule>

#
# Alternative authentication frameworks
#
#Include /etc/proftpd/ldap.conf
Include /etc/proftpd/sql.conf

#
# This is used for FTPS connections
#
Include /etc/proftpd/tls.conf

#
# Useful to keep VirtualHost/VirtualRoot directives separated
#
#Include /etc/proftpd/virtuals.conf

<Directory /srv/ftp*>
AllowOverwrite on
HideNoAccess   on
UserOwner       proftpd
GroupOwner     nogroup
ListOptions     "-lah"

<Limit FEAT>
AllowAll
</Limit>

<Limit READ>
AllowAll
</Limit>

<Limit DIRS>
AllowAll
</Limit>

<Limit WRITE>
AllowAll
</Limit>

<Limit STOR MKD>
AllowAll
</Limit>

<Limit PROT PBSZ>
AllowAll
</Limit>

<Limit SITE_CHMOD>
DenyAll
</Limit>
</Directory>

#########################################################################
<Limit SITE_CHMOD>
DenyAll
</Limit>

<Directory />
<Limit ALL>
DenyAll
</Limit>
</Directory>

<Directory /etc>
<Limit ALL>
DenyAll
</Limit>
</Directory>

<Directory /var>
<Limit ALL>
DenyAll
</Limit>
</Directory>

<Directory /usr>
<Limit ALL>
DenyAll
</Limit>
</Directory>
#########################################################################

# A basic anonymous configuration, no upload directories.

# <Anonymous ~ftp>
#   User                  ftp
#   Group                 nogroup
#   # We want clients to be able to login with "anonymous" as well as "ftp"
#   UserAlias             anonymous ftp
#   # Cosmetic changes, all files belongs to ftp user
#   DirFakeUseron ftp
#   DirFakeGroup on ftp
#
#   RequireValidShell          off
#
#   # Limit the maximum number of anonymous logins
#   MaxClients            10
#
#   # We want 'welcome.msg' displayed at login, and '.message' displayed
#   # in each newly chdired directory.
#   DisplayLogin               welcome.msg
#   DisplayChdir          .message
#
#   # Limit WRITE everywhere in the anonymous chroot
#   <Directory *>
#     <Limit WRITE>
#       DenyAll
#     </Limit>
#   </Directory>
#
#   # Uncomment this if you're brave.
#   # <Directory incoming>
#   #   # Umask 022 is a good standard umask to prevent new files and dirs
#   #   # (second parm) from being group and world writable.
#   #   Umask                  022 022
#   #           <Limit READ WRITE>
#   #           DenyAll
#   #           </Limit>
#   #          <Limit STOR>
#   #           AllowAll
#   #           </Limit>
#   # </Directory>
#
# </Anonymous>

# Include other custom configuration files
Include /etc/proftpd/conf.d/

В "/etc/proftpd/sql.conf" необходимо снова обратить внимание на uid системного пользователя "proftpd" и пароль для подключения к СУБД MySQL:

#
# Proftpd sample configuration for SQL-based authentication.
#
# (This is not to be used if you prefer a PAM-based SQL authentication)
#

<IfModule mod_sql.c>
#
# Choose a SQL backend among MySQL or PostgreSQL.
# Both modules are loaded in default configuration, so you have to specify the backend
# or comment out the unused module in /etc/proftpd/modules.conf.
# Use 'mysql' or 'postgres' as possible values.
#
SQLBackendmysql
#
SQLEngine on
SQLAuthenticate on
AuthPAM off
AuthOrder mod_sql.c*
#
# The passwords in MySQL are encrypted using CRYPT

SQLAuthTypes           Crypt
SQLAuthenticate         users groups

# used to connect to the database
# databasename@host database_user user_password
SQLConnectInfo ftp@localhost proftpd XXXXXXXX PERCONNECTION

# Here we tell ProFTPd the names of the database columns in the "usertable"
# we want it to interact with. Match the names with those in the db
SQLUserInfo     ftpuser userid passwd uid gid homedir shell

# Here we tell ProFTPd the names of the database columns in the "grouptable"
# we want it to interact with. Again the names match with those in the db
SQLGroupInfo   ftpgroup groupname gid members

# set min UID and GID - otherwise these are 999 each
SQLMinID       100
SQLDefaultUID   106
SQLDefaultGID   65534

# create a user's home directory on demand if it doesn't exist
CreateHome on 770 dirmode 770

# Update count every time user logs in
SQLLog PASS updatecount
SQLNamedQuery updatecount UPDATE "count=count+1, accessed=now() WHERE userid='%u'" ftpuser

# Update modified everytime user uploads or deletes a file
SQLLog STOR,DELE modified
SQLNamedQuery modified UPDATE "modified=now() WHERE userid='%u'" ftpuser

SQLLogFile /var/log/proftpd/proftpd_sql.log

# User quotas
# ===========
QuotaEngine on
QuotaDirectoryTally on
QuotaDisplayUnits Gb
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 ftpquotalimits 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 ftpquotatallies 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}'" ftpquotatallies
SQLNamedQuery insert-quota-tally INSERT "%{0}, %{1}, %{2}, %{3}, %{4}, %{5}, %{6}, %{7}" ftpquotatallies
QuotaLimitTable sql:/get-quota-limit
QuotaTallyTable sql:/get-quota-tally/update-quota-tally/insert-quota-tally

SQLNamedQuery gettally SELECT "ROUND((bytes_in_used/1073741824),2) FROM ftpquotatallies WHERE name='%u'"
SQLNamedQuery getlimit SELECT "ROUND((bytes_in_avail/1073741824),2) FROM ftpquotalimits WHERE name='%u'"
SQLNamedQuery getfree   SELECT "ROUND(((ftpquotalimits.bytes_in_avail-ftpquotatallies.bytes_in_used)/1073741824),2) FROM ftpquotalimits,ftpquotatallies WHERE ftpquotalimits.name = '%u' AND ftpquotatallies.name = '%u'"
SQLShowInfo   LIST,MLSD "226" "Used %{gettally}GB from %{getlimit}GB. You have %{getfree}GB available space."

RootLogin off
RequireValidShell off

#
</IfModule>

Содержимое"/etc/proftpd/tls.conf":

#
# Proftpd sample configuration for FTPS connections.
#
# Note that FTPS impose some limitations in NAT traversing.
# See http://www.castaglia.org/proftpd/doc/contrib/ProFTPD-mini-HOWTO-TLS.html
# for more information.
#

<IfModule mod_tls.c>
TLSEngine on
TLSLog /var/log/proftpd/proftpd_tls.log
TLSProtocol SSLv23
TLSOptions NoCertRequest EnableDiags
TLSRenegotiate required off
TLSRSACertificateFile /etc/ssl/certs/proftpd.cert.pem
TLSRSACertificateKeyFile /etc/ssl/private/proftpd.key.pem
TLSVerifyClient off
TLSRequired off
</IfModule>

Сгенерируем сертификат SSL/TLS:

openssl req -new -x509 -days 3650 -nodes -out /etc/ssl/certs/proftpd.cert.pem -keyout /etc/ssl/private/proftpd.key.pem
chmod 600 /etc/ssl/private/proftpd.key.pem
chmod 640 /etc/ssl/certs/proftpd.cert.pem

Создаем каталог для сервера FTP:

mkdir /srv/ftp
chown proftpd:nogroup mkdir /srv/ftp
chmod 755 /srv/ftp

Перезапускаем ProFTPD, и на этом настройка непосредственно самого сервера FTP закончена. Переходим к интерфейсу Web для управления базой пользователей. Устанавливаем Apache с поддержкой PHP:

apt-get install apache2 php5 libapache2-mod-php5 php5-mysqlnd php5-curl php5-gd php5-intl php-pear php5-imagick php5-imap php5-mcrypt php5-memcache php5-ming php5-ps php5-pspell php5-recode php5-snmp php5-sqlite php5-tidy php5-xmlrpc php5-xsl

Доступ к интерфейсу необходимо разрешить только авторизированным пользователям. Для этого в файле " /etc/apache2/sites-available/default" в секции "<Directory /var/www/>" добавляем следующие строки:

AuthType Digest
AuthName "FTP user management"
AuthDigestDomain /var/www/
AuthDigestProvider file
AuthUserFile /etc/apache2/ftpusermanagement.digest
Require valid-user

Создадим файл с паролями:

htdigest -c /etc/apache2/ftpusermanagement.digest "FTP user management" user

Включим в Apache поддержку механизма авторизации MD5 Digest, после чего его необходимо перезагрузить:

ln -s /etc/apache2/mods-available/auth_digest.load /etc/apache2/mods-enabled/auth_digest.load

В каталоге "/var/www/" необходимо разместить файл "ftpusermanagement.php" из данного архива. Внести правки в соответствии с вашими настройками. В первую очередь необходимо заполнить переменные, связанные с подключением к СУБД MySQL: $DBnaam, $DBuser, $DBpass и $DBhost. Можете изменить каталог сервера FTP, если он отличается от пути "/srv/ftp/": $GLOBALS[directory]. Опять же необходимо обратить внимание на uid системного пользователя "proftpd". Теперь обратившись к URL вида http://your.server/ftpusermanagement.php вы сможете добавлять, удалять пользователей сервера FTP, а также менять им размер дисковой квоты и пароль.

Поделиться ссылкой:

Оставить комментарий


Примечание - Вы можете использовать эти HTML tags and attributes:
<a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>