vsftpd-实战安装

VSFTP简介

FTP是仅基于TCP的服务,不支持UDP。与众不同的是FTP使用2个端口,一个数据端口和一个命令端口(也可叫做控制端口)。通常来说这两个端口是21(命令端口)和20(数据端口)。但FTP工作方式的不同,数据端口并不总是20。这就是主动与被动FTP的最大不同之处。

 

vsftpd提供了3种ftp登录形式:

anonymous(匿名帐号)

使用anonymous是应用广泛的一种FTP服务器.如果用户在FTP服务器上没有帐号,那么用户可以以anonymous为用户名,以自己的电子邮件地址为密码进行登录.当匿名用户登录FTP服务器后,其登录目录为匿名FTP服务器的根目录/var/ftp.为了减轻FTP服务器的负载,一般情况下,应关闭匿名帐号的上传功能.

real(真实帐号)

real也称为本地帐号,就是以真实的用户名和密码进行登录,但前提条件是用户在FTP服务器上拥有自己的帐号.用真实帐号登录后,其登录的目录为用户自己的目录,该目录在系统建立帐号时系统就自动创建.

guest(虚拟帐号)

如果用户在FTP服务器上拥有帐号,但此帐号只能用于文件传输服务,那么该帐号就是guest,guest是真实帐号的一种形式,它们的不同之处在于,geust登录FTP服务器后,不能访问除宿主目录以外的内容.

安装vsftpd

1
2
3
4
5
yum install vsftpd
## 启动ftp
systemctl start vsftpd
## 或者
/etc/init.d/vsftpd start

查看服务器端口是否存在

1
ss -lntup |grep 22

配置文件解释

生产配置文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
egrep -v "#|^$" /etc/vsftpd/vsftpd.conf
anonymous_enable=no ##禁止匿名账号登录
local_enable=YES
write_enable=YES
local_umask=022
dirmessage_enable=YES
xferlog_enable=YES
connect_from_port_20=YES
xferlog_file=/var/log/xferlog
xferlog_std_format=YES
chroot_local_user=YES
listen=NO
listen_ipv6=YES
pam_service_name=vsftpd
userlist_enable=YES
tcp_wrappers=YES

默认配置

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#使用户不能离开主目录
chroot_list_enable=YES

#设定不允许匿名访问
anonymous_enable=NO
#设定本地用户可以访问。注:如使用虚拟宿主用户,在该项目设定为NO的情况下所有虚拟用户将无法访问
local_enable=YES

write_enable=YES
local_umask=022
dirmessage_enable=YES
xferlog_enable=YES
connect_from_port_20=YES
xferlog_std_format=YES
#服务器独立运行
listen=YES

pam_service_name=vsftpd
userlist_enable=YES
tcp_wrappers=YES

配置日志和上传下载

1
2
3
4
5
6
7
8
9
10
#设定支持ASCII模式的上传和下载功能
ascii_upload_enable=YES
ascii_download_enable=YES

#配置vsftpd日志(可选)
xferlog_enable=YES
xferlog_std_format=YES
xferlog_file=/var/log/xfer.log
dual_log_enable=YES
vsftpd_log_file=/var/log/vsftpd.log

如果启用vsftpd日志需手动建立日志文件

1
2
touch /var/log/xfer.log
touch /var/log/vsftpd.log

配置到这里,一个普通的ftp就可以交付使用。
使用系统账号可以登录自己的ftp。

配置匿名用户

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
# 设定允许匿名访问
anonymous_enable=YES

# 增加匿名访问目录
anon_root=/var/ftp/pub

# 打开匿名用户上传/删除/重命名权限
anon_upload_enable=YES
anon_mkdir_write_enable=YES
anon_other_write_enable=YES

# 匿名用户的掩码
anon_umask=022

# 匿名登录时,不检验密码
no_anon_password=YES

# 匿名用户10分钟无操作则掉线
idle_session_timeout=600

默认情况下匿名用户没有创建目录的权限,增加匿名用户的权限

1
chown -R ftp.ftp pub/

配置虚拟用户登录

所谓虚拟用户就是没有使用真实的帐户,只是通过映射到真实帐户和设置权限的目的。虚拟用户不能登录CentOS系统。

创建虚拟用户6步走:

  1. 在vsftpd.cong文件中添加支持配置

  2. 建立虚拟FTP用户的账号数据库文件

  3. 创建FTP根目录及虚拟用户映射的系统用户

  4. 建立支持虚拟用户的PAM认证文件

  5. 在个别虚拟用户建立独立的配置文件以实现权限访问

  6. 重启vsftpd服务

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
vi /etc/vsftpd/vsftpd.conf
#PAM认证文件名。PAM将根据/etc/pam.d/vsftpd进行认证
pam_service_name=vsftpd
#设定启用虚拟用户功能
guest_enable=YES
#指定虚拟用户的宿主用户,CentOS中已经有内置的ftp用户了
guest_username=ftp
#设定虚拟用户个人vsftp的CentOS FTP服务文件存放路径。存放虚拟用户个性的CentOS FTP服务文件(配置文件名=虚拟用户名)
user_config_dir=/etc/vsftpd/vuser_conf
#配置vsftpd日志(可选)
xferlog_enable=YES
xferlog_std_format=YES
xferlog_file=/var/log/xferlog
dual_log_enable=YES
vsftpd_log_file=/var/log/vsftpd.log

进行认证

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
#安装Berkeley DB工具

yum install db4 db4-utils -y

#创建用户密码本,注意奇行是用户名,偶行是密码
cat >>/etc/vsftpd/vuser_passwd.txt<<EOF
test
123456
EOF

#生成虚拟用户认证的db文件
db_load -T -t hash -f /etc/vsftpd/vuser_passwd.txt /etc/vsftpd/vuser_passwd.db


# 指定认证文件名称,全部注释掉原来语句,再增加以下两句
vi /etc/pam.d/vsftpd

auth required pam_userdb.so db=/etc/vsftpd/vuser_passwd
account required pam_userdb.so db=/etc/vsftpd/vuser_passwd

#创建虚拟用户配置文件,为虚拟用户配置独立的权限
mkdir /etc/vsftpd/vuser_conf/
#文件名等于vuser_passwd.txt里面的账户名,否则下面设置无效
vi /etc/vsftpd/vuser_conf/test

#虚拟用户根目录,根据实际情况修改
local_root=/data/ftp
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

虚拟用户根目录必须具有FTP账号的权限。
为了使服务器能够使用上述生成的数据库文件,对客户端进行身份验证,需要调用系统的PAM模块。
PAM(Plugable Authentication Module)为可插拔认证模块,不必重新安装应用系统,通过修改指定的配置文件,调整对该程序的认证方式。
PAM模块配置文件路径为/etc/pam.d/目录,此目录下保存着大量与认证有关的配置文件,并以服务名称命名。

配置PASV(被动模式)

vsftpd默认没有开启PASV模式,FTP只能通过PORT模式连接。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#开启PASV模式
pasv_enable=YES
#最小端口号
pasv_min_port=40000
#最大端口号
pasv_max_port=40080
pasv_promiscuous=YES

#在防火墙配置内开启40000到40080端口(如果没有防火墙可以忽略)
-A INPUT -m state --state NEW -m tcp -p -dport 40000:40080 -j ACCEPT

#重启iptabls和vsftpd
service iptables restart
service vsftpd restart

现在可以使用PASV模式连接你的FTP服务器了~

设置FTP根目录权限

1
2
3
4
5
6
7
#最新的vsftpd要求对主目录不能有写的权限所以ftp为755,主目录下面的子目录再设置777权限
mkdir /data/ftp
chmod -R 755 /data
chmod -R 777 /data/ftp

#建立限制用户访问目录的空文件
touch /etc/vsftpd/chroot_list

vsftpd的高级玩法

配置SSL连接

我们登录ftp时的密码都是明文登录的,这样极不安全,所以我们可以使用基于ssl的ftp登录传输方式。
首先我们要为ftp签署证书;再在配置文件中添加下列内容

1
2
3
4
5
6
7
8
9
ssl_enable=YES     启用ssl
ssl_tlsv1=YES 启用tls v1版本
ssl_sslv2=YES 启用ssl v2版本
ssl_sslv3=YES
allow_anon_data_ssl=NO 匿名用户一般不需要
force_local_data_ssl=YES本地用户传输时是否使用ssl
force_local_logins_ssl=YES本地用户登录时是否使用ssl
rsa_cert_file=/etc/vsftpd/ssl/vsftpd.crt 证书路径
rsa_private_key_file=/etc/vsftpd/ssl/vsftpd.key私钥路径

注意事项

常见问题

默认情况下,ftp的根目录为/var/ftp,为了安全,这个目录默认不允许设置为777权限,否则ftp将无法访问。但是我们要匿名上传文件,需要“other”用户的写权限,正确的做法:
在/var/ftp中建立一个pub(名子自己起吧)文件夹,将个文件夹权限设置为777(视具体需要自己设),在upload这个文件夹中,匿名用户可以上传文件、创建文件夹、删除文件等。一般至此,便实现vsftpd匿名用户的上传下载了。如果还不行可能selinux的问题,关闭即可。

知识补充

主动连接和被动连接的区别

PORT(主动模式)

PORT中文称为主动模式,工作的原理: FTP客户端连接到FTP服务器的21端口,发送用户名和密码登录,登录成功后要list列表或者读取数据时,客户端随机开放一个端口(1024以上),发送 PORT命令到FTP服务器,告诉服务器客户端采用主动模式并开放端口;FTP服务器收到PORT主动模式命令和端口号后,通过服务器的20端口和客户端开放的端口连接,发送数据。

PASV(被动模式)

PASV是Passive的缩写,中文成为被动模式,工作原理:FTP客户端连接到FTP服务器的21端口,发送用户名和密码登录,登录成功后要list列表或者读取数据时,发送PASV命令到FTP服务器, 服务器在本地随机开放一个端口(1024以上),然后把开放的端口告诉客户端, 客户端再连接到服务器开放的端口进行数据传输。

两种模式的对比

  • 主动模式,服务器端使用20端口连接客户端的随机端口发送数据。
  • 被动模式:服务器端开发随机端口供客户端连接。
  • 主动模式:需要客户端必须开放端口给服务器,很多客户端都是在防火墙内,开放端口给FTP服务器访问比较困难。
  • 被动模式:只需要服务器端开放端口给客户端连接就行了。

我在实际项目中碰到的问题是,FTP的客户端和服务器分别在不同网络,两个网络之间有至少4层的防火墙,服务器端只开放了21端口, 客户端机器没开放任何端口。FTP客户端连接采用的被动模式,结果客户端能登录成功,但是无法LIST列表和读取数据。很明显,是因为服务器端没开放被动模式下的随机端口导致。

遇到的问题

由于被动模式下,服务器端开放的端口随机,但是防火墙要不能全部开放,解决的方案是,在ftp服务器配置被动模式下开放随机端口在 50000-60000之间(范围在ftp服务器软件设置,可以设置任意1024上的端口段),然后在防火墙设置规则,开放服务器端50000-60000之间的端口端。

主动模式下,客户端的FTP软件设置主动模式开放的端口段,在客户端的防火墙开放对应的端口段。

帮助文档

常见错误

报错一:
点击详细错误的时候是下面的提示
vsftpd: refusing to run with writable root inside chroot() 错误的解决办法
一下是解决办法:
为了避免一个安全漏洞,从 vsftpd 2.3.5 开始,chroot 目录必须不可写。使用命令:

1
2
# chmod a-w /home/user
user 为FTP所连接的目录

报错二:
500 OOPS: bad bool value in config file for: tcp_wrappers

tcp_wrappers 多了一个空格,删除空格问题解决。