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


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    [email protected]: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 [email protected]
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 [email protected] -vvvv
[email protected]'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    [email protected]: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 [email protected]
[email protected]'s password:
Permission denied, please try again.
[email protected]'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 のホスト鍵が適当
  • ディレクトリの自動作成はセキュリティ的にどう考えるべき なのか

参考