[Debian] Konfiguration von ProFTPd mit MySQL-Backend

Einleitung:
In diesem Tutorial möchte ich die Konfiguration eines FTP-Servers (ProFTPd)
mit einem MySQL-Backend erklären. Dazu werden wir einen ProFTPd-Server konfigurieren
der die Verifizierung des Benutzers anhand eines MySQL-Backends durchführt. Dabei werden alle Logindaten
sowie Quotadaten (Speicherplatzgröße) in Einträgen einer MySQL-Datenbank hinterlegt.
Dabei wird ledeglich nur ein weiterer System-Benutzer erfordert für alle Daten die via den FTP-Server
vom jeweiligen Client übertragen werden. Für die jeweiligen HomeDirectorys für die entsprechenden FTP-Benutzer
werden die Logindaten im MySQL-Backend hinterlegt. Diese Benutzer sind virtuelle Benutzer.

Vorteile:
– FTP-Benutzer lassen sich frei erweitern ohne weitere System-Benutzer zu hinterlegen
– Einrichtung eines Webinterface wie z.B. proftpd-adm (http://proftpd-adm.sourceforge.net/)

Installation von ProFTPd mit MySQL-Unterstützung:

Zu beginn müssen wir über den Paket-Manager (sofern nicht selbstkompiliert) die jeweiligen
Binarys holen und installieren.

apt-get install proftpd proftpd-mod-mysql

Anlegen von Benutzern für ProFTPd:

Als nächstes sollten wir für den FTP-Server den benötigen Benutzer anlegen, sowie eine Gruppe zu dem FTP-Benutzer:

groupadd -g 2001 ftpgroup
useradd -u 2001 -s /bin/false -d /bin/null -g ftpgroup ftpuser

Damit legen wir als erstes eine Benutzergruppe an mit dem Namen „ftpgroup“ mit der ID 2001.
Dazu legen wir dann einen neuen User an mit dem Namen „ftpuser“, der sich nicht via ssh einloggen darf
und dessen HomeDirectory das /dev/null Verzeichnis ist sprich „Blackhole“.

Anlegen von Tabellen für ProFTPd:

Als erstes müssen wir eine neue MySQL-Datenbank für ProFTPd anlegen. Dies kann via PhpMyAdmin geschehen
(sofern installiert) oder über die Kommandozeile.

Sollte eine Datenbank via die Kommandozeile angelegt werden sollten Sie sich zunächst einmal über die
Kommandozeile in das DBMS (Database Management System) einloggen.

Danach müssen Sie eine weitere Datenbank anlegen sowie einen Benutzer der auf diese Datenbank zugreifen
darf. Dies tun Sie mit:

CREATE DATABASE proftpd;
GRANT SELECT, INSERT, UPDATE, DELETE ON proftpd.* TO 'proftpd'@'localhost' IDENTIFIED BY '<password>';
GRANT SELECT, INSERT, UPDATE, DELETE ON proftpd.* TO 'proftpd'@'localhost.localdomain' IDENTIFIED BY '<password>';
FLUSH PRIVILEGES;

Hierbei sollten Sie natürlich die Variable gegen ein Passwort Ihrer Wahl ersetzen.
Ich empfehle hier mind. ein 10 Zeichen langes Passwort zu wählen aus kleinen Buchstaben, großen Buchstaben und
Zahlen.

Anschließend müssen Sie die jeweiligen Tabellen für den FTP-Server einrichten bzw. Erstellen ob Sie dies
über PhpMyAdmin tätigen oder über die Kommandozeile ist Ihnen überlassen:

CREATE TABLE ftpgroup (
	groupname varchar(16) NOT NULL default '',
	gid smallint(6) NOT NULL default '5500',
	members varchar(16) NOT NULL default '',
	KEY groupname (groupname)
) ENGINE=MyISAM COMMENT='ProFTP group table';

CREATE TABLE ftpquotalimits (
	name varchar(30) default NULL,
	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(20) unsigned NOT NULL default '0',
	bytes_out_avail bigint(20) unsigned NOT NULL default '0',
	bytes_xfer_avail bigint(20) 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'
) ENGINE=MyISAM;

CREATE TABLE ftpquotatallies (
	name varchar(30) NOT NULL default '',
	quota_type enum('user','group','class','all') NOT NULL default 'user',
	bytes_in_used bigint(20) unsigned NOT NULL default '0',
	bytes_out_used bigint(20) unsigned NOT NULL default '0',
	bytes_xfer_used bigint(20) 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;

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) NOT NULL default '2001',
	gid smallint(6) NOT NULL default '2001',
	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 '1000-00-00 00:00:00',
	modified datetime NOT NULL default '1000-00-00 00:00:00',
	PRIMARY KEY (id),
	UNIQUE KEY userid (userid)
) ENGINE=MyISAM COMMENT='ProFTP user table';

Konfiguration von ProFTPd für ein MySQL-Backend:

Als aller erstes müssen wir folgende Konfigurationsdatei bearbeiten „/etc/proftpd/modules.conf“:

Dies tun Sie beispielsweise über den Editor nano.

nano /etc/proftpd/modules.conf

Dort kommentieren Sie folgende Zeilen ein:

# Install one of proftpd-mod-mysql, proftpd-mod-pgsql or any other
# SQL backend engine to use this module and the required backend.
# This module must be mandatory loaded before anyone of
# the existent SQL backeds.
LoadModule mod_sql.c
[...]
# Install proftpd-mod-mysql and decomment the previous
# mod_sql.c module to use this.
LoadModule mod_sql_mysql.c
[...]
# Install one of the previous SQL backends and decomment
# the previous mod_sql.c module to use this
LoadModule mod_quotatab_sql.c

Hierbei ist es wichtig dass die Module „mod_sql“, „mod_sql_mysql“ sowie „mod_quotatab_sql“ geladen werden.

Als nächstes bearbeiten Sie bitte die File „/etc/proftpd/proftpd.conf“:

Dort tätigen Sie folgende Änderungen:

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

Diese Sektion müssen Sie komplett auskommentieren.

Ebenfalls in der selben Datei fügen Sie zu dem Part „Alternative authentication frameworks“ folgendes hinzu:

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

DefaultRoot ~

SQLBackend              mysql
# The passwords in MySQL are encrypted using CRYPT
SQLAuthTypes            Plaintext Crypt
SQLAuthenticate         users groups

# used to connect to the database
# databasename@host database_user user_password
SQLConnectInfo  proftpd@localhost proftpd <password>

# 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        500

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

# 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

# User quotas
# ===========
QuotaEngine on
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 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

RootLogin off
RequireValidShell off

Unter dem Punkt SQLConnectInfo fügen Sie ihr definiertes Kennwort für den ProFTPd MySQL-User ein. Dies muss exakt das selbe sein wie, dass welches Sie bei dem
Erstellungsvorgang für den MySQL-Benutzer gewählt haben sein.

Anschließend um alle Änderungen zu übernehmen starten Sie den FTP-Server neu:

/etc/init.d/proftpd restart

Soweit sollte nun die Kommunikation zwischen der Datenbank und dem FTP-Server stehen.

Einrichten der FTP-User:

Nun sind wir an der stelle wo wir die FTP-Benutzer anlegen müssen.
Als aller erstes legen wir eine neue Benutzergruppe in unserer Datenbank an:

INSERT INTO `ftpgroup` (`groupname`, `gid`, `members`) VALUES ('ftpgroup', 2001, 'ftpuser');

Damit teilen wir dem FTP-Server mit welchen System-Benutzer er nutzen soll und in welcher Gruppe dieser sich befindet.
Diesen Benutzer haben wir vor der Konfiguration unseres FTP-Servers angelegt.

Als nächstes wir einen neuen FTP-Benutzer an der dieser Gruppe zugeteilt wird:

INSERT INTO `ftpquotalimits` (`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 ('example', 'user', 'true', 'hard', 15728640, 0, 0, 0, 0, 0);

Hierbei bekommt der neue FTP-Benutzer den Usernamen „example“ und wird dem quotatype „user“ zugeordnet, hier legen wir bloß den Quota für den neuen Benutzer an.
Die maximale Quotagröße (Speicherplatz) beträgt 300 MB ausgedrückt in Kilobyte.

Nun müssen wir als nächstes en richtigen FTP-Benutzer anlegen. dies tun wir mit:

INSERT INTO `ftpuser` (`userid`, `passwd`, `uid`, `gid`, `homedir`, `shell`, `count`, `accessed`, `modified`)
VALUES ('example', '<password>', 2001, 2001, '/home/www.example.com', '/sbin/nologin', 0, '', '');

Hierbei legen wir einen Benutzer an mit dem Usernamen „example“ und einem Passwort ersetzen Sie hier gegen das Passwort das Sie sich für den Benutzer wünschen.
Außerdem bekommt der User das HomeDirectory „/home/www.example.com/“ welches ebenfalls dann jailed ist. Sowie die Shell „/sbin/nlogin“ zugewiesen, womit sich der User nicht
via SSH einloggen darf.

Rechteverwaltung:

Bestimmen Sie ein Verzeichnis für alle FTP-User bestenfalls schon im Vorfeld und geben Sie diesem die Besitzrechte für das gesamte Verzeichnis.

chown -R ftpuser:ftpgroup <verzeichnis>

Verzeichnis ersetzen Sie gegen das Verzeichnis in dem alle FTP-Verzeichnisse liegen.

7 Comments

  1. Florian Bert August 19, 2016
    • Ilya Beliaev August 25, 2016
    • Alexander Knauer Dezember 19, 2016
  2. treki Oktober 14, 2016
    • Ilya Beliaev Oktober 15, 2016
  3. Georg April 9, 2018
    • Ilya Beliaev April 9, 2018

Leave a Reply