서버 설정 · 6 min read · Jan 31, 2026

Proftpd와 MySQL을 이용한 가상 호스팅 (쿼터 포함) - Ubuntu 14.04LTS

이 문서는 실제 시스템 사용자 대신 MySQL 데이터베이스에서 가상 사용자를 사용하는 Proftpd 서버를 설치하는 방법을 설명합니다. 이는 성능이 훨씬 더 뛰어나며 단일 머신에서 수천 개의 FTP 사용자를 가질 수 있게 해줍니다. 또한 이 설정에서 쿼터 사용을 보여드리겠습니다. 이 튜토리얼은 Ubuntu 14.04LTS를 기반으로 합니다.

MySQL 데이터베이스 관리를 위해 phpMyAdmin과 같은 웹 기반 도구를 사용할 수 있으며, 이 방법에서도 설치됩니다. phpMyAdmin은 명령줄을 다룰 필요가 없는 편리한 그래픽 인터페이스입니다.

이 방법은 실용적인 가이드를 목적으로 하며, 이론적 배경은 다루지 않습니다. 이론적 배경은 웹의 많은 다른 문서에서 다루어집니다.

이 문서는 어떤 종류의 보증 없이 제공됩니다! 이러한 시스템을 설정하는 유일한 방법이 아니라는 점을 말씀드리고 싶습니다. 이 목표를 달성하는 방법은 여러 가지가 있지만, 제가 선택한 방법입니다. 이 방법이 귀하에게도 작동할 것이라는 보장을 하지 않습니다!

1 사전 참고

이 튜토리얼에서는 호스트 이름 server1.example.com과 IP 주소 192.168.0.100을 사용합니다. 이러한 설정은 귀하의 경우 다를 수 있으므로 적절한 곳에서 교체해야 합니다.

루트로 로그인했는지 확인하십시오:

sudo su

1.1 기본 셸 변경

/bin/sh는 /bin/dash에 대한 심볼릭 링크입니다. 그러나 우리는 /bin/dash가 아닌 /bin/bash가 필요합니다. 따라서 다음과 같이 합니다:

dpkg-reconfigure dash

Install dash as /bin/sh? <– 아니요

1.2 AppArmor 비활성화

AppArmor는 확장된 보안을 제공해야 하는 보안 확장(SELinux와 유사)입니다. 제 생각에는 안전한 시스템을 구성하는 데 필요하지 않으며, 일반적으로 장점보다 더 많은 문제를 일으킵니다(어떤 서비스가 예상대로 작동하지 않아 일주일 동안 문제를 해결한 후, 모든 것이 괜찮았고 AppArmor가 문제를 일으켰다는 것을 알게 되는 경우를 생각해 보십시오). 따라서 저는 이를 비활성화합니다.

다음과 같이 비활성화할 수 있습니다:

/etc/init.d/apparmor stop  
update-rc.d -f apparmor remove  
apt-get remove apparmor apparmor-utils

2 MySQL 및 phpMyAdmin 설치

다음의 단일 명령으로 모두 설치할 수 있습니다:

apt-get install mysql-server mysql-client phpmyadmin apache2

MySQL 루트 사용자에 대한 비밀번호를 제공하라는 메시지가 표시됩니다. 이 비밀번호는 root@localhost와 [email protected] 사용자 모두에 대해 유효하므로 나중에 MySQL 루트 비밀번호를 수동으로 지정할 필요가 없습니다:

New password for the MySQL “root” user: <– yourrootsqlpassword
Repeat password for the MySQL “root” user: <– yourrootsqlpassword

이 외에도 다음 질문이 표시됩니다:

Web server to reconfigure automatically: <– apache2
Configure database for phpmyadmin with dbconfig-common? <– 아니요

3 MySQL 지원이 있는 Proftpd 설치

Ubuntu에는 미리 구성된 proftpd-mod-mysql 패키지가 있습니다. 다음과 같이 독립 실행형 데몬으로 설치합니다:

apt-get install proftpd-mod-mysql

다음 질문이 표시됩니다:

Run proftpd: <– standalone

그런 다음 모든 가상 사용자가 매핑될 ftp 그룹(ftpgroup)과 사용자(ftpuser)를 생성합니다. 그룹 및 사용자 ID 2001을 시스템에서 사용 가능한 숫자로 교체하십시오:

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

4 Proftpd용 MySQL 데이터베이스 생성

이제 ftp라는 데이터베이스와 proftpd라는 MySQL 사용자를 생성합니다. 이 사용자는 나중에 proftpd 데몬이 ftp 데이터베이스에 연결하는 데 사용됩니다:

mysql -u root -p
CREATE 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;

문자열 password를 MySQL 사용자 proftpd에 사용할 비밀번호로 교체하십시오. 여전히 MySQL 셸에서 필요한 데이터베이스 테이블을 생성합니다:

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='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'  
) 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='ProFTP user table';

quit;

보시다시피, quit; 명령으로 MySQL 셸을 종료하고 리눅스 셸로 돌아왔습니다.

참고로, (귀하의 FTP 서버 시스템의 호스트 이름이 server1.example.com이라고 가정합니다) 브라우저에서 http://server1.example.com/phpmyadmin/ (server1.example.com 대신 IP 주소를 사용할 수 있습니다)로 phpMyAdmin에 접근하여 proftpd로 로그인할 수 있습니다. 그런 다음 데이터베이스를 살펴볼 수 있습니다. 나중에 phpMyAdmin을 사용하여 Proftpd 서버를 관리할 수 있습니다.

5 Proftpd 구성

/etc/proftpd/modules.conf를 열어…

vi /etc/proftpd/modules.conf

… 다음 세 가지 모듈을 활성화합니다:

| [...] # Install one of proftpd-mod-mysql, proftpd-mod-pgsql or any other # SQL backend engine to use this module and the required backend. # This module must be mandatory loaded before anyone of # the existent SQL backeds. LoadModule mod_sql.c [...] # Install proftpd-mod-mysql and decomment the previous # mod_sql.c module to use this. LoadModule mod_sql_mysql.c [...] # Install one of the previous SQL backends and decomment # the previous mod_sql.c module to use this LoadModule mod_quotatab_sql.c [...] |

그런 다음 /etc/proftpd/proftpd.conf를 열고 다음 줄의 주석을 제거합니다:

vi /etc/proftpd/proftpd.conf

| [...] # #QuotaEngine off # [...] |

파일의 아래쪽에서 다음 줄을 추가합니다:

| [...] # # Alternative authentication frameworks # #Include /etc/proftpd/ldap.conf #Include /etc/proftpd/sql.conf DefaultRoot ~ SQLBackend mysql # The passwords in MySQL are encrypted using CRYPT SQLAuthTypes Plaintext Crypt SQLAuthenticate users groups # used to connect to the database # databasename@host database_user user_password SQLConnectInfo ftp@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 [...] |

SQLConnectInfo의 줄에서 MySQL 사용자 proftpd의 실제 비밀번호로 문자열 password를 교체했는지 확인하십시오!

그런 다음 Proftpd를 재시작합니다:

/etc/init.d/proftpd restart
Share: X/Twitter LinkedIn

새 게시물을 받은 편지함에서 받기

스팸은 없습니다. 언제든지 구독 해지 가능합니다.