Su sistemi operativi unix-like è possibile realizzare un server ftp di semplice amministrazione, integrando il software ProFTPD con MySQL, il più popolare database open source. Questa soluzione utilizza le tabelle di MySQL per memorizzare impostazioni quali utenti, password, home directory e shell. Un simile approccio comporta alcuni vantaggi tra i quali:
- la gestione di utenti virtuali anziché utenti di sistema;
- l'aggiunta di un utente corrisponde ad una banale istruzione SQL di INSERT;
- risulta semplice realizzare un'amministrazione web scrivendo una piccola applicazione, ad esempio in PHP;
- utenti non molto esperti, se dotati di un'interfaccia semplice ed intuitiva, potranno eseguire le comuni operazioni di gestione;
- risulta immediato scalare da decine a centinaia di utenti;
- entrambi i software sono rilasciati sotto licenza open source GPL e distribuiti gratuitamente (per lo meno la versione Community Edition di MySQL).
Ci fermiamo qui, anche se risulta evidente che potremmo trovare altri punti a favore della soluzione proposta. Ai lettori più attenti non sarà sfuggita l'analogia con un precedente articolo dedicato ad un server di posta elettronica realizzato integrando Postfix e MySQL.
Mentre MySQL non ha bisogno di presentazioni, qualche cenno merita invece il server ProFTPD. Gli sviluppatori diedero vita al progetto dopo aver trovato frustrante e dispendioso in termini di tempo, cercare di aggiungere caratteristiche e correggere bug al software wu-ftpd, allora abbastanza popolare. Decisero di creare un programma completamente nuovo anziché basarsi sul codice di un server ftp esistente. Il risultato è un software altamente configurabile e facilmente espandibile in virtù del suo disegno modulare. La soluzione descritta in quest'articolo si basa proprio su uno dei vari moduli d'integrazione con i database SQL. Altri moduli sono stati scritti per interfacciarsi con i server LDAP, per la crittografia SSL/TLS o per il supporto a RADIUS.
C'è, inoltre, una buona notizia per chi ha una certa familiarità con Apache: il file di configurazione proftpd.conf, solitamente posizionato in /etc, ha una sintassi molto simile a quella dell'httpd.conf.
Infine, se volete tenere sotto controllo l'attività del server ftp, vari programmi sono in grado di analizzare il formato delle registrazioni degli accessi e da esse generare statistiche. Tra tutti ricordiamo Webalizer oggetto, tempo addietro, di un dettagliato articolo.
A riprova dell'interesse suscitato da questo software possiamo citare tra i suoi utilizzatori SourceForge, Samba, Linksys e Slackware.
Installazione
L'ambiente utilizzato negli esempi sarà Linux e precisamente la distribuzione Fedora 10 a 64 bit. Diamo per scontato che MySQL sia già installato e funzionante ed occupiamoci di ProFTPD. Utilizzeremo YUM per le nostre operazioni, prima fra tutte l'elencazione dei pacchetti relativi al software:
[root]# yum list proftpd*
Tra questi ci interessano in particolare proftpd.x86_64 e proftpd-mysql.x86_64. Ricordo che stiamo lavorando con una versione a 64 bit del sistema operativo altrimenti i pacchetti si chiamerebbero proftpd.i386 e proftpd-mysql.i386.
Passiamo ora all'installazione:
[root]# yum install proftpd.x86_64 proftpd-mysql.x86_64
Al termine dell'operazione sulla nostra macchina risulteranno installati il server ftp vero e proprio ed il modulo mod_sql_mysql che ci consentirà l'accesso al database.
Poiché i nostri utenti saranno virtuali, ovvero esisteranno solo all'interno del database, dovremo creare un unico utente reale che ci consenta di gestire le impostazioni:
[root]# groupadd -g 3000 ftpgroup [root]# useradd -u 3000 -s /bin/false -d /bin/null -c "proftpd user" -g ftpgroup ftpuser
A questo punto ci ritroveremo l'utente ftpuser appartenente al gruppo ftpgroup, privo di home directory e privo di shell. L'attribuzione del valore 3000 a uid e gid è ovviamente arbitraria, scegliete comunque un valore che garantisca di evitare collisioni con altri utenti di sistema.
Creazione del database e delle tabelle
Ora passiamo a MySQL, accediamo alla console con privilegi amministrativi, creiamo il database ed un utente che possa gestirlo:
mysql> CREATE DATABASE ftpserver; mysql> GRANT select,insert,update,delete ON ftpserver.* TO ftpadmin@localhost IDENTIFIED BY 'miapassword'; mysql> flush privileges;
Come primo passo creiamo la tabella ftp_group:
mysql> use ftpserver Database changed mysql> CREATE TABLE `ftp_group` ( -> `groupname` varchar(16) NOT NULL default '', -> `gid` smallint(6) NOT NULL default '3000', -> `members` varchar(16) NOT NULL default '', -> PRIMARY KEY (`groupname`) -> ) ENGINE=MyISAM COMMENT='ProFTPd tabella gruppi'; Query OK, 0 rows affected (0.00 sec)
Inseriamo nella tabella i valori corrispondenti al gruppo e all'utente reale che abbiamo poc'anzi creato:
mysql> INSERT INTO ftp_group VALUES('ftpgroup',3000,'ftpuser');
È la volta della tabella dedicata agli utenti:
mysql> CREATE TABLE `ftp_users` ( -> `id` int(10) unsigned NOT NULL auto_increment, -> `user` varchar(32) NOT NULL default '', -> `passwd` varchar(80) NOT NULL default '', -> `uid` smallint(6) NOT NULL default '3000', -> `gid` smallint(6) NOT NULL default '3000', -> `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', -> PRIMARY KEY (`id`), -> UNIQUE KEY `userid` (`user`) -> ) ENGINE=MyISAM COMMENT='ProFTPd tabella utenti'; Query OK, 0 rows affected (0.01 sec)
In cui inseriremo un utente per le nostre prove:
mysql> INSERT INTO ftp_users VALUES (1, 'testuser', PASSWORD('testpwd'), 3000, 3000, '/home/testuser', '/sbin/nologin', 0, '', '');
Come si può notare il nostro utente, denominato testuser, avrà password testpwd memorizzata in forma cifrata con la funzione PASSWORD di MySQL. Abbiamo inoltre scelto come home directory /home/testuser. Gli ultimi tre campi della tabella memorizzeranno informazioni relative agli accessi di testuser, come vedremo in dettaglio più avanti. Ora che il database è pronto per essere utilizzato da ProFTPD, nella prossima parte dell'articolo passeremo alla configurazione di quest'ultimo.
Nella prima parte di questo articolo abbiamo introdotto e proposto le prime configurazioni per usare il server Ftp Proftpd assieme ad un database MySQL. In questa seconda parte vedremo le ultime impostazioni necessarie e verificheremo il funzionamento di tutto il sistema.
Configurazione
Nella directory /etc troveremo il file proftpd.conf: copiamolo come proftpd.orig, in modo da non perdere l'originale, ed apriamolo con il nostro editor di testo preferito. Di seguito punteremo l'attenzione principalmente sulle direttive che consentono al server ftp di interfacciarsi con MySQL. Per gli aspetti più usuali della configurazione, come la porta di ascolto, l'ftp anonimo, il chroot degli utenti etc. potete tranquillamente riferirvi ai numerosi commenti all'interno del file o alla documentazione ufficiale.
Per prima cosa disabilitiamo l'uso del syslog e ridirigiamo l'output delle registrazioni verso uno specifico file /var/log/proftpd/proftpd.log. In questa fase di test è fondamentale ottenere sufficienti informazioni per il debug quindi impostiamo almeno un livello intermedio tra 0 e 9:
SystemLog /var/log/proftpd/proftpd.log DebugLevel 5
Assicuriamoci di caricare i moduli necessari all'utilizzo di MySQL con le seguenti direttive:
LoadModule mod_sql.c LoadModule mod_sql_mysql.c
Per questioni di spazio non prenderemo in considerazione l'eventuale problema della quota assegnata agli utenti. Accenniamo solo al fatto che per gestirla, oltre a modificare opportunamente le tabelle del database, dovremo attivare i corrispondenti moduli:
LoadModule mod_quotatab.c LoadModule mod_quotatab_sql.c
Passiamo ora alle direttive strettamente legate al sistema di autenticazione:
SQLAuthTypes Backend SQLAuthenticate users groups
Con la prima specifichiamo che adotteremo il metodo di cifratura delle password tipico del database, ovvero in MySQL la funzione PASSWORD(). Potremmo, in alternativa, scegliere di memorizzare le password mediante la funzione unix crypt() in tal caso dovremmo usare la parola chiave Crypt al posto di Beckend.
Con la seconda opzione indichiamo come il modulo eseguirà il lookup per l'autenticazione.
Non dobbiamo scordarci di disabilitare il metodo d'autenticazione di default basato su PAM. Cerchiamo all'interno del file le seguenti istruzioni e commentiamole:
#AuthPAMConfig proftpd #AuthOrder mod_auth_pam.c* mod_auth_unix.c
Ora forniamo le informazioni per la connessione al database che, nel nostro caso, risiede sulla medesima macchina su cui gira ProFTPD:
SQLConnectInfo ftpserver@localhost ftpadmin miapassword
Con le seguenti due direttive indichiamo al server ftp il nome delle tabelle (ftp_users, ftp_group) ed i campi da cui estrarre le informazioni rispettivamente per utenti e gruppi:
SQLUserInfo ftp_users user passwd uid gid homedir shell SQLGroupInfo ftp_group groupname gid members
Proseguiamo segnalando il valore minimo utilizzato per uid e gid e richiediamo la creazione automatica della home directory al momento del primo login dell'utente.
SQLMinID 3000 SQLHomedirOnDemand on
È giunto il momento di chiarire il significato dei campi count, accessed e modified che abbiamo inserito nel tracciato record della tabella ftp_users. I primi due saranno modificati ogni qual volta l'utente si autenticherà, in particolare count verrà incrementato di uno e accessed aggiornato con la data-ora attuale. Il terzo sarà aggiornato solo se l'utente eseguirà l'upload o la cancellazione di un file. Detto questo le seguenti direttive si commentano da sole:
SQLLog PASS updatecount SQLNamedQuery updatecount UPDATE "count=count+1, accessed=now() WHERE user='%u'" ftp_users SQLLog STOR,DELE modified SQLNamedQuery modified UPDATE "modified=now() WHERE user='%u'" ftp_users
Terminiamo disabilitando l'accesso come root e non richiedendo che l'utente abbia obbligatoriamente una shell elencata in /etc/shells:
RootLogin off RequireValidShell off
A questo punto le direttive inserite, unite alle istruzioni già presenti nella configurazione di default, dovrebbero essere sufficienti a testare il funzionamento del nostro server ftp.
Test del server
Prima di passare alle prove vere e proprie eseguiamo le ultime operazioni necessarie all'attivazione del servizio. Predisponiamo l'avvio automatico di ProFTPD nei run level che ci interessano e poi lanciamolo:
[root]# chkconfig --level 345 proftpd on [root]# service proftpd start
Ora tentiamo di collegarci localmente con l'utente di prova che abbiamo creato:
[root]# ftp localhost
Al prompt inseriamo nome utente e password ed effettuiamo il login. Verifichiamo che la home directory dell'utente sia stata creata automaticamente e proviamo l'upload di un file:
ftp> put prova.txt ftp> ls
Eseguiamo per completezza anche qualche test di download e cancellazione. Infine controlliamo che la tabella di database abbia correttamente memorizzato le informazioni d'accesso con la query:
mysql> SELECT * FROM ftp_users WHERE user = 'testuser';
Prima di utilizzare il server in produzione verificate tutte le funzionalità eventualmente attivate (chroot degli utenti, ftp anonimo etc.) e provate a connettervi da remoto. Quando il risultato sarà soddisfacente ricordatevi di modificare la direttiva DebugLevel per evitare la crescita eccessiva di proftpd.log. Inoltre in /etc/logrotate.d dovrebbe essere già predisposto uno script denominato proftpd, per la rotazione automatica del file di log.
L'analisi del binomio ProFTPD-MySQL si ferma qui, per mettere la classica ciliegina sulla torta potreste scrivere una piccola applicazione web che permetta attraverso semplici form di inserire, modificare e cancellare gli utenti.