Posted at

【写経】ProFTPDでバーチャルユーザ

More than 3 years have passed since last update.


TL;DR


  • とある用件で前知識が必要になったので、雑に検証する事が主目的

  • ProFTPD 一つで FTP/SFTP を提供できる事が分かった

  • ProFTPD は chroot するホームディレクトリを自動で作れる事が分かった

  • ProFTPD はデータベースにレコードを追加するだけで FTP/SFTP アカウントを発行できることが分かった


目標

ProFTPD を使って PostgreSQL で管理するバーチャルユーザで FTP と SFTP できる様にします。

運用に耐えられる設定になっているかは問題としません(棚上げ)。


インストール

Amazon Linux を使って EC2 インスタンスを用意します。

$ sudo yum install --enablerepo=epel -y proftpd postgresql94 proftpd-postgresql


PostgreSQL の準備


サーバ

RDS を利用するので省略。


アカウントテーブル

=> CREATE TABLE ftp_users (

user_id VARCHAR(20) NOT NULL,
passwd VARCHAR(20) NOT NULL
);
=> INSERT INTO ftp_users VALUES('user1', 'password');


DB接続ユーザ

=> CREATE USER nobody PASSWORD 'password';

=> GRANT SELECT ON ftp_users TO nobody;


ProFTPD と mod_sql


設定

$ sudo cp /etc/proftpd.conf /etc/proftpd.conf.orig

$ sudo vi /etc/proftpd.conf
$ sudo diff -u /etc/proftpd.conf.orig /etc/proftpd.conf
--- /etc/proftpd.conf.orig 2015-09-19 08:42:17.080279438 +0000
+++ /etc/proftpd.conf 2015-09-19 10:40:17.947791730 +0000
@@ -19,7 +19,7 @@

# Use pam to authenticate (default) and be authoritative
AuthPAMConfig proftpd
-AuthOrder mod_auth_pam.c* mod_auth_unix.c
+# AuthOrder mod_auth_pam.c* mod_auth_unix.c
# If you use NIS/YP/LDAP you may need to disable PersistentPasswd
#PersistentPasswd off

@@ -46,6 +46,25 @@
LogFormat default "%h %l %u %t \"%r\" %s %b"
LogFormat auth "%v [%P] %h %t \"%r\" %s"

+MasqueradeAddress 54.65.XXX.YYY
+PassivePorts 60001 60010
+LoadModule mod_sql.c
+LoadModule mod_sql_postgres.c
+<IfModule mod_sql_postgres.c>
+ SQLAuthenticate users
+ SQLAuthTypes Plaintext
+ SQLBackend postgres
+ SQLConnectInfo proftpd@proftpd.cpc1qsv2t7us.ap-northeast-1.rds.amazonaws.com:5432 nobody password
+ SQLLogFile /var/log/proftpd/sql.log
+ SQLUserInfo ftp_users user_id passwd Null Null Null Null
+ SQLDefaultUID 500
+ SQLDefaultGID 500
+ SQLDefaultHomedir "/home/ec2-user/"
+ CreateHome on
+ RequireValidShell off
+ AuthOrder mod_sql.c
+</IfModule>
+
# Dynamic Shared Object (DSO) loading
# See README.DSO and howto/DSO.html for more details
#


起動

$ sudo /sbin/service proftpd start


接続

ftp user1@54.65.XXX.YYY

Connected to 54.65.XXX.YYY.
220 FTP Server ready.
331 Password required for user1
Password:
230 User user1 logged in
Remote system type is UNIX.
Using binary mode to transfer files.
ftp> ls -al
229 Entering Extended Passive Mode (|||60006|)
150 Opening ASCII mode data connection for file list
drwx------ 3 user1 500 4096 Sep 19 10:44 .
drwx------ 3 user1 500 4096 Sep 19 10:44 ..
-rw-r--r-- 1 user1 500 18 Mar 4 2015 .bash_logout
-rw-r--r-- 1 user1 500 176 Mar 4 2015 .bash_profile
-rw-r--r-- 1 user1 500 124 Mar 4 2015 .bashrc
-rw------- 1 user1 500 658 Sep 19 09:49 .psql_history
drwx------ 2 user1 500 4096 Sep 19 08:29 .ssh
226 Transfer complete
ftp> put ~/test.txt ./test.txt
local: /Users/koshigoe/test.txt remote: ./test.txt
229 Entering Extended Passive Mode (|||60007|)
150 Opening BINARY mode data connection for ./test.txt
100% |****************************************************************************************************************************| 5 38.75 KiB/s 00:00 ETA
226 Transfer complete
5 bytes sent in 00:00 (0.28 KiB/s)


SFTP


設定

$ sudo cp /etc/proftpd.conf /etc/proftpd.conf.psql

$ sudo vi /etc/proftpd.conf
$ sudo diff -u /etc/proftpd.conf.psql /etc/proftpd.conf
--- /etc/proftpd.conf.psql 2015-09-19 10:47:04.221939858 +0000
+++ /etc/proftpd.conf 2015-09-19 10:55:37.965440674 +0000
@@ -65,6 +65,17 @@
AuthOrder mod_sql.c
</IfModule>

+LoadModule mod_sftp.c
+<IfModule mod_sftp.c>
+ SFTPEngine on
+ SFTPLog /var/log/proftpd/sftp.log
+
+ SFTPAuthMethods password
+ SFTPHostKey /etc/ssh/ssh_host_rsa_key
+ SFTPHostKey /etc/ssh/ssh_host_dsa_key
+ Port 2222
+</IfModule>
+
# Dynamic Shared Object (DSO) loading
# See README.DSO and howto/DSO.html for more details
#


再起動

$ sudo /sbin/service proftpd restart


接続

$ sftp -P 2222 user1@54.65.XXX.YYY -vvvv

user1@54.65.XXX.YYY's password:
Connected to 54.65.XXX.YYY.
sftp> ls
test.txt
sftp> put test.txt a.txt
Uploading test.txt to /a.txt
test.txt 100% 5 0.0KB/s 00:00


おまけ:ホームディレクトリ


ホームディレクトリカラムを追加

=> ALTER TABLE ftp_users ADD COLUMN homedir VARCHAR(255);

=> UPDATE ftp_users SET homedir='/home/ec2-user/user1' WHERE user_id='user1';
=> ALTER TABLE ftp_users ALTER COLUMN homedir SET NOT NULL;


設定

$ sudo cp /etc/proftpd.conf /etc/proftpd.conf.sftp

$ sudo vi /etc/proftpd.conf
--- /etc/proftpd.conf.sftp 2015-09-19 11:04:48.908558616 +0000
+++ /etc/proftpd.conf 2015-09-19 11:14:46.145880479 +0000
@@ -56,7 +56,7 @@
SQLBackend postgres
SQLConnectInfo proftpd@proftpd.cpc1qsv2t7us.ap-northeast-1.rds.amazonaws.com:5432 nobody password
SQLLogFile /var/log/proftpd/sql.log
- SQLUserInfo ftp_users user_id passwd Null Null Null Null
+ SQLUserInfo ftp_users user_id passwd Null Null homedir Null
SQLDefaultUID 500
SQLDefaultGID 500
SQLDefaultHomedir "/home/ec2-user/"


  • ディレクトリがなければ作る設定 CreateHome on は先の手順で設定済み

  • ホームディレクトリ用カラム homedir を使う様に SQLUserInfo の該当欄を Null から homedir に変更した


確認

$ sftp -P 2222 user1@54.65.XXX.YYY

user1@54.65.XXX.YYY's password:
Permission denied, please try again.
user1@54.65.XXX.YYY's password:
Connected to 54.65.XXX.YYY.
sftp> ls -al
drwx------ 2 user1 500 4096 Sep 19 11:14 .
drwx------ 2 user1 500 4096 Sep 19 11:14 ..

[ec2-user@ip-172-31-12-219 ~]$ ls /home/ec2-user

a.txt test.txt user1


まとめ


  • PostgreSQL で FTP/SFTP のアカウントを管理する事ができました

  • ProFTPD で FTP/SFTP を利用する事ができました

  • chroot するディレクトリを自動で作らせる事ができました


棚上げした課題


  • FTP と SFTP でアカウントが同一になっている

  • ProFTPD の設定に PostgreSQL の接続情報を埋め込んでいる

  • ユーザテーブルに平文パスワードを保存している

  • chroot するホームディレクトリのパーミッションまわりが適当

  • アカウントの UID/GID が適当

  • SFTP のポート番号の設定場所が適当(バーチャルホストで分けてない)

  • SFTP のホスト鍵が適当

  • ディレクトリの自動作成はセキュリティ的にどう考えるべき なのか


参考