Database Setup · 7 min read · Dec 17, 2025

PostgreSQL e Proftpd

Quindi vuoi impostare un server ftp, hai bisogno di funzionalità avanzate e non sai a chi rivolgerti? Prova proftpd.

Parte 1: Configurazione di proftpd con un backend postgresql

Questo tutorial è molto di nicchia, tratterò solo proftpd, e solo per farlo funzionare con Postgres. Si presume una comprensione di base di proftpd e Postgres. Questo tutorial ti permetterà di avviare proftpd abbastanza rapidamente, e di farlo utilizzare un database; se quel database ha trigger, le possibilità di questa configurazione sono quasi infinite.

Ottenere Proftpd

Prima di tutto avrai bisogno di proftpd, userò Dapper di Ubuntu; c’è un meta-pacchetto preparato grazie a Francesco Paolo Lovergine intitolato “proftpd-pgsql,” che installerà una copia di proftpd compilata con i seguenti moduli. Come nota a margine, mentre proftpd viene fornito con i moduli, il file di configurazione è il classico boilerplate di proftpd. Ti consiglio vivamente di controllare la documentazione di mod_sql, che anche se non è eccezionale è comunque utile – la documentazione sul sito di proftpd è molto vecchia, usa invece queste: Link alla documentazione. Inoltre, fai attenzione alla versione, proftpd è ora alla 1.3, anche se io userò la 1.2.10 – la versione utilizzata in Dapper.

I moduli compilati in questa versione di proftpd sono i seguenti

  mod_core.c  
  mod_xfer.c  
  mod_auth_unix.c  
  mod_auth_file.c  
  mod_auth.c  
  mod_ls.c  
  mod_log.c  
  mod_site.c  
  mod_auth_pam.c  
  mod_quotatab.c  
  mod_sql.c  
  mod_sql_postgres.c  
  mod_quotatab_sql.c  
  mod_ratio.c  
  mod_tls.c  
  mod_rewrite.c  
  mod_radius.c  
  mod_wrap.c  
  mod_quotatab_file.c  
  mod_delay.c  
  mod_readme.c  
  mod_ifsession.c  
  mod_cap.c

Procedi e emetti il comando per ottenere proftpd-pgsql:

apt-get install proftpd-pgsql

Configurazione dei permessi.

Per il mio scopo, (ricorda, io sono il centro dell’universo) tutto ciò di cui avevo bisogno era una struttura unidimensionale, perché i gruppi sono memorizzati a un livello diverso rispetto ai permessi unix. Quindi tutti i file dovrebbero arrivare con permessi statici – mi interessa solo il proprietario e il gruppo del proprietario. Il mio piano era di far appartenere l’utente predefinito di proftpd, ftp, al suo gruppo opportunamente chiamato che stavo per creare – ‘ftp’. Poi avrei fatto diventare Postgres un membro di questo gruppo, vedi parte 2 per il ragionamento. Avevo bisogno che entrambi fossero membri dello stesso gruppo, e avevo bisogno che la cartella chroot di proftpd fosse 775, in modo che l’intero gruppo potesse aggiungere (spostare) file; ho anche fatto in modo che la cartella fosse di proprietà dell’utente ‘ftp’, con gruppo ‘ftp’. Ho raggiunto questo obiettivo con il seguente script.

groupadd ftp
usermod -G ftp ftp
usermod -G ftp,postgres postgres
chown ftp:ftp ./ftp_directory/
chmod 775 ./ftp_directory/

Configurazione di Postgres

Ora, dobbiamo preparare le nostre tabelle sql. Progetto utilizzando schemi, e questo è ciò per cui è il prefisso ‘ftp.’ sulle tabelle. Ho messo tutte le mie tabelle in uno schema ftp, c’è una cosa da notare, sono stato estremamente restrittivo sui permessi per questo progetto, perché non sono sicuro di quanto sia sicuro mod_sql. Facendo ciò ho creato un utente speciale, chiamato proftp, per proftpd nel mio database (che più applicazioni utilizzano rispetto a proftpd), questo utente è limitato a selezioni sulla auth_table e inserimenti sulla tabella file_log. Ti consiglio vivamente di adottare qualche forma di questa politica. Almeno questo previene un certo grado di devastanti attacchi di sql injection o perdite di informazioni nel caso in cui il codice di mod_sql non sia sicuro come ci piacerebbe pensare. Una rapida ricerca su Google rivela un precedente problema di sicurezza con il codice di mod_sql. Ogni query che mod_sql invia al db è appesa con una clausola “LIMIT 1”, e con mod_delay anche configurato per impostazione predefinita, trovo che questo sia sufficiente per questo progetto.

Il mio script di inizializzazione sql è il seguente.

ALTER USER proftp UNENCRYPTED PASSWORD 'dealermadeftp';
CREATE SCHEMA ftp;
GRANT USAGE ON SCHEMA ftp TO proftp;

CREATE TABLE ftp.users (
        pkid      serial      PRIMARY KEY,
        userid    text        NOT NULL UNIQUE,
        passwd    text,
        uid       int,
        gid       int,
        homedir   text,
        shell     text
);
GRANT SELECT ON ftp.users TO proftp;
INSERT INTO ftp.users ( userid, passwd ) VALUES ( 'ecarroll', 'adm1n' );
INSERT INTO ftp.users ( userid, passwd ) VALUES ( 'jgallagher', 'adm1n' );

CREATE TABLE ftp.file_log (
        pkid               serial      PRIMARY KEY,
        userid             text        REFERENCES ftp.users(userid),
        abs_path           text,
        file               text,
        dns                text,
        time_transaction   text,
        ts_in              timestamp with time zone   NOT NULL DEFAULT CURRENT_TIMESTAMP
);
GRANT INSERT ON ftp.file_log TO proftp;
GRANT UPDATE ON TABLE ftp.file_log_pkid_seq TO proftp;

Collegati al tuo database e esegui quello con:

\i script_name

oppure, puoi usare invia ‘–file script_name’ a psql come argomento della riga di comando.

Coloro che utilizzano database inferiori (utilizzando questo tutorial con mysql), potrebbero voler sostituire text con varchar; ma, a causa del design di Postgres non c’è vantaggio in questo.

Configurazione di proftpd

Questa parte è complicata e varia leggermente se stai usando 1.3 – ancora una volta questo tutorial è per 1.2.10.

Ho aggiunto questa parte al mio file di configurazione boilerplate predefinito di proftpd, situato in /etc/proftpd.conf:

AuthOrder            mod_sql.c
SQLAuthTypes         Plaintext Empty
SQLAuthenticate      users
SQLConnectInfo       proftpd@localhost proftp dealermadeftp

SQLDefaultUID        110   # CAMBIA PER L'UID DEI TUOI UTENTI FTP TROVATO IN /etc/passwd
SQLDefaultGID        1001  # CAMBIA PER IL GID DEI TUOI UTENTI FTP, TROVATO IN /etc/groups
SQLDefaultHomedir    /home/ftp
RequireValidShell    off

SQLUserInfo          ftp.users userid passwd uid gid homedir shell

SQLNegativeCache     off
SQLLogFile           /var/log/proftpd-sql
SQLLog               STOR newfile
SQLNamedQuery        newfile FREEFORM "INSERT INTO ftp.file_log(userid,abs_path,file,dns,time_transaction) VALUES ('%U','%f','%J','%V','%T')"

# %U => userid
# %D => --Niente,
# %f => abs_path
# %J => file
# %h => dns_remote, %V => dns_local
# %a => remote_ip, %L => local_ip
# %t => localtime
# %T => transfer_time
  • Le variabili del template sono commentate e solo per il tuo riferimento. Un breve riepilogo della conf è il seguente:
  1. Qui impostiamo l’AuthOrder, su mod_sql.c, abilitando a sua volta mod_sql.
  2. Ho scelto di utilizzare password in chiaro, o nel caso in cui non ne assegni una, consentire password vuote. (Implementerò in seguito un trigger per SHA1 le password nel database.)
  3. Ho quindi impostato SQLAuthenticate su users, ho scelto di non utilizzare gruppi per questo progetto; se hai bisogno di gruppi, ulteriori informazioni possono essere trovate su quelle tabelle in: Questo sito per la documentazione sui gruppi.
  4. SQLConnectInfo è il dsn nel formato “database@host user password,”
  5. SQLDefaultUID, SQLDefaultGID, SQLDefaultHomedir, configurano il predefinito, lasciando la maggior parte delle mie colonne a NULL, raramente sovrascriverò questo.
  6. RequireValidShell è impostato su off, se lo imposti su on e fornisci una shell non valida fallirai l’autenticazione.
  7. L’SQLUserInfo corrisponde alle tabelle Postgres, è una mappatura letterale, ancora una volta il “ftp.” specifica lo schema per la tabella di autenticazione.
  8. SQLNegativeCache, memorizza nella cache i fallimenti di autenticazione,
  9. SQLLogFile per il logging dettagliato mentre configuri il tuo server. Disabiliterò quando andrò in produzione.
  10. SQLLog specifica quale azione ftp desideri registrare, poiché i miei utenti possono solo caricare, registro solo STOR, il formato è ‘ftpaction query_to_execute’.
  11. SQLNamedQuery Controlla la sintassi nella documentazione per una spiegazione migliore; il formato che uso è ‘qryname FREEFORM custom_query_here’, lo faccio principalmente perché desidero catturare molte delle variabili del template di proftpd, ci sono altre sintassi più semplici.

Questo è tutto. Se tutto va secondo i piani dovresti essere operativo. Ora, quando qualcuno carica un file, questo dovrebbe essere il risultato:

proftpd=# select * from ftp.file_log;
 pkid |  userid  |        abs_path        |     file      |  dns  | time_transaction |             ts_in 
------+----------+------------------------+---------------+-------+------------------+-------------------------------
    1 | ecarroll | /home/ftp/foo/testfile | /foo/testfile | AMD64 | 0.000            | 2006-06-11 20:49:12.623375-05
(1 row)

Parte II: Oltre il ‘funzionamento’

… Ma funzionante non è mai abbastanza, giusto? Procediamo a rispondere alla seguente domanda posta nel faq di configurazione per proftpd:
Posso ruotare i file da una directory di upload dopo il caricamento?

E la risposta è, certo che puoi. Riuscirò a farlo attraverso una stored procedure, in modo che i file vengano spostati nel modo giusto – al volo – senza un demone.

Dovrai prima installare untrusted plperlu sul sistema, questo può essere fatto con

apt-get install postgresql-plperl-8.1

Poi devi installare plperlu sul database

createlang plperlu your_database_here

Successivamente dobbiamo creare un trigger di script perl veloce, che verrà attivato su ogni inserimento nella nostra tabella ftp_log

CREATE OR REPLACE FUNCTION ftp_file() RETURNS TRIGGER AS $$
        use warnings;
        use Cwd;
        use File::Basename;
        use File::Spec;
        use File::Copy;
        move (
                $_TD->{new}{abs_path},
                File::Spec->catfile( '/home/ftp/', basename($_TD->{new}{file}) )
        );
        return;
$$ LANGUAGE 'plperlu' VOLATILE;

CREATE TRIGGER ftp_file
        BEFORE INSERT
        ON ftp.file_log
        FOR EACH ROW
        EXECUTE PROCEDURE ftp_file()
;

Questo script sql può essere installato nello stesso modo in cui è stato installato il precedente, (quello utilizzato per creare le tabelle)

Share: X/Twitter LinkedIn

Ricevi i nuovi post nella tua casella di posta.

Nessuno spam. Disiscriviti in qualsiasi momento.