Nel mondo GNU/Linux è molto diffuso il server FTP proFTD, considerato affidabile e con buone prestazioni. Purtroppo la gestione degli utenti, così come viene installato di default, non è molto comoda ed obbliga alla creazione di utenti interativi sul server, cosa che potrebbe non essere desiderata quando il servizio da dare prevede esclusivamente l'accesso FTP e WEB.
Il fatto di avere anche gli utenti interattivi non danneggia in sé le prestazioni del servizio FTP o WEB ma può rappresentare un ulteriore potenziale problema di sicurezza a fronte di una caratteristica non utilizzata.
Fortunatamente proFTP ci viene incontro ed ha la possibilità di configurare la gestione degli utenti tramite diversi backend tra cui alcuni database SQL.
Tra i differenti tipi di database disponibili, prenderemo in considerazione MySQL, che è il più diffuso, ma in linea di massima potete utilizzarne un altro, quale l'ottimo PostgreSQL, Sqlite o ODBC.
La descrizione di alcune operazioni si riferisce a distribuzioni GNU/Linux derivate da Debian per cui se ne utilizzate un tipo differente dovrete apportare le modifiche del caso ai comandi di installazione dei moduli. In particolare, queste note si riferiscono ad unserver con Ubuntu Server 10.4 LTS.
Quello che otterremo alla fine della procedura descritta sarà quindi un server FTP la cui utenza viene gestita su database MySQL, con la creazione automatica della directory utente contenente la struttura base standard per il sito dello stesso.
Lo scopo di questo articolo è mostrare come configurare il server proFTP, senza entrare nel merito dell'installazione e di come accedere al database, per cui partiamo dal presupposto di avere un server con sia proFTP che MySQL installati e che sappiate come interagire col sistema e con MySQL per creare e modificare i file interessati e per creare e popolare le tabelle necessarie.
Ovviamente dovremo per prima cosa creare un database dove mantenere le informazioni relative ai nostri utenti. Nel nostro caso prendiamo in considerazione un database dedicato ma nulla impedisce che sia condiviso per centralizzare la gestione di altri servizi come, ad esempio, la posta elettronica.
Creiamo quindi un database proftpd ed un utente proftpd con accesso in lettura ed aggiornamento ed inserimento di record. Effettueremo le suddette operazioni utilizzando un account amministratore del database, in quanto l'utente proftpd dovrà avere un accesso al database limitato alle operazioni necessarie a leggere le informazioni degli account, aggiornarne alcuni campi ed inserire i record per il log dei trasferimenti.
Iniziamo con la tabella groups che utilizzeremo per memorizzare le informazioni relative ai gruppi di utenti:
CREATE TABLE IF NOT EXISTS `groups` (
`id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
`groupname` varchar(64) NOT NULL,
`gid` bigint(20) unsigned NOT NULL,
`members` varchar(256) NOT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `groupname` (`groupname`),
UNIQUE KEY `gid` (`gid`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=1 ;
Come si può notare, la tabella è abbastanza semplice. Contiene i campi per
L'accesso viene configurato nel file sql.conf con la direttiva:
Va notato che utilizzando la direttiva SQLAuthenticate users* groups* ,per ogni gruppo possono essere presenti più record, con differenti utenti nella colonna members ed allo stesso tempo in quella colonna possono essere elencati più utenti (separati da virgole).
Potete approfondire l'argomento visitando la pagina sulla direttiva SQLAuthenticate di proFTP.
Proseguiamo con la creazione della tabella users dove manterremo le informazioni relative agli utenti:
CREATE TABLE IF NOT EXISTS `users` (
`id` bigint(20) UNSIGNED NOT NULL AUTO_INCREMENT,
`username` varchar(64) NOT NULL,
`passwd` varchar(256) NOT NULL,
`uid` int(10) UNSIGNED NOT NULL,
`gid` int(10) UNSIGNED NOT NULL,
`fullname` varchar(256) DEFAULT NULL,
`homedir` varchar(256) NOT NULL,
`shell` varchar(256) DEFAULT '/bin/false',
`lastlogin` datetime NOT NULL DEFAULT '0000-00-00 00:00:00',
`lastlogout` datetime NOT NULL DEFAULT '0000-00-00 00:00:00',
`logincount` bigint(20) UNSIGNED NOT NULL DEFAULT '0',
`disabled` tinyint(1) DEFAULT '0',
`expiration` datetime NOT NULL DEFAULT '0000-00-00 00:00:00',
PRIMARY KEY (`id`),
UNIQUE KEY `username` (`username`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=1 ;
la tabella contiene i campi per:
Per avere un livello di sicurezza più alto, nel campo passwd utilizzeremo la cifratura, compatibile con il meccanismo di autenticazione utilizzato da proFTP.
Vedremo più avanti come i campi disabled e expiration ci permettano di aggiungere due condizioni per convalidare l'accesso dell'utente; tramite essi potremo disabilitare l'utente senza la necessità di cancellara l'account ed impostare una data di scadenza oltre la quale l'utente non potrà più collegarsi.
L'accesso a questa tabella viene configurato nel file sql.conf le righe:
Ora aggiungiamo una tabella accesslog per memorizzare le operazioni di accesso e disconnessione dal nostro server FTP dove troveremo le indicazioni di login, logout ed i tentativi di accesso falliti:
CREATE TABLE IF NOT EXISTS `accesslog` (
`id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
`username` varchar(64) NOT NULL,
`host` varchar(256) NOT NULL,
`ip` varchar(32) NOT NULL,
`action` varchar(15) NOT NULL,
`accesstime` datetime NOT NULL,
`success` tinyint(1) DEFAULT '0',
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=1 ;
In questa tabella troviamo i campi:
In generale troveremo le operazioni di login e logout andate a buon fine ed i tentativi di accesso (password errata, utente inesistente) falliti.
La tabella viene configurata per l'utilizzo nel file sql.conf, con le righe:
Per tenere traccia delle operazioni, creiamo ora la tabella xferlog che ci servirà per memorizzare le operazioni di trasferimento file:
CREATE TABLE IF NOT EXISTS `xferlog` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`username` varchar(64) NOT NULL DEFAULT '',
`filename` text,
`size` bigint(20) DEFAULT NULL,
`host` tinytext,
`ip` tinytext,
`action` tinytext,
`duration` tinytext,
`localtime` timestamp NULL DEFAULT NULL,
`success` tinyint(1) NOT NULL DEFAULT '0',
PRIMARY KEY (`id`),
KEY `idx_usersucc` (`username`,`success`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=1 ;
la tabella contiene i campi:
La configurazione per l'utilizzo viene effettuata in sql.conf nelle righe:
Nel file /etc/proftpd/sql.log andremo a configurare quanto necessario per indicare a proFTP quale database utilizzare e come interfacciarsi alle tabelle.
Per l'accesso al database assumiamo di avere:
quindi dovrete apportare le necessarie modifiche per adattare la configurazione alla vostra situazione nella riga che contiene:
Abbiamo ancora alcune direttive da prendere in esame:
- <IfModule mod_sql.c>
- #
- # Choose a SQL backend among MySQL or PostgreSQL.
- # Both modules are loaded in default configuration, so you have to specify the backend
- # or comment out the unused module in /etc/proftpd/modules.conf.
- # Use 'mysql' or 'postgres' as possible values.
- #
- SQLBackend mysql
- #
- SQLEngine on
- SQLAuthenticate users* groups*
- #
- ## Use a backend-crypted or a crypted password
- ## may user MySQL ENCRYPT funtion to encript passwords
- #
- SQLAuthTypes Crypt
- #
- ## Set minimum GID and UID for SQL-managed accounts
- #
- SQLMinUserGID 5001
- SQLMinUserUID 5001
- #
- ## Database Connection:
- # SQLConnectionInfo dbname@hostname username password
- #
- SQLConnectInfo proftpd@127.0.0.1 proftpd FTPD-MYSQL-USER-PSSWORD
- #
- ##Describes both users/groups tables
- #
- # SQLGroupInfo <tablename> <groupname fieldname> <gid fieldname> <members fieldname>
- # SQLUserInfo <tablename> <username fieldname> <password fieldname> <uid fieldname> <gid fieldname> <home dir fieldname> <shell path fieldname>
- #
- SQLGroupInfo groups groupname gid members
- SQLUserInfo users username passwd uid gid homedir shell
- #
- ## Create user directory skeleton
- ## user directory skeleton must be created (not provided with default installation) and must NOT be world-writeable
- #
- CreateHome on skel /usr/local/etc/proftpd/skel dirmode 700
- #
- ## Add custom WHERE clause to every user query:
- ## Account must be NOT disabled and NOT expired ('disable' and 'expiration' fields must be added to users table)
- ##
- SQLUserWhereClause "disabled=0 AND (NOW()<=expiration OR expiration='0000-00-00 00:00:00')"
- #
- ## Log the user logging in:
- ## Increment login counter and update last login date ('lastlogin' and 'logincount' fields must be added to users table)
- #
- SQLLog PASS counter
- SQLNamedQuery counter UPDATE "lastlogin=now(), logincount=logincount+1 WHERE `username`='%u'" users
- #
- ## insert log record for succesful login and logout
- #
- SQLLog PASS accesslog1
- SQLLog BYE,QUIT,EXIT accesslog1
- SQLNamedQuery accesslog1 INSERT "NULL, '%u', '%h', '%a', '%m', now(), '1'" accesslog
- #
- ## insert log record for login fail
- #
- SQLLog ERR_USER,ERR_PASS accesslog2
- SQLNamedQuery accesslog2 INSERT "NULL, '%U', '%h', '%a', '%m', now(), '0'" accesslog
- #
- ## logout log
- ## update logout date ('lastlogout' field must be added to users table)
- #
- SQLLog BYE,QUIT,EXIT time_logout
- SQLNamedQuery time_logout UPDATE "lastlogout=now() WHERE username='%u'" users
- #
- #
- ## display last login time when PASS command is given
- #
- SQLNamedQuery login_time SELECT "lastlogin from users where username='%u'"
- SQLShowInfo PASS "230" "Last login was: %{login_time}"
- #
- ## transfers Log in mysql
- #
- SQLLog RETR,STOR transfer1
- SQLNamedQuery transfer1 INSERT "NULL, '%u', '%f', '%b', '%h', '%a', '%m', '%T', now(), '1'" xferlog
- #
- SQLLog ERR_RETR,ERR_STOR transfer2
- SQLNamedQuery transfer2 INSERT "NULL, '%u', '%f', '%b', '%h', '%a', '%m', '%T', now(), '0'" xferlog
- #
- </IfModule>

Se questa documentazione ti è stata utile, una donazione sarà ben accetta