ProFTPDとMySQLの仮想ホスティング構成
目的
- ProFTPDのLocal/Remoteのエンコーディング指定を可能にするパッチ適用
- MySQLと連携した仮想ホスティング(Linux上にユーザ登録しないでFTPユーザ作成)
- ProFTPDにはQuotaも組み込み
本当はapt-getで出来るだけ簡単導入してProFTPDのパッチのみを適用する形にしたかったが、MySQLもビルドしないとうまくいかなったので、とりあえずはその作業内容を残します。
※以前の情報では何とか出来上がった手順を載せていましたが、玄箱PROを組みなおす機会があったのでこうしんしました。ポイントはconfigureやmakeに何か足りずに失敗したらwget直後からやり直すことですね・・・変にconfigureしたものやmakeしたものが残っていると何がうまくいって何がうまくいっていないのか分からなくなりました・・・
導入するバージョン
MySQL 4.1.21
ProFTPD 1.3.0
MySQLの導入
ビルドに必要なパッケージを導入してからの手順です。
# apt-get install make gcc g++ zlib1g-dev libcdk5-dev
# groupadd mysql
# useradd -g mysql -d /usr/local mysql
# cd /usr/local/src
# wget http://downloads.mysql.com/archives/mysql-4.1/mysql-4.1.21.tar.gz
# tar zxvf mysql-4.1.21.tar.gz
# cd mysql-4.1.21
#/mysql-4.1.21# ./configure \
--with-charset=utf8 \
--with-extra-charsets=all \
--with-mysqld-user=mysql
# make
make終了まで2時間ほど待機。
make install には以下3つのパッケージが必要です。
# apt-get install autoconf2.13
# apt-get install automake1.4
# apt-get install libtool
# make install
# cp support-files/my-small.cnf /etc/my.cnf
# /usr/local/bin/mysql_install_db
# chmod -R 777 /usr/local/var
MySQLの初期設定
<password>にはrootとして使用するパスワードをmysqladminで設定します。
その後mysqlデータベースに接続します。
# su mysql
# /usr/local/bin/mysqld_safe &
# /usr/local/bin/mysqladmin -u root password <password>
# /usr/local/bin/mysql -u root -p mysql
Enter password:
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 2 to server version: 4.1.21-log
Type 'help;' or '\h' for help. Type '\c' to clear the buffer.
mysql> DELETE FROM user WHERE password='';
Query OK, 3 rows affected (0.00 sec)
mysql> select user, host, password from mysql.user;
+------+-----------+-------------------------------------------+
| user | host | password |
+------+-----------+-------------------------------------------+
| root | localhost | *EX4858XB86EXA20BX33X0AECXE8AX108X56BX7FA |
+------+-----------+-------------------------------------------+
1 row in set (0.00 sec)
mysql> exit
Bye
# exit
システム起動時に自動実行されるようにupdate-rc.dで/etc/init.d/mysqlをdefaultsで登録する。
# cp /usr/local/src/mysql-4.1.21/support-files/mysql.server \
/etc/init.d/mysql
# chmod +x /etc/init.d/mysql
# update-rc.d mysql defaults
ProFTPDの導入
サーバのエンコーディングとクライアントのエンコーディングが指定できるmod_codeconvを組み込んでビルドします。
# apt-get install patch
# groupadd proftpd
# useradd -g proftpd -d /dev/null -s /usr/sbin/nologin proftpd
# cd /usr/local/src
# wget ftp://ftp.proftpd.org/distrib/source/proftpd-1.3.0.tar.gz
# wget http://www.hakusan.tsg.ne.jp/tjkawa/software/misc/proftpd-iconv/\
pack/proftpd-1.3.0-iconv.patch.gz
# wget http://www.hayasoft.com/haya/linux/proftpd-nlst-patch/\
proftpd-1.3.0-nlst-ffftp.patch
# tar -zxvf proftpd-1.3.0.tar.gz
# gzip -d proftpd-1.3.0-iconv.patch.gz
# patch -p0 < proftpd-1.3.0-iconv.patch
# patch -p0 < proftpd-1.3.0-nlst-ffftp.patch
# cd /usr/local/src/proftpd-1.3.0
# ./configure --prefix=/usr/local \
--with-modules=mod_codeconv:mod_df\
:mod_sql:mod_sql_mysql:mod_quotatab:mod_quotatab_sql \
--with-libraries=/usr/local/lib/mysql \
--with-includes=/usr/local/include/mysql \
--disable-auth-pam
# make
# make install
導入されたproftpdに組み込まれたモジュールを確認します。mod_codeconv, mod_sql, mod_sql_mysql, mod_quotatab, mod_quotatab_sqlがあることを確認してください。
# proftpd -l
Compiled-in modules:
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_delay.c
mod_codeconv.c
mod_df.c
mod_sql.c
mod_sql_mysql.c
mod_quotatab.c
mod_quotatab_sql.c
mod_cap.c
# mkdir /var/log/proftpd
# chown -R proftpd:proftpd /var/log/proftpd/
# vi /etc/init.d/proftpd
proftpd起動用シェルを作成します。Debianのapt-getで導入されるシェルをそのまま使用します。
#!/bin/sh
# Start the proftpd FTP daemon.
PATH=/bin:/usr/bin:/sbin:/usr/sbin
DAEMON=/usr/sbin/proftpd
NAME=proftpd
# Defaults
RUN="yes"
OPTIONS=""
PIDFILE=`grep -i 'pidfile' /usr/local/etc/proftpd.conf | \
sed -e 's/pidfile[\t ]\+//i'`
if [ "x$PIDFILE" = "x" ];
then
PIDFILE=/usr/local/var/proftpd.pid
fi
# Read config (will override defaults)
[ -r /etc/default/proftpd ] && . /etc/default/proftpd
trap "" 1
trap "" 15
#test -f $DAEMON || exit 0
#
# These compatibility funcs are here just for sarge backports.
# They will be removed post-etch.
#
log_daemon_msg() {
echo -n "$1: $2"
}
log_end_msg() {
if [ $1 -ne 0 ]; then
echo " failed!"
else
echo "."
fi
}
[ -f /lib/lsb/init-functions ] && . /lib/lsb/init-functions
#
# Servertype could be inetd|standalone|none.
# In all cases check against inetd and xinetd support.
#
if ! egrep -qi "^[[:space:]]*ServerType.*standalone" \
/usr/local/etc/proftpd.conf
then
if [ $(dpkg-divert --list xinetd|wc -l) -eq 1 ]
then
if egrep -qi "server[[:space:]]*=[[:space:]]*/usr/sbin/proftpd" \
/etc/xinetd.conf 2>/dev/null || \
egrep -qi "server[[:space:]]*=[[:space:]]*/usr/sbin/proftpd" \
/etc/xinetd.d/* 2>/dev/null
then
RUN="no"
INETD="yes"
else
if ! egrep -qi "^[[:space:]]*ServerType.*inetd" \
/usr/local/etc/proftpd.conf
then
RUN="yes"
INETD="no"
else
RUN="no"
INETD="no"
fi
fi
else
if egrep -qi "^ftp.*/usr/sbin/proftpd" /etc/inetd.conf 2>/dev/null
then
RUN="no"
INETD="yes"
else
if ! egrep -qi "^[[:space:]]*ServerType.*inetd" \
/usr/local/etc/proftpd.conf
then
RUN="yes"
INETD="no"
else
RUN="no"
INETD="no"
fi
fi
fi
fi
# /var/run could be on a tmpfs
[ ! -d /var/run/proftpd ] && mkdir /var/run/proftpd
start()
{
log_daemon_msg "Starting ftp server" "$NAME"
start-stop-daemon --start --quiet --pidfile "$PIDFILE" --exec $DAEMON \
-- $OPTIONS
if [ $? != 0 ]; then
log_end_msg 1
exit 1
else
log_end_msg 0
fi
}
signal()
{
if [ "$1" = "stop" ]; then
SIGNAL="TERM"
log_daemon_msg "Stopping ftp server" "$NAME"
else
if [ "$1" = "reload" ]; then
SIGNAL="HUP"
log_daemon_msg "Reloading ftp server" "$NAME"
else
echo "ERR: wrong parameter given to signal()"
exit 1
fi
fi
if [ -f "$PIDFILE" ]; then
start-stop-daemon --stop --signal $SIGNAL --quiet --pidfile \
"$PIDFILE"
if [ $? = 0 ]; then
log_end_msg 0
else
SIGNAL="KILL"
start-stop-daemon --stop --signal $SIGNAL --quiet \
--pidfile "$PIDFILE"
if [ $? != 0 ]; then
log_end_msg 1
[ $2 != 0 ] || exit 0
else
log_end_msg 0
fi
fi
if [ "$SIGNAL" = "KILL" ]; then
rm -f "$PIDFILE"
fi
else
log_end_msg 0
fi
}
case "$1" in
start)
if [ "x$RUN" = "xyes" ] ; then
start
else
if [ "x$INETD" = "xyes" ] ; then
echo "ProFTPd is started from inetd/xinetd."
else
echo "ProFTPd warning: cannot start neither \
in standalone nor in inetd/xinetd mode. Check \
your configuration."
fi
fi
;;
force-start)
if [ "x$INETD" = "xyes" ] ; then
echo "Warning: ProFTPd is started from inetd/xinetd \
(trying to start anyway)."
fi
start
;;
stop)
if [ "x$RUN" = "xyes" ] ; then
signal stop 0
else
if [ "x$INETD" = "xyes" ] ; then
echo "ProFTPd is started from inetd/xinetd."
else
echo "ProFTPd warning: cannot start neither \
in standalone nor in inetd/xinetd mode. Check \
your configuration."
fi
fi
;;
force-stop)
if [ "x$INETD" = "xyes" ] ; then
echo "Warning: ProFTPd is started from inetd/xinetd \
(trying to kill anyway)."
fi
signal stop 0
;;
reload)
signal reload 0
;;
force-reload|restart)
if [ "x$RUN" = "xyes" ] ; then
signal stop 1
sleep 2
start
else
if [ "x$INETD" = "xyes" ] ; then
echo "ProFTPd is started from inetd."
else
echo "ProFTPd warning: cannot start neither \
in standalone nor in inetd/xinetd mode. Check \
your configuration."
fi
fi
;;
*)
echo "Usage: /etc/init.d/$NAME {start|force-start|stop|\
force-stop|reload|restart|force-reload}"
exit 1
;;
esac
exit 0
# chmod +x /etc/init.d/proftpd
# update-rc.d proftpd defaults
# mkdir /var/lock/subsys/
# touch /var/lock/subsys/proftpd
# ln -s /usr/local/sbin/proftpd /usr/sbin/proftpd
# vi /usr/local/etc/proftpd/proftpd.conf
proftpd.confを編集して下記をファイル上部に貼り付けます。
CharsetLocal UTF-8
CharsetRemote CP932
ServerIdent on ""
RootLogin off
ListOptions "-la"
DefaultRoot ~ !wheel
RequireValidShell off
UseReverseDNS off
IdentLookups off
TimesGMT off
TimeoutIdle 600
TimeoutLogin 300
TimeoutNoTransfer 600
TimeoutStalled 600
ShowSymlinks on
MaxClientsPerHost 2
MaxHostsPerUser 1
LogFormat allinfo "%t : %u (%a [%h]) : [%s], %T, %m (%f)"
LogFormat write "%t : %u : %F (%a)"
LogFormat read "%t : %u : %F (%a)"
LogFormat auth "%t : %u (%a [%h])"
ExtendedLog /var/log/proftpd/all.log ALL allinfo
ExtendedLog /var/log/proftpd/write.log WRITE write
ExtendedLog /var/log/proftpd/read.log READ read
ExtendedLog /var/log/proftpd/auth.log AUTH auth
<Directory /*>
AllowOverwrite on
AllowStoreRestart on
AllowRetrieveRestart on
</Directory>
ファイルの最後にMySQLとの連携とQuotaの設定を追加します。Anonymousブロックは必要に応じてコメントしておきます。
<IfModule mod_sql_mysql.c>
SQLAuthenticate users
SQLConnectInfo proftpd@localhost:3306 proftpd proftpd
SQLAuthTypes Crypt
SQLUserInfo users userid password uid gid homedir shell
SQLGroupInfo groups groupname gid members
AuthOrder mod_sql.c
</IfModule>
<IfModule mod_quotatab.c>
QuotaEngine on
QuotaLog /var/log/proftpd/quota-log
QuotaLimitTable sql:/get-quota-limit
QuotaTallyTable sql:/get-quota-tally/update-quota-tally/\
insert-quota-tally
SQLNamedQuery get-quota-limit SELECT "userid, 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 quotalimits WHERE userid = '%{0}' \
AND quota_type = '%{1}'"
SQLNamedQuery get-quota-tally SELECT "userid, quota_type, \
bytes_in_used, bytes_out_used, bytes_xfer_used, files_in_used, \
files_out_used, files_xfer_used FROM quotatallies WHERE \
userid = '%{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 userid = '%{6}' \
AND quota_type = '%{7}'" quotatallies
SQLNamedQuery insert-quota-tally INSERT "%{0}, %{1}, %{2}, \
%{3}, %{4}, %{5}, %{6}, %{7}" quotatallies
QuotaLock /tmp/proftpd-quota-lock
QuotaShowQuotas on
QuotaDisplayUnits Gb
QuotaDirectoryTally on
</IfModule>
仮想ユーザの登録
仮想ユーザをproftpdデータベースに登録します。
# chown -R mysql:mysql /usr/local/var/
# mysql -u root -p
Enter password:
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 55 to server version: 4.1.21-log
Type 'help;' or '\h' for help. Type '\c' to clear the buffer.
mysql> create database proftpd;
mysql> CREATE TABLE groups (
groupname VARCHAR(30) NOT NULL ,
gid SMALLINT(5) UNSIGNED NOT NULL DEFAULT 1000,
members varchar(255) default NULL,
PRIMARY KEY ( groupname ),
UNIQUE KEY gid (gid)
);
mysql> CREATE TABLE users (
userid varchar(30) NOT NULL,
password varchar(30) NOT NULL,
uid SMALLINT(5) UNSIGNED NOT NULL DEFAULT 1000,
gid SMALLINT(5) UNSIGNED NOT NULL DEFAULT 1000,
homedir varchar(255) default NULL,
shell varchar(255) default '/bin/true',
PRIMARY KEY (userid),
UNIQUE KEY uid (uid)
);
mysql> CREATE TABLE quotalimits (
userid VARCHAR(30) NOT NULL,
quota_type ENUM("user", "group", "class", "all") NOT NULL,
per_session ENUM("false", "true") DEFAULT 'true' NOT NULL,
limit_type ENUM("soft", "hard") DEFAULT 'soft' NOT NULL,
bytes_in_avail FLOAT DEFAULT '0' NOT NULL,
bytes_out_avail FLOAT DEFAULT '0' NOT NULL,
bytes_xfer_avail FLOAT DEFAULT '0' NOT NULL,
files_in_avail INT UNSIGNED DEFAULT '0' NOT NULL,
files_out_avail INT UNSIGNED DEFAULT '0' NOT NULL,
files_xfer_avail INT UNSIGNED DEFAULT '0' NOT NULL
);
mysql> CREATE TABLE quotatallies (
userid VARCHAR(30) NOT NULL,
quota_type ENUM("user", "group", "class", "all") DEFAULT 'user' NOT NULL,
bytes_in_used FLOAT DEFAULT '0' NOT NULL,
bytes_out_used FLOAT DEFAULT '0' NOT NULL,
bytes_xfer_used FLOAT DEFAULT '0' NOT NULL,
files_in_used INT UNSIGNED DEFAULT '0' NOT NULL,
files_out_used INT UNSIGNED DEFAULT '0' NOT NULL,
files_xfer_used INT UNSIGNED DEFAULT '0' NOT NULL
);
mysql> GRANT SELECT,UPDATE,INSERT ON proftpd.*
TO proftpd@localhost IDENTIFIED BY 'proftpd';
mysql> INSERT INTO groups VALUES ('testgroup',1000,'');
mysql> INSERT INTO users VALUES (
'testuser',encrypt('testuser'),1001,1000,'/var/ftpdata','/bin/true');
mysql> INSERT INTO quotalimits VALUES (
'testuser','user','false','hard', 524288000,0,0,0,0,0);
ProFTPdを起動してFTPで接続確認を行います。
# /etc/init.d/mysql restart
# /etc/init.d/proftpd restart
ルータ配下の玄箱PROでFTPサーバ提供する際のNAT問題
- 玄箱PROはルータ配下で稼動し割り当てられているIPアドレスはプライベートアドレス
- グローバルアドレスが割り当てられているルータからはポート番号(21)指定で玄箱PROへポート転送
- 家庭内のプライベートアドレスからFTP接続
- インターネット越しのグローバルIPアドレスからのFTP接続
- インターネット越しかつルータ配下のプライベートアドレスからのFTP接続
これらを実現するための設定がProFTPDでは可能であるようです。
proftpd.confに以下の設定を追加します。
MasqueradeAddress <domain-name | global-ipaddr>
PassivePorts <min-port-number> <max-port-number>
私の環境ではDynamicDNSを使用しているので登録されているドメイン名を<domain-name | global-ipaddr>に設定しました。これでStandalone時は起動時にIPアドレスを取得する動作をします。常時稼動でIPアドレスの動的変更に対応する場合はinetdにした方が良さそうです。
ポート番号はPassive接続で使用するポートの最小と最大で参考程度に私は10020 10034と15ほど取って設定しました。(MaxInstancesを15に設定したので)
この設定にあわせてPassice接続を受け付けるためにルータのポート転送設定に10020-10034を追加します。
追加したproftpd.confの設定でPASVコマンドに対してMasqueradeAddressで指定したアドレスで応答されるようになるため、プライベートアドレスを返されて接続先が分からない、といった状況にならなくなります。
あとはルータに設定したポート転送で玄箱PROに転送されてくればPassive接続完了です。
ただし、この設定ではPassive接続するとグローバルアドレスで応答されるため、家庭内ではPassive接続できません。Port接続のみ可能となります。
中ではPort接続、外ではPassive接続という使い分けになります。
関連パッケージ
KUROBOX-PRO:~# apt-get install libcdk5-dev
Reading package lists... Done
Building dependency tree... Done
The following extra packages will be installed:
libc6-dev libcdk5 libncurses5-dev linux-kernel-headers
Suggested packages:
glibc-doc manpages-dev
Recommended packages:
gcc c-compiler
The following NEW packages will be installed:
libc6-dev libcdk5 libcdk5-dev libncurses5-dev linux-kernel-headers
0 upgraded, 5 newly installed, 0 to remove and 15 not upgraded.
1 not fully installed or removed.
Need to get 1856kB/5843kB of archives.
After unpacking 27.1MB of additional disk space will be used.
Do you want to continue [Y/n]?
KUROBOX-PRO:~# apt-get install gcc
Reading package lists... Done
Building dependency tree... Done
The following extra packages will be installed:
binutils cpp cpp-4.1 gcc-4.1 libssp0
Suggested packages:
binutils-doc cpp-doc gcc-4.1-locales make manpages-dev autoconf automake1.9 libtool
flex bison gdb gcc-doc gcc-4.1-doc
Recommended packages:
libmudflap0-dev
The following NEW packages will be installed:
binutils cpp cpp-4.1 gcc gcc-4.1 libssp0
0 upgraded, 6 newly installed, 0 to remove and 15 not upgraded.
Need to get 16.6kB/4915kB of archives.
After unpacking 12.3MB of additional disk space will be used.
Do you want to continue [Y/n]?
KUROBOX-PRO:~# apt-get install make
Reading package lists... Done
Building dependency tree... Done
Suggested packages:
make-doc-non-dfsg
The following NEW packages will be installed:
make
0 upgraded, 1 newly installed, 0 to remove and 15 not upgraded.
Need to get 0B/381kB of archives.
After unpacking 1229kB of additional disk space will be used.
KUROBOX-PRO:~# apt-get install make
Reading package lists... Done
Building dependency tree... Done
Suggested packages:
make-doc-non-dfsg
The following NEW packages will be installed:
make
0 upgraded, 1 newly installed, 0 to remove and 15 not upgraded.
Need to get 0B/381kB of archives.
After unpacking 1229kB of additional disk space will be used.
KUROBOX-PRO:~# apt-get install g++
Reading package lists... Done
Building dependency tree... Done
The following extra packages will be installed:
g++-4.1 libstdc++6-4.1-dev
Suggested packages:
gcc-4.1-doc libstdc++6-4.1-doc
The following NEW packages will be installed:
g++ g++-4.1 libstdc++6-4.1-dev
0 upgraded, 3 newly installed, 0 to remove and 15 not upgraded.
Need to get 3408kB of archives.
After unpacking 11.7MB of additional disk space will be used.
Do you want to continue [Y/n]?
KUROBOX-PRO:~# apt-get install zlib1g-dev
Reading package lists... Done
Building dependency tree... Done
The following NEW packages will be installed:
zlib1g-dev
0 upgraded, 1 newly installed, 0 to remove and 15 not upgraded.
Need to get 0B/410kB of archives.
After unpacking 602kB of additional disk space will be used.
KUROBOX-PRO:/usr/local/src# apt-get install patch
Reading package lists... Done
Building dependency tree... Done
Suggested packages:
diff-doc
The following NEW packages will be installed:
patch
0 upgraded, 1 newly installed, 0 to remove and 15 not upgraded.
Need to get 0B/101kB of archives.
After unpacking 197kB of additional disk space will be used.
KUROBOX-PRO:~# apt-get install autoconf2.13
Reading package lists... Done
Building dependency tree... Done
The following extra packages will be installed:
autoconf m4
Suggested packages:
autobook autoconf-archive gnu-standards autoconf-doc
Recommended packages:
automaken automake1.4
The following NEW packages will be installed:
autoconf autoconf2.13 m4
0 upgraded, 3 newly installed, 0 to remove and 15 not upgraded.
Need to get 976kB of archives.
After unpacking 3547kB of additional disk space will be used.
Do you want to continue [Y/n]?
KUROBOX-PRO:~# apt-get install automake1.4
Reading package lists... Done
Building dependency tree... Done
The following extra packages will be installed:
autotools-dev
The following NEW packages will be installed:
automake1.4 autotools-dev
0 upgraded, 2 newly installed, 0 to remove and 15 not upgraded.
Need to get 333kB of archives.
After unpacking 1163kB of additional disk space will be used.
Do you want to continue [Y/n]?
KUROBOX-PRO:~# apt-get install libtool
Reading package lists... Done
Building dependency tree... Done
Suggested packages:
libtool-doc automaken g77 fortran77-compiler gcj
Recommended packages:
libltdl3-dev
The following NEW packages will be installed:
libtool
0 upgraded, 1 newly installed, 0 to remove and 15 not upgraded.
Need to get 328kB of archives.
After unpacking 950kB of additional disk space will be used.
Get:1 http://ftp.jaist.ac.jp etch/main libtool 1.5.22-4 [328kB]
Fetched 328kB in 0s (679kB/s)
Selecting previously deselected package libtool.
(Reading database ... 17513 files and directories currently installed.)
Unpacking libtool (from .../libtool_1.5.22-4_arm.deb) ...
Setting up libtool (1.5.22-4) ...
KUROBOX-PRO:/usr/local/src#
最終更新日:2007-05-29
最終更新:2007年05月29日 14:00