Server FTP · 14 min read · Dec 24, 2025

Server FTP con PureFTPd, MariaDB e Utenti Virtuali (incl. Gestione di Quota e Larghezza di Banda) su CentOS 7.2

Questo documento descrive come installare un server PureFTPd che utilizza utenti virtuali da un database MariaDB (compatibile con MySQL) invece di veri utenti di sistema. Questo è molto più performante e consente di avere migliaia di utenti FTP su una singola macchina. Inoltre, mostrerò l’uso di limiti di quota e di upload/download con questa configurazione. Le password saranno memorizzate criptate come stringhe MD5 nel database.

Per l’amministrazione del database MariaDB, puoi utilizzare strumenti basati sul web come phpMyAdmin che saranno anche installati in questo howto. phpMyAdmin è un’interfaccia grafica comoda che significa che non devi impazzire con la riga di comando.

Questo tutorial è basato su CentOS 7.2. Dovresti già aver configurato un sistema CentOS 7.2 di base e minimale.

Questo howto è inteso come una guida pratica; non copre i fondamenti teorici. Questi sono trattati in molti altri documenti sul web.

Questo documento viene fornito senza alcuna garanzia! Voglio dire che questo non è l’unico modo per configurare un sistema del genere. Ci sono molti modi per raggiungere questo obiettivo, ma questo è il modo che seguo.

1 Nota Preliminare

In questo tutorial, utilizzo il nome host server1.example.com con l’indirizzo IP 192.168.1.100. Queste impostazioni potrebbero differire per te, quindi devi sostituirle dove appropriato.

2 Installa MySQL e phpMyAdmin

Per prima cosa, abilitiamo il repository EPEL sul nostro sistema CentOS poiché alcuni pacchetti che installeremo nel corso di questo tutorial non sono disponibili nei repository ufficiali di CentOS 7.2:

rpm --import /etc/pki/rpm-gpg/RPM-GPG-KEY*

Poi abilitiamo il repository EPEL sul nostro sistema CentOS poiché molti dei pacchetti che installeremo nel corso di questo tutorial non sono disponibili nel repository ufficiale di CentOS 7:

yum -y install epel-release
yum -y install yum-priorities

Modifica /etc/yum.repos.d/epel.repo…

nano /etc/yum.repos.d/epel.repo

… e aggiungi la riga priority=10 alla sezione [epel]:

[epel]
name=Extra Packages for Enterprise Linux 7 - $basearch
#baseurl=http://download.fedoraproject.org/pub/epel/7/$basearch
mirrorlist=https://mirrors.fedoraproject.org/metalink?repo=epel-7&arch=$basearch
failovermethod=priority
enabled=1
priority=10
gpgcheck=1
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-EPEL-7
[...]

Poi aggiorniamo i pacchetti esistenti sul sistema:

yum update

Ora possiamo installare il server web Apache, PHP, MariaDB e phpMyAdmin come segue:

yum -y install mariadb mariadb-server phpmyadmin httpd php

Ora configuriamo phpMyAdmin. Modifichiamo la configurazione di Apache in modo che phpMyAdmin consenta connessioni non solo da localhost (commentando tutto nella sezione e aggiungendo la riga Require all granted):

nano /etc/httpd/conf.d/phpMyAdmin.conf

in modo che il file appaia così:

# phpMyAdmin - Browser MySQL basato sul web scritto in php
#
# Consente solo localhost per impostazione predefinita
#
# Ma consentire a phpMyAdmin a chiunque altro oltre a localhost dovrebbe essere considerato
# pericoloso a meno che non sia adeguatamente protetto da SSL

Alias /phpMyAdmin /usr/share/phpMyAdmin
Alias /phpmyadmin /usr/share/phpMyAdmin


    AddDefaultCharset UTF-8
#  
#     # Apache 2.4
#     
#       Require ip 127.0.0.1
#       Require ip ::1
#     
#   
#   
#     # Apache 2.2
#     Order Deny,Allow
#    # Deny from All
#     Allow from 127.0.0.1
     Options Indexes
     AllowOverride None
     Require all granted
#     Allow from ::1
#   



   
     # Apache 2.4
     
       Require ip 127.0.0.1
       Require ip ::1
     
   
   
     # Apache 2.2
     Order Deny,Allow
     Deny from All
     Allow from 127.0.0.1
     Allow from ::1
   


# Questi directory non richiedono accesso tramite HTTP - presi dall'originale
# tarball upstream di phpMyAdmin
#

    Order Deny,Allow
    Deny from All
    Allow from None



    Order Deny,Allow
    Deny from All
    Allow from None



    Order Deny,Allow
    Deny from All
    Allow from None


# Questa configurazione impedisce a mod_security nelle directory di phpMyAdmin di
# filtrare SQL ecc. Questo potrebbe interrompere la tua implementazione di mod_security.
#
#
#    
#        SecRuleInheritance Off
#    
#

Poi creiamo i collegamenti di avvio del sistema per MySQL e Apache (in modo che entrambi si avviino automaticamente ogni volta che il sistema si avvia) e avviamo entrambi i servizi.

Apri le porte http e https quando il firewall CentOS “firewalld” è installato sul tuo server.

firewall-cmd --permanent --zone=public --add-service=http  
firewall-cmd --permanent --zone=public --add-service=https  
firewall-cmd --reload

Poi avvia MariaDB e Apache.

systemctl enable mariadb.service  
systemctl start mariadb.service
systemctl enable httpd.service  
systemctl start httpd.service

Crea una password per l’utente root di MySQL (sostituisci yourmariadbpassword con la password che desideri utilizzare):

mysql_secure_installation

[root@server1 ~]# mysql_secure_installation
/usr/bin/mysql_secure_installation: line 379: find_mysql_client: command not found

NOTE: E’ CONSIGLIATO ESEGUIRE TUTTE LE PARTI DI QUESTO SCRIPT PER TUTTI I SERVER MariaDB IN USO IN PRODUZIONE!  PER FAVORE LEGGI ATTENTAMENTE OGNI PASSO!

Per accedere a MariaDB per metterlo in sicurezza, avremo bisogno della password attuale per l’utente root.  Se hai appena installato MariaDB e non hai ancora impostato la password root, la password sarà vuota, quindi dovresti semplicemente premere invio qui. <–INVIO
Inserisci la password attuale per root (premi invio per nessuna): <–INVIO
OK, password utilizzata con successo, procedendo…

Impostare la password root assicura che nessuno possa accedere all’utente root di MariaDB senza la corretta autorizzazione.

Impostare la password root? [Y/n] <–INVIO
Nuova password: <–yourmariadbpassword
Reinserisci la nuova password: <–yourmariadbpassword
Password aggiornata con successo!
Ricaricamento delle tabelle di privilegio..
… Successo!

Per impostazione predefinita, un’installazione di MariaDB ha un utente anonimo, consentendo a chiunque di accedere a MariaDB senza dover avere un account utente creato per loro.  Questo è inteso solo per testare e per rendere l’installazione un po’ più fluida.  Dovresti rimuoverli prima di passare a un ambiente di produzione.

Rimuovere gli utenti anonimi? [Y/n] <–INVIO
… Successo!

Normalmente, l’utente root dovrebbe essere autorizzato a connettersi solo da ‘localhost’.  Questo assicura che qualcuno non possa indovinare la password root dalla rete.

Negare l’accesso remoto all’utente root? [Y/n] <–INVIO
… Successo!

Per impostazione predefinita, MariaDB viene fornito con un database chiamato ‘test’ a cui chiunque può accedere.  Questo è anche inteso solo per testare e dovrebbe essere rimosso prima di passare a un ambiente di produzione.

Rimuovere il database di test e l’accesso ad esso? [Y/n] <–INVIO

  • Eliminazione del database di test…
    … Successo!
  • Rimozione dei privilegi sul database di test…
    … Successo!

Ricaricare le tabelle di privilegio garantirà che tutte le modifiche apportate finora abbiano effetto immediato.

Ricaricare le tabelle di privilegio ora? [Y/n] <–INVIO
… Successo!

Pulizia…

Tutto fatto!  Se hai completato tutti i passaggi sopra, la tua installazione di MariaDB dovrebbe ora essere sicura.

Grazie per aver utilizzato MariaDB!
[root@server1 ~]#

3 Installa PureFTPd con Supporto MySQL / MariaDB

Il pacchetto PureFTPd di CentOS supporta vari backend, come MySQL, PostgreSQL, LDAP, ecc. Pertanto, tutto ciò che dobbiamo fare è installare il normale pacchetto PureFTPd:

yum -y install pure-ftpd

Poi creiamo un gruppo ftp (ftpgroup) e un utente (ftpuser) a cui saranno mappati tutti i nostri utenti virtuali. Sostituisci il gruppo e l’ID utente 2001 con un numero che sia libero sul tuo sistema:

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

Il servizio ftp deve essere consentito da firewall-cmd come segue:

firewall-cmd --permanent --zone=public --add-service=ftp  
firewall-cmd --reload

4 Crea il Database per PureFTPd

Ora creiamo un database chiamato pureftpd e un utente MariaDB chiamato pureftpd che il demone PureFTPd utilizzerà in seguito per connettersi al database pureftpd:

mysql -u root -p
CREATE DATABASE pureftpd;  
GRANT SELECT, INSERT, UPDATE, DELETE, CREATE, DROP ON pureftpd.* TO 'pureftpd'@'localhost' IDENTIFIED BY 'ftpdpass';  
GRANT SELECT, INSERT, UPDATE, DELETE, CREATE, DROP ON pureftpd.* TO 'pureftpd'@'localhost.localdomain' IDENTIFIED BY 'ftpdpass';  
FLUSH PRIVILEGES;

Sostituisci la stringa ftpdpass con qualsiasi password tu voglia utilizzare per l’utente MySQL pureftpd. Ancora nella shell MySQL, creiamo la tabella del database di cui abbiamo bisogno (sì, c’è solo una tabella!):

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)  
) ENGINE=MyISAM;
quit;

Come avrai notato, con il comando quit; siamo usciti dalla shell MySQL e siamo tornati nella shell di Linux.

A proposito, (presumo che il nome host del tuo sistema FTP sia server1.example.com) puoi accedere a phpMyAdmin all’indirizzo http://server1.example.com/phpMyAdmin/ (puoi anche utilizzare l’indirizzo IP invece di server1.example.com) in un browser e accedere come utente pureftpd. Poi puoi dare un’occhiata al database. Più tardi, puoi utilizzare phpMyAdmin per amministrare il tuo server PureFTPd.

5 Configura PureFTPd

Modifica /etc/pure-ftpd/pure-ftpd.conf e assicurati che le righe ChrootEveryone, MySQLConfigFile e CreateHomeDir siano abilitate e appaiano così:

nano /etc/pure-ftpd/pure-ftpd.conf
[...]
ChrootEveryone              yes
[...]
MySQLConfigFile               /etc/pure-ftpd/pureftpd-mysql.conf
[...]
CreateHomeDir               yes
[...]

L’impostazione ChrootEveryone farà sì che PureFTPd chroot ogni utente virtuale nella sua home directory in modo che non possa navigare in directory e file al di fuori della sua home directory. La riga CreateHomeDir farà sì che PureFTPd crei la home directory di un utente quando l’utente accede e la home directory non esiste ancora.

Poi modifichiamo /etc/pure-ftpd/pureftpd-mysql.conf. Dovrebbe apparire così:

cp /etc/pure-ftpd/pureftpd-mysql.conf /etc/pure-ftpd/pureftpd-mysql.conf_orig  
cat /dev/null > /etc/pure-ftpd/pureftpd-mysql.conf  
nano /etc/pure-ftpd/pureftpd-mysql.conf
MYSQLSocket      /var/lib/mysql/mysql.sock
#MYSQLServer     localhost
#MYSQLPort       3306
MYSQLUser       pureftpd
MYSQLPassword   ftpdpass
MYSQLDatabase   pureftpd
#MYSQLCrypt md5, cleartext, crypt() or password() - md5 è MOLTO RACCOMANDATO rispetto al testo chiaro
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")

Assicurati di sostituire la stringa ftpdpass con la vera password per l’utente MySQL pureftpd nella riga MYSQLPassword! Si prega di notare che utilizziamo md5 come metodo MYSQLCrypt, il che significa che memorizzeremo le password degli utenti come una stringa MD5 nel database, che è molto più sicura rispetto all’uso di password in chiaro!

Ora creiamo i collegamenti di avvio del sistema per PureFTPd e lo avviamo:

systemctl enable pure-ftpd.service  
systemctl start pure-ftpd.service

6 Popola il Database e testa il Server

Per popolare il database puoi utilizzare la shell MySQL:

mysql -u root -p
USE pureftpd;

Ora creiamo l’utente exampleuser con lo stato 1 (il che significa che il suo account ftp è attivo), la password secret (che sarà memorizzata criptata utilizzando la funzione MD5 di MySQL), l’UID e GID 2001 (usa l’ID utente e l’ID gruppo dell’utente/gruppo che hai creato alla fine del secondo passaggio!), la home directory /home/www.example.com, una larghezza di banda di upload e download di 100 KB/sec. (kilobyte al secondo), e una quota di 50 MB:

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

Ora apri il tuo programma client FTP sulla tua workstation (qualcosa come FileZilla se sei su un sistema Windows o gFTP su un desktop Linux) e prova a connetterti. Come nome host utilizzi server1.example.com (o l’indirizzo IP del sistema), il nome utente è exampleuser e la password è secret.

Collegati al server FTP con FileZilla.

Se riesci a connetterti - congratulazioni! Se no, qualcosa è andato storto.

Ora, se esegui

ls -l /home

dovresti vedere che la directory /home/www.example.com (la home directory di exampleuser) è stata creata automaticamente, ed è di proprietà di ftpuser e ftpgroup (l’utente/gruppo che abbiamo creato alla fine del secondo passaggio):

[root@server1 ~]# ls -l /home  
total 0  
drwx------. 2 administrator administrator 59 Jun 21 16:13 administrator  
drwxr-xr-x. 2 ftpuser ftpgroup 22 Jul 4 18:30 www.example.com  
[root@server1 ~]#

7 Amministrazione del Database

Per la maggior parte delle persone è più facile avere un’interfaccia grafica per MySQL; pertanto puoi anche utilizzare phpMyAdmin (in questo esempio all’indirizzo http://server1.example.com/phpMyAdmin/) per amministrare il database pureftpd.

Il Dashboard di PHPMyAdmin

Il database MySQL di pure-ftpd

Ogni volta che vuoi creare un nuovo utente, devi creare un’entrata nella tabella ftpd, quindi spiegherò qui le colonne di questa tabella:

Tabella FTPD:

  • User: Il nome dell’utente virtuale PureFTPd (es. exampleuser).
  • status: 0 o 1. 0 significa che l’account è disabilitato, l’utente non può accedere.
  • Password: La password dell’utente virtuale. Assicurati di utilizzare la funzione MD5 di MySQL per salvare la password criptata come una stringa MD5:
    Aggiungi un utente FTP.
  • UID: L’ID utente dell’utente ftp che hai creato alla fine del secondo passaggio (es. 2001).
  • GID: L’ID gruppo del gruppo ftp che hai creato alla fine del secondo passaggio (es. 2001).
  • Dir: La home directory dell’utente virtuale PureFTPd (es. /home/www.example.com). Se non esiste, verrà creata quando il nuovo utente accede per la prima volta tramite FTP. L’utente virtuale sarà rinchiuso in questa home directory, cioè non può accedere ad altre directory al di fuori della sua home directory.
  • ULBandwidth: Larghezza di banda di upload dell’utente virtuale in KB/sec. (kilobyte al secondo). 0 significa illimitato.
  • DLBandwidth: Larghezza di banda di download dell’utente virtuale in KB/sec. (kilobyte al secondo). 0 significa illimitato.
  • comment: Puoi inserire qui qualsiasi commento (es. per la tua amministrazione interna). Normalmente lasci questo campo vuoto.
  • ipaccess: Inserisci qui gli indirizzi IP che sono autorizzati a connettersi a questo account FTP. * significa che qualsiasi indirizzo IP è autorizzato a connettersi.
  • QuotaSize: Spazio di archiviazione in MB (non KB, come in ULBandwidth e DLBandwidth!) che l’utente virtuale è autorizzato a utilizzare sul server FTP. 0 significa illimitato.
  • QuotaFiles: numero di file che l’utente virtuale è autorizzato a salvare sul server FTP. 0 significa illimitato.

8 FTP Anonimo

Se desideri creare un account ftp anonimo (un account ftp a cui chiunque può accedere senza una password), hai bisogno di un utente e di un gruppo chiamati ftp. Entrambi sono stati creati automaticamente quando hai installato il pacchetto pure-ftpd, quindi non è necessario crearli manualmente. Tuttavia, la home directory di ftp è /var/ftp per impostazione predefinita, ma mi piacerebbe creare la directory ftp anonima in /home/ftp (le normali directory ftp degli utenti sono anche in /home, ad esempio /home/www.example.com). Ma naturalmente, puoi utilizzare la directory /var/ftp per ftp anonimo, se lo preferisci.

Se desideri utilizzare /home/ftp, apri /etc/passwd e modifica la home directory dell’utente ftp da /var/ftp a /home/ftp (non farlo se desideri utilizzare /var/ftp):

nano /etc/passwd
[...]
#ftp:x:14:50:FTP User:/var/ftp:/sbin/nologin
ftp:x:14:50:FTP User:/home/ftp:/sbin/nologin
[...]

Poi sposta /var/ftp in /home (non farlo se desideri utilizzare /var/ftp):

mv /var/ftp /home

Poi creiamo la directory /home/ftp/incoming che consentirà agli utenti anonimi di caricare file. Daremo alla directory /home/ftp/incoming permessi di 311 in modo che gli utenti possano caricare, ma non vedere o scaricare alcun file in quella directory. La directory /home/ftp avrà permessi di 555 che consentono di vedere e scaricare file:

chown ftp:nobody /home/ftp  
cd /home/ftp  
mkdir incoming  
chown ftp:nobody incoming/  
chmod 311 incoming/  
cd ../  
chmod 555 ftp/

(Se desideri utilizzare /var/ftp invece, sostituisci /home/ftp con /var/ftp nei comandi sopra.)

Gli utenti anonimi potranno accedere, e saranno autorizzati a scaricare file da /home/ftp, ma i caricamenti saranno limitati a /home/ftp/incoming (e una volta che un file è stato caricato in /home/ftp/incoming, non può essere letto né scaricato da lì; l’amministratore del server deve spostarlo in /home/ftp prima di renderlo disponibile agli altri).

Ora dobbiamo configurare PureFTPd per ftp anonimo. Apri /etc/pure-ftpd/pure-ftpd.conf e assicurati di avere le seguenti impostazioni:

nano /etc/pure-ftpd/pure-ftpd.conf
[...]
NoAnonymous                 no
[...]
AntiWarez                   no
[...]
AnonymousBandwidth            8
[...]
AnonymousCantUpload         no
[...]

(L’impostazione AnonymousBandwidth è facoltativa - ti consente di limitare le larghezze di banda di upload e download per gli utenti anonimi. 8 significa 8 KB/sec. Usa qualsiasi valore tu voglia, o commenta la riga se non vuoi limitare le larghezze di banda.)

Infine, riavviamo PureFTPd:

systemctl restart pure-ftpd.service

9 Scarica questo server CentOS 7.2 come macchina virtuale

Questa configurazione è disponibile come download di macchina virtuale in formato ova/ovf (compatibile con VMWare e Virtualbox) per gli abbonati di howtoforge.

Dettagli di accesso per la VM

  • La password di root è: howtoforge
  • La password dell’utente “administrator” è: howtoforge

Si prega di cambiare entrambe le password al primo accesso.

  • L’indirizzo IP della VM è 192.168.1.100

10 Link

Share: X/Twitter LinkedIn

Ricevi i nuovi post nella tua casella di posta.

Nessuno spam. Disiscriviti in qualsiasi momento.