ProFTPD is als FTP server vergelijkbaar met andere populaire implementaties als vsftpd
, pure-ftpd
of wuftpd
, het protocol blijft immers steeds gelijk. Het allergrootste voordeel deze configuratie is dat de gebruikers virtueel zijn: de gebruikers bestaan alleen in MySQL maar hoeven niet als fysieke gebruikers op de server aanwezig te zijn. Daarnaast kun je de gebruikersnaam en het wachtwoord evenals de homedirectory zelf bepalen, wat deze configuratie heel flexibel maakt.
Met onderstaande handleiding kun je in een paar simpele stappen een snelle en betrouwbare FTP-server neerzetten.
Installatie van ProFTPD met Mysql back-end
Er wordt tijdend onderstaand stappenplan vanuit gegaan dat je al een werkende mysql-server
hebt geïnstalleerd.
-
Start allereerst met het installeren van de benodigde packages:
apt-get install proftpd proftpd-mod-mysql
Kies tijdens het installeren voor de "standalone" installatie:

-
Download het bestand met de SQL voor de proFTPd-tabellen en voeg deze toe aan een bestaande of nieuwe database. Dit kan bijvoorbeeld op onderstaande manier:
# Download de SQL
wget -O proftpd-structure.sql https://static.perfacilis.com/userfiles/1/proftpd-structure.sql
# Verbind met mysql
mysql --defaults-file=/etc/mysql/debian.cnf
# In de prompt van SQL, maak een nieuwe database aan indien gewenst
CREATE DATABASE `proftpd` DEFAULT CHARACTER SET utf8 COLLATE utf8_unicode_ci;
# Maak een nieuwe gebruiker aan en stel de rechten in.
# Verander het wachtwoord in onderstaande queries en sla het op een veilige plaats op:
CREATE USER 'proftpd'@'localhost' IDENTIFIED BY 'wachtwoord';
GRANT SELECT, INSERT, UPDATE, DELETE ON proftpd.* TO 'proftpd'@'localhost' IDENTIFIED BY 'wachtwoord';
FLUSH PRIVILEGES;
# Vervolgens wordt het gedownloadde bestand geïmporteerd
USE proftpd;
SOURCE proftpd-structure.sql;
QUIT;
-
Pas in het bestand /etc/proftpd/proftpd.conf
het volgende regels aan (of uncomment deze):
RequireValidShell off
DefaultRoot ~
PassivePorts 12000 12049
User ftp-data
Group ftp-data
Include /etc/proftpd/modules.conf
Include /etc/proftpd/sql.conf
De optie PassivePorts
is optioneel, pas de range indien gewenst aan en zorg dat een eventuele firewall TCP connecties op de betreffende poorten samen met poort 21 (de standaard poort voor FTP) toestaat.
Controleer daarnaast goed of modules.conf
al elders in het bestand wordt geladen, gezien de fout "error loading module" kan ontstaan als dit bestand twee keer is toegevoegd.
- In bovenstaande stap wordt de gebruiker en de groep
ftp-data
gedefinieerd, eventueel kun je hier een andere gebruiker voor kiezen - echter dient dit een gebruiker te zijn die fysiek in het systeem bestaat. Voer onderstaande opdrachten uit om de gebruiker en groep aan te maken:
groupadd -g 2001 ftp-data
useradd -u 2001 -s /bin/false -d /bin/null -c "proftpd user" -g ftp-data ftp-data
-
Verplaats of verwijder het bestand /etc/proftpd/sql.conf
en maak het opnieuw aan met de volgende inhoud:
# enable sql
SQLEngine on
SQLAuthTypes Plaintext
SQLAuthenticate users groups
SQLBackend mysql
# enable sql log
SQLLOGFILE /var/log/proftpd/sql.log
# connect to database
# databasename@host database_user user_password
SQLConnectInfo proftpddatabase@localhost proftpduser password
# set table and column names for users
SQLUserInfo proftpd_users user_name user_password user_id group_id user_homedir user_shell
# set table column names for groups
SQLGroupInfo proftpd_groups group_name group_id group_member
# min id for uids and gids
SQLMinID 30
# sql where for user
SQLUserWhereClause "user_enabled = 1"
# sql enabled check for group
SQLGroupWhereClause "group_enabled = 1"
# update login count and last login
SQLLog PASS update_login
SQLNamedQuery update_login UPDATE "user_login_count = user_login_count + 1, user_last_login = now() WHERE user_name = '%u'" proftpd_users
Pas in dit bestand de regel beginnend met SQLConnectInfo aan met de juiste gebruikersnaam, wachtwoord en database uit stap 2.
-
Schakel de benodigde modules in door de volgende regels te uncommenten in /etc/proftpd/modules.conf
:
LoadModule mod_sql.c
LoadModule mod_sql_mysql.c
-
Start als laatste de service opnieuw op:
/etc/init.d/proftpd restart
Gebruikers toevoegen
-
Het toevoegen van een gebruiker gaat in zijn geheel via de database:
mysql --defaults-file=/etc/mysql/debian.cnf
> use proftpd;
-
Allereerst dient de groep 'ftp-data' te worden toegevoegd aan de database (mits dat nog niet gebeurd is):
INSERT INTO proftpd_groups SET group_id = 2001, group_name = 'ftp-data', group_member = '', group_enabled = 1;
-
Vervolgens dient de gebruiker te worden toegevoegd aan de database (pas in onderstaande queries de vetgedruktde delen aan):
INSERT INTO proftpd_users SET user_name = 'gebruiker', group_id = 2001, user_password = 'plainpassword', user_homedir = '/ftp/gebruiker', user_id = 2001,
user_shell = '/bin/false', user_enabled = 1, user_login_count = 0, user_last_login = '';
UPDATE proftpd_groups SET group_member = CONCAT(group_member, ',gebruiker') WHERE group_id = 2001;
Versleutelde wachtwoorden
In bovenstaande configuratie worden wachtwoorden als PlainText
opgeslagen, handig wanneer een wachtwoord verloren raakt, maar absoluut onhandig wanneer een wachtwoord of je hele database op straat komt te liggen. De grootste uitdaging is dat de algoritmes die worden ondersteund door ProFTPD niet worden ondersteund door MySQL en vice-versa, CRYPT
uitgezonderd.
-
Pas de regel beginnend met SQLAuthTypes
in /etc/proftpd/sql.conf
als volgt aan:
SQLAuthTypes PlainText Crypt
-
Vervolgens kun je bestaande gebruikers aanpassen door gebruik te maken van mysql's ENCRYPT-functie:
UPDATE proftpd_users SET user_password = ENCRYPT(user_password);
Limieten instellen
Met onderstaande stappen zorg je dat elke gebruiker een maximale hoeveelheid schrijfruimte in zijn/haar FTP map heeft, ookwel Quota genoemd. Dit stuk is niet vereist voor een juiste werking van de FTP-server maar vaak wel handig.
-
Schakel de QuotaEngine
in door aan /etc/proftpd/proftpd.conf
het volgende toe te voegen:
QuotaEngine on
Include /etc/proftpd/sql_quota.conf
-
Maak vervolgens een nieuw bestand /etc/proftpd/sql_quota.conf
aan met de volgende inhoud:
# Enable quota
QuotaDirectoryTally on
#QuotaDisplayUnits Mb
QuotaShowQuotas on
# Quota log
QuotaLog /var/log/proftpd/quota.log
# sql get-quota-limit
SQLNamedQuery get-quota-limit SELECT "user_name, ql_quota_type, ql_per_session, ql_limit_type, ql_bytes_in_avail, ql_bytes_out_avail, ql_bytes_xfer_avail, \
ql_files_in_avail, ql_files_out_avail, ql_files_xfer_avail FROM proftpd_quota_limits WHERE user_name = '%{0}' AND ql_quota_type = '%{1}'"
# sql get-quota-tally
SQLNamedQuery get-quota-tally SELECT "user_name, qt_quota_type, qt_bytes_in_used, qt_bytes_out_used, qt_bytes_xfer_used, qt_files_in_used, qt_files_out_used, \
qt_files_xfer_used FROM proftpd_quota_tallies WHERE user_name = '%{0}' AND qt_quota_type = '%{1}'"
# sql update-quota-tally
SQLNamedQuery update-quota-tally UPDATE "qt_bytes_in_used = qt_bytes_in_used + %{0}, qt_bytes_out_used = qt_bytes_out_used + %{1}, \
qt_bytes_xfer_used = qt_bytes_xfer_used + %{2}, qt_files_in_used = qt_files_in_used + %{3}, qt_files_out_used = qt_files_out_used + %{4}, \
qt_files_xfer_used = qt_files_xfer_used + %{5} WHERE user_name = '%{6}' AND qt_quota_type = '%{7}'" proftpd_quota_tallies
# sql insert-quota-tally
SQLNamedQuery insert-quota-tally INSERT "%{0}, %{1}, %{2}, %{3}, %{4}, %{5}, %{6}, %{7}" proftpd_quota_tallies
QuotaLimitTable sql:/get-quota-limit
QuotaTallyTable sql:/get-quota-tally/update-quota-tally/insert-quota-tally
# list quota informations
# when listing directories
SQLNamedQuery gettally SELECT "round((qt_bytes_in_used / (1024 * 1024)),2) FROM proftpd_quota_tallies WHERE user_name = '%u'"
SQLNamedQuery getlimit SELECT "ROUND((ql_bytes_in_avail / (1024 * 1024)),2) FROM proftpd_quota_limits WHERE user_name = '%u'"
SQLNamedQuery getfree SELECT "ROUND(((proftpd_quota_limits.ql_bytes_in_avail - proftpd_quota_tallies.qt_bytes_in_used) / (1024 * 1024)),2) \
FROM proftpd_quota_limits,proftpd_quota_tallies WHERE proftpd_quota_limits.user_name = '%u' AND proftpd_quota_tallies.user_name = '%u'"
SQLShowInfo LIST "226" "Used %{gettally}MB from %{getlimit}MB. You have %{getfree}MB available space."
-
Schakel de benodigde modules in door de volgende regels uit te commenten in /etc/proftpd/modules.conf
:
LoadModule mod_quotatab.c
LoadModule mod_quotatab_sql.c
-
Start als laatste de service opnieuw op:
/etc/init.d/proftpd restart
-
Vervolgens kun je een schijfruimte limiet van 50MiB instellen voor een bepaalde gebruiker:
INSERT INTO proftpd_quota_limits SET user_name = 'gebruiker', ql_quota_type = 'user', ql_per_session = false, ql_limit_type = 'soft', ql_bytes_in_avail = 50 * POWER(2, 10);
ProFTPD samen met Apache - oplossing voor FTP rechtenprobleem
Doordat bestanden geuploadt door via de FTP server als gebruiker gelijkgesteld worden aan de gebruiker en groep die in de mysql database is ingesteld, kan het voorkomen dat Apache niet bij deze bestanden kan of de bestanden niet kan bewerken (dit kan bijvoorbeeld problemen opleveren bij het updaten van Wordpress). Dit kun je op twee manieren oplossen:
De gebruiker ftp-data toevoegen aan de groep www-data
Deze oplossing heeft mijn persoonlijke voorkeur. De bestanden worden op deze manier namelijk nog steeds als de ftp-gebruiker weggeschreven maar de groep www-data heeft wel de juiste rechten op deze bestanden. Voeg op onderstaande manier de gebruiker ftp-data
toe aan de groep www-data
:
usermod -a -G www-data ftp-data
De groep www-data toevoegen in ProFTPD
De tweede oplossing is het toevoegen van groep www-data
aan ProFTPD. Op deze manier wordt het bestand weggeschreven met als eigenaar de betreffende gebruiker, maar omdat deze gebruiker in de groep www-data
zit zijn de groepsrechten van deze groep op dat bestand van kracht. Zoek hervoor als eerste het unieke nummer van de groep op:
cat /etc/group | grep www-data
Voeg vervolgens de groep toe zoals bovenstaand beschreven. Wanneer de groep-id bijvoorbeeld 33 is, dan volgt daar onderstaande query uit:
INSERT INTO proftpd_groups SET group_id = 33, group_name = 'www-data', group_member = 'gebruiker', group_enabled = 'true';
Debuggen
Het debuggen van de configuratie gaat het gemakkelijkste en het snelst door de logs te volgen terwijl je in een apart venster (bijvoorbeeld via FileZilla) een FTP-verbinding maakt. In de logbestanden wordt meestal een duidelijke foutmelding gegeven waarmee de problemen opgelost kunnen worden. De 'algemene' fouten kun je terugvinden in het algemene logbestand voor ProFTPD:
tail -f /var/log/proftpd/proftpd.log
Fouten die specifiek gerelateerd zijn aan de configuratie met mysql vindt je in het sql.log
:
tail -f /var/log/proftpd/sql.log
Fouten die specifiek gerelateerd zijn aan de quota configuratie vindt je in het quota.log
:
tail -f /var/log/proftpd/quota.log
ProFTPD service stopt vanzelf
In Ubuntu 14.04 (waarschijnlijk ook in andere Linux relases) komt het voor dat ProFTPD elke nacht vanzelf stopt. De Logrotate service ruimt dagelijks de logs op, waarbij de service opnieuw wordt gestart (zie /etc/logrotate.d/proftpd-basic
). Doordat bij het herstaren van de service het stoppen van ProFTPD te lang duurt wordt er geen nieuwe instance meer gestart. Om dit op te lossen kun je een "retry" parameter toevoegen aan de cronjob.
Zoek in het bestand /etc/init.d/proftpd
de volgende regel op:
start-stop-daemon --stop --signal $SIGNAL --quiet --pidfile "$PIDFILE"
En pas deze als volgt aan:
start-stop-daemon --stop --signal $SIGNAL --retry 1 --quiet --pidfile "$PIDFILE"
Conclusie
In een paar simpele stappen heb je een goed werkende en stabiele FTP server geïnstallerd. Doordat deze FTP server "standalone" is, is deze - behalve de mysql laag - niet afhankelijk van andere services en hoeft deze ook geen andere service te vertragen.
Ondanks dat deze methode een tamelijk veilige manier is om gebruikersgegevens op te slaan, is een FTP-server op zichzelf een beveiligingsriciso; doordat FTP door zo veel servers geaccepteerd wordt is het een veelvuldig misbruikt doelwit voor kwaadwillenden. Omdat het FTP-protocol niet perfect is adviseren we om ProFTPD zo veel mogelijk up to date te houden en indien mogelijk een firewall in te stellen en indien mogelijk Fail2ban toe te voegen.