in CentOS, Software

server FTP con utenti virtuali, gestione quota e banda utilizzata

Al lavoro mi son ritrovato a dover risolvere lo scenario del dare accesso ad un certo numero di dati (di dimensione di qualche GB per file) e documenti ad un paio pool di utenti, per la maggior parte esterni alla nostra struttura.

Questo mi ha portato allo scarto di soluzioni che prevedevano l’accesso fisico alla macchina (no ssh quindi). Ho purtroppo dovuto scartare anche soluzioni basate sul “paradigma” LAMP, per le intrinseche limitaziondi di Apache come gestore di trasferimento file … ad esempio DocMgr che pure avevamo implementato ma che ha retto sino a quando ci si è trovati a dover caricare/scaricare file >1GB … e tenendo conto che ne ho diversi altri tra i 5/8GB capirai Perché ho ritenuto poco proficuo tenerlo in funzione.

Ancora, nel tempo è sorta anche la necessità di imporre ragionevoli limiti alla banda di rete utilizzabile da questo singolo servizio, specie in occasioni di limitazioni di utilizzo della banda “Internet” disponibile.
pureFTFd logo
Mi sono quindi messo alla ricerca di una soluzione collaudata, di semplice implementazione e ragionevolmente sicura, trovando alcuni tutorial su come implementare un servizio di FTP che mi permettesse di avere un pool di “Utenti Virtuali“.

La scelta è del server FTP da utilizzare è caduta alla fine su pureFTPd che implementa nativamente un modulo che permette questa funzionalità  di utenze virtuali mappando su un unico utente “reale” del sistema tutto un insieme di utenze del servizio le cui caratteristiche sono gestite da un database MySQL.
CentOS logo
Andiamo a vedere passo passo come procedere.

Come detto più volte al lavoro si è deciso l’utilizzo la distribuzione GNU/Linux CentOS e quindi la mia piccola guida trattarà questa piattaforma. Installo il server con un semplice:
yum install pure-ftpd

Vado a creare l’utente di sistema su cui andrò a mappare quelli virtuali con i comandi:

groupadd -g 2001 virtualftpuser
useradd -u 2001 -s /bin/false -d /bin/null -c "system pureftpd user" -g virtualftpuser virtualftpuser

Con i due precedenti comandi ho creato un utente virtualftpuser, facente parte del gruppo omonimo e, con il parametro -s /bin false ho detto al sistema di NON assegnare una shell all’utente e con -d /bin/null ho detto di non creare una home directory per esso.

Con il comando:
passwd virtualftpuser
vado ad inserire la password dell’utente di sistema appena creato.

Creiamo ora un database di nome pureftpd e un utente del DBMS che chiameremo a sua volta pureftpd, il quale vi avrà successivamente accesso ad esso con la password che scegliamo ed andiamo ad inserire come segue:

MySQL -u root -p

CREATE DATABASE pureftpd;

GRANT SELECT, INSERT, UPDATE, DELETE, CREATE, DROP ON pureftpd.* TO 'pureftpd'@'localhost' IDENTIFIED BY 'password-da-impostare';

GRANT SELECT, INSERT, UPDATE, DELETE, CREATE, DROP ON pureftpd.* TO 'pureftpd'@'localhost.localdomain' IDENTIFIED BY 'password-da-impostare';

FLUSH PRIVILEGES;

Sempre rimanendo nella shell di MySQL, su cui siamo autenticati, andiamo ora a popolare il database appena creato con il seguente comando:

USE pureftpd;

CREATE TABLE ftpd (
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 '-1',
Gid varchar(11) NOT NULL default '-1',
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)
) TYPE=MyISAM;

e quindi usciamo dal DBMS

quit;

Fatto questo siamo quasi al termine dei passi salienti della procedura, ci rimane da rifinire la configurazione di pureFTPd. Tra la pacchettizzazione di CentOS ed Ubuntu {su cui avevo implementato una prima istanza del servizio} ci sono alcune differenze (come per un numero fastidiosamente alto di altri programmi), in ogni caso nella nostra piattaforma operativa tutti i file di configurazione del nostro server sono contenuti in /etc/pure-ftpd/ e sono:

  • pure-ftpd.conf
  • pureftpd-ldap.conf
  • pureftpd-MySQL.conf
  • pureftpd-pgsql.conf

Come possiamo vedere pureFTPd presenta delle opzioni per gestire gli utenti anche tramite LDAP o su di un DBMS postgreSQL … ma torniamo a noi ed andiamo ad editare il file pureftpd-MySQL.conf assicurandoci che i seguenti valori siano selezionati:

MYSQLSocket /var/run/MySQLd/MySQLd.sock
#MYSQLServer localhost
#MYSQLPort 3306
MYSQLUser pureftpd
MYSQLPassword password-da-impostare
MYSQLDatabase pureftpd
#MYSQLCrypt md5, cleartext, crypt() or password() - md5 is VERY RECOMMENDABLE uppon cleartext
MYSQLCrypt md5
MYSQLGetPW SELECT Password FROM ftpd WHERE User="\L" AND status="1" AND (ipaccess = "*" OR ipaccess LIKE "\R")
MYSQLGetUID SELECT Uid FROM ftpd WHERE User="\L" AND status="1" AND (ipaccess = "*" OR ipaccess LIKE "\R")
MYSQLGetGID SELECT Gid FROM ftpd WHERE User="\L"AND status="1" AND (ipaccess = "*" OR ipaccess LIKE "\R")
MYSQLGetDir SELECT Dir FROM ftpd WHERE User="\L"AND status="1" AND (ipaccess = "*" OR ipaccess LIKE "\R")
MySQLGetBandwidthUL SELECT ULBandwidth FROM ftpd WHERE User="\L"AND status="1" AND (ipaccess = "*" OR ipaccess LIKE "\R")
MySQLGetBandwidthDL SELECT DLBandwidth FROM ftpd WHERE User="\L"AND status="1" AND (ipaccess = "*" OR ipaccess LIKE "\R")
MySQLGetQTASZ SELECT QuotaSize FROM ftpd WHERE User="\L"AND status="1" AND (ipaccess = "*" OR ipaccess LIKE "\R")
MySQLGetQTAFS SELECT QuotaFiles FROM ftpd WHERE User="\L"AND status="1" AND (ipaccess = "*" OR ipaccess LIKE "\R")

Dobbiamo poi impostare una “gabbia” chroot agli utenti in modo che non possano mettersi a curiosare nel nostro sistema una volta utenticati, andiamno quindi ad editare il file pure-ftpd.conf nel modo seguente:

# Cage in every user in his home directory
ChrootEveryone yes

quindi diamo la possibilità di creare le home directory quando l’utente si autentica sul sitema la prima volta ed essa non è presente:

# Automatically create home directories if they are missing
CreateHomeDir yes

infine andiamo a decommentare la linea relativa ai parametri di configurazione di MySQL:

# MySQL configuration file (see README.MySQL)
MySQLConfigFile /etc/pure-ftpd/pureftpd-MySQL.conf

nel mio caso ho scelto di disabilitare l’accesso anonimo al nostro server mediante l’impostazione del seguente parametro:

NoAnonymous yes

Ed infine, come ulteriore passaggio (forse inutile) disabilitiamo la possibilità di caricare nuovi file nel sistema da parte di utenti anonimi impostando a yes la voce seguente:

AnonymousCantUpload yes

A questo punto possiamo avviare il demone pureFTPd con il comando
/etc/init.d/pure-ftpd start

Se tutto e’ funzionante possiamo passare alla creazione di utenze e al loro testing:

MySQL -u root -p

USE pureftpd;

INSERT INTO `ftpd` (`User`, `status`, `Password`, `Uid`, `Gid`, `Dir`, `ULBandwidth`, `DLBandwidth`, `comment`, `ipaccess`, `QuotaSize`, `QuotaFiles`) VALUES ('exampleuser', '1', MD5('secret'), '2001', '2001', '/home/www.esempio.com', '100', '100', '', '*', '50', '0');

Con lo statement precedente abbiamo detto al sistema di:

  1. creare l’utente exampleuser
  2. con lo status = 1 (cioè l’account è attivo)
  3. la password ‘secret’ (che verrà criptata con l’algoritmo MD5 dal DBMS MySQL)
  4. avente UID e GID pari a 2001 (e cioè gli stessi dell’utenza virtuale creata all’inizio della procedura!!!)
  5. la sua home directory sarà  /home/www.esempio.com
  6. con una limitazione delle velocità di upload/download pari a 100 KB/sec. (kilobytes per second). Impostando a 0 tale valore non diamo alcuna limitazione
  7. ed una quota di 50 MB.

La gestione dei permessi su disco, e di come gli utenti possono interagire col sistema si lascia come esercizio al lettore 😛


Riferimenti:

11 Commenti

  1. Aspitina, che articoletto 😉
    C' ho capito poco . . . ma per mia scarsa cultura in materia, non per cattiva esposizione dell'argomento 😉

  2. Gran bel post, anche se come dice Alex neanch'io ho capito molto…ma solo per mia ignoranza nell'argomento. Comunque complimenti!

  3. Cercavo proprio una guida come questa per impostare pure-ftpd.
    Grazie per averla postata. Non è che mi sapresti indicare anche come configurare "pure-ftpd user manager".
    Dopo la provo.
    Grazie Ciao 🙂

  4. Grazie mille anche da parte mia. Serviva anche a me una cosa del genere 🙂

  5. ciao, ho letto la tua guida e mio cognato che si intende di informatica l'ha trovata molto completa!

    Hai pensato di iscrivere il tuo blog al bloggatore?

    il sito non è il mio, io ne sono una semplice ma appassionata lettrice, ma si tratta di un portale di oltre 700 blog di informatica che sta andando alla grande e il tuo blog merita di esserci!

    Aggiungo il tuo blog ai miei preferiti di internet.

    Ciao!
    Manuela

  6. Mi sembra un articolo con i fiocchi, anche se io ormai uso solo postgresql e MySQL l'ho mollato.

  7. Salve, non ho capito come modificare i permessi. Per esempio tutti i miei utenti non riescono a caricare file cambiare permessi file e altro!

    • ciao Stefano,
      gli utenti non possono cambiare i permessi perché sono mappati tutti su di un unico utente reale di sistema, quindi tutti hanno gli stessi permessi file di tutti gli altri(utenti che accedono allo specifico path di sistema/cartella ftp).

      La gestione (sul sistema e non via ftp) la deve fare quindi l’utente fisico di sistema …

  8. grazie per la risposta,

    ma il problema principale è che posso solo vedere cosa c’è nell’FTP ma non posso caricare nemmeno file!

    ho provato ad accedere con un utente di sistema e lo stesso non può caricare file e altro!!!

    credo che il problema sia nella configurazione del pure ftp

    • Stefano, capirai che in una configurazione così complessa ci possono essere diverse cose che provocano il comportamento “in sola lettura”. Ti consiglio di controllare passo passo tutto il procedimento, dando particolare attenzione ai path e ai relativi permessi da parte dell’utente che va ad accedervi …

I commenti sono chiusi.