vsftpd介绍
一般来讲,人们把计算机联网的首要目的就是获取资料,而文件传输是一种非常重要的获取资料的方式。今天的互联网是由几千万台个人计算机、工作站、服务器、小型机、大型机、巨型机等具有不同型号、不同架构的物理设备共同组成的,而且即便是个人计算机,也可能会装有Windows、Linux、UNIX、Mac等不同的操作系统。为了能够在如此复杂多样的设备之间解决问题解决文件传输问题,FTP(File Transfer Protocol)文件传输协议应运而生。FTP是一种在互联网中进行文件传输的协议,基于客户端/服务器模式,默认使用20、21号端口,其中端口20用于进行数据传输,端口21用于接受客户端发出的相关FTP命令与参数。FTP服务器普遍部署于内网中,具有容易搭建、方便管理的特点。而且有些FTP客户端工具还可以支持文件的多点下载以及断点续传技术,因此得到了广大用户的青睐。
FTP服务器是按照FTP协议在互联网上提供文件存储和访问服务的主机,FTP客户端则是向服务器发送连接请求,以建立数据传输链路的主机。FTP协议有下面两种工作模式,因此有些时候需要将FTP的工作模式设置为主动模式,才可以传输数据。
主动模式:FTP服务器主动向客户端发起连接请求。
被动模式:FTP服务器等待客户端发起连接请求(默认工作模式)。vsftpd作为更加安全的文件传输协议服务程序,允许用户以三种认证模式登录到FTP服务器上。
匿名开放模式:是一种最不安全的认证模式,任何人都可以无需密码验证而直接登录到FTP服务器。
本地用户模式:是通过Linux系统本地的账户密码信息进行认证的模式,相较于匿名开放模式更安全,而且配置起来也很简单。但是如果被骇客解密了账户的信息,就可以畅通无阻地登录FTP服务器,从而完全控制整台服务器。
虚拟用户模式:更安全的一种认证模式,它需要为FTP服务单独建立用户数据库文件,虚拟出用来进行口令验证的账户信息,而这些账户信息在服务器系统中实际上是不存在的,仅供FTP服务程序进行认证使用。这样,即使骇客解密了账户信息也无法登录服务器,从而有效降低了破坏范围和影响。
vsftpd安装
由于FTP、HTTP、Telnet等协议的数据都是经过明文进行传输,因此从设计的原理上就是不可靠的,但人们又需要解决文件传输的需求,因此便有了vsftpd服务程序。vsftpd(very secure ftp daemon,非常安全的FTP守护进程)是一款运行在Linux操作系统上的FTP服务程序,不仅完全开源而且免费,此外,还具有很高的安全性、传输速度,以及支持虚拟用户验证等其他FTP服务程序不具备的特点。在不影响使用的前提下,能够让管理者自行决定是公开匿名、本地用户还是虚拟用户的验证方式,这样即便被骇客拿到了我们的账号密码,也不见得能登陆的了服务器。在配置妥当软件仓库之后,就可以安装vsftpd服务程序了。ftp是Linux系统中以命令行界面的方式来管理FTP传输服务的客户端工具。我们首先手动安装这个ftp客户端工具。
[root@gby ~]# yum -y install vsftpd ftp
Loaded plugins: fastestmirror
Loading mirror speeds from cached hostfile
Resolving Dependencies
--> Running transaction check
---> Package ftp.x86_64 0:0.17-67.el7 will be installed
---> Package vsftpd.x86_64 0:3.0.2-29.el7_9 will be installed
--> Finished Dependency Resolution
Dependencies Resolved
===============================================================================================================================================
Package Arch Version Repository Size
===============================================================================================================================================
Installing:
ftp x86_64 0.17-67.el7 base 61 k
vsftpd x86_64 3.0.2-29.el7_9 updates 173 k
Transaction Summary
===============================================================================================================================================
Install 2 Packages
Total download size: 233 k
Installed size: 449 k
Downloading packages:
(1/2): vsftpd-3.0.2-29.el7_9.x86_64.rpm | 173 kB 00:00:00
(2/2): ftp-0.17-67.el7.x86_64.rpm | 61 kB 00:00:00
-----------------------------------------------------------------------------------------------------------------------------------------------
Total 1.0 MB/s | 233 kB 00:00:00
Running transaction check
Running transaction test
Transaction test succeeded
Running transaction
Installing : vsftpd-3.0.2-29.el7_9.x86_64 1/2
Installing : ftp-0.17-67.el7.x86_64 2/2
Verifying : ftp-0.17-67.el7.x86_64 1/2
Verifying : vsftpd-3.0.2-29.el7_9.x86_64 2/2
Installed:
ftp.x86_64 0:0.17-67.el7 vsftpd.x86_64 0:3.0.2-29.el7_9
Complete!
如果一会想用Windows主机测试实验的效果,可以从FileZilla、FireFTP、SmartFTP、WinSCP和Cyberduck中挑一个喜欢的软件从网上下载,会比ftp命令功能更加强大。 iptables防火墙管理工具默认禁止了FTP传输协议的端口号,因此在正式配置vsftpd服务程序之前,为了避免这些默认的防火墙策略“捣乱”,还需要清空iptables防火墙的默认策略,并把当前已经被清理的防火墙策略状态保存下来:
[root@gby ~]# iptables -F
[root@gby ~]# iptables-save
然后再把FTP协议添加到firewalld服务的允许列表中,前期准备工作一定要做充足:
[root@gby ~]# firewall-cmd --permanent --zone=public --add-service=ftp
success
[root@gby ~]# firewall-cmd --reload
success
sftpd服务程序的主配置文件(/etc/vsftpd/vsftpd.conf)内容总长度达到127行,但其中大多数参数在开头都添加了井号(#),从而成为注释信息,大家没有必要在注释信息上花费太多的时间。我们可以在grep命令后面添加-v参数,过滤并反选出没有包含井号(#)的参数行(即过滤掉所有的注释信息),然后将过滤后的参数行通过输出重定向符写回原始的主配置文件中,只剩下12行有效参数了,马上就不紧张了:
[root@gby ~]# mv /etc/vsftpd/vsftpd.conf /etc/vsftpd/vsftpd.conf.bak
[root@gby ~]# grep -v "#" /etc/vsftpd/vsftpd.conf.bak > /etc/vsftpd/vsftpd.conf
[root@gby ~]# cat /etc/vsftpd/vsftpd.conf
anonymous_enable=YES
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=NO
listen_ipv6=YES
pam_service_name=vsftpd
userlist_enable=YES
tcp_wrappers=YES
vsftpd服务程序主配置文件中常用的参数以及作用
参数 |
作用 |
listen=[YES|NO] |
是否以独立运行的方式监听服务 |
listen_address=IP地址 |
设置要监听的IP地址 |
listen_port=21 |
设置FTP服务的监听端口 |
download_enable=[YES|NO] |
是否允许下载文件 |
userlist_enable=[YES|NO]userlist_deny=[YES|NO] |
设置用户列表为“允许”还是“禁止”操作 |
max_clients=0 |
最大客户端连接数,0为不限制 |
max_per_ip=0 |
同一IP地址的最大连接数,0为不限制 |
anonymous_enable=[YES|NO] |
是否允许匿名用户访问 |
anon_upload_enable=[YES|NO] |
是否允许匿名用户上传文件 |
anon_umask=022 |
匿名用户上传文件的umask值 |
anon_root=/var/ftp |
匿名用户的FTP根目录 |
anon_mkdir_write_enable=[YES|NO] |
是否允许匿名用户创建目录 |
anon_other_write_enable=[YES|NO] |
是否开放匿名用户的其他写入权限(包括重命名、删除等操作权限) |
anon_max_rate=0 |
匿名用户的最大传输速率(字节/秒),0为不限制 |
local_enable=[YES|NO] |
是否允许本地用户登录FTP> |
local_umask=022 |
本地用户上传文件的umask值 |
local_root=/var/ftp |
本地用户的FTP根目录 |
chroot_local_user=[YES|NO] |
是否将用户权限禁锢在FTP目录,以确保安全 |
local_max_rate=0 |
本地用户最大传输速率(字节/秒),0为不限制 |
匿名访问模式
在vsftpd服务程序中,匿名开放模式是最不安全的一种认证模式。任何人都可以无需密码验证而直接登录到FTP服务器。这种模式一般用来访问不重要的公开文件(在生产环境中尽量不要存放重要文件)。vsftpd服务程序默认关闭了匿名开放模式,需要做的就是开放匿名用户的上传、下载文件的权限,以及让匿名用户创建、删除、更名文件的权限。需要注意的是,针对匿名用户放开这些权限会带来潜在危险
参数 |
作用 |
anonymous_enable=YES |
允许匿名访问模式 |
anon_umask=022 |
匿名用户上传文件的umask值 |
anon_upload_enable=YES |
允许匿名用户上传文件 |
anon_mkdir_write_enable=YES |
允许匿名用户创建目录 |
anon_other_write_enable=YES |
允许匿名用户修改目录名称或删除目录 |
[root@gby ~]# vim /etc/vsftpd/vsftpd.conf
anonymous_enable=YES
anon_umask=022
anon_upload_enable=YES
anon_mkdir_write_enable=YES
anon_other_write_enable=YES
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=NO
listen_ipv6=YES
pam_service_name=vsftpd
userlist_enable=YES
tcp_wrappers=YES
在vsftpd服务程序的主配置文件中正确填写参数,然后保存并退出。还需要重启vsftpd服务程序,让新的配置参数生效。在此需要提醒一定要把配置过的服务程序加入到开机启动项中,以保证服务器在重启后依然能够正常提供传输服务。
[root@gby ~]# systemctl restart vsftpd
[root@gby ~]# systemctl enable vsftpd
Created symlink from /etc/systemd/system/multi-user.target.wants/vsftpd.service to /usr/lib/systemd/system/vsftpd.service.
现在就可以在客户端执行ftp命令连接到远程的FTP服务器了。在vsftpd服务程序的匿名开放认证模式下,其账户统一为anonymous,密码为空。而且在连接FTP服务器后,默认访问的是/var/ftp目录。可以切换到该目录下的pub目录中,然后尝试创建一个新的目录文件,以检验是否拥有写入权限:
[root@gby ~]# ftp 172.24.54.169
Connected to 172.24.54.169 (172.24.54.169).
220 (vsFTPd 3.0.2)
Name (172.24.54.169:root): 用户名
331 Please specify the password.
Password:密码
230 Login successful.
Remote system type is UNIX.
Using binary mode to transfer files.
ftp> ls
227 Entering Passive Mode (172,24,54,169,206,185).
150 Here comes the directory listing.
drwxr-xr-x 2 0 0 4096 Jun 09 16:15 pub
226 Directory send OK.
ftp> cd pub
250 Directory successfully changed.
ftp> mkdir b
550 Create directory operation failed.
系统显示拒绝创建目录!我们明明在前面清空了iptables防火墙策略,而且也在vsftpd服务程序的主配置文件中添加了允许匿名用户创建目录和写入文件的权限啊。在vsftpd服务程序的匿名开放认证模式下,默认访问的是/var/ftp目录。查看该目录的权限得知,只有root管理员才有写入权限。下面将目录的所有者身份改成系统账户ftp即可。
[root@gby ~]# ls -ld /var/ftp/pub/
drwxr-xr-x 2 root root 4096 Jun 10 00:15 /var/ftp/pub/
[root@gby ~]# ls -ld /var/ftp/
drwxr-xr-x 3 root root 4096 Sep 1 14:50 /var/ftp/
[root@gby ~]# chown -R ftp /var/ftp
[root@gby ~]# ls -ld /var/ftp/
drwxr-xr-x 3 ftp root 4096 Sep 1 14:50 /var/ftp/
[root@gby var]# ftp 172.24.54.169
Connected to 172.24.54.169 (172.24.54.169).
220 (vsFTPd 3.0.2)
Name (172.24.54.169 .1:root): anonymous
331 Please specify the password.
Password:
230 Login successful.
Remote system type is UNIX.
Using binary mode to transfer files.
ftp> cd pub
250 Directory successfully changed.
ftp> mkdir cs
257 "/pub/cs" created
ftp> rmdir cs
250 Remove directory operation successful.
在上面的操作中,由于权限不足,所以我们将/var/ftp/pub目录的所有者设置成ftp用户本身。除了这种方法,也可以通过设置权限的方法让其他用户获取到写入权限(例如777这样的权限)。但是,由于vsftpd服务自身带有安全保护机制,因此不要直接修改/var/ftp的权限,这有可能导致服务被“安全锁定”而不能登录。一定要记得是对里面的pub目录修改权限哦:
[root@gby ~]# chmod 777 /var/ftp
[root@gby ~]# ftp 172.24.54.169
Connected to 172.24.54.169 (172.24.54.169).
220 (vsFTPd 3.0.2)
Name (172.24.54.169:root): anonymous
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
本地用户模式
相较于匿名开放模式,本地用户模式要更安全,而且配置起来也很简单。
参数 |
作用 |
anonymous_enable=NO |
禁止匿名访问模式 |
local_enable=YES |
允许本地用户模式 |
write_enable=YES |
设置可写权限 |
local_umask=022 |
本地用户模式创建文件的umask值 |
userlist_deny=YES |
启用“禁止用户名单”,名单文件为ftpusers和user_list |
userlist_enable=YES |
开启用户作用名单文件功能 |
默认情况下本地用户所需的参数都已经存在,不需要修改。而umask这个参数还是头一次见到,我们一起来看一下。unmask一般被称为“权限掩码”或“权限补码”,能够直接影响到新建文件的权限值。例如在Linux系统中,新建的普通文件的权限是644,新建的目录的权限是755。
其实,普通文件的默认权限是666,目录的默认权限是777,这都是写在系统配置文件中的。但默认值不等于最终权限值。umask参数的默认值是022,根据公式“默认权限−umask=实际权限”,所以普通文件的默认权限到手后就剩下644,而目录文件就剩下755了。
我们再来看一个例子。我们每个人的收入都要纳税,税就相当于umask值。如果*想让每个人到手的收入多一些,那么就减少税(umask);如果想让每个人到手的收入少一些,那么就多加税(umask)。也就是说,umask实际是权限的反掩码,通过它可以调整文件最终的权限大小。
[root@gby ~]# vim /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_std_format=YES
listen=NO
listen_ipv6=YES
pam_service_name=vsftpd
userlist_enable=YES
tcp_wrappers=YES
在vsftpd服务程序的主配置文件中正确填写参数,然后保存并退出。还需要重启vsftpd服务程序,让新的配置参数生效。
[root@gby ~]# systemctl restart vsftpd
按理来讲,现在已经完全可以用本地用户的身份登录FTP服务器了。但是在使用root管理员的身份登录后,系统提示如下的错误信息:
[root@gby ~]# ftp 172.24.54.169
Connected to 172.24.54.169 (172.24.54.169).
220 (vsFTPd 3.0.2)
Name (172.24.54.169:root): root
530 Permission denied.
Login failed.
在我们输入root管理员的密码之前,就已经被系统拒绝访问了。这是因为vsftpd服务程序所在的目录中默认存放着两个名为“用户名单”的文件(ftpusers和user_list)。不知道大家是否已看过一部日本电影“死亡笔记”,里面就提到有一个黑色封皮的小本子,只要将别人的名字写进去,这人就会挂掉。vsftpd服务程序目录中的这两个文件也有类似的功能—只要里面写有某位用户的名字,就不再允许这位用户登录到FTP服务器上。
[root@gby ~]# cat /etc/vsftpd/user_list
# vsftpd userlist
# If userlist_deny=NO, only allow users in this file
# If userlist_deny=YES (default), never allow users in this file, and
# do not even prompt for a password.
# Note that the default vsftpd pam config also checks /etc/vsftpd/ftpusers
# for users that are denied.
root
bin
daemon
adm
lp
sync
shutdown
halt
mail
news
uucp
operator
games
nobody
[root@gby ~]# cat /etc/vsftpd/ftpusers
# Users that are not allowed to login via ftp
root
bin
daemon
adm
lp
sync
shutdown
halt
mail
news
uucp
operator
games
nobody
果然如此!vsftpd服务程序为了保证服务器的安全性而默认禁止了root管理员和大多数系统用户的登录行为,这样可以有效地避免黑客通过FTP服务对root管理员密码进行暴力解码。如果您确认在生产环境中使用root管理员不会对系统安全产生影响,只需按照上面的提示删除掉root用户名即可。也可以选择ftpusers和user_list文件中不存在的一个普通用户尝试登录FTP服务器:
[root@gby ~]# ftp 127.0.0.1
Connected to 127.0.0.1 (127.0.0.1).
220 (vsFTPd 3.0.2)
Name (127.0.0.1:root): gby
331 Please specify the password.
Password:
230 Login successful.
Remote system type is UNIX.
Using binary mode to transfer files.
为什么同样是禁止用户登录的功能,却要制作两个一模一样的文件呢?
这个小玄机其实就在user_list文件上面。如果把上面主配置文件中userlist_deny的参数值改成NO,那么user_list列表就变成了强制白名单。它的功能与之前完全相反,只允许列表内的用户访问,拒绝其他人的访问。
虚拟用户模式
虚拟用户模式是这3种模式中最安全的一种认证模式,是专门创建出一个账号来登录FTP传输服务的,而且这个账号不能用于以SSH方式登录服务器。当然,因为它的安全性较之于前面两种模式有了提升,所以配置流程也会稍微复杂一些。
第1步:创建用于进行FTP认证的用户数据库文件,其中奇数行为账户名,偶数行为密码。例如创建账号cs,密码cs123。
[root@gby ~]# cd /etc/vsftpd/
[root@gby vsftpd]# vim vuser.list
cs
cs123
由于明文信息既不安全,也不符合让vsftpd服务程序直接加载的格式,因此需要使用db_load命令用哈希(hash)算法将原始的明文信息文件转换成数据库文件,并且降低数据库文件的权限(避免其他人看到数据库文件的内容),然后再把原始的明文信息文件删除。
[root@gby vsftpd]# db_load -T -t hash -f vuser.list vuser.db
[root@gby vsftpd]# chmod 600 vuser.db
[root@gby vsftpd]# rm -f vuser.list
第2步:创建vsftpd服务程序用于存储文件的根目录以及用于虚拟用户映射的系统本地用户。vsftpd服务用于存储文件的根目录指的是,当虚拟用户登录后所访问的默认位置。 由于Linux系统中的每一个文件都有所有者、所属组属性,例如使用虚拟账户“cs”新建了一个文件,但是系统中找不到账户“cs”,就会导致这个文件的权限出现错误。为此,需要再创建一个可以映射到虚拟用户的系统本地用户。简单来说,就是让虚拟用户默认登录到与之有映射关系的这个系统本地用户的家目录中。虚拟用户创建的文件的属性也都归属于这个系统本地用户,从而避免Linux系统无法处理虚拟用户所创建文件的属性权限。
为了方便管理FTP服务器上的数据,可以把这个系统本地用户的家目录设置为/var目录(该目录用来存放经常发生改变的数据)。并且为了安全起见,将这个系统本地用户设置为不允许登录FTP服务器,这不会影响虚拟用户登录,而且还能够避免黑客通过这个系统本地用户进行登录。
[root@gby ~]# useradd -d /var/vftp -s /sbin/nologin vftp
[root@gby ~]# ls -ld /var/vftp/
drwx------ 2 vftp vftp 4096 Sep 1 16:05 /var/vftp/
[root@gby ~]# chmod -Rf 755 /var/vftp/
第3步:建立用于支持虚拟用户的PAM文件。
PAM(可插拔认证模块)是一种认证机制,通过一些动态链接库和统一的API把系统提供的服务与认证方式分开,使得系统管理员可以根据需求灵活调整服务程序的不同认证方式。
通俗来讲,PAM是一组安全机制的模块,系统管理员可以用来轻易地调整服务程序的认证方式,而不必对应用程序进行任何修改。PAM采取了分层设计(应用程序层、应用接口层、鉴别模块层)的思想。
新建一个用于虚拟用户认证的PAM文件vsftpd.vu,其中PAM文件内的“db=”参数为使用db_load命令生成的账户密码数据库文件的路径,但不用写数据库文件的后缀:
[root@gby ~]# vim /etc/pam.d/vsftpd.vu
auth required pam_userdb.so db=/etc/vsftpd/vuser
account required pam_userdb.so db=/etc/vsftpd/vuser
第4步:在vsftpd服务程序的主配置文件中通过pam_service_name参数将PAM认证文件的名称修改为vsftpd.vu。PAM作为应用程序层与鉴别模块层的连接纽带,可以让应用程序根据需求灵活地在自身插入所需的鉴别功能模块。当应用程序需要PAM认证时,则需要在应用程序中定义负责认证的PAM配置文件,实现所需的认证功能。 在vsftpd服务程序的主配置文件中默认就带有参数pam_service_name=vsftpd,表示登录FTP服务器时是根据/etc/pam.d/vsftpd文件进行安全认证的。现在我们要做的就是把vsftpd主配置文件中原有的PAM认证文件vsftpd修改为新建的vsftpd.vu文件即可。
参数 |
作用 |
anonymous_enable=NO |
禁止匿名开放模式 |
local_enable=YES |
允许本地用户模式 |
guest_enable=YES |
开启虚拟用户模式 |
guest_username=virtual |
指定虚拟用户账户 |
pam_service_name=vsftpd.vu |
指定PAM文件 |
allow_writeable_chroot=YES |
允许对禁锢的FTP根目录执行写入操作,而且不拒绝用户的登录请求 |
[root@gby ~]# vim /etc/vsftpd/vsftpd.conf
anonymous_enable=NO
local_enable=YES
write_enable=YES
guest_enable=YES
guest_username=vftp
allow_writeable_chroot=YES
local_umask=022
anon_umask=022
dirmessage_enable=YES
xferlog_enable=YES
connect_from_port_20=YES
xferlog_std_format=YES
listen=NO
listen_ipv6=YES
pam_service_name=vsftpd.vu
userlist_enable=YES
tcp_wrappers=YES
第5步:为虚拟用户设置不同的权限。比如,允许cs上传、创建、修改、查看、删除文件。这可以通过vsftpd服务程序来实现。只需新建一个目录,在里面创建以cs命名的文件,其中在名为cs的文件中写入允许的相关权限(使用匿名用户的参数):
[root@gby ~]# mkdir /etc/vsftpd/vusers_dir/
[root@gby ~]# cd /etc/vsftpd/vusers_dir/
[root@gby vusers_dir]# vim cs
anon_upload_enable=YES
anon_mkdir_write_enable=YES
anon_other_write_enable=YES
然后再次修改vsftpd主配置文件,通过添加user_config_dir参数来定义这虚拟用户不同权限的配置文件所存放的路径。为了让修改后的参数立即生效,需要重启vsftpd服务程序:
[root@gby ~]# vim /etc/vsftpd/vsftpd.conf
anonymous_enable=NO
local_enable=YES
write_enable=YES
guest_enable=YES
guest_username=vftp
allow_writeable_chroot=YES
local_umask=022
anon_umask=022
dirmessage_enable=YES
xferlog_enable=YES
connect_from_port_20=YES
xferlog_std_format=YES
listen=NO
listen_ipv6=YES
pam_service_name=vsftpd.vu
userlist_enable=YES
tcp_wrappers=YES
user_config_dir=/etc/vsftpd/vusers_dir
[root@gby ~]# systemctl restart vsftpd
此时,可以使用虚拟用户模式成功登录到FTP服务器。
[root@gby ~]# ftp 172.24.54.169
Connected to 172.24.54.169 (172.24.54.169).
220 (vsFTPd 3.0.2)
Name (172.24.54.169:root): cs
331 Please specify the password.
Password:
230 Login successful.
Remote system type is UNIX.
Using binary mode to transfer files.
最后总结一下在使用不同的方式登录文件传输服务器后,默认所在的位置。
登录方式 |
默认目录 |
匿名公开 |
/var/ftp |
本地用户 |
该用户的家目录 |
虚拟用户 |
对应映射用户的家目录 |
结束之有话想说
既然看完了那就赶紧去试试吧骚年。????