★backend vsftpdサーバ×2

vi /etc/vsftpd/vsftpd.conf

pasv_enable=YES
pasv_min_port=60000
pasv_max_port=60001
pasv_address=lb.x.x.x

 

★frontend nginxサーバ

vi nginx.conf

stream {
#FTP
upstream ftp {
hash $remote_addr;
server vsftpd.nilesflow.net:21 weight=5 max_fails=3 fail_timeout=30s;
server aws-default.nilesflow.net:21 weight=5 max_fails=3 fail_timeout=30s;
# server pure-ftpd.nilesflow.net:10021 weight=5 max_fails=3 fail_timeout=30s;
}

server {
listen 20021;
proxy_connect_timeout 1s;
# proxy_timeout 3s;
proxy_pass ftp;
}

#FTP data
upstream ftpdata-v1 {
hash $remote_addr;
server vsftpd.nilesflow.net:60000 weight=5 max_fails=3 fail_timeout=30s;
server aws-default.nilesflow.net:60000 weight=5 max_fails=3 fail_timeout=30s;
}
upstream ftpdata-v2 {
server vsftpd.nilesflow.net:60001 weight=5 max_fails=3 fail_timeout=30s;
server aws-default.nilesflow.net:60001 weight=5 max_fails=3 fail_timeout=30s;
}

# vsftpd
server {
listen 60000;
proxy_connect_timeout 1s;
proxy_timeout 3s;
proxy_pass ftpdata-v1;
}
server {
listen 60001;
proxy_connect_timeout 1s;
proxy_timeout 3s;
proxy_pass ftpdata-v2;
}

 

★どこかのサーバから

ftp lb.nilesflow.net 20021

 

★補足

pasv_address= ドメイン名ではなくIPアドレス

vi /etc/vsftpd/vsftpd.conf

pasv_enable=YES
pasv_min_port=60000
pasv_max_port=60001
pasv_address=x.x.x.x

vi /etc/pure-ftpd/pure-ftpd.conf

Bind                            z.z.z.z,10021

PassivePortRange          60010 60011

ForcePassiveIP x.x.x.x

 

vi nginx.conf

stream {
#FTP
upstream ftp {
hash $remote_addr;
server z.z.z.z:21 weight=5 max_fails=3 fail_timeout=30s; #v
server z.z.z.z:10021 weight=5 max_fails=3 fail_timeout=30s; #p
}

server {
listen 20021;
proxy_connect_timeout 1s;
# proxy_timeout 3s;
proxy_pass ftp;
}

#FTP data
upstream ftpdata-v1 {
server z.z.z.z:60000 weight=5 max_fails=3 fail_timeout=30s;
}
upstream ftpdata-v2 {
server z.z.z.z:60001 weight=5 max_fails=3 fail_timeout=30s;
}
upstream ftpdata-p1 {
server z.z.z.z:60010 weight=5 max_fails=3 fail_timeout=30s;
}
upstream ftpdata-p2 {
server z.z.z.z:60011 weight=5 max_fails=3 fail_timeout=30s;
}

# vsftpd
server {
listen 60000;
proxy_connect_timeout 1s;
proxy_timeout 3s;
proxy_pass ftpdata-v1;
}
server {
listen 60001;
proxy_connect_timeout 1s;
proxy_timeout 3s;
proxy_pass ftpdata-v2;
}

# pure-ftpd
server {
listen 60010;
proxy_connect_timeout 1s;
proxy_timeout 3s;
proxy_pass ftpdata-p1;
}
server {
listen 60011;
proxy_connect_timeout 1s;
proxy_timeout 3s;
proxy_pass ftpdata-p2;
}

stream {
#FTP
upstream ftp {
server 127.0.0.1:21 weight=5 max_fails=3 fail_timeout=30s;
server 127.0.0.1:10021 weight=5 max_fails=3 fail_timeout=30s;
}

server {
listen 20021;
proxy_connect_timeout 1s;
proxy_timeout 3s;
proxy_pass ftp;
}

 

と思ったら、vsftpd/pureftpd共に、Passiveコマンドで失敗している

227 Entering Passive Mode (160,16,117,208,47,254)
421 Service not available, remote server has closed connection

 

vsftpdは以下設定で回避できたが、

pasv_promiscuous=yes

 

pure-ftpdは回避できるオプションがなさそう。

 

 

同一サーバ、単一PHPから、

ログイン、chdir後、異なる5000ファイルをアップロード

 

vsftpd 3.0.3 from source

pure-ftpd v1.0.30 from yum install

 

pure-ftpdの方が早いみたい。。

 

vsftpd
num : 5000
total : 2.30912 s
one : 0.00046s/req

pure-ftpd
num : 5000
total : 2.0004 s
one : 0.0004s/req

yum -y install tcp_wrappers-devel.x86_64

yum install libcap-devel

 

wget https://security.appspot.com/downloads/vsftpd-3.0.3.tar.gz

tar xvzf vsftpd-3.0.3.tar.gz

cd vsftpd-3.0.3

 

vi vsf_findlibs.sh

vi builddefs.h

make

make install

 

vi /etc/init.d/vsftpd-3.0.3

 

postreqsql のインストール

yum install postgresql-server

# pam_pgsql をbuildするため

yum install postgresql-client

yum install postgresql-contrib

yum install postgresql-devel

 

pam_pgsqlのインストール

cd /usr/local/src/

wget https://github.com/pam-pgsql/pam-pgsql/archive/release-0.7.3.2.zip

unzip release-0.7.3.2.zip

cd pam-pgsql-release-0.7.3.2/

./autogen.sh

./configure –libdir=/lib64

#pamのlibが入っている

make

make install

# /usr/local/lib/security/pam_pgsql.so

 

vsftpd on postgresql

# su – postgres
-bash-4.1$ createuser vsftpd
新しいロールをスーパーユーザとしますか? (y/n)y
パスワード:

-bash-4.1$ psql -U postgres
ユーザ postgres のパスワード:

postgres=# alter user vsftpd with password ‘vsftpd’;
ALTER ROLE

-bash-4.1$ createdb vsftpd -U vsftpd
パスワード:

-bash-4.1$ psql -U vsftpd
ユーザ vsftpd のパスワード:

vsftpd=# CREATE TABLE “accounts”(
vsftpd(# “i_id” SERIAL,
vsftpd(# “s_username” VARCHAR(30) NOT NULL,
vsftpd(# “s_password” VARCHAR(50),
vsftpd(# “b_expired” BOOLEAN DEFAULT false,
vsftpd(# CONSTRAINT “accounts_s_username_key” UNIQUE(“s_username”)
vsftpd(# );
NOTICE: CREATE TABLEはシリアル列”accounts.i_id”用に暗黙的なシーケンス”accounts_i_id_seq”を作成します。
NOTICE: CREATE TABLE / UNIQUEはテーブル”accounts”に暗黙的なインデックス”accounts_s_username_key”を作成します
CREATE TABLE

vsftpd=# insert into accounts(s_username, s_password) values(‘xxxx’,md5(‘yyyyy’));

 

vsftpd設定

vi /etc/vsftpd/vsftpd.conf

pam_service_name=vsftpd

anonymous_enable=NO

virtual_use_local_privs=YES
guest_enable=YES
local_root=/home/nilesflow/vsftpd_root/$USER
hide_ids=YES
guest_username=nilesflow
user_sub_token=$USER

chroot_local_user=YES

dual_log_enable=YES
vsftpd_log_file=/var/log/vsftpd.log
log_ftp_protocol=YES

 

vsftpd pam設定

vi /etc/pam.d/vsftpd

auth required pam_pgsql.so config_file=/etc/pam_pgsql_vsftpd.conf
account required pam_pgsql.so config_file=/etc/pam_pgsql_vsftpd.conf

 

vsftpd pam postgresql 設定

vi /etc/pam_pgsql_vsftpd.conf

debug
pw_type = md5
connect = hostaddr=127.0.0.1 port=5432 dbname=xxxxx user=xxxxx password=xxxxx connect_timeout=15
auth_query = select s_password from accounts where s_username = %u
acct_query = select b_expired as acc_expired, 0 as acc_new_pwreq, (s_password ISNULL OR s_password = ”) as user_password from accounts where s_username = %u

 

ディレクトリ作成

mkdir /home/nilesflow/vsftpd_root/nilesflow

 

local_rootでディレクトリ自動作成できないのが。。。

 

ディレクトリ作成できないのは、直接 secutil.c をいじればできるが(以下適当)

retval = str_mkdir(p_ext_dir_str, 0775);
chmod(str_getbuf(p_ext_dir_str), 0775);
retval = chown(str_getbuf(p_ext_dir_str), 0, 0);