在Debian Buster中配置vsFtpd并使用虚拟用户

本文参考了 /usr/share/doc/vsftpd 中的 README 文档

环境配置

使用 apt 包管理器安装配置必要软件包
apt install db-util vsftpd
此处 db-util 工具用来生成虚拟用户的 db 数据库文件,vsftpd 则为 ftp 服务器

配置 vsftpd 主程序

首先备份原有的 vstpd.conf 主程序
mv /etc/vsftpd.conf /etc/vsftpd.conf.bak

在 /usr/share/doc/vsftpd 中的 examples 文件夹找到我们所需的配置文件示例,这里是 VIRTUAL_USERS
将里面的 vsftpd.conf 考到 /etc/vsftpd.conf 中,然后对其进行一些修改
cp /usr/share/doc/vsftpd/examples/VIRTUAL_USERS/vsftpd.conf vsftpd.conf

anonymous_enable=NO #是否允许访客访问(若选项为 YES,则登录的时候不会询问用户名和密码)
local_enable=YES #允许本地用户登录该服务器

此处删除是因为可以加在用户独立的配置文件中

write_enable=NO #可写?
anon_upload_enable=NO #可上传
anon_mkdir_write_enable=NO #可新建文件夹?
anon_other_write_enable=NO #可有其他的写权限?编辑,重命名,删除)

chroot_local_user=YES #限制用户只能在主目录活动
guest_enable=YES #允许访客用户
guest_username=virtftp #访客用户名 此处对应 linux 系统中的用户
listen=YES #使 vsftpd 运行在 stand-alone 模式下
listen_port=10021 #设置监听端口,此处我不需要所以删除
pasv_min_port=30000 #pasv 安全模式下的最小端口
pasv_max_port=30999 #pasv 安全模式下的最大端口

同时,我们也可以加一点有趣的东西

pasv_enable=NO #是否启用 pasv 安全模式
max_per_ip=3 #每个 ip 的最大连接数
max_clients=100 #配置最大连接数

接着,使用 useradd 命令创建一个 ftp 用的账户
useradd -s /sbin/nologin -d /data/ftp_data virtftp
因为不需要该用户登录 shell,所以给的 shell 是 nologin
然后创建该用户的家目录并赋权
mkdir -p /data/ftp_data
chown virtftp:virtftp /data/ftp_data
为了安全起见,修改一下家目录的权限
chmod 700 /data/ftp_data

配置 vsftpd 虚拟用户数据库

由于此处文件较多,我新建一个文件夹 /etc/vsftpd 并将所有的配置文件链接并放置至其中

新建一个 txt 文件,隔行写上用户名和密码

ftpuser
password
ftpadmin
password

然后使用 db-util 工具将其封装为 db 数据库文件
db_load -T -t hash -f 刚刚写有用户名的txt文件 vlogin.db
安全起见,给该文件 600 权限
chmod 600 vlogin.db

配置 pam 认证模块

默认的 pam 认证是使用系统用户,这边将其替换成 userdb 模块
将 vsftpd 提供的样板 pam 文件替换现有的
cp /usr/share/doc/vsftpd/examples/VIRTUAL_USERS/vsftpd.pam /etc/pam.d/vsftpd
注意!pam.d 中的文件名不能修改,否则系统不会读
方便起见,做一条软连接到 /etc/vsftpd 目录
ln -s /etc/pam.d/vsftpd /etc/vsftpd.vu

查看该文件的内容,可以发现其调用了一个叫 pam_userdb 的模块

auth required **/lib/security/pam_userdb.so** db=/etc/vsftpd_login
account required **/lib/security/pam_userdb.so** db=/etc/vsftpd_login

但是这个模块并不存在,所以我们需要自行搜索该模块的位置并修改路径

root@ServerA:/etc/vsftpd# find / -name pam_userdb.so
**/usr/lib/x86_64-linux-gnu/security/pam_userdb.so**

此处我的环境路径在 /usr/lib/x86_64-linux-gnu/security/pam_userdb.so
替换 pam 文件,并修改其 db 的目录(注意不需要后缀)
此处是我的 pam 文件示例

auth required /usr/lib/x86_64-linux-gnu/security/pam_userdb.so db=/etc/vsftpd/vlogin
account required /usr/lib/x86_64-linux-gnu/security/pam_userdb.so db=/etc/vsftpd/vlogin

配置 vsftpd 虚拟用户

新建一个文件夹,用于存放虚拟用户的配置文件
mkdir /etc/vsftpd/ftp_user
建立并配置用户配置文件
常用参数如下

write_enable=YES #可写?
anon_upload_enable=YES #可上传
anon_mkdir_write_enable=YES #可新建文件夹?
anon_other_write_enable=YES #可有其他的写权限?编辑,重命名,删除)
local_umask=022 #配置 umask

接着,在 vsftpd.conf 主配置文件中添加一段参数以对接这个文件夹中的用户配置

user_config_dir=/etc/vsftpd/ftp_user

然后,重启 vsftpd 服务,然后使用客户端链接

GiriNeko-Laptop:/mnt/c/Users/GiriN# ftp
ftp> open 192.168.250.102
Connected to 192.168.250.102.
220 (vsFTPd 3.0.3)
Name (192.168.250.102:root): ftpuser
331 Please specify the password.
Password:
500 OOPS: vsftpd: refusing to run with writable root inside chroot()
Login failed.
421 Service not available, remote server has closed connection

可以看到,这边我们没有办法列出当前文件,这是因为我们没有赋予其读权限
可以在全局配置文件或者用户配置文件中添加 anon_world_readable_only=NO 参数
添加后,重启 vsftpd 服务
再连接 ftp 服务测试

ftp> close
221 Goodbye.
ftp> open 192.168.250.102
Connected to 192.168.250.102.
220 (vsFTPd 3.0.3)
Name (192.168.250.102:root): ftpuser
331 Please specify the password.
Password:
500 OOPS: vsftpd: refusing to run with writable root inside chroot()
Login failed.
421 Service not available, remote server has closed connection

现在连登录都不行了,这是因为我们指定 ftp 只能在 root 目录活动,但是 root 目录有写权限,所以就会报错
参考这篇文章
这时只需要再添加一个参数 allow_writeable_chroot=YES 即可

测试

现在我创建了 ftpuser 和 ftpadmin 两个账户,前者具有上传下载权限,后者在前者的基础上多了编辑及删除权限

ftpuser 部分

GiriNeko-Laptop:/mnt/c/Users/GiriN# ftp
ftp> open 192.168.250.102
Connected to 192.168.250.102.
220 (vsFTPd 3.0.3)
Name (192.168.250.102:root): ftpuser
331 Please specify the password.
Password:
230 Login successful.
Remote system type is UNIX.
Using binary mode to transfer files.
ftp> ls
200 PORT command successful. Consider using PASV.
150 Here comes the directory listing.
226 Directory send OK.
ftp> mkdir 123
257 "/123" created
ftp> ls
200 PORT command successful. Consider using PASV.
150 Here comes the directory listing.
drwx------    2 1001     1001         4096 Mar 11 01:59 123
226 Directory send OK.
ftp> rm 123
550 Permission denied.
ftp> bye
221 Goodbye.

ftpadmin 部分

GiriNeko-Laptop:/mnt/c/Users/GiriN# ftp
ftp> open 192.168.250.102
Connected to 192.168.250.102.
220 (vsFTPd 3.0.3)
Name (192.168.250.102:root): ftpadmin
331 Please specify the password.
Password:
230 Login successful.
Remote system type is UNIX.
Using binary mode to transfer files.
ftp> ls
200 PORT command successful. Consider using PASV.
150 Here comes the directory listing.
drwx------    2 1001     1001         4096 Mar 11 01:59 123
226 Directory send OK.
ftp> mkdir 321
257 "/321" created
ftp> rm 123
250 Remove directory operation successful.
ftp> ls
200 PORT command successful. Consider using PASV.
150 Here comes the directory listing.
drwx------    2 1001     1001         4096 Mar 11 02:00 321
226 Directory send OK.
ftp> bye
221 Goodbye.

本文链接:https://blog.ineko.cc/Setup-vsFTPd-In-Debian_Buster-with-virtualuser.html
本博客遵循CC BY-NC-SA 3.0协议进行许可.