以前中途半端に終わってしまった、ProFTPDのユーザーデータをMySQLに持たせるシリーズのリトライです。今度もTwitterがキッカケでしたw
みちょる:【proftpd】 MySQLでアカウント管理する リターンズ 201109 | (っ´∀`)っ ゃー | nullpopopo - https://t.co/2gmZQRpslm | ぐぐったら引っかかった @nullpopopo さんのブログ…これ進展してないかな(
— 東雲 @ ほっすぃ ミスリル (@H_Shinonome) November 5, 2015
今回はCentOS6にepelリポジトリをインストールし、ここからProFTPDを、標準リポジトリからmysql-serverをインストールして設定しています。ユーザー管理とクォータ管理をするところまでは確認しましたが、それ以外の細かなProFTPDの設定は一切弄っていません。
■ 事前準備
一旦iptablesとSELinuxを止めておきます。
$ sudo service iptables stop $ sudo chkconfig iptables off $ sudo sed -i.orig "/^SELINUX=/s/[[:alnum:]]*$/disabled/" /etc/selinux/config $ sudo reboot
■ epelリポジトリ インストール
yumコマンドでサックリとepelリポジトリをインストールします。普段使いしないので、あわせてリポジトリをデフォルトで無効化しておきます。
$ sudo yum -y install epel-release $ sudo sed -i.orig "/^enabled/s/1/0/g" /etc/yum.repos.d/epel.repo
■ proftpd proftpd-mysqlパッケージ インストール
epelリポジトリから、proftpdとproftpd-mysqlを、標準リポジトリからmysql-serverをインストールします。mysql-serverについては、お好みでOracleのリポジトリからインストールしても構わないでしょう。(この場合、パッケージ名はmysql-community-serverになります)
$ sudo yum -y install mysql-server $ sudo yum --enablerepo=epel -y install proftpd proftpd-mysql
これらインストールが終わったら、ひとまずmysqldを起動します。
$ sudo service mysqld start $ sudo chkconfig mysqld on
■ FTP用UNIXアカウント作成
FTP用UNIXユーザー「ftpuser」、同じくグループ「ftpgroup」を作成し、MySQLで管理するバーチャルユーザーとマッピングします。まずはグループから。UID、GIDは一旦2001で固定することにします。
$ sudo groupadd -g 2001 ftpgroup $ sudo useradd -u 2001 -s /bin/false -d /bin/null -c "proftpd user" -g ftpgroup ftpuser
■ データベースとDBユーザー作成
DB名「ftp」、DBユーザー「proftpd」を作成します。DBユーザーのパスワードは一旦「password」としますが、適宜変更してくださいね。
$ mysql -e "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;"
mysqlのシェルからはこんな感じでどうぞ。
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;
終わったら確認です。こんな感じで表示されればOKです。
$ mysql -N -s -e "select user,host,password from mysql.user;" | grep ^proftpd proftpd localhost *2470C0C06DEE42FD1618BB99005ADCA2EC9D1E19 proftpd localhost.localdomain *2470C0C06DEE42FD1618BB99005ADCA2EC9D1E19
■ グループ管理テーブル作成
FTPのグループを管理するテーブルを作成します。
$ mysql ftp -e "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) ) TYPE=MyISAM COMMENT='ProFTP group table';"
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) ) TYPE=MyISAM COMMENT='ProFTP group table';
■ FTPユーザーのquotaを管理するテーブル作成
ftpquotalimitsテーブルとftpquotatalliesテーブルの2つを作成します。
$ mysql ftp -e "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 int(10) unsigned NOT NULL default '0', bytes_out_avail int(10) unsigned NOT NULL default '0', bytes_xfer_avail int(10) 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;"
$ mysql ftp -e "CREATE TABLE ftpquotatallies ( name varchar(30) NOT NULL default '', quota_type enum('user','group','class','all') NOT NULL default 'user', bytes_in_used int(10) unsigned NOT NULL default '0', bytes_out_used int(10) unsigned NOT NULL default '0', bytes_xfer_used int(10) 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;"
mysqlのシェルからはこんな感じでどうぞ。
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 int(10) unsigned NOT NULL default '0', bytes_out_avail int(10) unsigned NOT NULL default '0', bytes_xfer_avail int(10) 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 int(10) unsigned NOT NULL default '0', bytes_out_used int(10) unsigned NOT NULL default '0', bytes_xfer_used int(10) 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;
■ FTPユーザーを管理するテーブル作成
$ mysql ftp -e "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) ) TYPE=MyISAM COMMENT='ProFTP user table';"
mysqlのシェルからはこんな感じでどうぞ。
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) ) TYPE=MyISAM COMMENT='ProFTP user table';
■ proftpd.conf 編集
proftpd.confを編集し、ユーザー管理とクォータ管理をMySQLで行えるようにします。
$ sudo cp -p /etc/proftpd.conf{,.orig} $ sudo vi /etc/proftpd.conf
以下、vimでの編集箇所です。「Use pam to authenticate (default) and be authoritative」の下の2行「AuthPAMConfig」と「AuthOrder」をコメントアウトします。
# Use pam to authenticate (default) and be authoritative ##--@--##AuthPAMConfig proftpd ##--@--##AuthOrder mod_auth_pam.c* mod_auth_unix.c
「# General database support (http://www.proftpd.org/docs/contrib/mod_sql.html)」の下の行「# LoadModule mod_sql.c」のコメントアウトを外します。
# General database support (http://www.proftpd.org/docs/contrib/mod_sql.html) # LoadModule mod_sql.c LoadModule mod_sql.c
「# Mysql support (requires proftpd-mysql package)」の2行下の「# LoadModule mod_sql_mysql.c」のコメントアウトを外します。
# Mysql support (requires proftpd-mysql package) # (http://www.proftpd.org/docs/contrib/mod_sql.html) # LoadModule mod_sql_mysql.c LoadModule mod_sql_mysql.c
「# Quota support (http://www.proftpd.org/docs/contrib/mod_quotatab.html)」の下の「# LoadModule mod_quotatab.c」のコメントアウトを外します。
# Quota support (http://www.proftpd.org/docs/contrib/mod_quotatab.html) # LoadModule mod_quotatab.c LoadModule mod_quotatab.c
「# SQL database "driver" for storing quota table information in SQL table」の2行下の「# LoadModule mod_quotatab_sql.c」のコメントアウトを外します。
# SQL database "driver" for storing quota table information in SQL tables # (http://www.proftpd.org/docs/contrib/mod_quotatab_sql.html) # LoadModule mod_quotatab_sql.c LoadModule mod_quotatab_sql.c
「# LoadModule mod_ifsession.c」の直下あたりに以下追記します。
# 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 ##--@Disabled@--##SQLHomedirOnDemand on # ここだけonにするとproftpdが起動しなかったのでコメントアウト # 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
あとはトラブル時の切り分けのため「ExtendedLog /var/log/proftpd/proftpd.log all」あたりを先頭くらいに付け加えてみてもよいでしょう。
■ proftpd起動
上記設定が終わったらproftpdをデーモンとして起動します。
$ sudo chkconfig proftpd on $ sudo chkconfig proftpd --list $ sudo service proftpd start
バージョン確認とモジュール一覧表示をしてみます。
$ sudo /usr/sbin/proftpd -vv ProFTPD Version: 1.3.3g (maint) Scoreboard Version: 01040003 Built: Thu Sep 10 2015 18:30:06 UTC Loaded modules: mod_quotatab_sql.c mod_quotatab/1.3.0 mod_sql_mysql/4.0.8 mod_sql/4.2.5 mod_lang/0.9 mod_ctrls/0.9.4 mod_cap/1.0 mod_vroot/0.9.2 mod_tls/2.4.2 mod_auth_pam/1.1 mod_readme.c mod_ident/1.0 mod_dso/0.5 mod_facts/0.1 mod_delay/0.6 mod_site.c mod_log.c mod_ls.c mod_auth.c mod_auth_file/0.8.3 mod_auth_unix.c mod_xfer.c mod_core.c
■ ftpgroupテーブルに実UID、実GIDをマッピングするデータを投入
$ mysql ftp -e "INSERT INTO \`ftpgroup\` (\`groupname\`, \`gid\`, \`members\`) VALUES ('ftpgroup', 2001, 'ftpuser');"
mysqlのシェルからはこんな感じでどうぞ。
INSERT INTO `ftpgroup` (`groupname`, `gid`, `members`) VALUES ('ftpgroup', 2001, 'ftpuser');
■ ftpquotalimitsテーブルにクォータ設定データを投入
$ mysql ftp -e "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 ('exampleuser', 'user', 'true', 'hard', 15728640, 0, 0, 0, 0, 0);"
mysqlのシェルからはこんな感じでどうぞ。
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 ('exampleuser', 'user', 'true', 'hard', 15728640, 0, 0, 0, 0, 0);
■ ftpuserテーブルにユーザーデータを投入
$ mysql ftp -e "INSERT INTO \`ftpuser\` (\`id\`, \`userid\`, \`passwd\`, \`uid\`, \`gid\`, \`homedir\`, \`shell\`, \`count\`, \`accessed\`, \`modified\`) VALUES (1, 'exampleuser', 'secret', 2001, 2001, '/home/www.example.com', '/sbin/nologin', 0, '', '');"
mysqlのシェルからはこんな感じでどうぞ。
INSERT INTO `ftpuser` (`id`, `userid`, `passwd`, `uid`, `gid`, `homedir`, `shell`, `count`, `accessed`, `modified`) VALUES (1, 'exampleuser', 'secret', 2001, 2001, '/home/www.example.com', '/sbin/nologin', 0, '', '');
■ ディレクトリ作成
FTPユーザーのホームディレクトリを作成し、オーナーをMySQLのユーザーとマッピングしているUNIXユーザーのオーナーとグループに変更します。
$ sudo mkdir -p /home/www.example.com $ sudo chown 2001:2001 /home/www.example.com
■ 確認
ここまでできたら設定を確認してみましょう。
$ mysql ftp -e "SELECT * FROM ftpgroup;" +-----------+------+---------+ | groupname | gid | members | +-----------+------+---------+ | ftpgroup | 2001 | ftpuser | +-----------+------+---------+
$ mysql ftp -e "SELECT * FROM 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 | +-------------+------------+-------------+------------+----------------+-----------------+------------------+----------------+-----------------+------------------+ | exampleuser | user | true | hard | 15728640 | 0 | 0 | 0 | 0 | 0 | +-------------+------------+-------------+------------+----------------+-----------------+------------------+----------------+-----------------+------------------+
$ mysql ftp -e "SELECT * FROM ftpquotatallies;" +-------------+------------+---------------+----------------+-----------------+---------------+----------------+-----------------+ | name | quota_type | bytes_in_used | bytes_out_used | bytes_xfer_used | files_in_used | files_out_used | files_xfer_used | +-------------+------------+---------------+----------------+-----------------+---------------+----------------+-----------------+ | exampleuser | user | 0 | 0 | 0 | 0 | 0 | 0 | +-------------+------------+---------------+----------------+-----------------+---------------+----------------+-----------------+
$ mysql ftp -e "SELECT * FROM ftpuser;" +----+-------------+--------+------+------+-----------------------+---------------+-------+---------------------+---------------------+ | id | userid | passwd | uid | gid | homedir | shell | count | accessed | modified | +----+-------------+--------+------+------+-----------------------+---------------+-------+---------------------+---------------------+ | 1 | exampleuser | secret | 2001 | 2001 | /home/www.example.com | /sbin/nologin | 18 | 2015-11-07 02:53:26 | 2015-11-07 02:56:32 | +----+-------------+--------+------+------+-----------------------+---------------+-------+---------------------+---------------------+
あとはFTPクライアントから接続できればOKです。なお、ユーザー単位でのクォータは0ですが、1セッションあたり15MBの転送制限があります。
■ テーブルのカラム解説
以下ザックリですがテーブルを解説を。
ftpuserテーブル
userid | proftpdのバーチャルユーザー名 |
passwd | proftpdバーチャルユーザーのパスワード (※ クリアテキストで格納されます。暗号化はご随意に!) |
uid | proftpdバーチャルユーザーの実UID |
gid | proftpdバーチャルユーザーの実GID |
homedir | proftpdバーチャルユーザーのホームディレクトリ(実際のPATH) |
shell | proftpdバーチャルユーザーのシェル(デフォルトは /sbin/nologin ) |
ftpquotalimitsテーブル
name | proftpdのバーチャルユーザー名 |
quota_type | userかgroupで選択。通常はuser。 |
per_session | 1セッションあたりのquota制限をするかどうかを選択。trueかfalseの2択。上記の例だとアップロード時に15MBを超えると制限がかかる。 |
limit_type | ソフトリミットかハードリミットを選択。 |
bytes_in_avail | アップロード時のquota上限をバイト数で指定。0で無制限。 |
bytes_out_avail | ダウンロード時のquota上限をバイト数で指定。0で無制限。 |
bytes_xfer_avail | 転送量のquota上限をバイト数で指定。0で無制限。 |
files_in_avail | アップロードするファイル数を指定。0で無制限。 |
files_out_avail | ダウンロードするファイル数を指定。0で無制限。 |
files_xfer_avail | 転送するファイル数を指定。0で無制限。 |
これだけのテーブルがあってどれが優先されるかまでは未検証です!><
いかがでしたでしょうか。案外簡単でしたね。でわ〜。
[amazonjs asin="4774151432" locale="JP" title="プロのための Linuxシステム・10年効く技術 (Software Design plus)"]
[参考URI]
Virtual Hosting With Proftpd And MySQL (Incl. Quota) On Fedora 9