搞它!!!深入了解FTP文件传输服务

2020-09-03 10:09:43 浏览数 (1)

前言

VSFTP是一个基于GPL发布的类Unix系统上使用的FTP服务器软件,它的全称是Very Secure FTP 从此名称可以看出来,编制者的初衷是代码的安全。

一、 服务理论

1、FTP连接及传输模式

FTP服务器默认使用TCP协议的20、21端口与客户端进行通信。20端口用于建立数据连接,并传输文件数据。21端口用于建立控制连接。并传输FTP控制命令。根据FTP服务器在建立数据连接过程中的主、被动关系。FTP数据连接分为主动模式和被动模式。两者的含义及主要区别如下。

主动模式:服务器主动发起数据连接。首先由客户端向服务端的21端口建立FTP控制连接,当需要传输数据时,客户端以PORT命令告知服务器“我打开了某端口,你过来连接我”,于是服务器从20端口向客户端的该端口发送请求并建立数据连接。

被动模式:服务器被动等待数据连接,如果客户机所在网络的防火墙禁止主动模式连接,通常会使用被动模式,首先由客户端向服务端的21端口建立FTP控制连接,当需要传输数据时,服务器以PASV命令告知客户端“我打开了某端口,你过来连接我”,于是客户端向服务器的该端口(非20)发送请求并建立连接

客户端与服务器建立好数据连接以后,就可以根据从控制连接中发送ftp命令上传或下载文件了,在创数文件时,根据是否进行字符转换,分为文本模式和二进制模式。

文本模式:又称为ASCII(American Standard Code for Information Interchange,美国信息交换标准码)模式,这种模式在传输文件时使用ASCII标准字符序列,一般只用于纯文件传输。

二进制模式:又称为Binary模式,这种模式不会转换文件中的字符序列,更适合传输程序,图片等非纯文本字符文件。

2、FTP用户类型

使用FTP客户端软件访问服务器时,通常要用到一类特殊的用户账号,其用户名为ftp或anonymous,提供任意密码(包括空密码)都可以通过服务器的验证,这样的用户成为“匿名用户”。匿名用户一般用于提供公共文件的下载,如提供一些免费软件、学习资料下载的站点。

除了不需要密码验证的匿名用户意外,FTP服务器还可以直接使用本机的系统用户账号来进行验证,这些用户通常称为“本地用户”。在RHEL6.5系统中,匿名用户也有对应的本地系统用户账号“ftp”,但对于vsftpd服务来说,本地用户指的除了匿名用户意外的其他系统用户。

有些FTP服务器软件还可以维护一份独立的用户数据库文件,而不是直接使用系统用户账户,这些誉为独立数据库文件中的FTP用户账号,通常被称为“虚拟用户”,通过使用虚拟用户,将FTP账户与Linux系统账户的关联性降至最,可以为系统提供更好的安全性。

3、FTP服务器软件的种类:

在Windows系统中,常见的FTP服务器软件包括FileZilla Sener、Serv-U等,而在Linux系统中,vsftpd是目前在Linux/UNIX领域应用十分广泛的一款FTP服务软件。本课程将以vsftpd进行讲解。

Vsftpd服务的名称来源于“Very Secure FTP Daemon”该软件针对安全特性方面做了大量的设计,除了安全意外,vsftpd在速度和稳定性方面的表现也相当突出,根据ftp.redhat.com服务器反应的数据,vsftpd可以支持15000个用户并发连接。

4、FTP客户端工具的种类:

最简单的FTP客户端工具莫过于ftp命令程序了,Windows系统和Linux系统默认都自带有ftp命令程序,可以连接到ftp服务器进行交互式的上传、下载通信。

除此之外,还有大量的图形化FTP客户端工具,windows中较常用的包括CuteFTP、FlashFXP、LeapFTP、Filezilla等,在图形化的客户端程序中,用户通过鼠标和菜单即可访问,管理FTP资源。而不需要掌握FTP交互命令,因此使用户的操作更加简单、易于使用。

还有一些下载工具软件,如FlashGET、Wget等,包括大多数网页浏览器程序,都支持通过FTP协议下载文件,但因为不具备FTP上传等管理功能,通常不称为FTP客户端工具。

二、vsftpd的配置文件

通过RPM方式安装的vsftpd软件包,将会自动添加名为vsftpd的系统服务,因此启动、停止vsftpd服务变得非常方便,构建vsftpd服务器的关键在于熟悉相关配置文件。Vsftpd服务的配置文件位于/etc/vsftpd目录下,包括用户列表文件(ftpusers、user_list)和主配置文件(vsftpd.conf)等。

1、用户列表文件ftpusers和user_list

在ftpusers、user_list文件中,各自记录了若干个ftp用户账号名称,两个列表文件都用于ftp登陆控制,但是控制方式存在一些差别。

ftpusers文件:此文件中列出的用户将禁止登陆vsftpd服务器,不管该用户是否在user_list文件中出现。默认已包括root、bin、daemon等用于系统运行的特殊用户。

user_list文件:此文件中包含的用户可能被禁止登陆,也可能被允许登陆,具体取决于主配置文件vsftpd.conf中的设置,当存在“userlist_enable=YES”的配置项时,user_list列表文件方可生效;若指定“userlist_deny=YES”,则仅禁止此列表中的用户登陆;若指定“userlist_deny=NO”,则仅允许列表中的用户登陆。

Ftpusers文件相当于黑名单,为vsftpd服务器提供了一份禁止登陆用户列表,而user_list文件提供了一份可以灵活控制的用户列表。二者相互结合,为FTP账号的登陆控制提供了便捷的途径。

2、主配置文件vsftpd.conf

在vsftpd的配置文件中,配置行采用“配置项=参数”的格式。下面列出最常见的一些配置项及其含义说明。

Vsftpd.conf常见配置项及含义: 匿名用户:

代码语言:javascript复制
anonymous_enable=YES               '是否允许匿名访问'

anon_umask=022                             '设置匿名用户所上传文件的默认权限掩码值'

anon_root=/var/ftp                         '设置匿名用户的FTP根目录'

anon_upload_enable=YES            '是否允许匿名用户上传文件'

anon_mkdir_write_enable=YES '是否允许匿名用户创建目录的写入权限'

anon_other_write_enable=YES '是否允许匿名用户有其他写入权限,如对文件改名、覆盖及删除文件等'

anon_max_rate=0                '限制匿名用户的最大传输速率(0为无限制),单位为字节/秒'

本地用户:

local_enable=YES                              '是否允许本地系统用户访问'

local_umask=022                               '设置本地用户所上传文件的默认权限掩码值'

local_root=/var/ftp                          '设置本地用户FTP根目录(默认为用户的宿主目录)'

chroot_local_user=YES                  ' 是否将FTP本地用户禁锢在宿主目录中'

local_max_rate=0                            ' 限制本地用户的最大传输速率(0为无限制),单位为字节/秒'

全局配置:

listen=YES                                            ' 是否以独立运行的方式监听服务'

listen_address=0.0.0.0                   ' 设置监听FTP服务的IP地址'

listen_port=21                                '    设置监听FTP服务的端口号'

write_enable=YES      '启用任何形式的写入权限(如上传、删除文件等)都需要开启此项'

download_enable=YES                           ' 是否允许下载文件(建立仅限于浏览、上传的FTP服务器时可将其设为NO)'

dirmessage_enable=YES      '用户切换进入目录时显示.message文件(如果存在)的内容'

xferlog_enable=YES                         '启用xferlog日志,默认记录到/var/log/xferlog'

xferlog_std_format=YES              '  启用标准的xferlog日志格式,若禁用此项,将使用vsftpd自己的日志格式'

connect_from_port_20=YES                 '允许服务器主动模式(从20端口建立数据连接)'

pasv_enable=YES                             ' 允许被动模式连接'

pasv_max_port=24600                 '  设置用于被动模式的服务器最大端口号'

pasv_min_port=24500                  '  设置用于被动模式的服务器最小端口号'

pam_service_name=vsftpd                   '设置用于用户认证的PAM文件位置(/etc/pam.d/目录中对应的文件名)'

userlist_enable=YES                       ' 是否启用user_list用户列表文件'

userlist_deny=YES                                   '  是否禁用user_list列表文件中的用户账号'

max_clients=0                                    '最多允许多少个客户端同时连接(0为无限制)'

max_per_ip=0  '对来自同一个IP地址的客户端,最多允许多少个并发连接(0为无限制)'

tcp_wrappers=YES                                    ' 是否启用TCP_Wrappers主机访问控制(TCP Wrappers的应用)'

三 、具体实操配置详解

1 准备环境

CENTOS7——服务机 ,WIN10——客户机 安装核心软件VSFTPD

代码语言:javascript复制
[root@sh network-scripts]# yum install -y vsftpd   安装核心软件
[root@sh network-scripts]# cd /etc/vsftpd/  查看配置文件
[root@sh vsftpd]# ls
ftpusers  user_list  vsftpd.conf  vsftpd_conf_migrate.sh

2 登录连接FTP

代码语言:javascript复制
在win10 设备上查看
C:UsersBIG>ftp 192.168.1.253
连接到 192.168.1.253。
220 (vsFTPd 3.0.2)
200 Always in UTF8 mode.
用户(192.168.1.253:(none)): ftp
331 Please specify the password.
密码:
230 Login successful.
ftp> pwd  // 查看当前路径
257 "/"    // 此意思为FTP的根目录
ftp>
ftp> ls -a
200 PORT command successful. Consider using PASV.
150 Here comes the directory listing.
.
..
pub
226 Directory send OK.
ftp: 收到 15 字节,用时 0.00秒 15000.00千字节/秒。
ftp>
[root@sh vsftpd]# ls /var/ftp
pub
[root@sh vsftpd]# echo "hello,world" > /var/ftp/123.txt
[root@sh vsftpd]# 
代码语言:javascript复制
[root@sh vsftpd]# man vsftpd.conf   查看man 手册看其配置

[root@sh vsftpd]# grep -v "#" /etc/vsftpd/vsftpd.conf 
anonymous_enable=YES
local_enable=YES
write_enable=YES
local_umask=022
anon_upload_enable=YES
anon_mkdir_write_enable=YES
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
anon_other_write_enable=YES

给其增加权限

代码语言:javascript复制
```handlebars
[root@sh var]# chmod 777 ftp
[root@sh var]# ll
total 8
drwxr-xr-x.  2 root root    6 Apr 11  2018 adm
drwxr-xr-x.  7 root root   74 Jun 18 08:19 cache
drwxr-xr-x.  2 root root    6 Nov  4  2018 crash
drwxr-xr-x.  3 root root   34 Jun 18 08:19 db
drwxr-xr-x.  3 root root   18 Jun 18 08:19 empty
drwxrwxrwx.  3 root root   32 Jul 13 05:25 ftp   改为777

再次登录,发现拒绝登录了,因为有保护功能,不允许权限到最大

代码语言:javascript复制
D:>ftp 192.168.1.253
连接到 192.168.1.253。
220 (vsFTPd 3.0.2)
200 Always in UTF8 mode.
用户(192.168.1.253:(none)): ftp
331 Please specify the password.
密码:
500 OOPS: vsftpd: refusing to run with writable root inside chroot()
远程主机关闭连接。

D:>
1
2
3
4
5
6
7
8
9
10
11

但是可以修改FTP子目录的权限

代码语言:javascript复制
[root@sh var]# chmod 755 ftp
[root@sh var]# cd ftp
[root@sh ftp]# ll
total 4
-rw-r--r--. 1 root root 12 Jul 13 05:25 123.txt
drwxr-xr-x. 2 root root  6 Apr  1 00:55 pub
[root@sh ftp]# chomd 777 pub
-bash: chomd: command not found
[root@sh ftp]# chmod 777 pub
[root@sh ftp]# ll
total 4
-rw-r--r--. 1 root root 12 Jul 13 05:25 123.txt
drwxrwxrwx. 2 root root  6 Apr  1 00:55 pub

3 在客户端上传与删除文件操作``

代码语言:javascript复制
00 PORT command successful. Consider using PASV.
150 Here comes the directory listing.
226 Directory send OK.
ftp> pwd
257 "/pub"
ftp> put 123.txt
200 PORT command successful. Consider using PASV.
150 Ok to send data.
226 Transfer complete.
ftp: 发送 12 字节,用时 0.00秒 12000.00千字节/秒。
ftp> ls
200 PORT command successful. Consider using PASV.
150 Here comes the directory listing.
123.txt
226 Directory send OK.
ftp: 收到 12 字节,用时 0.00秒 12000.00千字节/秒。
ftp> deleate 123.txt
无效命令。
ftp> delete 123.txt
250 Delete operation successful.
ftp> ls
200 PORT command successful. Consider using PASV.
150 Here comes the directory listing.
226 Directory send OK.
ftp>
代码语言:javascript复制
D:>ftp 192.168.1.253
连接到 192.168.1.253。
220 (vsFTPd 3.0.2)
200 Always in UTF8 mode.
用户(192.168.1.253:(none)): zhangsan
331 Please specify the password.
密码:
230 Login successful.
ftp> pwd
257 "/home/zhangsan"
ftp> put 123.txt
200 PORT command successful. Consider using PASV.
150 Ok to send data.
226 Transfer complete.
ftp: 发送 12 字节,用时 0.00秒 12000.00千字节/秒。
ftp> ls
200 PORT command successful. Consider using PASV.
150 Here comes the directory listing.
123.txt
226 Directory send OK.
ftp: 收到 12 字节,用时 0.00秒 12000.00千字节/秒。
ftp> cd
但是此时用户可以随时切换目录,有点隐患

修改之后发现登录报错

代码语言:javascript复制
D:>ftp 192.168.1.253
连接到 192.168.1.253。
220 (vsFTPd 3.0.2)
200 Always in UTF8 mode.
用户(192.168.1.253:(none)): zhangsan
331 Please specify the password.
密码:
500 OOPS: vsftpd: refusing to run with writable root inside chroot()
远程主机关闭连接。

一番研究发现这个问题发生是由于下面的更新造成的:

  • Add stronger checks for the configuration error of running with a writeable root directory inside a chroot(). This may bite people who carelessly turned on chroot_local_user but such is life.

从2.3.5之后,vsftpd增强了安全检查,如果用户被限定在了其主目录下,则该用户的主目录不能再具有写权限了!如果检查发现还有写权限,就会报该错误。

要修复这个错误,可以用命令chmod a-w /home/user去除用户主目录的写权限,注意把目录替换成你自己的。或者你可以在vsftpd的配置文件中增加下列两项中的一项: allow_writeable_chroot=YES

这里选择 在配置里面添加参数

代码语言:javascript复制
 allow_writeable_chroot=YES
继续尝试,重要登录成功
D:>ftp 192.168.1.253
连接到 192.168.1.253。
220 (vsFTPd 3.0.2)
200 Always in UTF8 mode.
用户(192.168.1.253:(none)): zhangsan
331 Please specify the password.
密码:
230 Login successful.
ftp> ls
200 PORT command successful. Consider using PASV.
150 Here comes the directory listing.
123.txt
226 Directory send OK.
ftp: 收到 12 字节,用时 0.00秒 12000.00千字节/秒。
ftp> pwd
257 "/"
ftp> cd /etc
550 Failed to change directory.
ftp> ls
200 PORT command successful. Consider using PASV.
150 Here comes the directory listing.
123.txt
226 Directory send OK.
ftp: 收到 12 字节,用时 0.00秒 12000.00千字节/秒。
ftp>
ftp> pwd
257 "/"
ftp>

此时发现,确实切换不了目录了,只能在自己的家目录活动了

5 chroot_local_user与chroot_list_enable详解

很多情况下,我们希望限制ftp用户只能在其主目录下(root dir)下活动,不允许他们跳出主目录之外浏览服务器上的其他目录,这时候我就需要使用到chroot_local_user,chroot_list_enable,chroot_list_file这三个选项了。以下是对三个配置项的解释: chroot_local_user #是否将所有用户限制在主目录,YES为启用 NO禁用.(该项默认值是NO,即在安装vsftpd后不做配置的话,ftp用户是可以向上切换到要目录之外的) chroot_list_enable #是否启动限制用户的名单 YES为启用 NO禁用(包括注释掉也为禁用) chroot_list_file=/etc/vsftpd/chroot_list #是否限制在主目录下的用户名单,至于是限制名单还是排除名单,这取决于chroot_local_user的值,我们可以这样记忆: chroot_local_user总是一个全局性的设定,其为YES时,全部用户被锁定于主目录,其为NO时,全部用户不被锁定于主目录。那么我们势必需要在全局设定下能做出一些“微调”,即,我们总是需要一种“例外机制",所以当chroot_list_enable=YES时,表示我们“需要例外”。而”例外“的含义总是有一个上下文的,即,当”全部用户被锁定于主目录“时(即chroot_local_user=YES),"例外"就是:不被锁定的用户是哪些;当"全部用户不被锁定于主目录"时(即chroot_local_user=NO),“例外”“就是:要被锁定的用户是哪些。这样解释和记忆两者之间的关系就很清晰了!

让我们举个例子: 假设有ftp1, ftp2两个ftp用户, 计划让ftp1用户锁定在主目录下,不允许切换到其他目录, 但是允许ftp2用户自由切换目录,则可以分如下两种方式实现: 方式一: 令:

代码语言:javascript复制
chroot_local_user=YES
chroot_list_enable=YES

/etc/vsftpd/chroot_list名单列表为: ftp2 解释:chroot_local_user=YES将所有用户限定在主目录内,chroot_list_enable=YES表示要启用chroot_list_file, 因为chroot_local_user=YES,即全体用户都被“限定在主目录内”,所以总是作为“例外列表”的chroot_list_file这时列出的是那些“不会被限制在主目录下”的用户。 方式二:

代码语言:javascript复制
chroot_local_user=YES
chroot_list_enable=NO
和
chroot_local_user=NO
chroot_list_enable=NO

当chroot_list_enable=NO时,就不再启用chroot_list_file,此时就是单纯的把全部用户限定或不限定在主目录下了! 补充: 关于chroot_local_user的设置,通常我们倾向于:全局禁止跳出主目录,使用chroot_list添加例外!即:使用Case 1的设置! 匿名用户默认的root是/var/ftp

6 user-list名单

代码语言:javascript复制
[root@sh vsftpd]# echo "zhangsan" >> user_list 
D:>ftp 192.168.1.253
连接到 192.168.1.253。
220 (vsFTPd 3.0.2)
200 Always in UTF8 mode.
用户(192.168.1.253:(none)): zhangsan
530 Permission denied.
登录失败。
ftp>

只有在user_list 名单里的才会生效此时张三又可以登录了

代码语言:javascript复制
D:>ftp 192.168.1.253
连接到 192.168.1.253。
220 (vsFTPd 3.0.2)
200 Always in UTF8 mode.
用户(192.168.1.253:(none)): zhangsan
331 Please specify the password.
密码:
230 Login successful.
ftp>

李四登录不了,因为它不再user_list 里面

代码语言:javascript复制
D:>ftp 192.168.1.253
连接到 192.168.1.253。
220 (vsFTPd 3.0.2)
200 Always in UTF8 mode.
用户(192.168.1.253:(none)): lisi
530 Permission denied.
登录失败。
ftp>

默认也登录不了了

代码语言:javascript复制
D:>ftp 192.168.1.253
连接到 192.168.1.253。
220 (vsFTPd 3.0.2)
200 Always in UTF8 mode.
用户(192.168.1.253:(none)): ftp
530 Permission denied.
登录失败。
ftp>

7 建立虚拟用户账户使用FTP

代码语言:javascript复制
root@sh vsftpd]# vi vuser
[root@sh vsftpd]# ls
ftpusers  user_list  vsftpd.conf  vsftpd_conf_migrate.sh  vuser
代码语言:javascript复制
[root@sh vsftpd]# db_load -T -t hash -f vuser vuser.db 转换成数据库文件
[root@sh vsftpd]# ls
ftpusers  user_list  vsftpd.conf  vsftpd_conf_migrate.sh  vuser  vuser.db

为了安全,不让其他用户查看,修改它们的属性 [

代码语言:javascript复制
root@sh vsftpd]# ll
total 36
-rw-------. 1 root root   125 Apr  1 00:55 ftpusers
-rw-------. 1 root root   370 Jul 13 07:52 user_list
-rw-------. 1 root root  5160 Jul 13 08:05 vsftpd.conf
-rwxr--r--. 1 root root   338 Apr  1 00:55 vsftpd_conf_migrate.sh
-rw-r--r--. 1 root root    23 Jul 13 08:09 vuser
-rw-r--r--. 1 root root 12288 Jul 13 08:11 vuser.db
[root@sh vsftpd]# chmod 600 vuser vuser.db
[root@sh vsftpd]# 
[root@sh vsftpd]# ll
total 36
-rw-------. 1 root root   125 Apr  1 00:55 ftpusers
-rw-------. 1 root root   370 Jul 13 07:52 user_list
-rw-------. 1 root root  5160 Jul 13 08:05 vsftpd.conf
-rwxr--r--. 1 root root   338 Apr  1 00:55 vsftpd_conf_migrate.sh
-rw-------. 1 root root    23 Jul 13 08:09 vuser
-rw-------. 1 root root 12288 Jul 13 08:11 vuser.db

创建一个用户为vuser 指定家目录/ opt/vuser 并不使用shell登录

代码语言:javascript复制
root@sh vsftpd]# useradd -d /opt/vuser -s /sbin/nologin vuser
[root@sh vsftpd]# 
[root@sh vsftpd]# id vuser
uid=1002(vuser) gid=1002(vuser) groups=1002(vuser)

编辑PAM认证模块支持虚拟用户登录

[root@sh vsftpd]# vi /etc/pam.d/vsftpd.vu 此处两个文件vuser并不是普通文件,而是刚才创建的vuser.db数据库文件,此处必须省略不写

代码语言:javascript复制
auth required pam_userdb.so db=/etc/vsftpd/vuser
account required pam_userdb.so db=/etc/vsftpd/vuser

Vi/etc/vsftpd/vsftpd.conf
添加3行参数
guest_enable=YES
guest_username=vuser
pam_service_name=vsftpd.vu  开启虚拟用户,使用PAM认证登录
代码语言:javascript复制
### 3.7.4 在WIN10上查看验证
D:>ftp 192.168.1.253
连接到 192.168.1.253。
220 (vsFTPd 3.0.2)
200 Always in UTF8 mode.
用户(192.168.1.253:(none)): lisa
331 Please specify the password.
密码:
230 Login successful.
ftp> put 45.txt
200 PORT command successful. Consider using PASV.
150 Ok to send data.
226 Transfer complete.
ftp: 发送 13 字节,用时 0.00秒 13000.00千字节/秒。
ftp> bye
代码语言:javascript复制
D:>ftp 192.168.1.253
连接到 192.168.1.253。
220 (vsFTPd 3.0.2)
200 Always in UTF8 mode.
用户(192.168.1.253:(none)): tom
331 Please specify the password.
密码:
230 Login successful.
ftp> put 123.txt
200 PORT command successful. Consider using PASV.
150 Ok to send data.
226 Transfer complete.
ftp: 发送 12 字节,用时 0.00秒 12000.00千字节/秒。
ftp>

[root@sh vsftpd]# cd /opt/vuser/
[root@sh vuser]# ls
代码语言:javascript复制
45.txt
[root@sh vuser]# ll
total 4
-rw-------. 1 vuser vuser 13 Jul 13 11:19 45.txt
[root@sh vuser]# ll
total 8
-rw-------. 1 vuser vuser 12 Jul 13 11:22 123.txt
-rw-------. 1 vuser vuser 13 Jul 13 11:19 45.txt
[root@sh vuser]# 

四 、用centos搭建一个小型的局域网FTP服务器

1 创建虚拟机,设置参数

这里选择虚拟机操作,选择桥接模式,与宿主机保持一个网段,网关相同,dns相同

2、开启相关服务

代码语言:javascript复制
systemctl start  nfs
   systemctl  start       vsftpd
      systemctl start       rpcbind

3、找到FTP 路径,将要共享的文件放到此处。

可采用此方法将windows电脑文件直接拖到此centos虚拟机目录

4、然后局域网的兄弟们就可以在windows系统 浏览器访问FTP了

0 人点赞