vsftpd配置过程

摘要:本文介绍如何使用 vsftpd 配置 FTP 服务器,同时介绍 vsftpd 的配置选项以及常用的使用方法。

目标

假设我们有若干用户:alicebob。每个用户需要有若干目录访问权限,而且这些目录分布并不一致,比如

  • alice: 允许且仅允许访问 /var/test1/var/www/alice_test
  • bob: 允许且仅允许访问 /var/test2/var/www/bob_test

安装

我们的环境是 centos,安装步骤很简单,参考

1
2
3
yum install vsftpd
systemctl start vsftpd
systemctl enable vsftpd

这里我们根据默认的端口配置防火墙

1
2
3
firewall-cmd --zone=public --permanent --add-port=21/tcp
firewall-cmd --zone=public --permanent --add-service=ftp
firewall-cmd --reload

这时候我们可以尝试匿名访问 ftp 服务器,应该是可以访问成功的。

用户

vsftpd 使用的是系统的用户,所以我们这里在 Linux 中创建用户。

假设我们已经有用户组 ftp,这个用户组拥有所有需求中文件夹的权限,然后我们也希望所有用户都加入到该组中。

创建用户目录

我们首先为每个用户创建用户目录,也意味着每个用户登陆 FTP 服务器后后将会只看到这个目录。

1
2
mkdir /var/alice_home
mkdir /var/bob_home

加入用户

1
2
useradd --home /var/alice_home --gid ftp alice
useradd --home /var/bob_home --gid ftp bob

这里也可以使用 -m 选项同时创建用户目录。

也可以使用 --shell /bin/false 将不允许用户使用 shell

如果是已有用户,可以将其加入到 ftp 组中

1
usermod -a -G groupName userName

The -a (append) switch is essential. Otherwise, the user will be removed from any groups, not in the list.

The -G switch takes a (comma-separated) list of additional groups to assign the user to.

为用户添加或修改 home 目录

1
usermod -m -d /newhome/username username

我们需要确保用户主目录的权限正确,这个目录应该归属 username:ftp, 所以我们修改其 owner

1
2
chown -R /var/alice_home alice:ftp
chown -R /var/bob_home bob:ftp

配置

首先我们备份原有配置文件

1
cp /etc/vsftpd/vsftpd.conf /etc/vsftpd/vsftpd.conf.orig

然后开始配置

基本配置

1
2
3
4
5
6
7
8
9
10
11
12
13
anonymous_enable=NO             # disable  anonymous login
local_enable=YES # permit local logins
write_enable=YES # enable FTP commands which change the filesystem
local_umask=022 # value of umask for file creation for local users
dirmessage_enable=YES # enable showing of messages when users first enter a new directory
xferlog_enable=YES # a log file will be maintained detailing uploads and downloads
connect_from_port_20=YES # use port 20 (ftp-data) on the server machine for PORT style connections
xferlog_std_format=YES # keep standard log file format
listen=NO # prevent vsftpd from running in standalone mode
listen_ipv6=YES # vsftpd will listen on an IPv6 socket instead of an IPv4 one
pam_service_name=vsftpd # name of the PAM service vsftpd will use
userlist_enable=YES # enable vsftpd to load a list of usernames
tcp_wrappers=YES # turn on tcp wrappers

这里我们处理修改禁止匿名访问外,保留了所有的选项。

配置用户权限

userlist_enableuserlist_deny 的组合使用。

userlist_deny
This option is examined if userlist_enable is activated. If you
set this setting to NO, then users will be denied login unless
they are explicitly listed in the file specified by
userlist_file. When login is denied, the denial is issued
before the user is asked for a password.

  Default: YES

userlist_enable
If enabled, vsftpd will load a list of usernames, from the file-
name given by userlist_file. If a user tries to log in using a
name in this file, they will be denied before they are asked for
a password. This may be useful in preventing cleartext passwords
being transmitted. See also userlist_deny.

  Default: NO

也就是说,userlist_enable 本身是希望禁用列表中的用户的访问的,所以默认是关闭的,一旦打开需要指定一个用户列表 userlist_file=/etc/vsftpd.userlist,然后这个列表中的用户将无法访问服务器。

但是如果我们希望放过来,只让用户列表中的用户访问呢?那么可以借助userlist_deny 配置项,其默认是 YES,也就是 Deny 列表中的用户,但是如我们设为 No,那么将 Deny 所有不是列表中的用户。

By default, users listed in userlist_file=/etc/vsftpd.userlist are denied login access with userlist_deny option set to YES, if userlist_enable=YES.

However, userlist_deny=NO alters the setting, meaning that only users explicitly listed in userlist_file=/etc/vsftpd.userlist will be permitted to login.

所以我们最终关于用户访问权限的配置为

1
2
3
userlist_enable=YES
userlist_file=/etc/vsftpd.userlist
userlist_deny=NO

同时需要创建用户列表文件并添加用户

1
2
3
touch /etc/vsftpd.userlist
echo "alice" | tee -a /etc/vsftpd.userlist
echo "bob" | tee -a /etc/vsftpd.userlist

这时候只有 alicebob 可以访问 FTP 服务器了。

配置用户访问目录权限

这时候实际上用户是可以访问自己的 home 目录了,但是由于我们设置allow_writeable_chroot=YES,所以存在安全隐患

Warning: Using allow_writeable_chroot=YES has certain security implications, especially if the users have upload permission, or shell access.
Only activate this option if you exactly know what you are doing. It’s important to note that these security implications arenot vsftpd specific, they apply to all FTP daemons which offer to put local users in chroot jails as well.

Therefore, we will look at a more secure way of setting a different non-writable local root directory in the next section.

参考1:https://blog.csdn.net/bluishglc/article/details/42398811
参考2:http://os.51cto.com/art/201008/221842_all.htm

这里用是有两个选项,有点类似于前面用户列表:chroot_local_userchroot_list_enable

chroot_local_user #是否将所有用户限制在主目录,YES为启用 NO禁用.(该项默认值是NO,即在安装vsftpd后不做配置的话,ftp用户是可以向上切换到要目录之外的)

chroot_list_enable #是否启动限制用户的名单 YES为启用 NO禁用(包括注释掉也为禁用,也就是默认是禁用)

这两个选项的组合参考下表

chroot_local_user=yes chroot_local_user=no
chroot_list_enable=yes 1 所有用户限制在主目录下,列表用户作为例外不受限制 3 所有用户不受限制,列表用户作为例外受限制
chroot_list_enable=no 2 所有用户限制在主目录下,没有例外 4 所有用户不受限制,没有例外

这里我们并不需要由用户可以访问除了主目录的其他目录,所以选择配置2:

1
2
chroot_local_user=YES
chroot_list_enable=NO #或者不写即默认

用户指定任意不同的目录访问权限

参考1:http://www.ducea.com/2006/07/27/allowing-ftp-access-to-files-outside-the-home-directory-chroot/
参考2:https://serverfault.com/a/566336

这里我们使用 mount 的方式,将任意目录 mount 到用户的 home 目录,同时注意目录权限,用户需要有适当的权限于目标目录。

1
2
3
4
mkdir /var/alice_home/test1
mkdir /var/alice_home/alice_test
mount --bind /var/test1 /var/alice_home/test1
mount --bind /var/www/alice_test /var/alice_home/alice_test

这里 mount --bind 目标目录 主目录下的目录,如果需要修改 mount 的目标目录,只需要重新 绑定就可以了。

总结

至此,配置完成,用户 alicebob 只能访问自己的主目录,同时主目录有两个其他的任意目录,具体的读写权限和 Linux 用户与用户组的权限一致,可以通过 ls -al 来查看,也可以通过 chmod 来修改对应的权限。