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.cProcedi e emetti il comando per ottenere proftpd-pgsql:
apt-get install proftpd-pgsqlConfigurazione 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_nameoppure, 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:
- Qui impostiamo l’AuthOrder, su mod_sql.c, abilitando a sua volta mod_sql.
- 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.)
- 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.
- SQLConnectInfo è il dsn nel formato “database@host user password,”
- SQLDefaultUID, SQLDefaultGID, SQLDefaultHomedir, configurano il predefinito, lasciando la maggior parte delle mie colonne a NULL, raramente sovrascriverò questo.
- RequireValidShell è impostato su off, se lo imposti su on e fornisci una shell non valida fallirai l’autenticazione.
- L’SQLUserInfo corrisponde alle tabelle Postgres, è una mappatura letterale, ancora una volta il “ftp.” specifica lo schema per la tabella di autenticazione.
- SQLNegativeCache, memorizza nella cache i fallimenti di autenticazione,
- SQLLogFile per il logging dettagliato mentre configuri il tuo server. Disabiliterò quando andrò in produzione.
- SQLLog specifica quale azione ftp desideri registrare, poiché i miei utenti possono solo caricare, registro solo STOR, il formato è ‘ftpaction query_to_execute’.
- 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.1Poi devi installare plperlu sul database
createlang plperlu your_database_hereSuccessivamente 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)
Ricevi i nuovi post nella tua casella di posta.
Nessuno spam. Disiscriviti in qualsiasi momento.