Installare un server ftp con Pure-FTPd su Ubuntu Linux Server

PureFTPd logo

Utilizzando pure-Ftpd con l'appoggio di un database MySQL, è possibile creare un server FTP basato su utenti virtuali. Con virtuali si intende che l'account utente del server FTP non deve necessariamente essere un account di sistema. Non è quindi necessario creare un utente Linux ed assegnargli tutti i privilegi necessari all'uso del server FTP e ripetere la procedura per ogni utente ftp che desideriamo aggiungere, ma è possibile creare utenti che possono connettersi ed utilizzare il server Ftp senza che questi siano utenti di sistema. In tal senso quindi si capisce il perché di "virtuali". Tutte le informazioni sugli utenti del server possono essere memorizzare su di un database (pure-ftpd supporta Postgre-SQL, MySQL) o utilizzare LDAP (it.wikipedia.org/wiki/LDAP e it.wikipedia.org/wiki/Servizio_di_directory).

Del resto, poiché sotto Linux tutto gira attorno ai permessi di utenti e gruppi, è necessario comunque predisporre un utente di sistema che tutti gli utenti virtuali condivideranno. In pratica tutti i file caricati tramite FTP dai diversi utenti virtuali, a livello di sistema risulteranno caricati da un unico utente reale. Prestate quindi attenzione quando assegnerete le cartelle ad diversi utenti, perché se tutti condivideranno la medesima cartella, non vi sarà nessuna "privacy"sui file. Una cattiva configurazione, potrebbe portare a dei possibili problemi di sicurezza.

Ricapitolando: con il metodo degli utenti virtuali è possibile avere un certo numero di utenti FTP, ciascuno con sua password, nome, id, cartella ecc... anche se questi non sono utenti di sistema. E' come se fossero in /etc/passwd ma in realtà vengono memorizzati in un file diverso, nel nostro caso in database MySQL. In tal modo è possibile creare utenti FTP senza dover configurare account di sistema, inoltre per ciascun utente è possibile specificare quote, banda disponibile etc... cosa che non sarebbe possibile fare con i normali account di sistema. In linea di principio migliaia di utenti ftp possono condividere lo stesso utente di sistema, a condizione che siano chrooted e che abbiano ciascuno la propria home. In tal senso è quindi buona pratica, prima di iniziare ad utilizzare gli utenti virtuali, creare un utente di sistema specifico a tale scopo. Tale procedura non è strettamente necessaria, nel senso che è possibile utilizzare allo scopo qualunque utente di sistema ad eccezione di root, tuttavia è consigliata.

Oltre alla comodità degli utenti virtuali, esistono inoltre diversi programmi di gestione visuale del server FTP, programmi che consentono tramite una semplice interfaccia grafica di eseguire tutte le operazioni necessarie sul server, dalla creazione alla gestione degli utenti del server. C'è da segnalare però che per lo più queste interfacce girano sotto KDE o Gnome. Tuttavia, dato che la macchina su cui lavoro è in ambiente Windows, e dato che sto installando pureftpd su di un VPS Ubuntu server, sostanzialmente non dispongo di un ambiente grafico Linux su cui operare, quindi non mi metterò a spiegare il funzionamento di questi "gestionali".

Esiste una possibile alternativa via browser web (User Manager for Pure-FTPd), scelta che confesso di aver preso in considerazione, tuttavia dopo vari tentativi andati pressochè a vuoto dovuti probabilmente ad una incompatibilità del software con PHP 5 (è solo una mia ipotesi, non ho indagato), ho optato per la soluzione più logica e forse più semplice, ovvero gestione del database MySQL di PureFTPd tramite PhpMyAdmin. Del resto è molto probabile che se state utilizzando MySQL, avrete già installato PhpMyAdmin sul vostro sistema.

In questa guida mostrerò quindi come installare e rendere operativo Pure-ftpd con autenticazione su database MySQL e gestione del server e relativo database tramite PhpMyAdmin, il tutto su di un sistema Linux Ubuntu 7.04.

Si noti che pure-ftpd consente l'utilizzo contemporaneo di differenti metodi di autenticazione. Questo significa che se stiamo utilizzando l'autenticazione tramite MySQL, possiamo utilizzare contemporaneamente anche quella tramite Unix o PAM, ovvero possiamo consentire agli utenti di sistema di loggarsi senza bisogno di creare per loro un utente virtuale nel database MySQL. Per maggiori informazioni vi rimando alla documentazione ufficiale di pure-ftpd.

Procediamo.

La prima operazione consiste ovviamente nell'installazione del server. Nel repository universe di Ubuntu è disponibile il pacchetto pure-ftpd da installare tramite apt-get; in particolare è già disponibile la versione configurata per il supporto a MySQL. Scelgo quest'ultima che installo digitando:

sudo apt-get install pure-ftpd-mysql

Per verificare lo stato del server, digito:

sudo netstat -ap | grep "*:ftp"

Od anche:

ps -e | grep pure-ftpd-mysql

Per default il server viene avviato in modalità stand-alone come demone.

Seguendo quando indicato nella guida ufficiale, creo un utente ftpuser ed il gruppo ftpgroup (ma è chiaro che posso anche utilizzare nomi differenti a mia scelta). E' possibile lasciar decidere al sistema l'id identificativo di entrambi, ed in tal caso sarà sufficiente il comando:

sudo groupadd ftpgroup
sudo useradd -s /bin/false -d /bin/null -c "utente pureftpd" -g ftpgroup ftpuser

oppure specificarli utilizzando un parametro aggiuntivo. Io che sono un maniaco del "controllo assoluto" preferisco scegliere l'identificativo di gruppo ed utente, quindi ad esempio supponendo di voler assegnare 1001 come identificativo (si suppone che tale valore sia disponibile sul proprio sistema), scrivo:

sudo groupadd -g 1001 ftpgroup
sudo useradd -u 1001 -s /bin/false -d /bin/null -c "utente pureftpd" -g ftpgroup ftpuser

Per una completa spiegazione dei parametri utilizzati, vi rimando al manuale di useradd e groupadd (man useradd e man groupadd).

E' possibile vedere / verificare gli ID assegnati utilizzando il comando "id":

pureftpd-1

Io ho scelto 1001, ma come detto sopra, potete scegliere voi stessi lo ID specificandolo al momento della creazione di utente e gruppo; preoccupatevi piuttosto di memorizzare tale valore in quanto vi servirà più avanti.

A questo punto posso procedere con la configurazione del database MySQL.

E' possibile effettuare l'operazione manualmente, via riga di comando (vedi anche qui per un'ottima guida), oppure è possibile creare e configurare il database utilizzando PhpMyAdmin. Per la creazione forse è più rapida la via di comando, mentre per la gestione potrebbe risultare più utile l'interfaccia grafica di PhpMyAdmin. La scelta comunque spetta a voi.

Io qui vi mostro come configurare il database via riga di comando, cosa che con un po' di copia ed incolla e le dovute personalizzazioni si rivela sostanzialmente più veloce.

Come prima cosa creo il database ed assegnamo all'utente ftp i privilegi necessari. Chiamo con poca fantasia "utenteftp" l'utente che utilizzo per interagire con il database "pureftpd" (sempre a corto di fantasia...). Devo anzitutto loggarmi nella shell di mysql come utente root (o qualunque altro utente con i sufficienti privilegi):

mysql -u root -p

e scrivo i seguenti comandi (più sotto vedete uno screenshot con tutte le operazioni):

CREATE DATABASE pureftpd;
GRANT SELECT, INSERT, UPDATE, DELETE, CREATE, DROP ON pureftpd.* TO 'utenteftp'@'localhost' IDENTIFIED BY 'password_ftp';
FLUSH PRIVILEGES;

Ricordatevi di sostituire 'password_ftp' con la vostra password.

pureftpd-2

A questo punto devo creare la tabella degli utenti virtuali per il server FTP. La struttura della tabella stessa è funzione dei parametri che si desidera potrer gestire in modo individuale per ogni singolo utente.

L'interazione tra il server FTP ed il database MySQL è controllata dal file /etc/pure-ftpd/db/mysql.conf (questo è il percorso predefinito in ubuntu 7.04 server).

In base al manuale di pure-ftpd, le direttive (i parametri) che è possibile controllare sono:

MYSQLGetPW

SELECT Password FROM users WHERE User="\L"

MYSQLGetUID

SELECT Uid FROM users WHERE User="\L"

MYSQLGetGID

SELECT Gid FROM users WHERE User="\L"

MYSQLGetDir

SELECT Dir FROM users WHERE User="\L"

MYSQLDefaultUID

Specifica lo userID di default (sovrascrive MYSQLGetUID che diventa quindi inutile)

MYSQLDefaultGID

Specifica il groupID di default (sovrascrive MYSQLGetGID che diventa quindi inutile)

MySQLGetQTAFS

Indica il numero massimo di file che l'utente può mettere nella sua home (0 per nessun limite)

MySQLGetQTASZ

La quota massima in MB assegnata ad ogni singolo utente, ovvero la spazio massimo in MB occupato dai file caricati dall'utente (0 per nessun limite)

MySQLGetRatioUL

MySQLGetRatioDL

Questa funzione consente di impostare per ciascun singolo utente un rapporto specifico tra upload/download. Ad esempio un rapporto 2:5 indica che per per poter scaricare 5MB di file, è necessario prima averne caricati almeno 2.

MySQLGetBandwidthUL

MySQLGetBandwidthDL

Restrizioni sulla banda massima disponibile in upload ed in download espressa in KB/s (0 per nessun limite)

MySQLForceTildeExpansion

Abilita "~" nei path. Da utilizzare esclusivamente se gli utenti reali del sistema coincidono con quelli virtuali di MySQL

MySQLTransactions On

Abilita il supporto alla scrittura transazionale nel nostro DB (vedi qui)

In pratica se desidero poter controllare per ogni singolo utente ciascuna delle direttive sopra elencate, è chiaro che dovrò avere nel database la colonna relativa. Faccio un rapido esempio. Se voglio limitarmi a poter gestire per ogni singolo utente semplicemente password, user-id, group-id e home directory, rispettivamente MYSQLGetPW, MYSQLGetUID, MYSQLGetGID, MYSQLGetDir, sarà sufficiente una tabella piuttosto semplice, che posso creare dalla shell di mysql con il seguente comando:

CREATE TABLE utenti_virtuali ( User VARCHAR(16) BINARY NOT NULL, Password VARCHAR(64) BINARY NOT NULL, Userid INT(11) NOT NULL default '-1', Groupid INT(11) NOT NULL default '-1', Dir VARCHAR(128) BINARY NOT NULL, PRIMARY KEY(User) );

Nel file di configurazione mysql.conf andrò a controllare che siano attive (decommentate) le relative query, ovvero:

MYSQLGetPW SELECT Password FROM utenti WHERE User="\L" MYSQLGetUID
SELECT Uid FROM utenti WHERE User="\L" MYSQLGetGID
SELECT Gid FROM utenti WHERE User="\L" MYSQLGetDir
SELECT Dir FROM utenti WHERE User="\L"

Dove \L sarà sostituito dal nomeutente (login) che si sta connettendo al server ftp, ovvero se mi sto connettendo con il nome utente andrea, allora "\L" sarà sostituito con "andrea". Oltre a \L esistono anche altre "scorciatoie" predefinite, le riassumo nella tabella seguente:

\L

sostituito dal nomeutente con cui ci stimo autenticando nel server FTP

\I

sostituito dall'indirizzo IP della macchina a cui mi sto connettendo (indirizzo IP del server)

\P

sostituito dal numero della porta a cui mi sto connettendo

\R

sostituito dal nostro indirizzo IP (indirizzo IP del client)

\D

sostituito dal nostro indirizzo IPv4 in rappresentazione decimale

NOTA: utilizzando la sintassi SQL è possibile introdurre controlli ulteriori, ad esempio sull'indirizzo IP di o su un eventuale stato utente attivo/disabilitato. Più avanti quando andrò a settare il file di configurazione mysql.conf, vi mostrerò alcuni esempi.

Ma torniamo alla creazione della nostra tabella. Se i campi che desidero poter controllare per ogni singolo utente sono maggiori, più complessa sarà anche la tabella risultante. E' chiaro che è possibile aggiungere una nuova colonna alla tabella anche in un momento successivo, tuttavia non è una soluzione ottimale in quanto potrebbero esserci dei problemi con gli utenti già attivi. E' bene quindi pianificare in anticipo la struttura definitiva della tabella del database di pureftpd, se non altro, almeno per non complicarsi la vita in futuro.

Dopo le dovute considerazioni, decido quindi di aver piena libertà e di poter gestire in modo indipendente e per ogni singolo utente i seguenti parmetri:

  • userid e groupid
  • home dir
  • bandwidth in upload ed in download
  • quota massima sia per numero di file che per MB totali
  • commento
  • IP con permesso di accesso

I parametri di default li imposto come di seguito:

  • userid = groupid = 1001, ovvero utente ftpuser e gruppo ftpgroup come impostazione predefinita per ogni utente ftp virtuale, secondo quanto visto all'inizio;
  • ipaccess = '*' ovvero accesso consentito per l'utente da qualunque indirizzo IP;
  • DLBandwith = 100 (valore in KB/s)

Ora aggiungo la tabella "utenti_virtuali" al database "pureftpd"; utilizzando sempre la shell di mysql loggato come root (mysql -u root -p), mi limito a scrivere il seguente comando (voi andate di copia ed incolla con le eventuali dovute personalizzazioni):

USE pureftpd;
CREATE TABLE utenti_virtuali ( User varchar(16) NOT NULL default '', Status enum('0','1') NOT NULL default '0', Password varchar(64) NOT NULL default '', Userid int(11) NOT NULL default '1001', Groupid int(11) NOT NULL default '1001', Dir varchar(128) NOT NULL default '', ULBandwidth smallint(5) NOT NULL default '0', DLBandwidth smallint(5) NOT NULL default '100', 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 DEFAULT CHARSET=latin1;

pureftpd-3

Rimane ora da configurare il server pure-ftpd-mysql per permettergli di interagire con il database appena creato.

Faccio come prima cosa una copia di backup e poi edito il file /etc/pure-ftpd/db/mysql.conf (qui uso il semplice editor nano, comodo per chi non ha dimestichezza con Vi e simili):

sudo cp /etc/pure-ftpd/db/mysql.conf /etc/pure-ftpd/db/mysql.conf-backup
sudo nano /etc/pure-ftpd/db/mysql.conf

pureftpd-4

Ricapitolando quanto fatto fin'ora, mi ritrovo tra le mani un database "pureftpd" ed un utente mysql "utenteftp" con password "password_ftp" che possiede tutti i privilegi per interagire con questo DB.

Il file mysql.conf è molto ben commentato, quindi se lo desiderate potete dargli una letta per capire l'uso dei diversi parametri, oppure potete semplicemente sostituirne il contenuto con quando mostrato di seguito, avendo prima l'accortezza di sostituire la password per MYSQLPassword ed eventualmente apportare tutte le personalizzazioni del vostro caso.

Ecco il mio file /etc/pure-ftpd/db/mysql.conf:

#MYSQLServer localhost
#MYSQLPort 3306 

MYSQLSocket /var/run/mysqld/mysqld.sock
MYSQLDatabase pureftpd
MYSQLUser utenteftp
MYSQLPassword password_ftp

#Criptazione delle password, metodo md5
MYSQLCrypt md5

MYSQLGetPW SELECT Password FROM utenti_virtuali WHERE User="\L" AND Status="1" AND (IPaccess = "*" OR IPaccess LIKE "\R")

#UID e GID
MYSQLGetUID SELECT Userid FROM utenti_virtuali WHERE User="\L" AND Status="1" AND (IPaccess = "*" OR IPaccess LIKE "\R")
MYSQLGetGID SELECT Groupid FROM utenti_virtuali WHERE User="\L" AND Status="1" AND (IPaccess = "*" OR IPaccess LIKE "\R")

#HOME DIR
MYSQLGetDir SELECT Dir FROM utenti_virtuali WHERE User="\L" AND Status="1" AND (IPaccess = "*" OR IPaccess LIKE "\R")

#BANDA
MySQLGetBandwidthUL SELECT ULBandwidth FROM utenti_virtuali WHERE User="\L" AND Status="1" AND (IPaccess = "*" OR IPaccess LIKE "\R")
MySQLGetBandwidthDL SELECT DLBandwidth FROM utenti_virtuali WHERE User="\L" AND Status="1" AND (IPaccess = "*" OR IPaccess LIKE "\R")

#QUOTE
MySQLGetQTASZ SELECT QuotaSize FROM utenti_virtuali WHERE User="\L" AND Status="1" AND (IPaccess = "*" OR IPaccess LIKE "\R")
MySQLGetQTAFS SELECT QuotaFiles FROM utenti_virtuali WHERE User="\L" AND Status="1" AND (IPaccess = "*" OR IPaccess LIKE "\R")

Come potete vedere sopra, è stato utilizzato l'operatore booleano AND per effettuare dei controlli incrociati permettendo così di avere delle condizioni di accesso più restrittive, quali il controllo sullo stato dell'utente, se attivo o meno (Status="1") ed eventuali limitazioni sull'indirizzo IP in combinazione con l'opzione \R sostituita dal server pure-ftpd con l'indirizzo IP del client che si connette (ricordate la tabella di sopra?).

Qui sotto, l'interfaccia testo di "nano" nella nostra shell:

pureftpd-5

Per salvare le modifiche, CTRL+O quindi INVIO e quindi CTRL+X per uscire.

Mi restano due ulteriori aggiunte. Rendere automatica la creazione della directory home per ogni singolo utente nel caso questa non sia presente, utilizzando l'opzione di configurazione CreateHomeDir, ed impedire agli utenti di navigare liberamente sul mio sistema impostanto come directory root la rispettiva home, con l'opzione ChrootEveryone. Per far questo, è necessario impostare alcuni parametri di configurazione del server pure-ftpd.

In Ubuntu, almeno dalla versione 7.04 alla 8.04, è possibile configurare le opzioni di avvio del demone pure-ftpd utilizzando dei semplici file di configurazione inseriti nella cartella /etc/pure-ftpd/conf. Sostanzialmente si tratta di creare dei semplici file di testo, un singolo file per ogni singola opzione, dove il nome del file corrisponde all'opzione che si desidera configurare, ed il contenuto è il parametro dell'opzione di configurazione, che può essere un numero, un semplice yes, no, etc... Per le opzioni del tipo ON/OFF, ovvero booleane, il parametro da inserire nel file sarà semplicemente un valore booleano come yes / no.

Per una lista dei parametri disponibili, consultate il manuale da riga di comando di pure-ftpd (man pure-ftpd) e controllate nella lista "Alternative style". I nomi estesi che sono indicati accanto ad ogni comando sono i nomi dei file utilizzabili per le impostazioni di configurazione (i nomi dei file non sono case sensitive). Ad esempio, l'opzione -A da riga di comando equivale a ChrootEveryone.

Detto questo, posso procedere ad editare o creare il file /etc/pure-ftpd/conf/ChrootEveryone (a seconda che sia o meno già presente), e scrivere al suo interno "yes" (semplicemente):

sudo nano /etc/pure-ftpd/conf/ChrootEveryone

pureftpd-6

CTRL+O, INVIO e CTRL+X, e facciamo la stessa identica cosa con il file /etc/pure-ftpd/conf/CreateHomeDir che conterrà a sua volta semplicemente "yes".

sudo nano /etc/pure-ftpd/conf/CreateHomeDir

pureftpd-7

Salviamo ed usciamo CTRL+O, INVIO e CTRL+X.

Per rendere effettive le modifiche, è necessario riavviare il server FTP:

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

(ricordo che se avete installata la versione con supporto a mysql, lo script è pure-ftpd-mysql in init.d e non pure-ftpd). Al momento del riavvio, le opzioni che ho configurato utilizzando i file di configurazione nella cartella /etc/pure-ftpd/conf verranno tradotte nelle relative opzioni a linea di comando:

Restarting ftp server: Running: /usr/sbin/pure-ftpd-mysql -l mysql:/etc/pure-ftpd/db/mysql.conf -l pam -O clf:/var/log/pure-ftpd/transfer.log -u 1001 -A -j -I 120 -E -D -B

Il server FTP ora è pronto all'uso. Posso verificarne il funzionamento aggiungendo il mio primo utente virtuale.

Chiamo "paolorossi" tale utente, con password "passwordrossi", userid e groupid predefiniti, cartella home /var/www/_ftpfolder/paolorossi, banda 100Kb/s in download ed in upload, commento "Utente semplice", quota 100MB, file illimitati. Per far questo, sempre all'interno della shell di mysql scrivo (se non è già selezionato, ricordatevi di selezionare il database "pureftpd"):

INSERT INTO utenti_virtuali (User, Status, Password, Dir, ULBandwidth, DLBandwidth, Comment, QuotaSize) VALUES ('paolorossi', '1', MD5('passwordrossi'), '/var/www/_ftpfolder/paolorossi', '100', '100', 'Utente semplice', '100');

Per la password ho utilizzato la crittografia MD5 come avevo specificato nel file di configurazione mysql.conf.

pureftpd-9

Per lasciare alcuni campi al valore predefinito, semplicemente basta non includerli nell'istruzione SQL; come potete notare qui sopra, non no incluso i campi UID, GID, ipaccess e QuotaFiles che rimangono al valore predefinito.

A questo punto tutto dovrebbe essere pronto per la prima connessione. Posso provare a collegarmi con un qualunque client FTP al server appena configurato utilizzando l'utente virtuale appena creato; per la macchina virtuale in locale su cui sto facendo le prove di installazione i parametri sono i seguenti:

  • Indirizzo del server: 192.168.0.10
  • Nome utente: paolorossi
  • Password: passwordrossi

Posso provare ad esempio con il client predefinito ftp di windows, da una finestra del prompt di MS-DOS:

pureftpd-10

Perfetto, tutto ok! Il mio server FTP è ora pronto all'uso.

Vi ricordo infine che anche tutti gli utenti Linux possono connettersi con il proprio nomeutente e password al server pure-FTPd, e che si connetteranno alla propria cartella utente (/home/nomeutente).