Abgesichertes PureFTPd mit MySQL für Virtual FTP-Hosting

In diesem Beitrag möchte ich euch eine PureFTPd Installation näher bringen, die mit virtuellen Benutzern aus einer MySQL Datenbank, anstatt mit Systembenutzern arbeitet. Neben der verbesserten Leistung können so auch viele FTP-Benutzer auf ein einziges System gelegt werden. Zudem besteht eine Sicherheit für das „jailen“ von Benutzern in Ihren entsprechenden „Home“-Ordnern. Auch können auf diesem Wege Transferraten, Speicherplatz sowie „Home“-Ordner simpel über die Datenbank konfiguriert werden. Diese „Anleitung“ wird auf einem Ubuntu 12.04 LTS durchgeführt, sollte jedoch problemlos auf andere Ubuntu Versionen sowie Debian Versionen anwendbar sein.

 

Share-Online

Die Vorbereitung

Nachdem wir uns mit unserem Server verbunden haben, sollten wir zunächst zu einem Administratorkonto wechseln, da wir für die Installation entsprechende Rechte benötigen. Auch sollte auf dem Server bereits ein Webserver (z.B. Apache oder Nginx) sowie eine MySQL (optional mit phpMyAdmin) Datenbank, installiert sein. Sollte dies nicht der Fall sein, kann die Installation z.B. wie folgt ausgeführt werden:

apt-get install mysql-server mysql-client phpmyadmin apache2

Nähere Informationen zur Installation der einzelnen Dienste, findet man leicht über Google (Apache, Nginx, MySQL, phpMyAdmin).

 

Die Installation und weitere Vorbereitung

Beginnen wir mit der Installation von PureFTPd. Hierfür können wir, nachdem wir unsere Paketliste aktualisiert haben, folgenden Befehl verwenden:

apt-get install pure-ftpd-mysql

Nach erfolgreicher Installation müssen wir nun noch einen Standard-Benutzer sowie eine Standard-Gruppe für den FTP-Dienst anlegen. Hierfür lege ich die Gruppe „ftpgroup“ und den Benutzer „ftpuser“ an (beide mit der GID / UID 2000 – sollten diese bereits in Verwendung sein, bitte eine andere nutzen!).

groupadd -g 2000 ftpgroup
useradd -u 2000 -s /bin/false -d /bin/null -c „pureftpd user“ -g ftpgroup ftpuser

 

Anlegen der Datenbank in MySQL

Als nächstes sollten wir die Datenbank sowie einen neuen Datenbank-Benutzer für PureFTPd anlegen. Bei mir wird der neue Datenbank-Benutzer sowie die neue Datenbank „pureftpd“ heißen (bitte MY_PASSWORD in den nachfolgenden Befehlen durch ein gutes Passwort ersetzen – dies wird nach dem Tutorial nicht mehr benötigt und kann deshalb auch zufällig erstellt werden mit z.B. einer Passwort-Generator-Webseite).

mysql -u root -p

CREATE USER ‚pureftpd’@’localhost‘ IDENTIFIED BY ‚MY_PASSWORD‚;
CREATE DATABASE pureftpd;
GRANT SELECT, INSERT, UPDATE, DELETE, CREATE, DROP ON pureftpd.* TO ‚pureftpd’@’localhost‘ IDENTIFIED BY ‚MY_PASSWORD‚;
GRANT SELECT, INSERT, UPDATE, DELETE, CREATE, DROP ON pureftpd.* TO ‚pureftpd’@’localhost.localdomain‘ IDENTIFIED BY ‚MY_PASSWORD‚;
FLUSH PRIVILEGES

Nun, da wir unseren Benutzer und unsere Datenbank haben, müssen wir noch die Tabelle für die Benutzer-Authentifizierung anlegen. Hierfür können wir direkt im MySQL-Dienst angemeldet bleiben und folgende Befehle verwenden (man beachte im „CREATE TABLE“-Befehl die Standard UID und GID – diese sollte mit den angelegten Informationen von oben übereinstimmen):

USE pureftpd;

CREATE TABLE users (
User varchar(16) NOT NULL default “,
status enum(‚0′,’1‘) NOT NULL default ‚0‘,
Password varchar(64) NOT NULL default “,
Uid varchar(11) NOT NULL default ‚2000‘,
Gid varchar(11) NOT NULL default ‚2000‘,
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 varchar(15) NOT NULL default ‚*‘,
QuotaSize smallint(5) NOT NULL default ‚0‘,
QuotaFiles int(11) NOT NULL default 0,
PRIMARY KEY (User),
UNIQUE KEY User (User)
) ENGINE=MyISAM;

Anschließend können wir wie folgt uns vom MySQL-Dienst abmelden:

quit;

Alternativ lässt sich dies natürlich auch über phpMyAdmin vereinfacht anlegen und verwalten.

 

Konfiguration von PureFTPd

Kommen wir nun endlich zur Konfiguration von PureFTPd. Hierfür sollten wir uns zunächst die originale Konfiguration sichern, anschließend die bestehende leeren und folgenden Inhalt einfügen:

cp /etc/pure-ftpd/db/mysql.conf /etc/pure-ftpd/db/mysql.conf_orig
cat /dev/null > /etc/pure-ftpd/db/mysql.conf
nano /etc/pure-ftpd/db/mysql.conf

# MYSQLServer     127.0.0.1
# MYSQLPort       3306

MYSQLSocket      /var/run/mysqld/mysqld.sock

MYSQLUser       pureftpd
MYSQLPassword   MY_PASSWORD
MYSQLDatabase   pureftpd

# You can also use „any“, „cleartext“, „crypt“, „sha1“, „md5“ or „password“
MYSQLCrypt      sha1

MYSQLGetPW      SELECT Password FROM users WHERE User=’\L‘

MYSQLGetUID     SELECT Uid FROM users WHERE User=’\L‘
#MYSQLDefaultUID 1000

MYSQLGetGID     SELECT Gid FROM users WHERE User=’\L‘
#MYSQLDefaultGID 1000

MYSQLGetDir     SELECT Dir FROM users WHERE User=’\L‘
MySQLGetQTAFS  SELECT QuotaFiles FROM users WHERE User=’\L‘
MySQLGetQTASZ  SELECT QuotaSize FROM users WHERE User=’\L‘

# MySQLGetRatioUL SELECT ULRatio FROM users WHERE User=’\L‘
# MySQLGetRatioDL SELECT DLRatio FROM users WHERE User=’\L‘

MySQLGetBandwidthUL SELECT ULBandwidth FROM users WHERE User=’\L‘
MySQLGetBandwidthDL SELECT DLBandwidth FROM users WHERE User=’\L‘

Hier muss das festgelegte MySQL-Passwort für unseren Benutzer wieder ersetzt werden (MY_PASSWORD). Beim Feld „MYSQLCrypt“ sollte die gewünschte Methode ausgewählt werden – ich würde hier „sha1“ oder mindestens „md5“ empfehlen (dies muss später nur beim Anlegen der Benutzer berücksichtigt werden).

Nun müssen wir für einige Konfiguration – wie u.a. auch das chrooten – noch einige Dateien erstellen. Hierbei würde ich folgende erstellen:

echo „yes“ > /etc/pure-ftpd/conf/ChrootEveryone

Dies lässt PureFTPd jeden virutellen Benutzer in seinem, in der Datenbank konfigurieren, „Home“-Verzeichnis chrooten, sodass er keine Verzeichnisse außerhalb dessen sehen kann.

echo „yes“ > /etc/pure-ftpd/conf/CreateHomeDir

Dies sorgt dafür, dass PureFTPd ein „Home“-Verzeichnis erstellt, wenn sich ein Benutzer anmeldet und das entsprechende Verzeichnis nicht existiert.

echo „yes“ > /etc/pure-ftpd/conf/DontResolve

Dies verhindert, dass PureFTPd nicht nach Hostnamen sucht, was Verbindungen signifikant beschleunigen und Bandbreitennutzung verringern kann.

Anschließend müssen wir den PureFTPd Dienst nur noch neustarten. Dies geht mit folgendem Befehl:

/etc/init.d/pure-ftpd-mysql restart

 

Ersten Benutzer anlegen und testen

Nun sind wir soweit, dass wir den ersten Benutzer anlegen können und anschließend unsere Konfiguration testen können. Dies können wir via phpMyAdmin machen oder erneut über die MySQL-Command-Shell. Falls wir die Shell benutzen würde dies z.B. wie folgt aussehen:

mysql -u root -p

USE pureftpd;

Nun erstellen wir einen Benutzer. Hier im Beispiel mit den Benutzernamen „example“, dem Status „1“ (für Aktiv), dem Passwort „secret“ (welches mittes Sha1-Algorhytmus verschlüsselt wird), der UID sowie GID „2000“ (oder anders, falls es einen anderen Benutzer gehören soll), dem „Home“-Verzeichnis „/home/test“, eine Upload- sowie Downloadbandbreite von maximal 100 KB/Sek. und einem maximal Speicherplatz von 20 MB.

INSERT INTO `users` (`User`, `status`, `Password`, `Uid`, `Gid`, `Dir`, `ULBandwidth`, `DLBandwidth`, `comment`, `ipaccess`, `QuotaSize`, `QuotaFiles`)
VALUES (‚example‘, ‚1‘, SHA1(’secret‘), ‚2000‘, ‚2000‘, ‚/home/test‘, ‚100‘, ‚100‘, “, ‚*‘, ’20‘, ‚0‘);

quit;

Nun sollte es möglich sein, sich mittels FTP-Client (z.B. FileZilla, WS_FTP, SmartFTP, gFTP oder simpltes Windows-Explorer FTP) und den verwendeten Logindaten mit dem Server zu verbinden. Wenn dem nicht so ist, ist etwas bei der Einrichtung schief gelaufen oder der Standard Port „21“ für FTP ist in der Firewall gesperrt. Wenn alles geklappt hat, sollte nun im Verzeichnis „/home“ ein Unterverzeichnis „test“ existieren, welches dem Benutzer „ftpuser“ und der Gruppe „ftpgroup“ gehört.

Ich würde jedoch eine Einrichtung über phpMyAdmin empfehlen, da dies viel komfortabler ist.

 

TLS aktivieren

Wer die Kommunikation etwas absichern möchte, sollte TLS für den Server aktivieren. Dies geschieht mit folgender simplen Befehlsfolge:

cd /etc/pure-ftpd/conf
echo 1 > TLS
mkdir -p /etc/ssl/private/
openssl req -x509 -nodes -newkey rsa:1024 -keyout /etc/ssl/private/pure-ftpd.pem -out /etc/ssl/private/pure-ftpd.pem
chmod 600 /etc/ssl/private/*.pem

 

Anonymes FTP erlauben

Wer FTP ohne Authentifizierung möchte, kann dies auch simpel einrichten. Zunächst wird ein Benutzer ftp (mit dem Home-Verzeichnis „/home/ftp“) und die Gruppe ftp angelegt:

groupadd ftp
useradd -s /bin/false -d /home/ftp -m -c „anonymous ftp“ -g ftp ftp

Nun müssen wir wieder eine PureFTPd Konfigurationsdatei anglegen und zwar wie folgt:

echo „no“ > /etc/pure-ftpd/conf/NoAnonymous

Anschließend nur noch einmal den PureFTPd Dienst neustarten.

/etc/init.d/pure-ftpd-mysql restart

Nun sollte noch das Verzeichnis „/home/ftp/upload“, das anonymen Benutzern erlauben wird Daten hochzuladen mit den Zugriffsrechten 311 erstellt, sodass Benutzer Daten hochladen, jedoch nicht sehen oder herunterladen können. Das „/home/ftp“ Verzeichnis wird die Zugriffsrechte 555 haben, was sehen und herunterladen aber keinen Upload erlaubt:

cd /home/ftp
mkdir upload
chown ftp:nogroup upload/
chmod 311 upload/
chmod 555 ./

Nun können sich anonyme Benutzer anmelden und von „/home/ftp“ Daten herunterladen, Daten jedoch nur nach „/home/ftp/upload“ hochladen (diese müssen anschließend vom Administrator verschoben werden, um anonymen Benutzern einen Download zu ermöglichen).

 

Weiteres