RHEL6: FTP Server - VSFTPD

FTP是最经典的网络服务(之一),就是用来传文件啦。
暑假的时候一同学在Win7上折腾了半天FTP没搞成(估计是防火墙?),而在Linux上整个FTP Server是件很轻松的事情。
推荐使用vsftpd作为FTP server,因为它Very Secure,关键是简单易用。

参考文档

1. 鸟哥Linux私房菜-FTP http://linux.vbird.org/linux_server/0410vsftpd.php
2. vsftpd文档 https://security.appspot.com/vsftpd/vsftpd_conf.html
3. Redhat Document FTP and SELinux https://access.redhat.com/documentation/en-US/Red_Hat_Enterprise_Linux/6/html/Managing_Confined_Services/chap-Managing_Confined_Services-File_Transfer_Protocol.html

实验环境

1. Server和Client操作系统均为RHEL6.5;
2. Server机的IP地址是192.168.122.30;
3. Client机的IP地址是192.168.122.92;


安装

在Server端,安装vsftpd.

[root@localhost ~]# yum install vsftpd

在Client端,安装ftp.(还有很多ftp client可以选择~)

[root@main ~]# yum install ftp


简单配置

基本上vsftpd安装好启动就能使用。
现在只要配置pasv的端口,iptables和SELinux,就可以测试了。

vsftpd.conf

在/etc/vsftpd/vsftpd.conf的最后添加参数。
规定被动模式时使用5000-5100之间的端口传输数据。

pasv_min_port=5000
pasv_max_port=5100

保存配置,重启。

iptables

在iptables加上规则,允许FTP的流量通过。
修改/etc/sysconfig/iptables,在中间加上两行

-A INPUT -m state --state NEW -m tcp -p tcp --dport 21 --sport 1024:65534 -j ACCEPT
-A INPUT -m state --state NEW -m tcp -p tcp --dport 5000:5100 --sport 1024:65534 -j ACCEPT

或者如果不想指定pasv传输的端口范围,可以修改/etc/sysconfig/iptables-config 这个module能动态放行ftp传输端口。

IPTABLES_MODULES="nf_conntrack_ftp"

SELinux

如果用实体用户登录,默认会转到该用户的家目录下。
但SELinux不会让ftp进入到这个目录下。想要实体用户登录能顺利进入它的家目录,需要进行如下设置。

[root@localhost ~]# setsebool -P ftp_home_dir=1

要让匿名用户能上传,需要开放

[root@s2 ~]# setsebool -P allow_ftpd_anon_write=on
[root@s2 ~]# chcon -t public_content_rw_t /var/ftp/pub/ -R

其他相关bool请参考 ftpd_selinux 文档。

测试

在Client端进行测试。
1. 用anonymous登录(匿名登录),尝试下载文件;
2. 用实体用户(feichashao)进行登录,尝试下载文件;

[root@main ~]# ftp 192.168.122.30
Connected to 192.168.122.30 (192.168.122.30).
220 (vsFTPd 2.2.2)
Name (192.168.122.30:root): anonymous
331 Please specify the password.
Password:
230 Login successful.
Remote system type is UNIX.
Using binary mode to transfer files.
ftp> ls
227 Entering Passive Mode (192,168,122,30,19,192).
150 Here comes the directory listing.
-rw-r--r--    1 0        0               0 Dec 05 06:46 aaa
-rw-r--r--    1 0        0               0 Dec 05 06:47 bbb
drwxr-xr-x    2 0        0            4096 Feb 12  2013 pub
226 Directory send OK.
ftp> get aaa
local: aaa remote: aaa
227 Entering Passive Mode (192,168,122,30,19,188).
150 Opening BINARY mode data connection for aaa (0 bytes).
226 Transfer complete.
ftp> bye
221 Goodbye.
[root@main ~]# ftp 192.168.122.30
Connected to 192.168.122.30 (192.168.122.30).
220 (vsFTPd 2.2.2)
Name (192.168.122.30:root): feichashao
331 Please specify the password.
Password:
230 Login successful.
Remote system type is UNIX.
Using binary mode to transfer files.
ftp> pwd
257 "/home/feichashao"
ftp> ls
227 Entering Passive Mode (192,168,122,30,19,145).
150 Here comes the directory listing.
-rw-rw-r--    1 500      500             0 Dec 05 06:47 homefile1
226 Directory send OK.
ftp> get homefile1
local: homefile1 remote: homefile1
227 Entering Passive Mode (192,168,122,30,19,168).
150 Opening BINARY mode data connection for homefile1 (0 bytes).
226 Transfer complete.
ftp> bye
221 Goodbye.

Chroot

chroot可以帮助保护server的安全,就算别人攻破了你的FTP,也只能在chroot后的根下进行操作。
修改vsftpd.conf,设置chroot相关参数。

chroot_local_user=YES
chroot_list_enable=YES
chroot_list_file=/etc/vsftpd/chroot_list

/etc/vsftpd/chroot_list需要自己创建,把不需要chroot的用户一个一行地写进这个文件里。(文件必须要存在,我里面暂时留白)
重启vsftpd服务。

测试

1.尝试用anonymous登录,试试能不能切换到系统根目录;
2.尝试用实体用户feichashao登录,试试能不能切换到系统根目录;

[root@main ~]# ftp 192.168.122.30
Connected to 192.168.122.30 (192.168.122.30).
220 (vsFTPd 2.2.2)
Name (192.168.122.30:root): anonymous
331 Please specify the password.
Password:
230 Login successful.
Remote system type is UNIX.
Using binary mode to transfer files.
ftp> pwd
257 "/"
ftp> ls
227 Entering Passive Mode (192,168,122,30,19,165).
150 Here comes the directory listing.
-rw-r--r--    1 0        0               0 Dec 05 06:46 aaa
-rw-r--r--    1 0        0               0 Dec 05 06:47 bbb
drwxr-xr-x    2 0        0            4096 Feb 12  2013 pub
226 Directory send OK.
ftp> bye
221 Goodbye.

匿名用户登录FTP后,能看到当前目录是“根目录”,但实际上/var/ftp/这个目录。

[root@main ~]# ftp 192.168.122.30
Connected to 192.168.122.30 (192.168.122.30).
220 (vsFTPd 2.2.2)
Name (192.168.122.30:root): feichashao
331 Please specify the password.
Password:
230 Login successful.
Remote system type is UNIX.
Using binary mode to transfer files.
ftp> pwd
257 "/"
ftp> ls
227 Entering Passive Mode (192,168,122,30,19,233).
150 Here comes the directory listing.
-rw-rw-r--    1 500      500             0 Dec 05 06:47 homefile1
226 Directory send OK.
ftp> bye
221 Goodbye.

同样,实体用户登录,它看到的“根目录”实际是自己的家目录。


带宽、用户数量限制

服务器的能力是有限的,联网的带宽也是有限的。如果用户一下子涌进来拼命下载,服务器会hold不住的。
当然,可以配置VSFTPD来限制最高下载速度,同一IP的登录用户数等。
设置anon_max_rate,可以限制匿名用户的下载速率,比如anon_max_rate=5000,限制匿名用户的下载速率为5KB/s.
设置local_max_rate,可以限制实体用户的下载速率,比如local_max_rate=100000,限制实体用户的下载速率为1MB/s.
max_clients可以设置最高用户数,max_per_ip可以设置每个IP的最多用户数。


允许/拒绝特定用户访问

1. 只允许userlist列出的用户访问ftp;
修改/etc/vsftpd/vsftpd.conf

userlist_enable=YES
userlist_deny=NO
userlist_file=/etc/vsftpd/userlist

编辑/etc/vsftpd/userlist 加上允许访问用户的名单。

ftpuser1
ftpuser2

重启vsftpd。
在Client中测试。

[root@feichashao ~]# ftp 192.168.122.108
Connected to 192.168.122.108 (192.168.122.108).
220 (vsFTPd 2.2.2)
Name (192.168.122.108:root): ftpuser1
331 Please specify the password.
Password:
230 Login successful.
Remote system type is UNIX.
Using binary mode to transfer files.
ftp> bye
221 Goodbye.

[root@feichashao ~]# ftp 192.168.122.108
Connected to 192.168.122.108 (192.168.122.108).
220 (vsFTPd 2.2.2)
Name (192.168.122.108:root): ftpuser3
530 Permission denied.
Login failed.

2. 拒绝userlist列出的用户,允许其他用户。
将/etc/vsftpd/userlist 中的userlist_deny改为YES,就会拒绝userlist列出的用户。

userlist_enable=YES
userlist_deny=YES
userlist_file=/etc/vsftpd/userlist

重启,测试。

[root@feichashao ~]# ftp 192.168.122.108
Connected to 192.168.122.108 (192.168.122.108).
220 (vsFTPd 2.2.2)
Name (192.168.122.108:root): ftpuser1
530 Permission denied.
Login failed.
ftp> bye
221 Goodbye.

[root@feichashao ~]# ftp 192.168.122.108
Connected to 192.168.122.108 (192.168.122.108).
220 (vsFTPd 2.2.2)
Name (192.168.122.108:root): ftpuser3
331 Please specify the password.
Password:
230 Login successful.
Remote system type is UNIX.
Using binary mode to transfer files.
ftp> bye
221 Goodbye.


为用户定制的配置

VSFTPD可以给不同用户不同的配置。比如,不同的用户有不同的速率限制,不同的用户使用不同的数据传输端口。
1. 修改/etc/vsftpd/vsftpd.conf文件,加上以下配置。

user_config_dir=/etc/vsftpd/user_config_dir/

/etc/vsftpd/user_config_dir/ 这个目录需要自行建立,当然也可以制定其他目录。
在该目录下,可以建立以用户名为名的配置文件。比如,对feichashao这个用户的配置,应该写在/etc/vsftpd/user_config_dir/feichashao这个文件当中。
比如,/etc/vsftpd/user_config_dir/feichashao中可以加上 local_max_rate=0, 那么feichashao这个用户下载就没有速度限制啦。要注意的是,用户配置文件里没有指定的参数,还是会按全局的参数进行。


IP-Based VSFTPD

基于用户的配置简单吧。那么基于IP地址的配置呢?
比如,我想让192.168.122.0/24这个网段的用户获得最高1M的下载速度;让192.168.100.0/24这个网段的用户获得最高2M的下载速度,应该怎么做?

那就要借助TCP Wrapper啦。它可以匹配服务和IP,进行特定的操作。

在 /etc/vsftpd/vsftpd.conf 中,确认

tcp_wrappers=YES

在 /etc/hosts.allow 中加入

vsftpd:192.168.122.0/255.255.255.0:setenv VSFTPD_LOAD_CONF /etc/vsftpd/vsftpd122.conf
vsftpd:192.168.100.0/255.255.255.0:setenv VSFTPD_LOAD_CONF /etc/vsftpd/vsftpd100.conf

在/etc/vsftpd/vsftpd122.conf文件中,写入anon_max_rate=1000000 ;
在/etc/vsftpd/vsftpd100.conf文件中,写入anon_max_rate=2000000 ;


Troubleshooting

1. No route to host.
检查两机之间能否ping通,如果能,检查iptable是否开放了FTP的端口(21端口和数据端口)。

2. 500 OOPS: cannot change directory:/home/feichashao
检查SELinux。

3. 不能上传文件
检查目录/文件读写权限,检查selinux。