一、FTP服务简介

1. FTP服务和FTP协议

FTP服务是Internet上最早应用主机之间进行数据传输的基本服务之一。FTP服务的一个非常重要的特点就是可以独立于平台,也就是说在UNIX、MAC、Windows等操作系统中都可以实现FTP的客户端和服务器。尽管目前已经普遍采用HTTP方式传送文件,但FTP仍然是跨平台直接传送文件的主要方式。

FTP文件传输协议(File Transfer Protocol,FTP)。该协议定义了一个在远程计算机系统和本地计算机系统之间传输文件的一个标准。FTP运行在OSI模型的应用层,并利用传输控制协议TCP在不同的主机之间提供可靠的数据传输。FTP在文件传输中还支持断点续传功能,可以大幅度地减小CPU和网络带宽的开销。


2. FTP的工作原理

与大多数的Internet服务一样,FTP协议也是一个客户机/服务器系统,用户通过一个支持FTP协议的客户机程序,连接到远程主机上的FTP服务器程序,用户通过客户机程序向服务器程序发送命令,服务器程序执行用户所发出的命令,并将结果返回给客户机。


FTP协议模型:

CentOS 7.3 FTP服务器的安装与配置_第1张图片

用户接口(UI):提供了一个用户接口并使用客户端协议解释器的服务;

客户端协议解释器(CPI):向远程服务器协议机发送命令并且驱动客户数据传输过程;

服务端协议解释器(SPI):响应客户协议机发出的命令并驱动服务器端数据传输过程;

客户端数据传输协议(CDTP):负责完成和服务器数据传输过程及客户端本地文件系统通信;

服务端数据传输协议(SDTP):负责完成和客户数据传输过程及服务器端文件系统的通信。


3. FTP的数据传输模式

FTP使用的端口号:

    数据传输端口    20  --用于数据的上传和下载

    命令传输端口    21  --用于ftp命令的传输

FTP的两种模式:

PORT(主动)方式的连接过程是:

           客户端向服务器的FTP端口(默认是21)发送连接请求,服务器接受连接,建立一条命令链路。

           当需要传送数据时,客户端在命令链路上用 PORT命令告诉服务器:“我打开了****端口(大于1024的随机端口),你过来连接我”。

           于是服务器从20端口向客户端的****端口发送连接请求,建立一条数据链路来传送数据。

 

PASV(被动)方式的连接过程是:

           客户端向服务器的FTP端口(默认是21)发送连接请求,服务器接受连接,建立一条命令链路。

           当需要传送数据时,服务器在命令链路上用 PASV命令告诉客户端:“我打开了****端口(大于1024的随机端口),你过来连接我”。

           于是客户端向服务器的****端口发送连接请求,建立一条数据链路来传送数据。

           CentOS 7.3 FTP服务器的安装与配置_第2张图片


主动模式好还是被动模式好?

先假设一种场景:客户端用户安装个人防火墙,但又不懂防火墙的配置,所以防火墙默认配置。

个人防火墙的默认一般只会拒绝进来的包,而不会拒绝你出去的包和你出去再回来的包。

所以上面的主动模式是有可能被拒绝掉的。

主动ftp对ftp服务器的管理有利,但对客户端的管理不利。因为是服务端主动与客户端去建立连接,可能会被客户端的防火墙把来自于服务器的包给阻塞掉。

被动ftp对ftp客户端的管理有利,但对服务端的管理不利。因为客户端主动与服务端去连,可能会被服务端的防火墙给阻塞掉。

折中的方法就是使用被动模式,并指定一个连接过来的端口范围,可以针对这个范围的端口进行一个防火墙的设置。


二、系统环境

系统平台: CentOS 7.3

FTP Server: 192.168.8.88

关闭防火墙

# systemctl stop firewalld  --临时关闭防火墙
# systemctl disable firewalld  --永久关闭防火墙


临时关闭:关闭selinux

# setenforce 0


永久关闭:

# vim /etc/selinux/config
SELINUX=disabled   --将enforcing改为disabled

# reboot  --重启系统永久生效


三、CentOS下的vsftpd服务

在Linux下搭建FTP服务器一般会用VSFTP,全称为“Very Secure FTP Daemon”,是一个以安全为重心的FTP服务器,关于VSFTP的介绍就不多写了,大家可以浏览官方网站http://vsftpd.beasts.org进行了解。

1. 安装vsftpd

# yum -y install vsftpd     --服务端
# yum -y install ftp lftp   --客户端
如果已经安装过了,则显示“无须任何处理”

如果在服务器将三个都安装,那么服务器也可以作为客户端登录本台服务器的FTP。


FTP配置文件主要有下面三个:

  • 主配置文件:/etc/vsftpd/vsftpd.conf

  • 用户访问控制配置文件:/etc/vsftpd/{ftpusers, user_list}


FTP的家目录:/var/ftp ,也就是存放上传文件的目录

# systemctl start vsftpd.service   --启动服务
# systemctl enable vsftpd.service  --设为开机自启动

 image.png

# netstat -ntl | grep :21  --现在是只能看到监听21端口

image.png

# lsof -i:21   --查看监听21端口

FTP的工作模式解析为:

vsftpd默认的工作模式是被动模式。


FTP的匿名用户

ftp                           --系统用户,/etc/passwd里有此用户,默认进入ftp用户的家目录

anonymous            --系统中无此用户(匿名),默认是可以进入/var/ftp的


2. CentOS 7中vsftpd默认的主配置文件

查看vsftpd的默认主配置文件

# cat -n /etc/vsftpd/vsftpd.conf | grep -v "#"     --grep -v ^# 代表是过滤以#号开头的行


 12 anonymous_enable=YES            # 是否允许匿名用户登陆,yes是允许
 16 local_enable=YES                # 允许本地用户登陆
 19 write_enable=YES                # 允许本地用户写权限
 23 local_umask=022                 # 本地用户上传或创建文件时的权限
 29 # anon_upload_enable=YES        # 默认是注释的,意为允许匿名用户上传文件
 33 # anon_mkdir_write_enable=YES   # 默认是注释的,意为允许匿名用户创建文件
 37 dirmessage_enable=YES           # 文件的描述
 40 xferlog_enable=YES              # 开启日志(/var/log/xferlog),只上传和下载的记录
 43 connect_from_port_20=YES        # 是否允许开启主动模式,通过20端口传输数据
 57 xferlog_std_format=YES          # 为yes的话代表创建一个新的日志文件,为no的话,日志放到/var/log/vsftpd.log文件里
114 listen=NO                       # 独立模式,为yes代表是用vsftpd本身脚本启动,为no代表要以xinetd守护进程启动
123 listen_ipv6=YES                 # 若要打开独立模式,需要把此项关闭,这是CentOS 7 和 6 的区别
125 pam_service_name=vsftpd         # 支持模块的植入
126 userlist_enable=YES             # 打开用户列表
127 tcp_wrappers=YES                # 通过TCP把数据打包再传输

CentOS 7.3 FTP服务器的安装与配置_第3张图片


3. 登录FTP服务器

# ftp 192.168.8.88  --也可以自己做客户端,连接自己的服务端

CentOS 7.3 FTP服务器的安装与配置_第4张图片

# ftp 192.168.8.88   --也可以自己做客户端,连接自己的服务端
Connected to 192.168.8.88 (192.168.8.88).
220 (vsFTPd 3.0.2)
Name (192.168.8.88:root): ftp   --输入匿名用户ftp
331 Please specify the password.
Password:       --它的密码为空,直接敲回车
230 Login successful.
Remote system type is UNIX.
Using binary mode to transfer files.
ftp> ?    --使用?号可以查看能使用哪些命令
Commands may be abbreviated.  Commands are:
!        debug        mdir      sendport  site
$        dir          mget      put       size
account  disconnect   mkdir     pwd       status
append   exit         mls       quit      struct
ascii    form         mode      quote     system
bell     get          modtime   recv      sunique
binary   glob         mput      reget     tenex
bye      hash         newer     rstatus   tick
case     help         nmap      rhelp     trace
cd       idle         nlist     rename    type
cdup     image        ntrans    reset     user
chmod    lcd          open      restart   umask
close    ls           prompt    rmdir     rerbose
cr       macdef       passive   runique   ?
delete   mdelete      proxy     send
ftp> help passive    --help+命令可以查看命令的帮助
passive   	enter passive transfer mode
ftp> passive   --使用passive命令切换模式
Passive mode off.
ftp> passive   --这时表示被动模式关闭
Passive mode on.   --这时表示被动模式开启
ftp> ls   --建立数据链路(列出当前ftp家目录中的内容)
227 Entering Passive Mode (192,168,8,88,128,190).
150 Here comes the directory listing.
drwxr-xr-x   2 0     0     6 Aug 03 06:10 pub
226 Directory send OK.
ftp> cd pub    --切换路径
ftp> ls         --建立数据链路(列出当前ftp家目录中的pub内容)
200 PORT command successful. Consider using PASV.
150 Here comes the directory listing.
-rw-r--r--   1 0     0      0 Dec 17 15:31 abc.txt
226 Directory send OK.
ftp> get abc.txt    --get是下载文件命令,下载的文件在当前登录ftp的目录里
local: abc.txt remote: abc.txt
200 PORT command successful. Consider using PASV.
150 Opening BINARY mode data connection for abc.txt (0 bytes).
226 Transfer complete.
ftp> put text.txt      --put是上传文件文件命令
local: text.txt remote: text.txt
200 PORT command successful. Consider using PASV.
550 Permission denied.
--这时候使用下载命令会报权限拒绝,因为默认匿名用户是没有上传权限的。(通过配置文件可以修改权限)


四、配置vsftpd服务器

配置实例:

例1:不允许匿名用户登录

# vim /etc/vsftpd/vsftpd.conf
12 anonymous_enable=NO  --改为NO


匿名用户有两个:ftp                     密码为任意值或空

                             anonymous      密码为任意值或空

# systemctl restart vsftpd.service --修改完成以后需要重启服务


使用匿名用户登录测试,发现登录不了

#  ftp  192.168.8.88
Connected to 192.168.8.88 (192.168.8.88).
220 (vsFTPd 3.0.2)
Name (192.168.8.88:root): ftp      --输入匿名用户ftp
331 Please specify the password.
Password:             --它的密码为空,直接敲回车
530 Login incorrect.
Login failed.    --登陆失败
ftp>


例2:匿名用户的下载

# vim /etc/vsftpd/vsftpd.conf
anonymous_enable=YES  --改回yes


默认使用匿名用户登录的服务端的/var/ftp目录下,因为/etc/passwd里的ftp用户的家目录就是/var/ftp,所以其实就是登录到它的家目录。

# systemctl restart vsftpd.service  --修改完成以后需要重启服务


匿名用户默认是可以登录,也可以下载,因为/var/ftp是755权限

ftp> get abc.txt


能读表示能下载,能写表示能上传

chmod 750 /var/ftp   后使用匿名用户登录,ls都看不到文件列表,也下载不了。

chmod 754 /var/ftp   后使用匿名用户登录,ls都看不到文件列表,也下载不了,因为不能cd到/var/ftp。

chmod 751 /var/ftp   后使用匿名用户登录,ls都看不到文件列表,但是可以下载;因为它能cd到/var/ftp,ls虽然看不到,但get文件名,是可以下载下来的。


还要注意文件的权限对其是否能被下载也有关系,要登录用户对其有r权限,才可以下载。


任何服务的权限控制是要经过两道门的,一个是服务本身的权限控制,一个是操作系统的权限控制,也就是说两个都允许,才有权限;如果有防火墙的话,则还要考虑防火墙的控制。


这里可以总结一下:匿名用户对登录的目录有rx权限,对目录里的文件有r权限就可以下载


例3:匿名用户的上传

默认是不允许匿名用户上传的

#  ftp  192.168.8.88Connected to 192.168.8.88 (192.168.8.88).
220 (vsFTPd 3.0.2)
Name (192.168.8.88:root): ftp      --输入匿名用户ftp
331 Please specify the password.
Password:            --它的密码为空,直接敲回车
230 Login successful.
Remote system type is UNIX.
Using binary mode to transfer files.

ftp> put  a.txt           --上传a.txt文件
local: a.txt remote: a.txt
227 Entering Passive Mode (192,168,30,10,32,237).
550 Permission denied.             --权限拒绝,因为/var/ftp不允许ftp用户写
ftp> exit


如果你把/var/ftp被改为777后,发现登录不了,所以还得改回去755。

因为ftp服务本身不允许系统权限给匿名写,所以解决方法是在登录目录下创建一个用于上传的目录,给一个写的权限。

# chmod 777 /var/ftp/pub   --把pub改为可写,用于上传文件


如果你现在登录ftp服务之后,上传文件,但还是权限拒绝。

因为系统权限允许了,但是服务本身的权限还是不允许,所以要去改服务的配置参数。

# vim /etc/vsftpd/vsftpd.conf
anonymous_enable=YES
anon_upload_enable=YES    --允许匿名用户上传文件,这行默认是注释掉的,要把#去掉
anon_mkdir_write_enable=YES    --允许匿名用户创建目录,这行默认是注释掉的,要把#去掉
 
# systemctl restart vsftpd.service  --重启服务


这时候上传就可以成功了!

ftp> put  a.txt                               --上传a.txt文件
local: a.txt remote: a.txt
227 Entering Passive Mode (192,168,30,10,177,88).
150 Ok to send data.
226 Transfer complete.

ftp> mkdir bb                             --也可以创建目录
257 "/pub/bb" created
ftp> rename a.txt 3.txt  --不能重命名
550 Permission denied.
ftp> delete a.txt     --不能删除
550 Permission denied.


这里可以总结一下:匿名用户只能对登录目录内的子目录里面进行上传,并且对这个子目录要有w权限,还要有anon_upload_enable=YES和anon_mkdir_write_enable=YES的支持就可以上传了。


例4:允许匿名下载刚上传的文件

为什么默认不允许下载自己上传的文件?

文件上传之后权限自动改为600,

而默认情况下anon_world_readable_only=YES,规定了匿名用户只能下载world readable的文件(也就是others里有r位的)

对于600权限文件是没有权限下载

-rw-------    1 14       50            845 Jul 19 06:12 fstab      --不可以上传

-rw-r--r--    1 0        0            1666 Jul 19 06:13 inittab     --可以上传


方法一:让匿名帐号上传的文件权限自动更改为644的权限

# man vsftpd.conf       --查看帮助手册
# vim /etc/vsftpd/vsftpd.conf
 anon_umask=022

# systemctl restart vsftpd.service   --重启服务


如果要文件上传后的权限是444 ,umask怎么设定?


anon_umask=222

umask

目录

文件

0

7

6

1

6

6

2

5

4

3

4

4

4

3

2

5

2

2

6

1

0

7

0

0


方法二:允许匿名帐号下载不是所有人都可以读的文件

# vim /etc/vsftpd/vsftpd.conf anon_world_readable_only=NO  --默认是yes,只允许下载所有人都可以读的文件

# systemctl restart vsftpd.service     --重启服务


例5:关于普通用户(系统的普通用户)的登录

普通用户默认是允许登录ftp的,并且是登录到自己的家目录,登录密码也就是普通用户登录系统的密码。

禁止普通用户登录

方法一:

# vim /etc/vsftpd/vsftpd.conf local_enable=NO  --建议使用服务的参数去禁止,但是这里会把所有的普通用户给禁止掉,要实现特定的用户的控制

# systemctl restart vsftpd.service             --重启服务


方法二:/etc/passwd 里把普通用户最后一列,改为/bin/false

 提示:

  • /bin/bash         --可以登录系统,也可以登录ftp,也可以收邮件

  • /sbin/nologin   --不可以登录系统,但可以登录ftp,也可以收邮件

  • /bin/false         --又不可以登录系统,又不可以登录ftp,可以收邮件


例6:使用用户列表来控制(建议使用这种方式)

方法一:(黑名单)

# vim /etc/vsftpd/vsftpd.conf
userlist_enable=yes   --打开用户列表功能,默认就是打开的
userlist_deny=YES     --加上这句,启用黑名单
 
# vim /etc/vsftpd/user_list   --文件最后加上要禁止的用户,一个用户写一行

# systemctl restart vsftpd.service  --重启服务

方法二:(白名单)

# vim /etc/vsftpd/vsftpd.conf
userlist_enable=yes
userlist_deny=NO         --加上这句,启用白名单

# systemctl restart vsftpd.service  --重启服务


上面的主要要注意的是:

    userlist_enable      --指定的是用户列表功能是否有效

    userlit_deny          --指定的是用户列表是允许还是拒绝


如果允许root用户登录ftp,则要/etc/vsftpd/user_list和/etc/vsftpd/ftpusers都不要禁用root登录ftp就可以了。但为了安全,不会这样去开放root用户的。


例7:FTP的日志

# vim /etc/vsftpd/vsftpd.conf 
 xferlog_enable=YES             --打开日志记录功能
 xferlog_std_format=YES         --使用xferlog,而不是vsftpd.log
 xferlog_file=/var/log/xferlog  --打开注释,指定日志文件路径

# systemctl restart vsftpd.service  --重启服务

# cat /var/log/xferlog  --查看日志,这里面只记录上传和下载的信息


例8:下载限速

# vim /etc/vsftpd/vsftpd.conf
anon_max_rate=10000   --anon_max_rate匿名用户下载传输率,下载传输率为 10k
local_max_rate=10000  --local_max_rate本地用户下载传输率,下载传输率为 10k

# systemctl restart vsftpd.service  --重启服务


测试:使用一个普通用户登录,去下载test.img文件做测试

# dd if=/dev/zero of=/var/ftp/pub/test.img bs=1M count=1000


新打开一个终端,测试限速下载,如果要重复输入一个命令去查看状态的话,可以在前面加 watch(默认是每 2 秒查看一次,但不支持 ll 这种别名,换成 ls -l 就可以)

# watch ls -lh


关于限制连接数的 max_clients      --ftp 服务允许的总的连接数

# vim /etc/vsftpd/vsftpd.conf
 max_per_ip=2     --指定单个客户端的最大连接数为 2
 max_clients=5    --限制客户端最大连接数为 5

# systemctl restart vsftpd.service   --重启服务


测试:使用一个客户端去连接 ftp 服务器,第三次连接就会报下面的错误

# ftp 192.168.8.88
Connected to 192.168.5.118 (192.168.5.118).
421 There are too many connections from your internet address