vsftpd 三种模式的配置

1. 安装

1
2
3
4
5
6
7
sudo apt install vsftpd
vsftpd -v # 截至本文发布日期,最新版为 v3.0.5

# sudo sed -i 's/listen_ipv6=YES/listen_ipv6=NO/' /etc/vsftpd.conf # 报 500 OOPS: could not bind listening IPv6 socket 错误时执行
sudo systemctl start vsftpd # 以守护进程模式运行
sudo systemctl enable vsftpd # 开机自启
sudo ufw allow 20:21/tcp comment FTP-Server # 放行端口

2. 认证模式

vsftpd作为更加安全的文件传输的服务程序,允许用户以三种认证模式登录到FTP服务器上。

认证模式 解释
匿名开放模式 是最不安全的认证模式,任何人都可以无需密码验证而直接登录到FTP服务器。
本地用户模式 是通过Linux系统本地的账户密码信息进行认证的模式,相较于匿名开放模式更安全,而且配置起来也很简单。但是如果被黑客破解了账户的信息,就有可能被登录FTP服务器(除非不给本地用户分配可登录shell)。
虚拟用户模式 是这三种模式中最安全的一种认证模式,它需要为FTP服务单独建立用户数据库文件,虚拟出用来进行口令验证的账户信息,而这些账户信息在服务器系统中实际上是不存在的,仅供FTP服务程序进行认证使用。这样,即使黑客破解了账户信息也无法登录服务器,从而有效降低了破坏范围和影响。

2.1 匿名开放模式

  1. 修改配置文件
1
2
3
4
5
6
7
8
9
sudo sed -i 's/anonymous_enable=NO/anonymous_enable=YES/' /etc/vsftpd.conf  # 匿名用户可登陆
sudo sed -i 's/#anon_upload_enable=YES/anon_upload_enable=YES/' /etc/vsftpd.conf # 匿名用户可上传
sudo sed -i 's/#anon_mkdir_write_enable=YES/anon_mkdir_write_enable=YES/' /etc/vsftpd.conf # 匿名用户可创建文件夹
echo anon_other_write_enable=YES | sudo tee -a /etc/vsftpd.conf # 匿名用户可删除和重命名文件和文件夹
echo anon_umask=022 | sudo tee -a /etc/vsftpd.conf # 匿名用户创建文件时的umask值
echo anon_root=/var/ftp/anonymous | sudo tee -a /etc/vsftpd.conf # 指定匿名用户的主目录, 默认为ftp用户的主目录/srv/ftp
echo no_anon_password=YES | sudo tee -a /etc/vsftpd.conf # 匿名用户跳过输入密码提示
echo pasv_min_port=50000 | sudo tee -a /etc/vsftpd.conf # 指定ftp被动模式下的最小端口号
echo pasv_max_port=50020 | sudo tee -a /etc/vsftpd.conf # 指定ftp被动模式下的最大端口号
  1. 创建ftp共享目录
1
2
3
4
sudo mkdir -p /var/ftp/anonymous/test  # 在匿名用户主目录下创建测试文件夹
sudo chmod a-w /var/ftp/anonymous # 匿名用户主目录必须去掉'写'权限,否则连接会失败报错(500 OOPS: vsftpd: refusing to run with writable root inside chroot)
sudo chown -R ftp:ftp /var/ftp/anonymous # 修改匿名用户主目录的所有者和所属组为安装vsftpd时自动创建的ftp用户及ftp组,控制访问权限
echo vsftpd test file | sudo tee /var/ftp/anonymous/test/test.txt # 创建测试文件
  1. 应用配置
1
sudo systemctl restart vsftpd ; sudo systemctl status vsftpd

本机连接测试

alt text

外网连接测试

由于FTP服务器被动模式的端口为随机端口(范围为前面指定的50000-50020),因此还需要放行此端口范围: sudo ufw allow 50000:50020/tcp

alt text

2.2 本地用户模式

使用本地用户模式则建议关闭匿名用户模式:

1
2
sudo sed -i 's/anonymous_enable=YES/anonymous_enable=NO/' /etc/vsftpd.conf
sudo systemctl restart vsftpd ; sudo systemctl status vsftpd
  1. 修改配置文件
1
2
3
4
5
6
7
8
9
10
sudo sed -i 's/#write_enable=YES/write_enable=YES/' /etc/vsftpd.conf  # 允许本地用户写入文件(前提是有w权限)
sudo sed -i 's/#local_umask=022/local_umask=022/' /etc/vsftpd.conf # 本地用户创建文件时的umask值

echo chroot_local_user=YES | sudo tee -a /etc/vsftpd.conf # 将所有用户限制在主目录
echo chroot_list_enable=YES | sudo tee -a /etc/vsftpd.conf # 开启限制用户切换主目录的白名单模式
sudo mkdir /etc/vsftpd ; echo chroot_list_file=/etc/vsftpd/vsftpd.chroot_list | sudo tee -a /etc/vsftpd.conf # 指定例外名单(限制切换主目录用户白名单)文件路径
echo test >> /etc/vsftpd/vsftpd.chroot_list # 将test用户添加进白名单,使其可访问主目录之外的文件和目录

echo pasv_min_port=50000 | sudo tee -a /etc/vsftpd.conf # 指定ftp被动模式下的最小端口号
echo pasv_max_port=50020 | sudo tee -a /etc/vsftpd.conf # 指定ftp被动模式下的最大端口号
  1. 应用修改
1
sudo systemctl restart vsftpd ; sudo systemctl status vsftpd
  1. 创建用于登录ftp服务器的本地用户:
1
2
3
4
5
6
adduser test  # 按提示设置好密码
sudo -u test touch /home/test/test.txt ; sudo chmod 666 /home/test/test.txt # 创建测试文件

adduser test2 # 按提示设置好密码
sudo chmod a-w /home/test2 # test2没有加到vsftpd.chroot_list文件,因此必须移除'写'权限,否则无法登录
sudo mkdir /home/test2/test ; sudo chown test2:test2 /home/test2/test # 由于test2用户去掉了'写'权限,因此需要和匿名用户一样创建一个具有读写权限的子目录用于修改文件
  1. 连接测试

本机连接测试

alt text

alt text

外网连接测试

由于FTP服务器被动模式的端口为随机端口(范围为前面指定的50000-50020),因此还需要放行此端口范围: sudo ufw allow 50000:50020/tcp

alt text

alt text

2.3 虚拟用户模式

  1. 修改配置文件
1
2
3
4
5
6
7
8
9
echo guest_enable=YES | sudo tee -a /etc/vsftpd.conf  # 开启虚拟用户登陆模式
echo guest_username=ftp | sudo tee -a /etc/vsftpd.conf # 绑定本地用户ftp(安装vsftpd时自动创建的用户,家目录在/srv/ftp)
echo user_config_dir=/etc/vsftpd/vuser_conf | sudo tee -a /etc/vsftpd.conf # 虚拟用户配置目录,子文件名为用户名,文件内容为配置项

echo virtual_use_local_privs=YES | sudo tee -a /etc/vsftpd.conf # 虚拟用户和本地用户登陆时不限制在ftp用户的家目录下(/srv/ftp),并且开启了虚拟用户模式才需添加此项
echo chroot_local_user=YES | sudo tee -a /etc/vsftpd.conf # 将所有用户限制在主目录
echo chroot_list_enable=YES | sudo tee -a /etc/vsftpd.conf # 开启限制用户切换主目录的白名单模式
echo chroot_list_file=/etc/vsftpd/vsftpd.chroot_list | sudo tee -a /etc/vsftpd.conf # 指定例外名单(限制切换主目录用户白名单)文件路径
echo user1 >> /etc/vsftpd/vsftpd.chroot_list # 将user1用户添加进白名单,使其可访问主目录之外的文件和目录
  1. 创建虚拟用户及其密码(奇数行为用户名,偶数行为密码)
1
2
3
4
5
6
7
sudo mkdir -p /etc/vsftpd/vuser_conf
sudo sh -c 'cat >> /etc/vsftpd/vuser_conf/vuser_passwd.list << EOF
user1
pas1
user2
pas2
EOF'
  1. 生成认证文件
1
2
3
sudo apt install db5.3-util
sudo db5.3_load -T -t hash -f /etc/vsftpd/vuser_conf/vuser_passwd.list /etc/vsftpd/vuser_conf/vuser_passwd.db
sudo rm /etc/vsftpd/vuser_conf/vuser_passwd.list # 删除明文用户文件
  1. 引用认证文件
1
2
sed -i '1i\auth sufficient pam_userdb.so    db=/etc/vsftpd/vuser_conf/vuser_passwd' /etc/pam.d/vsftpd
sed -i '1i\account sufficient pam_userdb.so db=/etc/vsftpd/vuser_conf/vuser_passwd' /etc/pam.d/vsftpd
  1. 创建虚拟用户配置文件并添加相应配置
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
sudo sh -c 'cat >> /etc/vsftpd/vuser_conf/user1 << EOF
local_root=/var/ftp/virtuser/user1
write_enable=YES
anon_umask=022
anon_world_readable_only=NO
anon_upload_enable=YES
anon_mkdir_write_enable=YES
anon_other_write_enable=YES
EOF'

sudo sh -c 'cat >> /etc/vsftpd/vuser_conf/user2 << EOF
local_root=/var/ftp/virtuser/user2
write_enable=YES
anon_umask=022
anon_world_readable_only=NO
anon_upload_enable=YES
anon_mkdir_write_enable=YES
anon_other_write_enable=YES
EOF'
  1. 应用配置
1
sudo systemctl restart vsftpd ; sudo systemctl status vsftpd
  1. 创建虚拟用户user1和user2的主目录
1
2
3
4
5
6
7
sudo mkdir -p /var/ftp/virtuser/user1 
sudo chown ftp:ftp /var/ftp/virtuser/user1
echo test1 | sudo -u ftp tee -a /var/ftp/virtuser/user1/test.txt

sudo mkdir -p /var/ftp/virtuser/user2/test
sudo chown -R ftp:ftp /var/ftp/virtuser/user2
sudo chmod a-w /var/ftp/virtuser/user2 # 和前面一样,没有加进vsftpd.chroot_list文件就必须移除'写'权限,否则无法登录
  1. 连接测试

本机连接测试

alt text

alt text

外网连接测试

alt text

alt text

3. SSL/TLS 加密(FTPS)

  1. 生成自签证书
1
2
3
sudo mkdir /var/ftp/cert ; cd /var/ftp/cert
openssl ecparam -genkey -name prime256v1 -out ca.key # 生成私钥
openssl req -new -x509 -days 36500 -key ca.key -out ca.crt -subj "/CN=lololowe.com" # 生成证书
  1. 修改配置文件
1
2
3
sudo sed -i 's#rsa_cert_file=/etc/ssl/certs/ssl-cert-snakeoil.pem#rsa_cert_file=/var/ftp/cert/ca.crt#' /etc/vsftpd.conf
sudo sed -i 's#rsa_private_key_file=/etc/ssl/private/ssl-cert-snakeoil.key#rsa_private_key_file=/var/ftp/cert/ca.key#' /etc/vsftpd.conf
sudo sed -i 's#ssl_enable=NO#ssl_enable=YES#' /etc/vsftpd.conf
  1. 应用配置
1
sudo systemctl restart vsftpd ; sudo systemctl status vsftpd
  1. 连接测试

本机连接测试:

自带的ftp客户端不支持跳过证书验证,可以使用lftp客户端:

1
2
sudo apt install lftp
lftp -e 'set ssl:verify-certificate no' user1@127.0.0.1 # 使用-e选项跳过证书验证

alt text

外网连接测试:

alt text

参考文章

VSFTPD.CONF, vsftpd
vsftp常见配置测试与故障排除, wangsongbai
vsftpd虚拟用户和本地用户不能共存, linux—jock
如何搭建VSFTP及配置虚拟用户, 阿里云
How To Set Up vsftpd for Anonymous Downloads on Ubuntu 16.04, Melissa Anderson
FTPS, 维基百科