Installare un server FTP con utenti virtuali su MySQL
Attenzione. Questa guida è da considerarsi abbandonata, per via del tempo trascorso dall'ultima verifica.
Potrà essere resa obsoleta, previa segnalazione sul forum, se nessuno si propone per l'adozione. |
Versioni Compatibili Debian 8 "jessie" |
Introduzione
Dopo aver installato Apache (Installare un ambiente LAMP: Linux, Apache2, SSL, MySQL, PHP5) e configurato i Virtual Host (Apache e Virtual Hosts: configurare Apache2 per ospitare più siti web) abbiamo adesso bisogno di permettere ai proprietari dei domini ospitati sui Virtual Host di accedere al loro spazio web via FTP senza causare danni agli altri Virtual Host e senza avere la possibilità di gironzolare per il nostro server.
Supponiamo quindi di avere una situazione del genere:
- /var/www/www.esempio.it
- /var/www/www.esempio.org
e di voler creare due utenti virtuali, senza accesso alla console:
- esempio-it
- esempio-org
che possano accedere via FTP solo alle directory del loro sito web.
Installazione di ProFTPD
La scelta sul server FTP da utilizzare è caduta su ProFTPD, che ora dobbiamo configurare in modo opportuno per avere due utenti distinti che gestiscano i due siti. Per fare ciò creeremo due siti FTP virtuali, con l’ausilio di un database dedicato su MySQL.
Installiamo innanzitutto ProFTPD con il supporto per MySQL:
# apt-get install proftpd-basic proftpd-mod-mysql
Per aumentare il tempo massimo prima che una connessione FTP vada in timeout per mancanza di attività possiamo aprire il file di configurazione:
# vi /etc/proftpd/proftpd.conf
e aumentare il valore della direttiva:
TimeoutNoTransfer 1200
Consiglio inoltre di aggiungere le seguenti direttive:
#Abilita resume per upload AllowStoreRestart on DeleteAbortedStores off #Abilita resume per il download AllowRetrieveRestart on
Ora creiamo un utente e un gruppo di sistema, che useremo per mappare tutti gli utenti virtuali che saranno utilizzati da ProFTPD:
# groupadd -g 2001 ftpgroup # useradd -u 2001 -s /bin/false -d /bin/null -c "Utente ProFTPD" -g ftpgroup ftpuser
Sostituite ovviamente i numeri UID e GID con due valori che siano liberi sul vostro server.
Ora dobbiamo creare il database per ProFTPD, entrando in MySQL col comando:
$ mysql -u root -p
Creeremo un database chiamato proftpd
e un utente MySQL chiamato proftpd
, che sarà in seguito utilizzato da ProFTPD per connettersi al database server:
CREATE DATABASE proftpd; GRANT SELECT, INSERT, UPDATE, DELETE ON proftpd.* TO 'proftpd'@'localhost' IDENTIFIED BY 'password'; GRANT SELECT, INSERT, UPDATE, DELETE ON proftpd.* TO 'proftpd'@'localhost.localdomain' IDENTIFIED BY 'password'; FLUSH PRIVILEGES;
Ovviamente sostituite la stringa password
con la password che volete assegnare al vostro utente MySQL.
Già che siamo collegati alla shell di MySQL ne approfittiamo per creare anche tutte le tabelle che ci servono:
USE proftpd; CREATE TABLE ftpgroup ( groupname varchar(16) NOT NULL default '', gid smallint(6) NOT NULL default '2001', members varchar(16) NOT NULL default '', KEY groupname (groupname) ) TYPE=MyISAM COMMENT='ProFTP group table'; CREATE TABLE ftpquotalimits ( name varchar(30) default NULL, quota_type enum('user','group','class','all') NOT NULL default 'user', per_session enum('false','true') NOT NULL default 'false', limit_type enum('soft','hard') NOT NULL default 'soft', bytes_in_avail bigint(20) unsigned NOT NULL default '0', bytes_out_avail bigint(20) unsigned NOT NULL default '0', bytes_xfer_avail bigint(20) unsigned NOT NULL default '0', files_in_avail int(10) unsigned NOT NULL default '0', files_out_avail int(10) unsigned NOT NULL default '0', files_xfer_avail int(10) unsigned NOT NULL default '0' ) TYPE=MyISAM; CREATE TABLE ftpquotatallies ( name varchar(30) NOT NULL default '', quota_type enum('user','group','class','all') NOT NULL default 'user', bytes_in_used bigint(20) unsigned NOT NULL default '0', bytes_out_used bigint(20) unsigned NOT NULL default '0', bytes_xfer_used bigint(20) unsigned NOT NULL default '0', files_in_used int(10) unsigned NOT NULL default '0', files_out_used int(10) unsigned NOT NULL default '0', files_xfer_used int(10) unsigned NOT NULL default '0' ) TYPE=MyISAM; CREATE TABLE ftpuser ( id int(10) unsigned NOT NULL auto_increment, userid varchar(32) NOT NULL default '', passwd varchar(32) NOT NULL default '', uid smallint(6) NOT NULL default '2001', gid smallint(6) NOT NULL default '2001', 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 (userid) ) TYPE=MyISAM COMMENT='ProFTP user table'; quit;
A questo punto dovremmo essere ritornati alla shell del nostro server.
Configurazione di ProFTPD
La configurazione di ProFTPD per utilizzare MySQL come backend comporta la modifica di alcuni file:
/etc/proftpd/modules.conf
Apriamo il file:
# vi /etc/proftpd/modules.conf
e abilitiamo i moduli seguenti:
[...] # Install proftpd-mod-mysql or proftpd-mod-pgsql to use this LoadModule mod_sql.c [...] # Install proftpd-mod-mysql to use this LoadModule mod_sql_mysql.c [...] # Install proftpd-mod-pgsql or proftpd-mod-mysql to use this LoadModule mod_quotatab_sql.c [...]
/etc/proftpd/proftpd.conf
Apriamo il file:
# vi /etc/proftpd/proftpd.conf
decommentiamo la linea Include /etc/proftpd/sql.conf
:
[...] #<IfModule mod_quotatab.c> #QuotaEngine off #</IfModule> [...] # # Alternative authentication frameworks # #Include /etc/proftpd/ldap.conf Include /etc/proftpd/sql.conf [...]
e cambiamo la linea:
AuthOrder mod_auth_pam.c mod_auth_unix.c
in:
#AuthOrder mod_auth_pam.c mod_auth_unix.c AuthOrder mod_sql.c
/etc/proftpd/sql.conf
Di questo file, in particolare, notiamo la riga SQLConnectInfo
(in cui vanno inseriti i parametri di connessione al database)che, se utilizziamo un database MySQL configurato come descritto in precedenza, va scritta così:
SQLConnectInfo proftpd@localhost proftpd password
Apriamo quindi il file:
# vi /etc/proftpd/sql.conf
e modifichiamolo come segue:
# # Proftpd sample configuration for SQL-based authentication. # # (This is not to be used if you prefer a PAM-based SQL authentication) # <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 on # # Use both a crypted or plaintext password #SQLAuthTypes Crypt Plaintext # # Use a backend-crypted or a crypted password #SQLAuthTypes Backend Crypt # # Connection #SQLConnectInfo proftpd@sql.example.com proftpd_user proftpd_password # # Describes both users/groups tables # #SQLUserInfo users userid passwd uid gid homedir shell #SQLGroupInfo groups groupname gid members # DefaultRoot ~ SQLBackend mysql # The passwords in MySQL are encrypted using CRYPT #SQLAuthTypes Plaintext Crypt SQLAuthTypes Crypt Plaintext SQLAuthenticate users groups # used to connect to the database # databasename@host database_user user_password #SQLConnectInfo ftp@localhost proftpd password SQLConnectInfo proftpd@localhost proftpd password # Here we tell ProFTPd the names of the database columns in the "usertable" # we want it to interact with. Match the names with those in the db SQLUserInfo ftpuser userid passwd uid gid homedir shell # Here we tell ProFTPd the names of the database columns in the "grouptable" # we want it to interact with. Again the names match with those in the db SQLGroupInfo ftpgroup groupname gid members # set min UID and GID - otherwise these are 999 each SQLMinID 500 # create a user's home directory on demand if it doesn't exist CreateHome on # Update count every time user logs in SQLLog PASS updatecount SQLNamedQuery updatecount UPDATE "count=count+1, accessed=now() WHERE userid='%u'" ftpuser # Update modified everytime user uploads or deletes a file SQLLog STOR,DELE modified SQLNamedQuery modified UPDATE "modified=now() WHERE userid='%u'" ftpuser # User quotas # =========== QuotaEngine on QuotaDirectoryTally on QuotaDisplayUnits Mb QuotaShowQuotas on SQLNamedQuery get-quota-limit SELECT "name, quota_type, per_session, limit_type, bytes_in_avail, bytes_out_avail, bytes_xfer_avail, files_in_avail, files_out_avail, files_xfer_avail FROM ftpquotalimits WHERE name = '%{0}' AND quota_type = '%{1}'" SQLNamedQuery get-quota-tally SELECT "name, quota_type, bytes_in_used, bytes_out_used, bytes_xfer_used, files_in_used, files_out_used, files_xfer_used FROM ftpquotatallies WHERE name = '%{0}' AND quota_type = '%{1}'" SQLNamedQuery update-quota-tally UPDATE "bytes_in_used = bytes_in_used + %{0}, bytes_out_used = bytes_out_used + %{1}, bytes_xfer_used = bytes_xfer_used + %{2}, files_in_used = files_in_used + %{3}, files_out_used = files_out_used + %{4}, files_xfer_used = files_xfer_used + %{5} WHERE name = '%{6}' AND quota_type = '%{7}'" ftpquotatallies SQLNamedQuery insert-quota-tally INSERT "%{0}, %{1}, %{2}, %{3}, %{4}, %{5}, %{6}, %{7}" ftpquotatallies QuotaLimitTable sql:/get-quota-limit QuotaTallyTable sql:/get-quota-tally/update-quota-tally/insert-quota-tally RootLogin off RequireValidShell off </IfModule>
Controllate di aver inserito la corretta password di connessione a MySQL e riavviate il servizio FTP:
# /etc/init.d/proftpd restart
Creazione degli utenti FTP
Giunti fino a qui, dobbiamo ora inserire gli utenti virtuali FTP nel database MySQL.
Nell’inserimento vero e proprio degli utenti nel database proftpd in MySQL, dobbiamo prestare attenzione ad indicare la home directory su cui verrà rimbalzato l’utente che si autentica su ProFTPD; in particolare, facendo riferimento all’articolo riguardante l’hosting virtuale con Apache, creeremo:
- un gruppo chiamato ftpgroup;
- un utente chiamato esempio-it con password passwordit e home directory
/var/www/www.esempio.it
; - un utente chiamato esempio-org con password passwordorg e home directory
/var/www/www.esempio.org
.
Per popolare il database abbiamo due strade.
1) shell mysql>
Colleghiamoci alla shell di MySQL:
mysql -u root -p
e impartiamo le seguenti istruzioni:
USE proftpd; INSERT INTO `ftpgroup` (`groupname`, `gid`, `members`) VALUES ('ftpgroup', 2001, 'ftpuser'); INSERT INTO ftpuser (userid, passwd, uid, gid, homedir, shell, count, accessed, modified) VALUES (’esempio-it’, ENCRYPT(’passwordit’), 2001, 2001, ‘/var/www/www.esempio.it’, ‘/sbin/nologin’, 0, ”, ”); INSERT INTO ftpuser (userid, passwd, uid, gid, homedir, shell, count, accessed, modified) VALUES (’esempio-org’, ENCRYPT(’passwordorg’), 2001, 2001, ‘/var/www/www.esempio.org’, ‘/sbin/nologin’, 0, ”, ”); INSERT INTO `ftpquotalimits` (`name`, `quota_type`, `per_session`, `limit_type`, `bytes_in_avail`, `bytes_out_avail`, `bytes_xfer_avail`, `files_in_avail`, `files_out_avail`, `files_xfer_avail`) VALUES ('esempio-it', 'user', 'true', 'hard', 15728640, 0, 0, 0, 0, 0); INSERT INTO `ftpquotalimits` (`name`, `quota_type`, `per_session`, `limit_type`, `bytes_in_avail`, `bytes_out_avail`, `bytes_xfer_avail`, `files_in_avail`, `files_out_avail`, `files_xfer_avail`) VALUES ('esempio-org', 'user', 'true', 'hard', 15728640, 0, 0, 0, 0, 0); quit;
Si noti che insieme agli utenti sono state create due regole per lo spazio su disco, con una quota impostata a 15MB.
Da notare che per inserire la password è stata usata la funzione di MySQL ENCRYPT, che utilizza la chiamata di sistema crypt() presente sul sistema operativo, quindi di fatto utilizza lo stesso metodo di cifratura utilizzato da Linux per cifrare le password degli utenti di sistema.
2) phpMyAdmin
In alternativa alla linea di comando, possiamo creare i nostri utenti collegandoci all'interfaccia web phpMyAdmin e aprendo il database proftpd.
Una volta aperto, troveremo al suo interno alcune tabelle; quelle che ci interessano nella creazione e nella gestione degli utenti sono però solo due:
- ftpquotalimits
- ftpuser
Vediamone il contenuto.
ftpuser
I campi da riempire sono i seguenti (i restanti campi sono utilizzati da ProFTPD e/o da MySQL, quindi non riempiteli!):
- userid: il nome dell'utente FTP virtuale (es: esempio-it)
- passwd: la password dell'utente
- uid: il valore userid dell'utente di sistema ftp creato in precedenza (2001)
- gid: il valore groupid dell'utente di sistema ftp creato in precedenza (2001)
- homedir: il percorso della home directory dell'utente FTP virtuale (
/var/www/www.esempio.it
). Se non esiste sarà creata al momento della connessione. L'utente virtuale sarà chrooted in questa directory e non potrà uscirne - shell: la shell di sistema assegnata all'utente. Dato che non vogliamo permettere accesso al server, lasciamo il valore di default
ftpquotalimits
I campi da riempire sono i seguenti (i restanti campi sono utilizzati da ProFTPD e/o da MySQL, quindi non riempiteli!):
- name: il nome dell'utente FTP virtuale (es: esempio-it)
- quota_type: user o group. Normalmente useremo user
- per_session: true o false. true significa che la quota limite è valida per una singola sessione: se l'utente effettua un logout e un nuovo login la quota si azzera. false significa che l'utente ha a disposizione la quota stabilita
- limit_type: hard o soft. Un hard quota limit non permette eccezioni, mentre un soft quota limit può temporaneamente essere superato. Normalmente viene usato hard
- bytes_in_avail: limite di upload in bytes. 0 significa senza limite
- bytes_out_avail: limite di download in bytes. 0 significa senza limite
- bytes_xfer_avail: limite di transfer bytes. È la quantità massima di bytes che un utente può uploadare o downloadare. 0 significa senza limite
- files_in_avail: numero limite di file uploadabili. 0 significa senza limite
- files_out_avail: numero limite di file scaricabili. 0 significa senza limite
- files_xfer_avail: numero limite di file trasferibili. 0 significa senza limite
Altre tabelle
La tabella ftpquotatallies è utilizzata da Proftpd per gestire le quotas e non va modificata.
Impostazione dei permessi corretti
Ora rimangono da impostare i permessi sulle directory dei due siti web, per far sì che gli utenti FTP possano scrivere al loro interno, dando l’autorizzazione in scrittura all’utente ftpuser creato in precedenza:
# chown -R ftpuser:www-data /var/www/www.esempio.it # chown -R ftpuser:www-data /var/www/www.esempio.org # chmod -R 775 /var/www/www.esempio.it # chmod -R 775 /var/www/www.esempio.org
Test di connessione
Aprite il vostro client FTP preferito e connettetevi al vostro server utilizzando le credenziali seguenti:
- Host: ftp.esempio.it
- Utente: esempio-it
- Password: passwordit
- Porta: 21
Provate a caricare un file e controllate eventuali messaggi di errore.
Una volta completato l'upload, fate login come root sulla console del server e spostatevi nella DocumentRoot del sito www.esempio.it:
# cd /var/www/www.esempio.it # ls -la
Dovreste trovare listato anche il file che avete appena caricato.
FTP anonimo
È possibile creare anche un account ftp anonimo, cioè un account ftp che chiunque possa usare senza una password, in questo modo.
Creiamo innanzitutto un utente, un gruppo di sistema e una home directory:
# mkdir /var/www/anonymous_ftp # groupadd -g 2002 anonymous_ftp # useradd -u 2002 -s /bin/false -d /var/www/anonymous_ftp -m -c "Anonymous FTP User" -g anonymous_ftp anonymous_ftp
Poi creiamo la directory /home/anonymous_ftp/incoming
dove gli utenti anonimi potranno caricare i file:
# mkdir /var/www/anonymous_ftp/incoming # chown anonymous_ftp:nogroup /var/www/anonymous_ftp/incoming
Infine apriamo il file di configurazione /etc/proftpd/proftpd.conf
e aggiungiamo le direttive:
# vi /etc/proftpd/proftpd.conf
[...] <Anonymous /var/www/anonymous_ftp> User anonymous_ftp Group nogroup # We want clients to be able to login with "anonymous" as well as "ftp" UserAlias anonymous anonymous_ftp # Cosmetic changes, all files belongs to ftp user DirFakeUser on anonymous_ftp DirFakeGroup on anonymous_ftp RequireValidShell off # Limit the maximum number of anonymous logins MaxClients 10 # We want 'welcome.msg' displayed at login, and '.message' displayed # in each newly chdired directory. DisplayLogin welcome.msg DisplayChdir .message # Limit WRITE everywhere in the anonymous chroot <Directory *> <Limit WRITE> DenyAll </Limit> </Directory> # Uncomment this if you're brave. <Directory incoming> # Umask 022 is a good standard umask to prevent new files and dirs # (second parm) from being group and world writable. Umask 022 022 <Limit READ WRITE> DenyAll </Limit> <Limit STOR> AllowAll </Limit> </Directory> </Anonymous>
Riavviamo il servizio:
# /etc/init.d/proftpd restart
e verifichiamo che gli utenti anonimi possano ora effettuare il login.
L'impostazione data prevede che gli utenti anonimi possano:
- scaricare i file messi in
/var/www/anonymous_ftp
- caricare i file nella directory
/var/www/anonymous_ftp/incoming
Una volta che un file è stato caricato, nessuno può leggerlo o scaricarlo prima che un amministratore lo sposti nella directory /var/www/anonymous_ftp
per renderlo disponibile a tutti.
Configurazione del Firewall
Se il server FTP è protetto da un firewall iptables occorre abilitare la direttiva PassivePorts:
# nano /etc/proftpd/proftdp.conf
in questo modo:
PassivePorts 60000 65000
In questo modo abbiamo istruito ProFTPD a utilizzare uno specifico range di porte dinamiche per le transazioni FTP. Lo stesso range va abilitato nello script del nostro firewall:
-A INPUT -m state --state NEW -m tcp -p tcp --dport 60000:65000 -j ACCEPT
Un riavvio del demone FTP e dello script del firewall completerà l'opera.
Guida scritta da: Ferdybassi 19:40, 8 nov 2010 (CET) | Debianized 40% |
Estesa da: | |
Verificata da:
| |
Verificare ed estendere la guida | Cos'è una guida Debianized |