1 需求
可以上传文件的非匿名FTP服务器,用来上传网站程序。要把访问限制在特定目录,最好可以实现数据加密传输。
2 系统
系统环境:Debian 7
FTP服务器:vsftpd 2.3.5
3 配置
vsftpd可使用系统用户或虚拟用户作为登录账户。我最终使用虚拟用户作为FTP账户,所有虚拟用户都会映射到一个实际的系统用户。下面先创建这个系统用户。
3.1 账户
3.1.1 添加vsftpd专用账户
注意,-m参数是必须的。虽然你可能不用这个用户的家目录,但如果没它,登录FTP账户的时候就会报“500 OOPS: cannot change directory:/home/virtual”错误。
# useradd -m -s /usr/sbin/nologin virtual
3.1.2 添加虚拟账户及密码
首先要创建一个文本文件,格式是每行交替写上用户名或密码:
用户1 密码1 用户2 密码2
简单起见,我只添加一个用户foo,保存到logins.txt文件中:
foo bar
接下来生成PAM数据库文件:
# db5.1_load -T -t hash -f logins.txt /etc/vsftpd_login.db
3.1.3 其他配置
创建PAM文件,用来鉴定用户。把下面内容保存在/etc/pam.d/vsftpd-virtual
中。
auth required pam_userdb.so db=/etc/vsftpd_login account required pam_userdb.so db=/etc/vsftpd_login
给每个用户设定自己的上传目录并相应设置权限。foo目录作为FTP根目录,upload作为文件上传目录。因为vsftpd不允许chroot的目录具有写权限,因此不把foo作为文件上传目录。upload要存放网站文件,因此apache的用户www-data必须有它的读写权限。我的实现方式是把www-data加入virtual用户组,并给予virtual用户组完全权限(读取、写入、执行)。
# mkdir -p /var/www/foo/upload # chown virtual.virtual /var/www/foo/upload # chmod 775 /var/www/foo/upload # chmod -aG virtual www-data
3.2 配置vsftpd
vsftpd可以给每个用户使用不同的配置。为了多用户使用的灵活性,我们采用这种配置方式。首先建立保存用户配置文件的目录:
# mkdir /etc/vsftpd_user_conf
3.2.1 全局配置
打开/etc/vsftpd.conf
文件,替换为下面内容。
listen=YES connect_from_port_20=NO pasv_enable=YES pasv_max_port=50100 pasv_min_port=50001 max_clients=5 max_per_ip=4 write_enable=NO anonymous_enable=NO anon_upload_enable=NO anon_mkdir_write_enable=NO anon_other_write_enable=NO local_enable=YES pam_service_name=vsftpd-virtual guest_enable=YES guest_username=virtual user_config_dir=/etc/vsftpd_user_conf/ user_sub_token=$USER local_root=/var/www/$USER chroot_local_user=YES file_open_mode=0666 local_umask=022 anon_umask=022 hide_ids=YES xferlog_enable=YES secure_chroot_dir=/var/run/vsftpd/empty
- listen=YES
- 让vsftpd独立运行,不通过inetd之类的软件调用。
- connect_from_port_20=NO
- 不从TCP 20端口传输数据。
- pasv_enable=YES
pasv_max_port=50100
pasv_min_port=50001 - 允许被动模式并设置被动模式的端口范围(方便设置防火墙)。
- max_clients=5
- 允许连接的客户端数量。
- max_per_ip=4
- 同一IP允许连接的客户端数量。
- write_enable=NO
- 禁止所有修改文件系统的操作。
- anonymous_enable=NO
anon_upload_enable=NO
anon_mkdir_write_enable=NO
anon_other_write_enable=NO - 禁用匿名用户,禁止匿名用户上传、创建文件夹、写入(修改和删除等操作)。
- local_enable=YES
- 允许本地用户登录。使用虚拟用户必须把此选项设为YES。
- pam_service_name=vsftpd-virtual
- 指出vsftpd将要使用的PAM服务名称。注意“vsftpd-virtual”是在3.1.3 其他配置一节创建的PAM文件名。
- guest_enable=YES
guest_username=virtual - 激活虚拟用户,并把所有虚拟用户映射到系统用户“virtual”。
- user_config_dir=/etc/vsftpd_user_conf/
- 存储用户配置文件目录。
- user_sub_token=$USER
local_root=/var/www/$USER - 让每个用户使用自己单独的家目录,并在连接FTP时自动切换到此目录。
- chroot_local_user=YES
- 把用户限制在自己的家目录中。
- file_open_mode=0666
- 设置文件基准权限为666。
- local_umask=022
- 本地用户(local user)创建文件时应用的umask值。目录的基准权限是777,文件的基准权限在上面设置成了666,应用022这个umask之后,最终的目录权限是755,文件权限是644。
- anon_umask=022
- 匿名用户创建文件时应用的umask值。
- hide_ids=YES
- 在FTP客户端中隐藏文件所有者的真实信息。
- xferlog_enable=YES
- 保存文件传输日志。日志文件在/var/log目录,名称是vsftpd.log。
- secure_chroot_dir=/var/run/vsftpd/empty
- 当vsftpd不需要文件系统访问权限时,用作安全chroot jail的目录。
3.2.2 单用户配置
创建/etc/vsftpd_user_conf/foo,写入下面内容。由于虚拟用户默认作为匿名用户对待,因此修改的都是匿名用户的选项。777的目录权限和666的文件权限应用002这个umask之后,最终的权限是目录775,文件664。这样apache就对上传的文件具有读写权限,可以作为网站文件使用。
write_enable=YES anon_upload_enable=YES anon_mkdir_write_enable=YES anon_other_write_enable=YES anon_umask=002
4 防火墙
需要在防火墙允许20、50001-50100这些TCP端口。我使用iptables作为防火墙,配置命令如下:
iptables -A INPUT -p tcp --dport 21 -j ACCEPT iptables -A INPUT -p tcp --dport 50001:50100 -j ACCEPT
5 存在的问题
5.1 未实现加密传输。
5.2 apache创建的文件,所有者和用户组都是www-data,权限644,用户通过FTP登录后无法操作这些文件。使用ACL可解决此问题,迟些时候会另写一篇文章进行讨论。
6 参考文档
6.1 vsftpd示例配置及说明,在/usr/share/doc/vsftpd/examples/
目录。
6.2 man vsftpd.conf
6.3 What is Umask and How To Setup Default umask Under Linux?
Visits: 307