Servidor FTP · 7 min read · Jan 31, 2026
Alojamiento Virtual Con Proftpd Y MySQL (Incl. Cuota) En Ubuntu 14.04LTS
Este documento describe cómo instalar un servidor Proftpd que utiliza usuarios virtuales de una base de datos MySQL en lugar de usuarios reales del sistema. Esto es mucho más eficiente y permite tener miles de usuarios ftp en una sola máquina. Además, mostraré el uso de cuotas con esta configuración. Este tutorial se basa en Ubuntu 14.04LTS.
Para la administración de la base de datos MySQL, puedes usar herramientas basadas en la web como phpMyAdmin, que también se instalará en este tutorial. phpMyAdmin es una interfaz gráfica cómoda, lo que significa que no tienes que lidiar con la línea de comandos.
Este tutorial está destinado a ser una guía práctica; no cubre los antecedentes teóricos. Estos se tratan en muchos otros documentos en la web.
¡Este documento se proporciona sin garantía de ningún tipo! Quiero decir que esta no es la única forma de configurar un sistema así. Hay muchas maneras de lograr este objetivo, pero este es el camino que elijo. No emito ninguna garantía de que esto funcione para ti!
1 Nota Preliminar
En este tutorial utilizo el nombre de host server1.example.com con la dirección IP 192.168.0.100. Estas configuraciones pueden diferir para ti, así que debes reemplazarlas donde sea apropiado.
Asegúrate de estar conectado como root:
sudo su1.1 Cambiar La Shell Predeterminada
/bin/sh es un enlace simbólico a /bin/dash, sin embargo, necesitamos /bin/bash, no /bin/dash. Por lo tanto, hacemos esto:
dpkg-reconfigure dash¿Instalar dash como /bin/sh? <– No
1.2 Deshabilitar AppArmor
AppArmor es una extensión de seguridad (similar a SELinux) que debería proporcionar seguridad extendida. En mi opinión, no lo necesitas para configurar un sistema seguro, y generalmente causa más problemas que ventajas (piensa en ello después de haber pasado una semana solucionando problemas porque algún servicio no funcionaba como se esperaba, y luego descubres que todo estaba bien, solo que AppArmor estaba causando el problema). Por lo tanto, lo deshabilito.
Podemos deshabilitarlo así:
/etc/init.d/apparmor stop
update-rc.d -f apparmor remove
apt-get remove apparmor apparmor-utils2 Instalar MySQL Y phpMyAdmin
Todo esto se puede instalar con un solo comando:
apt-get install mysql-server mysql-client phpmyadmin apache2Se te pedirá que proporciones una contraseña para el usuario root de MySQL; esta contraseña es válida para el usuario root@localhost así como para [email protected], por lo que no tenemos que especificar una contraseña de root de MySQL manualmente más tarde:
Nueva contraseña para el usuario “root” de MySQL: <– tucontraseñarootsql
Repetir contraseña para el usuario “root” de MySQL: <– tucontraseñarootsql
Además de esto, verás las siguientes preguntas:
Servidor web para reconfigurar automáticamente: <– apache2
¿Configurar la base de datos para phpmyadmin con dbconfig-common? <– No
3 Instalar Proftpd Con Soporte MySQL
Para Ubuntu hay un paquete proftpd-mod-mysql preconfigurado disponible. Instálalo como un demonio independiente así:
apt-get install proftpd-mod-mysqlSe te hará la siguiente pregunta:
Ejecutar proftpd: <– standalone
Luego creamos un grupo ftp (ftpgroup) y un usuario (ftpuser) al que se mapearán todos nuestros usuarios virtuales. Reemplaza el grupo y el ID de usuario 2001 con un número que esté libre en tu sistema:
groupadd -g 2001 ftpgroup
useradd -u 2001 -s /bin/false -d /bin/null -c "usuario proftpd" -g ftpgroup ftpuser4 Crear La Base De Datos MySQL Para Proftpd
Ahora creamos una base de datos llamada ftp y un usuario MySQL llamado proftpd que el demonio proftpd utilizará más tarde para conectarse a la base de datos ftp:
mysql -u root -pCREATE DATABASE ftp;
GRANT SELECT, INSERT, UPDATE, DELETE ON ftp.* TO 'proftpd'@'localhost' IDENTIFIED BY 'password';
GRANT SELECT, INSERT, UPDATE, DELETE ON ftp.* TO 'proftpd'@'localhost.localdomain' IDENTIFIED BY 'password';
FLUSH PRIVILEGES;Reemplaza la cadena password con la contraseña que desees usar para el usuario MySQL proftpd. Aún en la consola de MySQL, creamos las tablas de base de datos que necesitamos:
USE ftp;
CREATE TABLE ftpgroup (
groupname varchar(16) NOT NULL default '',
gid smallint(6) NOT NULL default '5500',
members varchar(16) NOT NULL default '',
KEY groupname (groupname)
) ENGINE=MyISAM COMMENT='Tabla de grupos ProFTP';
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'
) ENGINE=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'
) ENGINE=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 '5500',
gid smallint(6) NOT NULL default '5500',
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)
) ENGINE=MyISAM COMMENT='Tabla de usuarios ProFTP';
quit;Como habrás notado, con el comando quit; hemos salido de la consola de MySQL y estamos de vuelta en la consola de Linux.
Por cierto, (asumo que el nombre de host de tu sistema de servidor ftp es server1.example.com) puedes acceder a phpMyAdmin en http://server1.example.com/phpmyadmin/ (puedes usar la dirección IP en lugar de server1.example.com) en un navegador e iniciar sesión como proftpd. Luego puedes echar un vistazo a la base de datos. Más adelante puedes usar phpMyAdmin para administrar tu servidor Proftpd.
5 Configurar Proftpd
Abre /etc/proftpd/modules.conf…
vi /etc/proftpd/modules.conf… y habilita los siguientes tres módulos:
| [...] # Instala uno de proftpd-mod-mysql, proftpd-mod-pgsql o cualquier otro # motor de backend SQL para usar este módulo y el backend requerido. # Este módulo debe ser cargado obligatoriamente antes de cualquiera de # los backends SQL existentes. LoadModule mod_sql.c [...] # Instala proftpd-mod-mysql y descomenta el anterior # módulo mod_sql.c para usar esto. LoadModule mod_sql_mysql.c [...] # Instala uno de los backends SQL anteriores y descomenta # el anterior módulo mod_sql.c para usar esto LoadModule mod_quotatab_sql.c [...] |
Luego abre /etc/proftpd/proftpd.conf y comenta las siguientes líneas:
vi /etc/proftpd/proftpd.conf| [...] # |
Más abajo en el archivo, agrega las siguientes líneas:
| [...] # # Marcos de autenticación alternativos # #Include /etc/proftpd/ldap.conf #Include /etc/proftpd/sql.conf DefaultRoot ~ SQLBackend mysql # Las contraseñas en MySQL están encriptadas usando CRYPT SQLAuthTypes Plaintext Crypt SQLAuthenticate users groups # usado para conectarse a la base de datos # nombrebase@host usuario_base_de_datos contraseña_usuario SQLConnectInfo ftp@localhost proftpd password # Aquí le decimos a ProFTPd los nombres de las columnas de la base de datos en la "usertable" # con las que queremos interactuar. Coincide los nombres con los de la base de datos SQLUserInfo ftpuser userid passwd uid gid homedir shell # Aquí le decimos a ProFTPd los nombres de las columnas de la base de datos en la "grouptable" # con las que queremos interactuar. Nuevamente los nombres coinciden con los de la base de datos SQLGroupInfo ftpgroup groupname gid members # establecer UID y GID mínimos - de lo contrario, estos son 999 cada uno SQLMinID 500 # crear el directorio home de un usuario a demanda si no existe CreateHome on # Actualizar el conteo cada vez que el usuario inicia sesión SQLLog PASS updatecount SQLNamedQuery updatecount UPDATE "count=count+1, accessed=now() WHERE userid='%u'" ftpuser # Actualizar modificado cada vez que el usuario sube o elimina un archivo SQLLog STOR,DELE modified SQLNamedQuery modified UPDATE "modified=now() WHERE userid='%u'" ftpuser # Cuotas de usuario # =========== 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 [...] |
Asegúrate de reemplazar la cadena password con la contraseña real para el usuario MySQL proftpd en la línea SQLConnectInfo!
Luego reinicia Proftpd:
/etc/init.d/proftpd restartRecibe nuevas publicaciones en tu bandeja de entrada.
No spam. Cancela la suscripción en cualquier momento.